Difference Between Gemfile and Gemfile.Lock in Ruby on Rails

What is the difference between Gemfile and Gemfile.lock in Ruby on Rails

The Gemfile is where you specify which gems you want to use, and lets you specify which versions.

The Gemfile.lock file is where Bundler records the exact versions that were installed. This way, when the same library/project is loaded on another machine, running bundle install will look at the Gemfile.lock and install the exact same versions, rather than just using the Gemfile and installing the most recent versions. (Running different versions on different machines could lead to broken tests, etc.) You shouldn't ever have to directly edit the lock file.

Check out Bundler's Purpose and Rationale, specifically the Checking Your Code into Version Control section.

Difference between Gemfile and Gemfile.lock in Ruby on Rails

Gemfile contains the gems that will be included in your project once you run bundle install. You can group them, as well as specify their origin (where they will be fetched from), and version/branch.

Gemfile.lock is generated by bundler and contains a list of all the gems which are actually installed and their version, and including all their dependencies.

Gemfile with exact versions vs Gemfile.lock

No, an exactly specified Gemfile and using a Gemfile.lock is not the same.

Your Gemfile might include all gems you are using with a specific version. But the Gemfile.lock will also include all gems that are dependencies of the gem you use. That means that a typical Gemfile.lock will include way more gems when a Gemfile.

Furthermore: You might have gems or gem versions to your Gemfile that are incompatible with each other. A Gemfile.lock is generated by bundler and represents a set of gem versions that are compatible with each other. If bundler is not able to fulfill all required dependencies then it will not generate a Gemfile.lock.

That said: Pin only versions in your Gemfile that you need to pin because of version requirements of your app. Let bundler find a valid combination and check that Gemfile.lock into version control system.

Difference between = and ~ for specifying versions in Gemfile and Gemfile.lock

See http://docs.rubygems.org/read/chapter/16#page74

From that page...

gem 'library', '~> 2.2'

Notice that we only include 2 digits of the version. The operator will
drop the final digit of a version, then increment the remaining final
digit to get the upper limit version number. Therefore ‘~> 2.2’ is
equivalent to: [‘>= 2.2’, ‘< 3.0’]. Had we said ‘~> 2.2.0’, it would
have been equivalent to: [‘>= 2.2.0’, ‘< 2.3.0’]. The last digit
specifies the level of granularity of version control. (Remember, you
can alway supply an explicit upper limit if the pessimistic operator
is too limited for you).

is it desirable to remove Gemfile.lock?

Does bundle install take specific gems in my Gemfile or Gemfile.lock?

bundle install looks first into gemfile.lock, then looks into gemfile to generate a valid gem list, checks, tries to resolve the dependencies, and then install/update the gems.

My Gemfile and Gemfile.lock are not the same.

They don't need to be the same. gemfile.lock is a specific file to keep the gems' state at the time of running bundle install/update.

Do I have to remove Gemfile.lock?

You can, but then bundle install will generate gemfile.lock again. Then, you could really lose and break all gem dependencies, and might need to resolve them manually.

As an investigation procedure, you can copy old gemfile.lock to a secluded place, then regenerate gemfile.lock, and compare both with diff

Can add Gemfile and Gemfile.lock to git

The issue is probably because your config/database.yml needs to be configured to use postgresql instead of sqlite.

I highly suggest using postgres for both production AND development by removing the gem 'sqlite3', group: :development from your gemfile and just add gem 'pg' outside of the production group (so it applies to all environments: dev, prod, and test).

Then in your database.yml, in the default: &default section, change adapter to:

  adapter: postgresql

Or if you want to continue using sqlite in dev, just change the production: section in your database.yml to the following:

production:
adapter: postgresql
encoding: unicode
pool: 5

You might need to change the database: value to something like:

  database: your_app_name_production

where "your_app_name" is the name of your app.

NOTE: Be sure to keep the spacing exact as YAML files are whitespace sensitive.

Hope that helps.

Parsing direct and indirect Gems of Gemfile.lock file

indirect dependencies were automatically ignored

It would have helped if you'd included the full output. I just ran it myself, and you get:

[{"name"=>"coderay", "version"=>"1.1.3"},
{"name"=>"domain_name", "version"=>"0.5.20190701"},
{"name"=>"http-accept", "version"=>"1.7.0"},
{"name"=>"http-cookie", "version"=>"1.0.4"},
{"name"=>"json", "version"=>"2.5.1"},
{"name"=>"method_source", "version"=>"1.0.0"},
{"name"=>"mime-types", "version"=>"3.3.1"},
{"name"=>"mime-types-data", "version"=>"3.2021.0704"},
{"name"=>"netrc", "version"=>"0.11.0"},
{"name"=>"rest-client", "version"=>"2.1.0"},
{"name"=>"unf", "version"=>"0.1.4"}, # <------ !!!!!!!!!!!!
{"name"=>"unf_ext", "version"=>"0.0.7.7"},
{"name"=>"yaml", "version"=>"0.1.1"}]

So in summary, the indirect dependency of domain_name, i.e. unf, which is presumably what you were referring to, is included further down the list. Your code already works exactly as you intended.

One minor point, though: You can simplify the implementation a little by doing this:

gemlock_array = context.specs.map { |s| {'name' => s.name, 'version' => s.version.to_s} }

In ruby, assigning a temporary array and appending to it within a .each loop is usually sub-optimal. Use map instead, to just construct the array directly.



Related Topics



Leave a reply



Submit