|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang='en'> |
| 3 | +<head> |
| 4 | +<meta charset='utf-8'> |
| 5 | +<meta content='IE=edge' http-equiv='X-UA-Compatible'> |
| 6 | +<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> |
| 7 | +<meta content='276VSYOko8B8vIu1i8i5qbj7_ql5PXo0dU69XQy-SL' name='globalsign-domain-verification'> |
| 8 | +<title> |
| 9 | +Bundler: Bundler v2.3: Locking the version of Bundler itself |
| 10 | +</title> |
| 11 | + |
| 12 | +<script src="/application.min.js"></script> |
| 13 | +<link href="/application.css" rel="stylesheet" /> |
| 14 | +<link href='/images/apple-touch-icon.png' rel='apple-touch-icon' sizes='180x180'> |
| 15 | +<link href='/images/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'> |
| 16 | +<link href='/images/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'> |
| 17 | +<link href='/manifest.json' rel='manifest'> |
| 18 | +<link color='#50bced' href='/images/safari-pinned-tab.svg' rel='mask-icon'> |
| 19 | +<meta content='bundler.io' name='apple-mobile-web-app-title'> |
| 20 | +<meta content='bundler.io' name='application-name'> |
| 21 | +<meta content='#ffffff' name='theme-color'> |
| 22 | + |
| 23 | +<link rel="alternate" type="application/atom+xml" title="Atom Feed" href="/blog/feed.xml" /> |
| 24 | + |
| 25 | +</head> |
| 26 | +<body class=''> |
| 27 | +<nav class='navbar navbar-default'> |
| 28 | +<div class='container'> |
| 29 | +<div class='navbar-header'> |
| 30 | +<button aria-expanded='false' class='navbar-toggle collapsed' data-target='#bs-navbar-collapse' data-toggle='collapse' type='button'> |
| 31 | +<span class='sr-only'>Toggle navigation</span> |
| 32 | +<span class='icon-bar'></span> |
| 33 | +<span class='icon-bar'></span> |
| 34 | +<span class='icon-bar'></span> |
| 35 | +</button> |
| 36 | +<b><a href="/" class="navbar-brand">Bundler</a></b> |
| 37 | +</div> |
| 38 | +<div class='collapse navbar-collapse' id='bs-navbar-collapse'> |
| 39 | +<ul class='nav navbar-nav navbar-right'> |
| 40 | +<li> |
| 41 | +<div class='search-wrapper'> |
| 42 | +<div class='form-group has-feedback'> |
| 43 | +<i class='glyphicon glyphicon-search form-control-feedback'></i> |
| 44 | +<input class='input-search' id='input-search' placeholder='Type to search...' type='text'> |
| 45 | +</div> |
| 46 | +</div> |
| 47 | +</li> |
| 48 | +<li><a href="/docs.html">Docs</a></li> |
| 49 | +<li><a href="/contributors.html">Team</a></li> |
| 50 | +<li><a href="/blog">Blog</a></li> |
| 51 | +<li><a href="https://github.com/rubygems/rubygems/tree/master/bundler" target="_blank" rel="noopener noreferrer">Repository</a></li> |
| 52 | +</ul> |
| 53 | +</div> |
| 54 | +</div> |
| 55 | +</nav> |
| 56 | + |
| 57 | +<div class='main-wrapper'> |
| 58 | +<div class='row bg-light-blue header'> |
| 59 | +<img src=" /images/blog_header_transparent_bg.png" srcset=" /images/blog_header_transparent_bg.png 1x, /images/[email protected] 2x, /images/[email protected] 3x" class=" img-responsive header-padding" style=" max-width: 350px; padding-top: 5px; width: 64%;" alt="" /> |
| 60 | +</div> |
| 61 | + |
| 62 | +<div class='container'> |
| 63 | +<div class='row'> |
| 64 | +<div class='col-md-12 col-lg-10 col-lg-offset-1'> |
| 65 | +<div class='contents blog'> |
| 66 | +<h2 class='title'> |
| 67 | +<a href="/blog/2022/01/23/bundler-v2-3.html">Bundler v2.3: Locking the version of Bundler itself</a> |
| 68 | +</h2> |
| 69 | +<div class='subtitle'> |
| 70 | +by |
| 71 | +<a href="https://github.com/deivid-rodriguez/" target="_blank">David Rodríguez</a> |
| 72 | +on |
| 73 | +<time> |
| 74 | +Jan 23 2022 |
| 75 | +</time> |
| 76 | +</div> |
| 77 | +<div class='blog-content'> |
| 78 | +<p>2021 saw a fair amount of development in the RubyGems & Bundler repositories. We |
| 79 | +tried to release more often than ever to catch and fix bugs and distribute our |
| 80 | +improvements as early as possible to our users. That has led to 33 patch-level versions |
| 81 | +in the Bundler 2.x series released about a year ago.</p> |
| 82 | + |
| 83 | +<p>Our goal for Bundler 2.3 was to implement a long-wanted feature of being able to |
| 84 | +fully control the version of Bundler itself an application runs. There’s a long |
| 85 | +story with this feature, because it was shipped a few years ago in a manner that |
| 86 | +was too strict and ended up causing more harm than good, so had to be partially |
| 87 | +reverted.</p> |
| 88 | + |
| 89 | +<h2 id="so-how-did-things-work-before-bundler-23">So, how did things work before Bundler 2.3?</h2> |
| 90 | + |
| 91 | +<p>Up until now, RubyGems would try to activate the version of Bundler recorded in |
| 92 | +the <code>Gemfile.lock</code> file if already installed, and would fall back to the |
| 93 | +highest version installed otherwise. That’s better than nothing, but it did not |
| 94 | +ensure the exact version in the lockfile was always used, which led to |
| 95 | +workarounds like <a href="https://bundler.io/blog/2019/05/14/solutions-for-cant-find-gem-bundler-with-executable-bundle.html">manually parsing the lockfile and then installing that |
| 96 | +version</a>.</p> |
| 97 | + |
| 98 | +<h2 id="and-how-do-they-work-now">And how do they work now?</h2> |
| 99 | + |
| 100 | +<p>In Bundler 2.3 and up (if you also have RubyGems 3.3 or higher), running |
| 101 | +<code>bundle install</code> will use the exact version from the BUNDLED WITH section of |
| 102 | +the lockfile. If that version is not installed before you run <code>bundle
install</code>, the running version of Bundler will install the locked version, and |
| 103 | +then run your original command using the newly-installed locked version.</p> |
| 104 | + |
| 105 | +<p>So, if you have a lockfile ending with</p> |
| 106 | + |
| 107 | +<div class="highlight"><pre class="highlight plaintext"><code>BUNDLED WITH
 2.2.33
