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
Stop Devise from Clearing Session
Iterate Over Ruby Time Object With Delta
Can Ruby Print Out Time Difference (Duration) Readily
Set Utf-8 as Default String Encoding in Heroku
What Does "≪≪-" Mean in Ruby
How to Access a Variable Defined in a Ruby File I Required in Irb
How to Run Untrusted Ruby Code Inside a Safe Sandbox
Why Doesn't Ruby Find Classes in a Higher Scope When Module Is Specified Using ::
How to Test a Function With Gets.Chomp in It
Returning All Maximum or Minimum Values That Can Be Multiple
Ruby on Rails Callback, What Is Difference Between :Before_Save and :Before_Create
Ruby: How to Write Multi-Line String With No Concatenation
Serve Current Directory from Command Line
Getting "Warning! Path Is Not Properly Set Up" When Doing Rvm Use 2.0.0 --Default