How to work with gemspec add_runtime_dependency and `bundle install` - ruby

I have a codebase which has a gemspec file like:
require "rubygems"
::Gem::Specification.new do |specification|
specification.add_development_dependency "yard", "~> 0.9"
specification.add_runtime_dependency "dry-validation", "~> 0.13"
end
bundle install will install both dependency types. So I want to just install the runtime dependencies for my CI scripts. I see bundle install --with <group> exists, but I don't have groups. Run interactively, the returned specification has an empty result returned from .groups. I would love to rationalize these two worlds. Must I explicitly add a group for each gem dependency? Does add_runtime_dependency and add_development_dependency even make a difference?

from bundler's documentation
Because we have the gemspec method call in our Gemfile, Bundler will automatically add this gem to a group called “development” which then we can reference any time we want to load these gems with the following line:
Bundler.require(:default, :development)
in your case, if you wish to install all rubygems that are not for development, then try
bundle install --without development
for future bundler version, you can configure it locally (or globally)
bundle config set --local without 'development'
to make it all work, verify that you have a Gemfile in your project, which will look like
# frozen_string_literal: true
source 'https://rubygems.org'
gemspec

Related

Optional runtime dependency for Ruby gem with executables

I'm writing a gem aipp which exposes a few executables, nothing fancy here:
#!/usr/bin/env ruby
require 'aipp'
AIPP::NOTAM::Executable.new(File.basename($0)).run
Parts of the gem optionally use database adapters (pg or ruby-mysql gem). But since these can be a pain in the butt when the gem is used on the cloud, I'd like to really make them optional and not require them as runtime dependency in the .gemspec.
So I require them conditionally at runtime:
require 'pg' if ENV['AIPP_POSTGRESQL_URL']
require 'mysql' if ENV['AIPP_MYSQL_URL']
Unfortunately, that doesn't work as expected. When either of the environment variables is set and the executable is used, the require fails – probably because there's no dependency declared.
I've tried an inline Gemfile on the executable like the following. Works in development (repo checkout), but not when the gem is intalled via Rubygems:
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'aipp'
gem 'pg', '~> 1' if ENV['AIPP_POSTGRESQL_URL']
gem 'ruby-mysql', '~> 3' if ENV['AIPP_MYSQL_URL']
end
AIPP::NOTAM::Executable.new(File.basename($0)).run
What's the correct approach to require gems which are not listed as runtime dependency but installed additionally (via gem install or Gemfile)?
Maybe somebody knows of an existing gem which has already solved this problem somehow.
Thanks for your help!
I would use bundler groups for that.
gemfile do
source 'https://rubygems.org'
gem 'aipp'
group :database do
gem 'pg', '~> 1'
gem 'ruby-mysql'
end
end
There is more info about how to use them in the link.

How to create a Gemfile?

I'm very new to Ruby.
I was following a blog post that says that in order to install a required dependencies I need to create a Gemfile.
How do I create a Gemfile with rspec as a dependency?
bundle init generates a Gemfile into the current working directory.
$ bundle init
Writing new Gemfile to /app/Gemfile
$ cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
The Gemfile is just a text file within your project which contains a list of gems for use in your application.
If you do not have one in your application, you can create the file using an editor of your choice, saving it as Gemfile (with no extension), and in your example, containing:
source 'https://rubygems.org'
gem 'rspec'
A gemfile is automatically created when you start a new rails application.
type rails new appName and then it will be generated automatically. It will also be populated with some gems.
To install the gems run bundle install or simply bundle
Make sure you are requiring the gems you need. specifically rspec and jruby
group :development, :test do
gem 'rspec-rails', '~> 3.0'
end
Look at this website for more information
http://bundler.io/

Making a Ruby project that is not a gem (or some other kind)

