NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.74k stars 13.86k forks source link

rake: associated Gem is not exposed #78900

Open vincentbernat opened 4 years ago

vincentbernat commented 4 years ago

Describe the bug

I am trying to package a Ruby application. Inside its gemspec, it does:

require 'rake'

So, to build Gemfile.lock and gemset.nix, I am using this shell.nix:

with import <nixpkgs> {};
stdenv.mkDerivation {
  name = "env";
  buildInputs = [
    ruby.devEnv
    rake
    git
    bundix
  ];
}

However, when running bundle lock, it complains:

$ bundle lock
[!] There was an error parsing `Gemfile`:
[!] There was an error while loading `jerakia.gemspec`: cannot load such file -- rake
Does it try to require a relative path? That's been removed in Ruby 1.9. Bundler cannot continue.

 #  from /home/bernat/code/blade/jerakia/jerakia.gemspec:1
 #  -------------------------------------------
 >  require 'rake'
 #  require './lib/jerakia/version'
 #  -------------------------------------------
. Bundler cannot continue.

 #  from /home/bernat/code/blade/jerakia/Gemfile:3
 #  -------------------------------------------
 #
 >  gemspec
 #
 #  -------------------------------------------

Unlike bundix, rake doesn't expose its gem for build. Note that I am not very experienced with Nix. Maybe I am missing something obvious.

To Reproduce Steps to reproduce the behavior:

  1. git clone git@github.com:jerakia/jerakia.git
  2. cd jerakia
  3. Use above shell.nix
  4. nix-shell
  5. bundle lock

Alternative:

  1. nix-shell -p rake ruby
  2. require 'rake'
    Traceback (most recent call last):
        6: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/bin/irb:23:in `<main>'
        5: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/bin/irb:23:in `load'
        4: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        3: from (irb):1
        2: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:92:in `require'
        1: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:92:in `require'
    LoadError (cannot load such file -- rake)

Expected behavior require 'rack' should load the appropriate lib.

Metadata

Maintainer information:

attribute: [ rake ]
module:

cc @manveru @nicknovitski

manveru commented 4 years ago

The rake derivation is only useful for its executable when you want to execute a Rakefile. To get a Ruby that can find rake, use this:

nix-shell -p 'ruby.withPackages (p: [ p.rake ])' --run 'ruby -rrake -e "p Rake::VERSION"'

Or for use in nix-shell:

let
  pkgs = import (fetchTarball {
    url = https://github.com/nixos/nixpkgs-channels/archive/690dd986b2349d2c9cd6437e820954ed400f37f7.tar.gz;
    sha256 = "0p7amn7raw5rahyxw3jq21378n7i7ld4122hm5dddlbcvmpw60p0";
  }) {};
in pkgs.mkShell {
  buildInputs = [
    (pkgs.ruby.withPackages (p: [ p.rake ]))
  ];
}

The ruby.withPackages will wrap Ruby with the appropriate GEM_PATH from a large selection of gems:

[nix-shell:~]$ cat $(which ruby)
#! /nix/store/715fljdrspphbdk255r729zxp4w7lcgk-bash-4.4-p23/bin/bash -e
export GEM_PATH='/nix/store/vcm0inyl5y59168ah5g7wy8z5bcfm2rm-ruby-gems/lib/ruby/gems/2.6.0'
exec "/nix/store/nni62pjp1f43x06hdd8mbxzspx7nsdqx-ruby-2.6.5/bin/ruby"  "$@"
vincentbernat commented 4 years ago

Thanks for your input! I thought I had already tried to do that, but I've always left ruby.devEnv in buildInputs and in this case, this doesn't work. With nix-shell:

$ nix-shell -p ruby.devEnv 'ruby.withPackages (p: [ p.rake ])' --run 'ruby -rrake -e "p Rake::VERSION"'
Traceback (most recent call last):
        1: from /nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:92:in `require'
/nix/store/c1y1h2qw06sql1vlwxixkqk9fpw33a8s-ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:92:in `require': cannot load such file -- rake (LoadError)

How to install gems when using ruby.devEnv?

Thanks!

manveru commented 4 years ago

The two are mutually exclusive, the ruby.devEnv is meant to be used with bundlerEnv, which you'll need to combine with a gemset.nix generated from Bundix. You cannot have two ruby executables be used in your environment at the same time easily.

vincentbernat commented 4 years ago

In my case, the gemspec is requiring rake, so to be able to generate Gemfile.lock and gemset.nix, I need to have both a ruby with rake as a gem and ability to execute bundle and bundix.

stale[bot] commented 4 years ago

Hello, I'm a bot and I thank you in the name of the community for opening this issue.

To help our human contributors focus on the most-relevant reports, I check up on old issues to see if they're still relevant. This issue has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.

The community would appreciate your effort in checking if the issue is still valid. If it isn't, please close it.

If the issue persists, and you'd like to remove the stale label, you simply need to leave a comment. Your comment can be as simple as "still important to me". If you'd like it to get more attention, you can ask for help by searching for maintainers and people that previously touched related code and @ mention them in a comment. You can use Git blame or GitHub's web interface on the relevant files to find them.

Lastly, you can always ask for help at our Discourse Forum or at #nixos' IRC channel.