how to manage ruby's bundler own version? - ruby

I use bundler to manage my dependencies' versions.
The question I am asking myself now, is: how to manage bundler's version itself. I mean, "bundler install/update/outdated" helps me understand what I am holding back, update them optimistically or pessimistically ... but I am not sure what's the best practice / procedure to decide about bundler itself.
In other words, is there a gem- or bundler-based workflow that ensures that I and my coworkers do use the latest (or the to-be-specified) version. Bundler gives us this workflow for all the other gems, but what about bundler itself ?

I hope this might be of some help to you here.
First, you need to install the appropriate version of bundler:
% gem install bundler -v '~> 1.12.5'
Successfully installed bundler-1.12.5
Then force RubyGems to use the version you want.
% bundle _1.12.5_ install
This pattern gem-binary _gem-version_ works for any gem binary.
You can check the available versions for Bundler from here.

Related

Install gems in parallel (faster)

Bundler has a feature where you can install gems in parallel using the --jobs option. For example:
bundle install --jobs 4
Does a similar feature exist for RubyGems?
I want to be able to run gem update in the same way.
The root problem is that it takes FOREVER to update my global system gems.
No, this feature does not currently exist. However, there’s an unmerged pull request on RubyGems regarding downloading gems in parallel that may be integrated by the time you read this: https://github.com/rubygems/rubygems/pull/649. However, this PR does not address the installation of gems in parallel like Bundler does. So, some of functionality might partially be coming soon.
That said, telling RubyGems to do fewer things during installation is a good way to speed up installation. There are three relevant CLI options worth looking at.
Don't install documentation:
gem update --no-document
Don't attempt to upgrade gems already meeting version requirement:
gem update --conservative
Don't upgrade any dependencies that already meet version requirements:
gem update --minimal-deps
I recommend simply installing gems without documentation. The intent behind running a global gem update is usually “just give me all the latest stuff” so limiting the gems you’re updating would be in conflict that goal. However, many people don’t look at the RDocs generated for their installed gems, and it saves a lot of installation time.
http://guides.rubygems.org/command-reference/#gem-update

Can I control the version of rubygems that IntelliJ uses?

