How to put Ruby dependencies in local project folder - ruby

Is there a way to put a ruby gem dependencies inside the project root folder ( in vendor directory or something similar ) ?

Run bundle package to cache gems to ./vendor/cache. As the docs point out, bundler will still look for platform-specific gems on rubygems.org. If you have control over the platforms (e.g. same development and deployment platforms), then you can use bundle install --local in addition to bundle package. You may also want to consider a command like bundle install --path vendor/bundle in this case.

Just generate gemfile with proper app dependencies, place it into the root of your app, and use bunlder to keep depencencies up-to-date. Since by default all gem will be placed into system folders, I strongly recommend you to use rvm or rbenv utilities to use for purpose of gem keeping.

Related

Load bundle dependencies from a global executable

Good evening,
I did a gem which contains executables which are called globally.
cd my_exec_gem
bundle install --deployment
gem build my_exec.gemspec
gem install my_exec-1.0.gem
my_exec <arguments>
My question is, what is the best way to execute my_exec with the version of the gems which have been installed in the my_exec_gem/vendor directory? How to adapt the gem path at the moment of the execution?
I want to keep the gems of the application isolated from the gems of the systen. (That's why there is --deployment)
Thank you!
The solution seems to be to use --binstubs to generate relative executables which change the ruby environment to run using the specified gems.

Can I get Bundler to share Git-based gems across projects?

Without the gemsets provide by a tool like RVM, all gem installations are global. So if two projects use the same version of Ruby, and both have identical gemfiles, I would expect that running bundle install for the first one would install the gems, then running bundle install for the second would be able to use the already-downloaded gems to satisfy its requirements.
However, this doesn't appear the be the case with gems that are located in Github repos. For example, I have several projects with identical gem references, similar to this:
gem 'some_gem', git: 'git#github.com/me/some_gem.git', ref: 'a293bkd9d23'
Yet, although bundle install in one project clearly has to download this particular commit, it seems that bundle install in the next project repeats that process.
Bundler does not appear to store these Git-based gems in ~/.gem with my normal gems.
Where does it put them, and can I make it check for the specified commit locally before fetching from the repo again?

Using Bundler in deployment

Pretty fundamental question but I'm trying to understand how best to use Bundler in a deployment situation.
I'm working on a Sinatra application that has about 20 dependent gems. During development, I'm using RVM with a custom gemset for the application, and I run bundle install to update the gemset in accordance with the gemfile.
When it comes to deployment (manually for now, so I can understand how it all works before using a tool like capistrano), I need to do bundle install --development right? This downloads the gems and places them in vendor/bundle.
My question is what else do I need to do? I'm using Unicorn on the server - do I just bundle exec unicorn ... and everything just works? (i.e. bundler finds the vendor directory and uses the gems from there?)
Should unicorn be a vendored gem in the application or a separate 'system' gem on the server that all applications share?
You need --deployment key, not --development: http://gembundler.com/man/bundle-install.1.html#DEPLOYMENT-MODE
On first run bundler creates config in .bundle directory. You can check it by running bundle config or just cat .bundle/config in project's directory. So bundle exec unicorn is enough since bundler knows where gems are installed. On development machine you can also install gems to arbitrary directory using --path key. For more details see manpage for bundle install (link above or bundle help install).

Is it possible to bundle / install gems from a local cache?

I have bunch of gems on my computer that I want to use in a chef recipe.
I know it is possible to put them in a directory like /tmp/gems and just:
cd /tmp/gems
gem install *.gem
Is it possible to put all gems in one directory where I can install them with bundler without downloading them again?
cd /somedir/my_rails_project
bundle
I want to save bandwidth.
bundle install --local should be what you want. From the bundle-install manpage:
--local
Do not attempt to connect to rubygems.org, instead using just the
gems located in vendor/cache. Note that if a more appropriate
platform-specific gem exists on rubygems.org, this will bypass
the normal lookup.
You can add local directories to your Gemfile (example from the docs):
gem "nokogiri", :path => "~/sw/gems/nokogiri"
Alternatively, you can set up a local Git repository with the gems in it and write a Gemfile like this:
gem "gem1", :git => "file:///tmp/gems",
:branch => "gem1"
Use
bundle package
Locks and then caches the gems into ./vendor/cache.
The package command will copy the .gem files for your gems in the
bundle into ./vendor/cache. Afterward, when you run bundle install,
Bundler will use the gems in the cache in preference to the ones on
rubygems.org.
http://bundler.io/v1.6/bundle_package.html
You can use the BUNDLE_CACHE_PATH configuration key:
cache_path (BUNDLE_CACHE_PATH): The directory that bundler will place cached gems in when running bundle package, and that bundler will look in when installing gems. Defaults to vendor/bundle.
Source: https://bundler.io/v1.16/bundle_config.html#LIST-OF-AVAILABLE-KEYS
In GitLab CI, I defined this value in the environment of runners: "BUNDLE_CACHE_PATH=/cache-ci/bundle", this directory is mounted automatically in CI runners.
Then bundle install will install gems from the cache directory (once cache will be populated).
If you want to use a local cache for the purpose of speeding up bundle install on CI, for example when a docker container is used to run the tests, you could use --path. This will use gems in the given path unless they are not present, otherwise it will download them to that location.
This assumes the CI build can mount a persistent volume inside the docker container. So for example if the CI machine has a directory /var/cache/drone which can be mounted in the docker container as ./cache then you can do:
bundle install --without=development --quiet --path=cache

bundler and rvm: how should i best i package my current installed gems into my folder?

I've recently started using rvm (and bundler) and am in the process of boxing up a project so that everything needed for the project lives in the project folder (and hence in source control), enabling someone checking it out to fire it up straight away with no external dependencies.
So, i'm sitting in my project's root folder, in an rvm with a named gemset, with all the gems i need installed in the current gemset.
Using bundler, can i package all these gems into the project, so that when the project is checked out into a new environment (which will be in an identically named rvm & gemset) i can either
a) install the gems from the gems folder in the project (rather than from rubygems.org for example) or
b) use them directly out of that folder?
rvm and bundler seem to replicate each other's purpose/functionality to some degree and i'm a bit confused...
Grateful for any advice - max
You can use the bundle package command to do that.
You can check the documentation about it : http://gembundler.com/man/bundle-package.1.html

Resources