Wed 28 Mar 2018
Reading time: (~ mins)
I found my self making a new gem recently to wrap an api. It's been awhile since I've done gem development. Creating gems has come a long way with it being mostly automagically initialized with bundler and rubygems. They have somewhat standardized gem layout and get you going quickly.
After spending a few hours working on the my gem and writing tests via rspec I wanted to use it as if I were a real user. This means installing the gem locally, opening a ruby session and requireing my gem for some smoke testing.
bundle gem foodie cd foodie # add new class in my gem echo "module Foodie class Price; end end" >> lib/foodie/price.rb # require it in top level file echo -e "require \"foodie/price\"\n$(cat lib/foodie.rb)" > lib/foodie.rb # edit .gemspec sed -i '' '/spec\.[^sm].*TODO/d' foodie.gemspec sed -i 's/%q{TODO.*$/"summary"/g' foodie.gemspec rm foodie.gemspec-e # locally install gem rake install # use my gem ruby -e 'require "foodie"'
Alessandros-MacBook-Air:foodie alessandrominali$ ruby -e 'require "foodie"' /Users/alessandrominali/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/price (LoadError) from /Users/alessandrominali/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require' from /Users/alessandrominali/.rvm/gems/ruby-2.4.1/gems/foodie-0.1.0/lib/foodie.rb:1:in `' from /Users/alessandrominali/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in `require' from /Users/alessandrominali/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require' from /Users/alessandrominali/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:40:in `require' from -e:1:in ` '
Uh oh...what's happening. All my rspec tests are passing and requiring the right files, why does it suddenly fail here?
Can you guess why? Maybe rspec load path is configured more leniently? Do I need to prepend all the files paths with ./ or should I be using require_relative. Nope, no, and I don't think so.
In all it's auto-generated glory the foodie.gemspec file we are given states that it will be only including files that are tracked via git. It was ignoring all the work I had done since I never committed those files. This is slightly tricky to know and reason about since specs were working.
# foodie.gemspec spec.files = `git ls-files -z`.split("\x0").reject do |f| f.match(%r{^(test|spec|features)/}) end
The solution then is quite easy:
git add . rake install ruby -e 'require "foodie"'
Just remember this little necessary detail in the future so that hopefully you can stay productive!