Use additional gem in deployment - ruby-on-rails

does anyone have any idea how to add ruby gems if Gemfile.lock exists?
I’m using an application from an apt package but I want to add my custom gem.
In the Gemfile it says:
# Want to extend Zammad with additional gems?
# ZAMMAD USERS: Specify them in Gemfile.local
# (That way, you can customize the Gemfile
# without having your changes overwritten during upgrades.)
But if I create the Gemfile.local with my Gem the Application couldn start.
You are trying to install in deployment mode after changing
your Gemfile. Run bundle install elsewhere and add the
updated Gemfile.lock to version control.
If this is a development machine, remove the / opt / zammad / Gemfile freeze
by running bundle install --no-deployment.
The list of sources changed
The dependencies in your gem file changed
You have added to the Gemfile:
mySpecialGem
I used to be able to do this with bundle install --no-deployment , but when I do that I always get the same message

Are you installing the gem as:
gem "gem_name", path: "/Users/Matthies/gem_location"
Could you post what your Gemfile looks like?

the gemfile from the original package is
https://github.com/zammad/zammad/blob/stable/Gemfile
in my Gemfile.local is this:
gem 'gem_name', git: 'https://github.com/myname/mygem'

Related

Is there a way to get a gem's version before running bundle install (from Gemfile.lock)

I want to get a Gem's version without running bundle install.
Which is to say I want figure out what version bundle is planning to install without actually installing the gem.
Say read it from the Gemfile.lock(and Gemfile) combined.
Is there a way I can resolve what version bundler plans to install?
I need this because I want to cache the expensive installs while running docker build.
Gems like rails(nokogiri) take a while to install and I would like to do gem install rails -v ... in a previous step before running bundle install.
For this purpose i need to get the rails version before hand
If you add a new gem to your gemfile, but don't do bundle install, it doesn't install yet. Instead, you can run bundle lock, which generates a new lock file. This includes the gem version of the new gem that would be installed.
By running bundle show new_gem, it shows it isn't actually installed.
To be sure maybe get a backup of the original Gemfile.lock before running the command though.
By default if no version is specified in the Gemfile, running bundle install will attempt to install the latest version of the gem which is compatible with the rest of the gems and ruby version in your project. This will create a Gemfile.lock file if one doesn't already exist. If a Gemfile.lock file is already committed to git repo, it should then install the versions specified in Gemfile.lock. The point of bundler is to handle dependencies to insure your stack works correctly.
To see the version of a gem bundler is currently using you can run
bundle show rails
You will probably want to specify the ruby version in the Gemfile for example
ruby '~> 2.5' #
You can specify exact version of a gem in the Gemfile like this which you should be able to rely on to be the version bundler will install so long as it's compatible with the rest of the stack. bundle install will throw errors if there are incompatible gem versions.
gem 'rails', '4.2.11' # this will always install only this version.
You may also use pessimistic operator (~>) to set for only minor updates
gem 'influxdb', '~> 0.6.1' # could go to 0.6.2 but never 0.7.0
You can also set minimum versions like this although it's probably not what you need for your question.
gem 'pg_query', '>= 0.9.0'
If you have a Gemfile.lock already in your repo you can see which version would be installed by running for example:
gem show rails
Which would show you the version and weather it or not it is currently installed.
For more info see bundle --help

Update local gem source code

I'm testing a gem in a Rails project.
The current Gemfile:
gem 'mygemname', path: '/path/to/my/gem'
When I edit a gem locally I can build the gem, remove the gem from Gemfile, run bundle install, add the gem back to the Gemfile and run bundle install again. Is there an easier way to do this locally?
If you use bundle config local.GEM_NAME /path/to/local/git/repository from the command line then every time you reload your application it will load the latest source from your file system.
To remove the changes (when you have pushed your code to GitHub or RubyGems), you need to run bundle config --delete local.GEM_NAME
Source: http://bundler.io/v1.10/git.html
You can bump your Gem's version. Next time you run bundle your gem will be updated to the next iteration.
VERSION = "1.0.0"
Bump the patch version to
VERSION = "1.0.1"
Now just run bundle. Bundler will notice it and log 1.0.1 (was 1.0.0) in the output.

LoadError when using a Minitest extension from one vendored gem in another vendored gem

