Gemfile: Difference Between branch and ref in a github Reference - ruby

In the Gemfile it's possible to refer a gem hosted on github:
gem 'spree', github: 'spree/spree', branch: '2-3-stable'
gem 'spree_gateway', github: 'spree/spree_gateway', ref: '2-1-stable'
The Gemfile manpage describes three attributes for git: branch, ref and tag. What's the difference between ref and branch? And how does bundler handle the gems differently depending on the attribute?
This especially seems to be interesting because you can only use one of the attributes at a time.

With branch, you're just specifying the git branch to pull from. If you did a bundle up <gem> when targeting a branch, it would update to the tip of that branch.
The ref is really nailing it down to an individual commit. You wouldn't give a "human-readable" name as you did in your question, you'd do something like:
gem 'something', github: 'someone/something', ref: '832e76a9'
And now you've pinned it to that ref. If you did a bundle up something, it wouldn't change that gem (it may update its dependencies though).

Related

How to force bundler to re-fetch tag ref from GitHub

I have a gem that I manage, and have recently updated the ref for a tag (the SHA for the tag is now different on GitHub)
In my Gemfile, I have:
gem 'my_gem', tag: '0.25.0', git: 'http://github.com/Example/my_gem.git'
However, running $ bundle install only uses the old SHA for that tag. How can I force it to get the latest code?
I tried removing the path to my gem, like so:
$ rm -rf /usr/local/rvm/gems/ruby-2.4.5/bundler/gems/my_gem-*
... but bundler just downloads it again.
The only way I've been able to make this happen is by modifying the revision in my Gemfile.lock, but that only works on that one repo. I have multiple repos using this gem. It seems like Bundler has a database/cache mapping gem tags to revisions, but I can't find where that is.
PS: I know re-tagging things isn't best practice.

force ruby gem to use alternative gem source

I have a gem that I one of the owner/authors (hyperloop) that depends on another gem (opal-rails) which depends on another gem (opal-jquery).
All gems depend on the gem opal. The problem is the current released version of opal-query is locked to an older version of the opal gem.
The version of opal-jquery on master is okay. For whatever reason the author(s) have not pushed ruby gems, so I have to work around this.
The work around is that I have to say
gem 'hyperloop'
gem "opal-jquery", git: "https://github.com/opal/opal-jquery.git", branch: "master"
in the application Gemfile.
I am hoping somebody can give a workaround that could be embedded in the hyperloop gemspec, so that the problem is taken care of there.
I thought if I added
gem "opal-jquery", git: "https://github.com/opal/opal-jquery.git", branch: "master"
to the hyperloop Gemfile this would take care of it, but apparently not.
There isn't really a way to manage the dependencies of your dependencies. You have 2 options here:
1) Use an older version of opal
2) Clone the opal-jquery gem and modify its Gemfile, pointing to the version of opal you want it to use, then, in your Gemfile, point the opal-jquery gem to pull from your cloned version of the repo
Neither of these is really ideal and you'd have issues if you ever decided to upgrade to a newer version of opal-jquery if you go with the second route

How to manage dependencies between my ruby projects?

This sounds like a basic question, but I can't find any answer to it on the Internet.
So I have a git ruby project database_models. It's a gem. I want 3 other project to use it. I've added a dependency on this project to those 3 projects like this:
gem "database_models", :git => "path", :branch => master
Now, I want a a develop branch of those 3 projects to use the develop branch of database_models, and I want a master branch of those 3 projects to use the master branch of database_models, so that my production environment is stable and independent of my development environment.
I can see 4 options of doing this, and I don't like any of them:
Deploy database_models to the server, and update those 3 projects to reference database_models using a path, instead of git
Git submodule
User different versions of database_models gem (1.1, 1.2, 1.3...). I would probably need my own gem server for that, right?
Write some code in a Gemfile that would choose the correct branch based on the environment where "bundle install" is run.
Usually you'd use Bundler with a local path. Your Gemfile points to the Git or Github repo using git or github:
gem 'spree', github: 'spree/spree', branch: 'master'
Note that includes the branch. You can make each of your projects use a different branch of your gem if you want to. You can make each of your projects use a different branch of your gem if you want to. You can also use groups to deploy different versions of your gem depending on the environment:
group :development, :test
gem 'spree', github: 'spree/spree', branch: 'bleedinedge'
end
group :staging, :production
gem 'spree', github: 'spree/spree', branch: 'master'
end
The above will work fine as long as you keep pushing to the Github. But thanks to local config, you can run the following on your command line:
bundle config local.database_modules ~/Projects/gems/spree
That will add a line to your ~/.bundle/config, so when you run bundle in your projects, it will pull it from your local repo.
User different versions of database_models gem (1.1, 1.2, 1.3...). I would probably need my own gem server for that, right?
I would do this and simply have my Gemfile select the correct gem via a tag. Here is an example:
git 'https://github.com/rails/rails.git', tag: 'v5.0.0'
So you can do the same while storing your custom gem on github (no gem server required).
Here is how to use tags with Git.
This should give you the flexibility you need.

In github, how do i know when/how a merge is integrated to a gem?

I use the last version of the ruby Faker gem (1.1.2). It seems it does not integrate this merge :
https://github.com/stympy/faker/commit/e33484a531715937d8d4b520852f2029b9be83ff#commitcomment-3377208
How do you know the git commit version (is it how i call it?) that a gem uses.
How does the gem maintainers goes from a git commit to a gem available via bundler?
There is no way in general - there is nothing in a gemspec that says what git commit a gem was built from.
It is often the case that the developer will create a git tag for each release, failing that the last commit before a release is usually one updating the version/changelog.

Bundler: always use latest revision of git branch in Gemfile

I have a Gemfile with a private git repo in the following format:
gem 'magic_beans', :git => "git#git.example.com:magic_beans.git', :branch => 'super_beans'
When I bundle install, the Gemfile.lock locks it to a specific SHA revision.
Can I get bundler to always check and use the latest SHA commit and/or update the Gemfile.lock? Notice that when I push updates to the super_beans branch I am not modifying the gem version.
Ideally, every time I run bundle it would check upstream git repo for a newer SHA revision of the branch.
This isn't how bundler works.
The point is to allow seamless versioning of dependencies.
(particularly so you know exactly what version of the code is deployed at any given time).
If want the latest version, you should just run.
bundle update magic_beans
This is exactly the same functionality as if you just say
gem "rails"
I'd suggest though, if you have a range of specific things you want to update
then add a custom binary (say an executable file named bundle_update)
#!/usr/bin/env bash
bundle install
bundle update magic_beans
Then just do a ./bundle_update when you want to update these things.
You can run bundle update to update all or specific gems to their latest available version, as stated in the docs.
Would that help?
After searching through the documents I finally found the magic way to do this:
bundle update magic_beans --source magic_beans
That is to update the magic_beans gem only, but not to touch other locked gems. The doc about this is: http://bundler.io/man/bundle-update.1.html
delete .gemlock is what worked for me :/

Resources