</code></pre></div> |
| 108 | +<p>and you only have Bundler 2.3.5 installed, you’ll see the following output when |
| 109 | +running <code>bundle install</code>.</p> |
| 110 | + |
| 111 | +<div class="highlight"><pre class="highlight plaintext"><code>$ bundle install
Bundler 2.3.5 is running, but your lockfile was generated with 2.2.33. Installing Bundler 2.2.33 and restarting using that version.
Fetching gem metadata from https://rubygems.org/.
Fetching bundler 2.2.33
Installing bundler 2.2.33
...
</code></pre></div> |
| 112 | +<p>After that all your commands will automatically use Bundler 2.2.33, as specified |
| 113 | +by your lockfile. If you want to upgrade the Bundler version used by your |
| 114 | +application, you can run <code>bundle update --bundler</code>, and your lockfile will be |
| 115 | +regenerated using the latest version. From that moment, all users of the |
| 116 | +lockfile will automatically pick up the new version, no matter whether they have |
| 117 | +a newer or older version installed instead.</p> |
| 118 | + |
| 119 | +<p>But..</p> |
| 120 | + |
| 121 | +<h2 id="why-are-we-doing-this">Why are we doing this?</h2> |
| 122 | + |
| 123 | +<p>Being able to lock the version of Bundler itself, just like Bundler is able to |
| 124 | +lock other dependencies, has been a goal of the Bundler team for years. There are |
| 125 | +a number of benefits of locking your dependencies, like avoiding dependency |
| 126 | +nightmares where your application breaks due to third party releases, or |
| 127 | +avoiding “works on my machine” issues. Bundler has a ton of features and edge |
| 128 | +cases, and</p> |
| 129 | + |
| 130 | +<ul> |
| 131 | + <li> |
| 132 | + <p>We sometimes introduce regressions when trying to improve things. Locking the |
| 133 | +version of Bundler prevents those issues from hitting you.</p> |
| 134 | + </li> |
| 135 | + <li> |
| 136 | + <p>Once in a while we need to put a security fix out there. Being able to lock |
| 137 | +the Bundler version allows you to ensure that every user of your application |
| 138 | +gets a secure version of Bundler.</p> |
| 139 | + </li> |
| 140 | + <li> |
| 141 | + <p>Occasionally, you might want to use a new feature of the Bundler DSL in your |
| 142 | +Gemfile. However, old versions of Bundler don’t understand this feature and |
| 143 | +you don’t want to suddenly break things for the users of yours that use those |
| 144 | +old versions. With version locking this is no longer a concern. Bundler is now |
| 145 | +able to upgrade itself to the version that your application understands.</p> |
| 146 | + </li> |
| 147 | +</ul> |
| 148 | + |
| 149 | +<p>All in all, we aim to provide a less surprising, less error prone and more |
| 150 | +consistent experience when using Bundler, and let each application be in control |
| 151 | +of the version that they use, and the moment that they upgrade.</p> |
| 152 | + |
| 153 | +<h1 id="whats-coming-next">What’s coming next?</h1> |
| 154 | + |
| 155 | +<p>Future enhancements to this feature might include:</p> |
| 156 | + |
| 157 | +<ul> |
| 158 | + <li>Full support for <code>gem "bundler", "<arbitrary_requirement>"</code> in <code>Gemfile</code>.</li> |
| 159 | + <li>Automatic update of Bundler when running <code>bundle install</code> without a lockfile.</li> |
| 160 | + <li>Automatic update of Bundler when running <code>bundle update</code>.</li> |
| 161 | +</ul> |
| 162 | + |
| 163 | +<p>In other words, our end goal is to be able to treat Bundler just like any other |
| 164 | +dependency of your application.</p> |
| 165 | + |
| 166 | +</div> |
| 167 | +</div> |
| 168 | +</div> |
| 169 | +</div> |
| 170 | +</div> |
| 171 | + |
| 172 | + |
| 173 | +</div> |
| 174 | +<div class='footer'> |
| 175 | +<div class='row'> |
| 176 | +<div class='container text-center'> |
| 177 | +<ul class='nav navbar-nav'> |
| 178 | +<li><a href="/docs.html">Docs</a></li> |
| 179 | +<li><a href="/contributors.html">Team</a></li> |
| 180 | +<li><a href="/blog">Blog</a></li> |
| 181 | +<li><a href="https://github.com/rubygems/rubygems/tree/master/bundler">Repository</a></li> |
| 182 | +</ul> |
| 183 | +</div> |
| 184 | +</div> |
| 185 | + |
| 186 | +</div> |
| 187 | +</body> |
| 188 | +</html> |
0 commit comments