I'm trying to start a rails application in IntelliJ with the Ruby plugin.
I've imported the application and set up the run configuration as best I can. When I try to run it I get the error:
NoMethodError: undefined method `version_requirements' for #<Gem::Dependency:0x7de21f45>
When looking for an answer I found this page saying that I should do this:
$ gem install rubygems-update -v='1.4.2'
$ gem uninstall rubygems-update -v='1.5.0'
$ update_rubygems
Since it's IntelliJ's ruby plugin that is managing the gems, I assume that I have to change the version of rubygems-update that the plugin is using.
Is this the right approach to take? And if so, can anyone tell me how to go about it?
I tried listing the gems but that gem is not shows so I must not be listing the gems in the right place, but I don't know where to look.
Many thanks :)
IntelliJ IDEA cannot handle it, you will need to install the appropriate rubygems version from the command line.
Note that your current rubygems-update version may be different, verify it with gem list and use the reported version when uninstalling.

why is gem still outdated after bundle update

I am working on a gem and it's on github.
When I include the gem in an application, do a capistrano deploy, and (on the server) run:
bundle outdated
I see:
* authengine (0.0.1 d8baa49 > 0.0.1 de43dfa)
which tells me that a more recent commit is available. Why doesn't the bundle update (part of capistrano deploy) pull the more recent version? There is no version constraint in the Gemfile of the host application, and anyway they have the same version number, just different commits.
Even if I log into the server and run
bundle update authengine
I get the same "outdated" result afterwards.
What am I missing here?
One thing I've found that can cause this is if other gems in the bundle make requirements on gems by version that are incompatible. Bundler tries to reconcile these by selecting versions of gems such that their requirements can all be satisfied. The result is that it quietly refuses to update gems.
The way to check this is to set an explicit version requirement in your Gemfile. Something like
gem "authengine", "> 0.0.2" #(you'll need to bump the version to make this work)
#or
gem "authengine", :ref => "d8baa49"
Then run
bundle update authengine
You should see something like (this is taken from my particular case):
Bundler could not find compatible versions for gem "json": In
Gemfile:
chef (> 10.8) ruby depends on
json (<= 1.6.1, >= 1.4.4) ruby
logical-construct (>= 0) ruby depends on
json (1.7.5)
So, in my case it's a problem with explicitly requiring a newer version of json.
The author, André Arko, stated in 2014 that:
The Bundler resolver is definitely a work in progress, and we adjust
the tradeoffs between specific versions and resolving quickly based on
user feedback.
Bundler has consistently not provided the newest possible version of
every gem for the entirety of its existence, and it does result in a
lot of tickets being opened. In most cases, it turns out to be the
result of Bundler having to pick between the newest version of one gem
or a different gem, and Bundler picks the gem the user doesn’t care
about having the newest version of. That’s why it’s so important to
make your Gemfile version requirements accurately reflect your actual
requirements.
I recognize that your assumption that Bundler would give you the
newest possible version seemed valid at the time, but the docs only
say that you will get a version that meets your requirements, not the
latest. Is there anywhere we could expand the docs to make it clearer
that the newest versions of everything simply isn’t feasible?
What is the output returned when you run bundle update authengine? Does it actually say it updated the gem? Or does it ignore the gem?
You can try using the --source parameter to specifically tell Bundler to use the git repository. That, or your
bundle update authengine --source https://github.com/mustardseeddatabase/authengine.git
Also, when unexpected things like this happen, I like to clean up my gemlist in general. It could be that you still have older versions of the gem laying around, not using in bundler.
So you could do:
gem list
gem check
gem cleanup
Or do a complete reinstall
gem uninstall authengine
bundle install

Is there a way to use Bundler for production gems?

I tried searching for this several times, but if this question has been answered already I didn't find it.
So, let's say I've developed a plain old gem (not a Rails app). I already know how to use Bundler for development, so I have a Gemfile and everything in my repository. However, I want this gem to use Bundler for dependency resolution when I install it, not just when I work on it.
Is there a way to do so, or would I have to resort to running its commands from a git checkout with bundle exec?
Bundler resolves dependencies not only for development. Just run bundle install on production server after deployment and it will install all needed gems there too.
If you need to install gems from several repositories, add row in you Gemfile:
source 'http://you_repository.com

What does Bundler offer over RVM?

I am not sure what the differences are between these two tools. There seems to be a big overlap, but I have been using RVM and facing some miss-compatibility issues.
What does Bundler do that RVM does not?
They serve different purposes. RVM creates a sandbox to manage your Ruby installations. As a part of that, it also lets you define gemsets.
Bundler doesn't manage your Rubies, it works with the currently selected Ruby.
So, I think you should consider RVM as the configuration manager for your development environment, and Bundler the gem manager for an application.
EDIT: Additional thoughts -
Whether we use RVM or not, typically we'd have to load all the gems we're going to use for an app by hand, using gem install blah, for every gem we want to use.
I end up managing my gems across multiple Rubies by hand. Once they're installed I can create gemsets using RVM, but RVM won't automatically retrieve a particular version of a gem if it's not installed, or go get it again if it was removed. Because RVM is more concerned with your Ruby environment, it mostly leaves the versioning of gems to gem and to us.
Bundler, on the other hand, does care about those missing parts in RVM. When you create the Gemfile for bundler, it will retrieve the necessary gems and specific versions if specified. So, the task of installing a Ruby app on a different machine becomes much simpler. Push the files to the other machine, then run bundle install and it'll do the rest.
It works nicely with Rails and is a sensible solution for my production files. It will be much simpler than how I have to handle Perl distributions in order to run Perl apps on the same hosts.
RVM is more like a containment unit. While Bundler is like a manifest (dependency manager) of what the application will require or use in it's lifecycle (among other things).
If you are working in Rails, you will not be able to escape Bundler. But I use it all the time just so I know what Gems I'll need, and so will others who later come into the project.
RVM helps me separate out my Rubies and then further into Rubies/projects. This way I don't have a slew of Gems and different versions all in one pile.
Not exactly the most action packed answer, but hope it helps a little.
To directly answer your question...
What does Bundler do that RVM does
not?
Bunlder will install all gems that are needed by a project (that uses bundler, and have all needed gems specified in a Gemfile). RVM does not do this.
Using the Gemfile you can specify what gem groups (ie: development, testing)...
There are many 'small' things like these that bundler does but RVM does not. In general as the good people above explained, RVM has a different set of goals from that of bundler. RVMs about managing ruby runtimes while bundler is about managing dependent gems for a application.
Bundler is a tool for managing dependencies in your code -- i.e., all the gems it requires. It will make sure that all the gems you specify in your Gemfile, and any dependencies, are installed on your system. It doesn't really care which version of ruby you are using, it just installs the gems for you under whichever interpreter is in use.
RVM is a tool for running multiple rubies, and in theory, multiple gemsets as well. It doesn't handle dependencies for you at all -- it's still up to you to install the gems.
My experience (and I'm new to RVM), is that you don't want to bother with RVM unless you have a need for running multiple rubies, or need gems installed for different projects that somehow conflict with each other. Even if you are using RVM, it makes sense to use Bundler to manage gem dependencies so that your Gemfile can be tracked in whatever code repository you are using.

Resources