nix-community / bundix

Generates a Nix expression for your Bundler-managed application. [maintainer=@manveru]
163 stars 55 forks source link

attribute '"http_parser.rb"' missing #105

Open retpolanne opened 1 year ago

retpolanne commented 1 year ago

Hey folks!

I'm trying to code a nix-shell for my Jekyll project. However, I get this error:

error: attribute '"http_parser.rb"' missing

I see that http_parser.rb is my Gemfile:

gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]

This is my shell.nix file

with import <nixpkgs> {};

let
  gems = pkgs.bundlerEnv {
    name = "jekyll-gems";
    inherit ruby;
    gemfile = ./Gemfile;
    lockfile = ./Gemfile.lock;
    gemset = ./gemset.nix;
  };
in stdenv.mkDerivation {
  name = "jekyll_env";
  buildInputs = [
    gems
    ruby.devEnv
    bundix
    jekyll
  ];
  shellHook = ''
    exec jekyll serve --watch
  '';
}

In my gemset.nix, http_parser.rb is the only dependency with quotes surrounding it, because of the .rb extension maybe

  google-protobuf = {
    groups = ["default" "jekyll_plugins"];
    platforms = [];
    source = {
      remotes = ["https://rubygems.org"];
      sha256 = "0ldmvy09adac1yqal61ip4iw53zl5jjbs808m6mfrpvgn0bw860r";
      type = "gem";
    };
    version = "3.23.3";
  };
  "http_parser.rb" = {
    groups = ["default" "jekyll_plugins"];
    platforms = [{
      engine = "jruby";
    }];
    source = {
      remotes = ["https://rubygems.org"];
      sha256 = "1gj4fmls0mf52dlr928gaq0c0cb0m3aqa9kaa6l0ikl2zbqk42as";
      type = "gem";
    };
    version = "0.8.0";
  };

If I remove this dependency, the shell starts fine, albeit with some errors from Jekyll.

Trace attached. nix-shell-trace.txt

retpolanne commented 1 year ago

I wonder if this is an error caused by the .rb on the package name.

This is the whole error

       error: attribute '"http_parser.rb"' missing

       at /nix/store/afaxhwsgvx1q56f0wqds6a6b7dmdbvq2-nixpkgs/nixpkgs/lib/attrsets.nix:279:34:

          278|     # The set to get the named attributes from
          279|     attrs: genAttrs names (name: attrs.${name});
             |                                  ^
          280|

Any way to debug attrsets.nix with a debugger?


Debugging

$ nix repl --file shell.nix --debugger
nix-repl> buildInputs 
[ error: attribute '"http_parser.rb"' missing

       at /nix/store/afaxhwsgvx1q56f0wqds6a6b7dmdbvq2-nixpkgs/nixpkgs/lib/attrsets.nix:279:34:

          278|     # The set to get the named attributes from
          279|     attrs: genAttrs names (name: attrs.${name});
             |                                  ^
          280|

Starting REPL to allow you to inspect the current state of the evaluator.

Welcome to Nix 2.16.1. Type :? for help.

nix-repl> attrs
«derivation { addressable = { ... }; colorator = { ... }; concurrent-ruby = { ... }; em-websocket = { ... }; eventmachine = { ... }; ffi = { ... }; forwardable-extended = { ... }; google-protobuf = { ... }; i18n = { ... }; jekyll = { ... }; jekyll-feed = { ... }; jekyll-sass-converter = { ... }; jekyll-seo-tag = { ... }; jekyll-watch = { ... }; kramdown = { ... }; kramdown-parser-gfm = { ... }; liquid = { ... }; listen = { ... }; mercenary = { ... }; minima = { ... }; pathutil = { ... }; public_suffix = { ... }; rb-fsevent = { ... }; rb-inotify = { ... }; rexml = { ... }; rouge = { ... }; safe_yaml = { ... }; sass-embedded = { ... }; terminal-table = { ... }; unicode-display_width = { ... }; webrick = { ... }; }

nix-repl> 

I don't see http_parser.rb here. However, removing the .rb and the quotes makes nix-shell work!

  http_parser = {
    groups = ["default" "jekyll_plugins"];
    platforms = [];
    source = {
      remotes = ["https://rubygems.org"];
      sha256 = "1gj4fmls0mf52dlr928gaq0c0cb0m3aqa9kaa6l0ikl2zbqk42as";
      type = "gem";
    };
    version = "0.8.0";
  };

Obviously it just skips the validation, to make the dependency work properly I had to fork it and rename it.

felipelalli commented 1 year ago

Some issue here. Have you found a solution?

retpolanne commented 1 year ago

Hey @felipelalli check my Gemfile: https://github.com/retpolanne/retpolanne.com/blob/f87303ce39c8c83b8456527911606e9890a75ce2/Gemfile#L28

I forked it with a different name so I can workaround this issue.

PS: make a fork in your own github, for security reasons ;)

