ruby gem inclusion still requires explicit dependencies in Gemfile - ruby

I have a Gem project that has the following in the mygem.gemspec file:
Gem::Specification.new do |s|
s.add_dependency 'some_other_gem'
end
Everything builds and publishes just fine for the Gem.
In my Rails projects that use it, I have the following in my Gemfile:
source 'http://abc123#gem.fury.io/my_user/' do
gem 'mygem', '1.12'
end
When I run my projects, I need to explicitly add the following in the Gemfile or else I wind up with dependency errors:
'some_other_gem', '3.14'
source 'http://abc123#gem.fury.io/my_user/' do
gem 'mygem', '1.12'
end
Project's Rails version is 5.0.6 running on Ruby 2.3.1.
Is there more necessary than just s.add_dependency in my mygem.gemspec file?

Related

Could not find a custom installed gem during runtime

On rhel8, I built and installed a custom gem test1.
$ gem build test1.gemspec
Successfully built RubyGem
Name: test1
Version: 0.0.1
File: test1-0.0.1.gem
$ gem install test1-0.0.1.gem
Successfully installed test1-0.0.1
1 gem installed
# check if gem is installed. All gems are installed in this path
$ gem which test1
/usr/local/share/gems/gems/test1-0.0.1/lib/test1.rb
Now in another custom gem I build, the gemspec file looks like this:
# in test2.gemspec file
Gem::Specification.new do |spec|
spec.name = "test2"
...
spec.add_runtime_dependency "test1", "0.0.1"
...
end
When I try to go install test2 gem it fails and says it could not find the test1 gem which is already installed. This problem started happening on rhel8. I tested on debian and alpine and it had no issues finding and installing the gem.
$ gem build test2.gemspec
Successfully built RubyGem
Name: test2
Version: 0.0.1
File: test2-0.0.1.gem
$ gem install test2-0.0.1.gem
ERROR: Could not find a valid gem 'test1' (= 0.0.1) in any repository
If I change to add_development_dependency, it builds and installs the gem. The image works as expected and has no issues. Does anyone know why its not able to find the gem when I add add_runtime_dependency?
If you are building a private gem that requires another private gem, you will need to define the dependency gem in both the gemspec and the Gemfile, while providing the actual source in the Gemfile.
For example, we are using GemFury to host private gems, and then in any other gem that needs this private gem, we do this:
# Gemfile
source 'https://gem.fury.io/your-user/' do
gem 'your-gem'
end
gemspec
# your-gem.gemspec
s.add_runtime_dependency 'your-gem', '0.0.1'

How can I install a gem (via bundler using gemspec) before parsing the gemspec?

I have a gem that exists for the purpose of helping with versioning. It's useful to have this gem available when defining the version in the gemspec file.
The problem, however, is that running bundle install first causes the gemspec to be parsed, which results in an error because the required gem isn't installed yet.
I can get around it by running gem install <other_gem> before bundle install, but I'd much prefer bundler manage it, especially when taking into account that I'm using a custom gem server.
I've tried adding the gem to the Gemfile directly before the gemspec line, but no luck.
Gemfile:
source 'https://my.gemserver.com/gems'
gemspec
mygem.gemspec:
require 'external/dependency'
Gem::Specification.new do |spec|
spec.name = 'mygem'
spec.version = External::Dependency.version_helper
....
spec.add_development_dependency 'external-dependency'
end
EDIT:
Another workaround is to rescue the LoadError and specify a default version if the dependency isn't loaded. Also, not ideal
begin
require 'external/dependency'
rescue LoadError; end
Gem::Specification.new do |spec|
spec.name = 'mygem'
spec.version = defined?(External::Dependency) ? External::Dependency.version_helper : ''
....
spec.add_development_dependency 'external-dependency'
end
I think you're stuck with gem install. But I would solve this by adding that step to the Dockerfile I use for the project.
Maybe it's possible to do something like this using rbenv or rvm? Haven't used either of those since migrating to Docker, but rvm gemset is kind of a bootstrap...
I got around it by making the gemspec install the gem during a bundle update or install.
EXTERNAL_DEPENDENCY = Gem::Dependency.new('external-dependency', '~> 0.1')
if File.basename($0) == 'bundle' && ARGV.include?('update') || ARGV.include?('install')
require 'rubygems/dependency_installer'
Gem::DependencyInstaller.new.install(EXTERNAL_DEPENDENCY)
end
and then...
spec.add_development_dependency EXTERNAL_DEPENDENCY.name, EXTERNAL_DEPENDENCY.requirements_list

Dependency issues with Rubygems

I created a gem that has some dependency. I published that gem on Rubygems.org. My gem gets installed on other system, but the gem package is not located. I figured out that this is likely due to my gem dependency not getting installed. Do I need to do any specific thing to get all my dependency installed?
Looking at existing gems I see these components: Gemfile, Gemfile.lock, and whatever.gemspec. Note the gem name is lowercase to match the gemspec file name (I think this was a problem for me before)
Gemfile
source 'https://rubygems.org'
# Specify your gem's dependencies in whatever.gemspec
gemspec
whatever.gemspec
Gem::Specification.new do |spec|
spec.name = "whatever"
spec.add_dependency "hashie"
end

gem install fails with "Could not find a valid gem 'yaml'"

I'm building a gem from a currently working ruby program. It's using jruby 1.7.12 and, among other things, does a "require 'yaml". For the gem, my Gemfile contains:
source 'https://rubygems.org'
gemspec
When I run
gem build program.gemspec
that works just fine, but when I run
gem install program-0.15.01.gem
it fails with
ERROR: Could not find a valid gem 'yaml' (>= 0) in any repository
ERROR: Possible alternatives: aml, cyaml, haml, maml, raml
Doesn't make any sense since the yaml module is part of the ruby 1.9.3 standard library.
I've upgraded to the latest rubygems (2.4.5).
What the heck am I missing?
yaml is part of Ruby. There is no yaml gem (see https://rubygems.org/search?query=yaml).
Therefore remove
s.add_runtime_dependency 'yaml'
from your gemspec and just add require 'yaml' to the file in which you want to use YAML.

Install *gem file with bundle

I try to develop a gem. I include it in my rails application through Gemfile with :path option for testing purpose, but there are some errors that appear when I build it and release to rubygems that does not appear when gem included from local path. How can I install gem from *gem file (made with rake build command) in rails or any bundle driven application for testing?
This will give you the best help: http://guides.rubygems.org/make-your-own-gem/
But in summary you need to build your gem from the .gemspec then using irb require your gem to test it out.
Example:
gem build hola.gemspec
% irb
require 'hola'
=> true

Resources