I'm working on a project currently that I don't want to be a gem (or some other kind of project). How would I go about setting it up so that I can still have the same compatibility requirement abilities as a gem (e.g. Gemfile dependencies) but simultaneously not be a gem (or some other kind of project)?
You have to actually try to build a gem so this is easy!
to use bundler without Rails, a gem, whatever just create a directory
mkdir my-non-gem-project
cd my-non-gem-project
install bundler
gem install bundler
and initialize your Gemfile
bundle init
that will create a Gemfile for you and you can add to it and run bundle to install the dependencies from it
The simplest way to use bundler in your project would then be to open your main app file and add
require 'bundler/setup'
Bundler.require
This will require all of the gems you have in your Gemfile in the file this is added to. I am pretty sure that this file must be in the same directory as your Gemfile. More information here
Have fun with your Ruby project!

Gem and bundler: Adding a development dependency with a relative path

I'm helping on the development of a series of interrelated gems. As such, I don't want them to have a hard dependency on each other, but I do want them to run tests in development that use each other. Simple right? Just use add_development_dependency in the gemspec, right? Well, there is one little wrinkle - the git repository contains all the gems, and so I want the Gemfile to point to the local copy of the gem. This works with a hard dependency. In the gemspec, I have this line for my hard dependency:
s.add_dependency "mygem-core"
And then in the Gemfile, I have this line:
gem "mygem-core", :path => "../mygem-core"
This works PERFECT. The dependency exists for when I push this package out, and when I'm testing, it will use the local copy of mygem-core. The problem is that when I put THIS in the gemspec:
s.add_development_dependency "mygem-runtime"
And then this in the Gemfile:
gem "mygem-runtime", :path => "../mygem-runtime"
Then I get an error when I run bundle:
You cannot specify the same gem twice coming from different sources. You specified that mygem-packager (>= 0) should come from source at ../mygem-packager and
Yes, that's not a typo at the end. There is literally a blank, empty space at the end for the second 'location'. Is there any smart ways to work around this? I want to add this as a development dependency, and use the local source. What am I missing?
It's probably better that you leave that gem out of the .gemspec manifest and put it in the Gemfile under the :development group.
# Gemfile
source :rubygems
gemspec
gem "mygem-runtime", :path => '../mygem-runtime', :group => :development
If your using Gemfile to specificy a local path to a gem you will need to remove it from gemspec. Bundler will parse gemspec and add the dependencies those bundler is installing, so its like having the gem specified twice.

Bundle install to development

For some reason when I run bundle install it installs to production:
Your bundle is complete! It was installed into ./RAILS_ENV=production
Arrrghh, how do I switch back to development??
Notes:
I haven't modified any environment files
When I run Rails.env from the console I get "development"
Gem file:
source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'sqlite3-ruby', '1.3.2', :require => 'sqlite3'
group :development do
gem 'rspec-rails'
gem 'nokogiri'
gem 'will_paginate'
end
group :test do
gem 'rspec'
end
Also worth noting, it creates a folder in my app called RAILS_ENV=production which I posted a question about here which now I guess is linked to this issue.
Update
When I run bundle config I get the following information, you can clearly see the Path is set to the culprit! Any ideas how I change this? I tried re-installing the bundler gem but to no avail, maybe this is a bug within Bundler?
$ bundle config
Settings are listed in order of priority. The top value will be used.
disable_shared_gems
Set for your local app (/Users/zinc/ror/site/.bundle/config): "1"
path
Set for your local app (/Users/zinc/ror/site/.bundle/config): "RAILS_ENV=production"
The explanation to that is in in the bundler manual. Read the heading Grouping Your Dependencies. Specifically
Bundler will remember that you installed the gems using --without production. For curious readers, bundler stores the flag in APP_ROOT/.bundle/config. You can see all of the settings that bundler saved there by running bundle config, which will also print out global settings (stored in ~/.bundle/config), and settings set via environment variables. For more information on configuring bundler, please see Advanced Usage: Configuring Bundler.
And the solution is to pass a different value for the property or remove the file APP_ROOT/.bundle/config.
Ok I fixed this.
I simply removed the path from my bundle config file and it seems to default back to my original path. I somehow set this accidentally I guess.
Your bundle config file is located in:
APP_ROOT/.bundle/config

Resources