Bundler Introduction20:32 with Jason Seifer
Bundler is the standard application dependency manager for Ruby. In this workshop, you'll learn what problems Bundler solves, how it works, how to use it in your own projects, and more.
[SOUND] So in this workshop we're going to be taking a look at Bundler. 0:00 Now, Bundler is going to help you manage different dependencies for 0:08 your Ruby project. 0:14 Now, these dependencies are going to be your Ruby gems, and Ruby gem versions. 0:16 If you want to see a little bit more about why Bundler exists, 0:22 you can click on the why Bundler exists button over on the Bundler site. 0:25 Now you can see Bundler let's you declare all of your application dependencies 0:32 in a file at the root of your application, and this is called the gem file. 0:36 You need to specify a source where you'll be getting your gems. 0:41 More often than not, this is going to be ruby gems, however, 0:45 there are services that allow you to define different sources, and 0:49 you can even run your own sources. 0:53 After that, you specify the different gems and 0:56 versions of your application's dependencies. 0:59 Now why do we need to do this? 1:03 Well, different gems depend on different versions of other gems and 1:06 you might have more than one gem installed. 1:11 If I go over to my terminal here and 1:14 I do gem list, you can see I have a ton of different gems in here. 1:17 The gems are stated on the left side here and 1:23 then in parentheses you'll see the different versions. 1:25 Now depending on the different version of a gem, and it's dependencies, 1:29 it can be quite cumbersome to make sure that you have the right one installed and 1:34 it's not going to conflict with another project on your system. 1:38 For example, you may have a Rails project that 1:42 depends on an old version of a Gem and one that depends on a new one. 1:46 And there could be a little bit of trouble if you have both installed. 1:51 So what Bundler will do is declare your Gem environment 1:57 to be separate from the rest of your Gems and 2:02 only load the ones inside and specified in the Gemfile. 2:05 Now the Gemfile, you'll notice, has these dependencies specified in a certain way. 2:12 So we're using the Rails gem and we're using this particular version of it. 2:18 Now, the way that these are specified, 2:24 is using something called semantic versioning. 2:27 Now, semantic versioning, you can find out, at semver.org. 2:31 And it's very, very simple. 2:37 Each version of something has a major, minor, and patch version. 2:39 The major version where you make incompatible API changes. 2:45 So let's say you've coded a gem, and 2:50 the gem has a certain method that you call quite a bit. 2:53 Well, if you were creating a new major version, you can change the method name. 2:57 However, in a minor version, 3:02 you can only add functionality in a backwards-compatible manner, and 3:04 the patch version allows you to make backwards-compatible bug fixes. 3:09 So, if there's an error in your gem, 3:14 a new release will be specified with a patch that fixes that particular error. 3:16 Now the way these are specified in Bundler is as follows. 3:22 If you have a particular gem you can do a comma and then specify an exact version. 3:27 If an exact version of a gem is specified, 3:34 then that is what will be used in the project. 3:38 If no version is specified, the latest version available will be used. 3:40 Now, this can be any particular version on the system. 3:46 If it's not installed it will be fetched from whatever sources are available. 3:50 And then finally, there's this little tilde and greater than sign, 3:55 which specifies that it's using the same major and minor version. 4:01 So a version of nokogiri that's greater than or equal to the 6.1, 4:07 but less than 1.7.0. 4:11 That means that only those patches can be used. 4:15 Once all of the gems are specified, 4:21 then you need to run the command bundle install. 4:23 And that will install the different versions of the gems. 4:28 When you create a new Ruby on Rails project, bundler is run automatically. 4:32 So, let's go ahead and do that right now. 4:38 I'm going to clear my screen and write rails new bundler_example. 4:39 And this will use the latest version of Ruby on Rails on my system, 4:43 generate a new Rails application. 4:49 And then while it's doing that, you'll see on the bottom here it runs bundle install. 4:51 That will go out and 4:56 fetch the different versions that are specified by rails in the default gemfile. 4:58 So then if we go in there, we can open this up and 5:04 see exactly what has been created. 5:08 Now if I open up this gem file, we can see how 5:14 Bundler has specified everything in here for the default rails gem file. 5:21 We're using a rails gem at this particular version, any version of SQL Lite, 5:27 any version of SAS Rails that is at least 5.0 or above and less than 5.1. 5:31 Now here's a difference in text we haven't seen yet, 5:40 which is using a gem that is greater than or 5:45 equal to this specific version, which is 1.3.0. 5:48 Now this is going to be different when we're using the Tilt syntax in that if 5:53 it's greater than 1.3, it can be 1.4, it can be 2.0.0, it could be anything. 5:58 And we'll use that particular gem. 6:05 Now here jquery-rails, no particular version is specified, so 6:09 we'll use the latest one of that as well as Turbolinks. 6:13 Now here's something that we haven't seen just yet. 6:18 We've got this particular gem sdoc, which is specified as any 6:21 version greater than 0.4.0 and less than 0.5.0. 6:26 And this is specified with a group key and the group is doc. 6:32 Now, different groups can be used in Bundler. 6:38 Frequently in a rails application, you'll see groups for 6:41 development, test, production and all groups. 6:45 There are two different ways that you can specify a group. 6:50 You can use this group key in the jam hash command, or if we scroll down, 6:54 you can use the group method name and then the different groups that these belong to. 7:01 So, in the development and test groups, we'll have these gems available. 7:08 If we're in the production group, these gems will not be available. 7:14 Now, let's go ahead and see how this works. 7:20 I'm gonna clear my screen here. 7:22 And if we want to install the gems we run the bundle install command. 7:24 That will go out and fetch the gems, 7:29 if we don't have any particular versions of them installed on our machine. 7:32 Bundle install is a very interesting command. 7:37 We can click learn more and see that it supports. 7:43 Different options. 7:47 We can give it a bin stubs option which will generate different binaries for 7:48 the gems specified in your application. 7:54 Now here, let's go ahead and see how that looks. 7:59 If I added the different gem, and let's go ahead 8:02 to Rubygems.org and search for rspec-rails. 8:08 You'll see that that version is 3.3.3. 8:13 So if I were to specify that in my gem file, 8:20 then return to my command prompt and do bundle install, 8:24 we'll see that it's fetching the different gem metadata for Rubygems.org, 8:28 and now this bundle install is taking a little bit longer than it was before. 8:35 And we'll see that it installed different gems. 8:42 We installed rspec-rails which depends on these specific gems, 8:47 rspec-support, rspec-core, 8:52 rspec-expectations, rspec-mocks, and rspec-rails. 8:55 We now have different gems installed in our project with these different versions. 9:00 So let's talk for a moment about that bin stubs command. 9:06 If we wanted to execute something within the context of the bundle, 9:10 we would need to use the command bundle exec. 9:14 So, if we typed bundle exec rspec, 9:18 this is going to fail because I haven't installed it yet. 9:21 No examples found. 9:25 In fact, what we need to do is say bundle exec rails generate rspec. 9:28 Oh. 9:36 Let's say bundle rails generate --help to see what installers we have. 9:38 Let's just generate an rspec install. 9:44 There it is. 9:47 Here we go. 9:54 Forgot the rails command here. 9:56 Okay, these specific files were created. 10:03 You'll notice that I have to type bundle exact to get this to execute within 10:08 the context of the gem file and in the context of Bundler. 10:13 Bundler supports something called bin stubs, which is going to 10:18 generate a binary of this, so that I don't have to type bundle exec all the time. 10:21 And that can be done by typing bundle binstubs 10:26 and the name of the gem, which in this case is rspec-core. 10:33 Now, if I look inside of the bin directory, 10:39 I have this rspec command that was generated by Bundler. 10:43 So now instead of typing bundle exec rspec, 10:49 I can type bin/rspec, 10:54 and that will run everything within the context of the gem file. 10:58 Something else that's neat that we can do is do a bundle install and 11:03 tell Bundler the path to use. 11:08 Now, if we were deploying an application with Bundler, 11:11 it would install with the default tuned for deployment and CI environments. 11:14 Well, what exactly does that mean? 11:19 Well, if we're doing a deploy of an application, 11:22 we wanna have all of its dependencies in our application. 11:25 We don't want it going out to RubyGems to fetch them. 11:28 They should be available in our application. 11:31 So to do that, we can specify a path, and 11:34 if we look at this path, we specify a different path than the system default, 11:39 which is either $BUNDLE_PATH or $GEM_HOME. 11:44 So if I look in the vendor directory, we have assets. 11:48 But, if I do bundle install and give it a path of vendor and 11:55 bundle, it will go out and install all of these gems if they're 12:01 not installed already, just like the regular install command does. 12:06 However, this time, they'll be saved to the path of vendor/bundle. 12:10 And we'll see all of the different dependencies in this application will be 12:16 installed, and you'll notice that there is now a bundle directory, and 12:20 this will mimic the ruby gem directory 12:27 layout inside of the vendor bundle directory. 12:33 So we can see all these different gems are now kept inside of our application. 12:38 And this will take a few minutes, 12:46 depending on the size of your application, and its dependencies. 12:47 Now, you might be wondering how Bundler keeps track 12:52 of all of the different dependencies. 12:55 Those are placed inside of this file, gemfile.lock. 12:57 Now, if we look inside of this gemfile.lock, 13:05 we'll see different versions of gems that are installed. 13:09 Right here, actionmailer version 4.2.3 depends on these different gems below it, 13:13 actionpack, actionview, activejob, mail, rains-dom-testing. 13:21 And, using the syntax, 13:27 we also see the different versions that are specified in parentheses afterwards. 13:29 Now it's going to go through and create this dependency graph for 13:36 every gem in our gem file and their dependent gems as well. 13:40 By doing this, Bundler will have an overarching view of 13:46 everything that's needed in the application. 13:49 So we can see turbolinks depends on coffee-rails, any version. 13:53 And it will say the platforms, which is ruby. 13:59 Now, there are different versions of ruby install available. 14:01 It could say something like jruby or 14:05 any of the alternate ruby implementations that there are. 14:08 For the most part, you will not need to mess with this gemfile.lock. 14:12 In fact, you should leave it alone, never touch it, and 14:18 just let Bundler manage it for you. 14:21 If you ever get into a situation where you have modified the gemfile.lock, 14:24 something is probably wrong. 14:30 It may be safer to delete your gemfile.lock and 14:32 regenerate it by doing bundle install. 14:35 So we can see now that all of these gems are installed, 14:40 they are now installed into vendor/bundle. 14:44 13 Gemfile dependencies, 59 gems installed. 14:47 Now should your gems become out of date, one other thing that you can do is update 14:54 your gems, so let's say that one of these gems had an update to it. 14:59 We can run the bundle update command, and that will go out 15:05 and check to see if any new versions of any of the gems are installed. 15:11 And then it will fetch them and update the vendor bundle. 15:16 Now, as we're watching this, we'll see it's checking the gem metadata. 15:22 If something is updated, it will be shown in green rather than the normal dark text. 15:26 And we can see that so 15:35 far it doesn't look like any updates were needed in this bundle. 15:36 Now, when we do the deployment option, 15:44 this will automatically be installed into the vendor bundle directory. 15:46 And there's pretty much no need to modify that for 15:53 deployment unless it depends on the system that you're using. 15:55 Now, without is also an interesting command. 15:59 We'll see that we have different groups available in this Gemfile. 16:04 Here we have the development and test group. 16:09 If we used the without keyword, and we can say without the test environment, 16:11 any gems that are specified only in the test environment would be installed. 16:16 For the most part, what you'll be doing is using bundle install, 16:23 bundle update, and bundle exec. 16:29 If you wanted to create your own application using Bundler, 16:36 you can do that with the bundler.setup command. 16:39 And that's very, very easy to use. 16:42 So let's go ahead and say we're creating a project. 16:48 my_bundler_project. 16:52 Clear my screen here. 16:58 Close this. 17:03 Now, here is my Bundler project. 17:05 I'm gonna create a new file and save it as Gemfile. 17:10 Now I've got a Gemfile, what I need to do is specify some kind of gem, 17:18 we'll just say I'm gonna specify the money gem, and 17:23 in order to require it, we can say require rubygems and require bundler/setup, 17:29 so, I'll just do a new file and we'll say example.rb. 17:36 And if I were going to use the money gem, 17:40 let's go ahead and check it out, 17:46 ruby money gem, we can just copy and 17:51 paste this, run it. 17:56 So if I run example.rb, we get this uninitialized constant money. 18:04 Well, I haven't done any bundle installs yet, so let me do that. 18:09 Now, if I just type bundle, that will automatically try to do a bundle install. 18:15 It says uh-oh, your Gemfile has no gem server sources. 18:20 If you need gems that are not already installed, 18:25 add a line like this to your Gemfile specifying a gem source. 18:27 Okay, let me copy and paste rubygems.org into my gem file. 18:31 Save that. 18:37 Run bundle again. 18:40 Now, this is going to install the gem and its dependencies. 18:44 So now let me clear my screen and run the example.rb again and watch it fail. 18:49 We still get this uninitialized constant Money error, 18:54 and if we go back, we can see, 18:59 the reason is we need to require rubygems and bundler/setup. 19:02 So let's do that and see what happens. 19:07 Let's go ahead and print that to the screen. 19:12 Now if we run this again, we still get this uninitialized constant Money, and 19:15 let's see why, now we can require money. 19:20 If only it was that easy in real life, right? 19:24 Uninitialized constant Currency. 19:27 Let's see why that is. 19:31 We're requiring money. 19:35 And let's just get currency out of here for now so we can see how this works. 19:40 Probably haven't updated their gem documentation. 19:47 Okay, now we have access to the Money constant and the Currency constant. 19:51 So if we were to specify any other gems in here, 19:57 we would need to put them in the Gemfile and then require them. 19:59 Now, those are the basics of using Bundler. 20:05 If we had different groups, we could call this bundler.setup method and 20:07 that would add groups from not just the default group but any group we specify. 20:12 So these are the basics, you can read more about Bundler on the Bundler website. 20:20 Definitely go through and check it out, 20:25 and you can also find some helpful info in the notes below this video. 20:27
You need to sign up for Treehouse in order to download course files.Sign up