PuercoPop commented 11 months ago

@retpolanne Hey I tried to look into this issue but I have not been able to reproduce it. Do you have a minimal reproducible recipe?

I've tried with the following

# Gemfile
source "https://rubygems.org"

# Generate the lock and gemset file by
# rm Gemfile.lock gemset.nix
# nix-shell -p ruby_3_2 bundix
# bundle lock
# bundix
gem "http_parser.rb"
# default.nix
{ system ? builtins.currentSystem, nixpkgs ? fetchTarball {
  url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/23.05.tar.gz";
  sha256 = "10wn0l08j9lgqcw8177nh2ljrnxdrpri7bp0g7nvrsn9rkawvlbf";
}, pkgs ? import nixpkgs {
  overlays = [ ];
  config = { };
  inherit system;
} }:
let
  ruby = pkgs.ruby_3_2;
  gems = pkgs.bundlerEnv {
    inherit ruby;
    name = "jekyll-gems";
    gemfile = ./Gemfile;
    lockfile = ./Gemfile.lock;
    gemset = ./gemset.nix;
  };
in
{
  shell = pkgs.stdenv.mkDerivation {
    name = "jekyll_env";
    src = ./.;
    buildInputs = [
      gems
      gems.wrappedRuby
    ];
  };
}

and the following works

cd ~/src/bundix-http-parser.rb
$ nix-shell -A shell
these 3 derivations will be built:
  /nix/store/4vlyrj5p9ka7nm1bdvbi882bf5p4iqj0-gemfile-and-lockfile.drv
  /nix/store/bgbipxqjywsk8xviar3wr2wzi5350wg2-jekyll-gems.drv
  /nix/store/f56rgy57dn50jkhp8hmxk7fv6s6p72gl-wrapped-ruby-jekyll-gems.drv
building '/nix/store/4vlyrj5p9ka7nm1bdvbi882bf5p4iqj0-gemfile-and-lockfile.drv'...
building '/nix/store/bgbipxqjywsk8xviar3wr2wzi5350wg2-jekyll-gems.drv'...
created 6 symlinks in user environment
building '/nix/store/f56rgy57dn50jkhp8hmxk7fv6s6p72gl-wrapped-ruby-jekyll-gems.drv'...
patching sources
configuring
no configure script, doing nothing
building
running tests
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/ruby
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/racc
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/rdbg
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/erb
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/typeprof
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/ri
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/rdoc
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/rbs
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/rake
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/bundle
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/bundler
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/gem
shrinking /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin/irb
checking for references to /build/ in /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems...
patching script interpreter paths in /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems
stripping (with command strip and flags -S -p) in  /nix/store/s5zcf1vi685dhfpb34vk4d9iz1pyxpyg-wrapped-ruby-jekyll-gems/bin

[nix-shell:~/src/bundix-http-parser.rb]$ irb
>> require 'http/parser'
=> true

Are you using jruby as the ruby?

retpolanne commented 11 months ago

@PuercoPop can you share the generated gemset.nix? That looks like a minimal example to me.

PuercoPop commented 11 months ago

Sure this is the setup I've used to trying to reproduce ithe issue https://github.com/PuercoPop/bundix-http-parser.rb

Note: One thing I haven't done when generating the lock file but I normally do is to set BUNDLE_FORCE_RUBY_PLATFORM: "true so that one can use the same Gemfile.lock across different different platforms/systems

retpolanne commented 10 months ago

@PuercoPop yea, from what I see your setup should trigger this bug. Weird why it didn't trigger it. Maybe it's fixed?

PuercoPop commented 10 months ago

@retpolanne I think the difference that triggers the issue was due to including the :platforms => [:jruby] in the Gemfile. That results in bundix adding an engine = "jruby" entry to "http-parser.rb".platform entry in the reported Gemset.


 platforms = [{
      engine = "jruby";
    }];
``

That is why I asked whether you were trying to build jekyll on jruby or not.

I'm not sure what exactly is the reason, but it seems that adding the platform entry results in cruby trying to load jruby specific code