I have a problem with two vendored gems of a Rails 3.2 app. One gem is a Minitest extension, the other a piece of code which should use the Minitest extension in it's test suite. Since both are under development, both are vendored and not yet pushed to Rubygems.
To reproduce the issue, I've bootstrapped a bare Rails 3.2 app and added two gems to vendor/gems: minitest-great_expectations (a working Minitest extension cloned from Github) and mygem which only reports and tests it's VERSION.
First let's try with the minitest-great_expectations gem from path:
git clone https://github.com/svoop/minitest_sandbox.git
cd minitest_sandbox/vendor/gems/mygem/
cat Gemfile # note "path:"
bundle install # note "Using minitest-great_expectations (0.0.5) from source at ../minitest-great_expectations"
ruby test/lib/mygem/version_test.rb # => test_helper.rb:6 - cannot load such file -- minitest/great_expectations (LoadError)
And now the same with the minitest-great_expectations gem from Rubygems. Edit the Gemfile and use the line without the "path:".
$EDITOR Gemfile # remove the "path: ..."
bundle install # note "Installing minitest-great_expectations (0.0.5)"
ruby test/lib/mygem/version_test.rb # => PASS
Reverting back will now work since the gem is installed. However, it doesn't matter whether the Gemfile contains the "path:" or not. Explicitly uninstall the gem with gem uninstall minitest-great_exceptions and you're back to LoadError.
Any idea what's missing here?
You should be running bundle exec ruby test/lib/mygem/version_test.rb.
Path gems are a Bundler-specific extension to Rubygems, so bundle exec is necessary to set up the load path correctly.

install gem from command line vs changing gemfile

I'm trying to understand what exactly happen when I'm installing gems.
At first I thought that using the "gem install gem_name" command (and after it the "bundle install) will make sure I have the proper files and dependencies and then it will update the gemfile.
But I've noticed that whenever I add gem using the commend line it doesn't appears at the gemfile yet I'm still able to use its functionality.
so is there is any reason to use the comment "gem install gem_name" insted of just adding the gem name to the gemfile?
The reason to use a Gemfile is that you can install all required gems in a single go.
Imagine that you work in a development team and a new member starts contributing to your application.
Al he has to do is checkout the repository and run bundle install.
Only use the command gem install if you just want to install a gem that is not nessecarily relevant to your project.
If the project requires the gem; put it in the Gemfile.

Difference between bundle show gemname and gem list gemname

If I do gem list rack-cache in rails command prompt then it shows no gem with that name but if I do bundle show rack-cache then it gives me the path like /vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2 of where the gem is stored.
I didn't understood this behavior because if the gem is present in the path with the latter command then why its not showing when I gives gem list rack-cache command.
What's the difference.
The confusion comes from the issue bundler is solving.
When you install Gems into your system-wide gem repository you end up with multiple versions of the gem once you have a couple of apps.
So for example you could end up with 3 Rails versions: 3.2.8, 3.2.6 and 3.1.0
If you do a require rails rubygems could use any of these versions and you'll end up with confusion if your App that was initially built against 3.1.0 isn't compatible with some change s in 3.2.8.
What bundler does is install exactly the gems that are specified in the Gemfile.lock and locks those down for the use of that app. Bundler therefore modifies the load-paths for rubygems so only the Gems in the Gemfile.lock are really available to the app.
Therefore bundle install is not installing gems into the system-wide gem directory but rather installs to a different path for each project. That's why you see the gem in a bundler directory and not system wide.
If you install rack-cache through gem install you'll also see it in gem list.
There is a small difference between bundle show and gem list
bundle show will list all the gems which are installed in your current application[you can see them in Gemfile.lock file],where as gem list will list all the gems installed under any gemset which is set to be using.
bundle show gem_name will give path where it is.
gem list gem_name will give same gem_name with all versions installed into your local gems or gemset.
bundle show :
Shows all gems that are part of the bundle, or the path to a given gem
$ bundle show [GEM] [--paths]
When in development mode on your mac, the gems still get installed in the default gem path, whereas in production mode, they get installed in a folder specific to your project. Try doing a bundle show rails on each machine and you'll see what I mean.
When you run gem list it looks in the main gem folder, and since your production gems are sitting in a project-specific folder, the global gem command doesn't know to look there. So you will need to do a bundle exec to run any of those project-specific gemscommands on the server. For my purposes, I created a be alias to bundle exec. Also, to list your project's gems, you can do bundle list.
See http://gembundler.com/rationale.html#deploying-your-application for the rationale behind this

Resources