bundix icon indicating copy to clipboard operation
bundix copied to clipboard

Serialization of Nil object crashes the CLI

Open paulrbr-fl opened this issue 6 years ago • 5 comments

Reproduce the bug

While trying to generate a gemset.nix with Bundix I got the following error and stacktrace:

Traceback (most recent call last):                                                                                       
        30: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/bin/.bundix-wrapped:18:in `<main>'                                                                                                      
        29: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/bin/.bundix-wrapped:18:in `load'                 
        28: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/bin/bundix:5:in `<top (required)>'
        27: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/commandline.rb:22:in `run' 
        26: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/commandline.rb:36:in `run'
        25: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/commandline.rb:158:in `save_gemset'                                                    
        24: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/commandline.rb:152:in `object2nix'                                                     
        23: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:20:in `serialize'                                                             
        22: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:83:in `serialize'                                                             
        21: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `result'                                                                                                     
        20: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `eval'                                                                                                       
        19: from (erb):2:in `serialize'                                                                                                                                                                           
        18: from (erb):2:in `each'                                                                                                                                                                                
        17: from (erb):2:in `block in serialize'                                                                                                                                                                  
        16: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:69:in `sub'        
        15: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:83:in `serialize'
        14: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `result'                                                                                                     
        13: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `eval'                           
        12: from (erb):2:in `serialize'                                                                                                                                                                           
        11: from (erb):2:in `each'                                                                                                                                                                                
        10: from (erb):2:in `block in serialize'                                                                                        
         9: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:69:in `sub'
         8: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:85:in `serialize'
         7: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `result'             
         6: from /nix/store/ircjrhgliaq9r64jzk7gi2xi881521km-ruby-2.5.3/lib/ruby/2.5.0/erb.rb:876:in `eval'             
         5: from (erb):1:in `serialize'                                                                                                                    
         4: from (erb):1:in `each_with_index'                                                                                                     
         3: from (erb):1:in `each'                                                                                                                  
         2: from (erb):1:in `block in serialize'                                                                                                
         1: from /nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:69:in `sub' 
/nix/store/dfrk2vp3g8xj8jm9gdb8hs83vqqfzmvx-bundix-2.4.1/lib/ruby/gems/2.5.0/gems/bundix-2.4.1/lib/bundix/nixer.rb:100:in `serialize': Cannot convert to nix: nil (RuntimeError)

This happened to me with a generic 'gem' Gemfile:

source "https://rubygems.org"

gemspec

With the gem specification in the *.gemspec file:

Gem::Specification.new do |s|
  [...]

  s.add_dependency "pg", "~> 1.1.4"

  s.add_development_dependency "pry"
  s.add_development_dependency "standard"
  s.add_development_dependency "rake"
  s.add_development_dependency "minitest"
  s.add_development_dependency "vcr"
  s.add_development_dependency "webmock"
end

Quick fix

After applying a manual patch to handle nil object in the serializer case in bundix, the result works (with some extra junk in the platforms list of some gems)

Solution

I would rather have someone from the maintainer of bundix to check if it is safe to simply handle the nil cases in the serializer or if the problem comes from somewhere else before submitting a PR.

paulrbr-fl avatar May 16 '19 11:05 paulrbr-fl

I am encountering what appears to be a similar issue. Looks like it comes from Bundix::PLATFORM_MAPPING lacking certain Ruby platforms:

#!/usr/bin/env nix-shell                                        
#! nix-shell -i ruby -p bundler bundix                          
                                                                
require 'bundix'                                                
require 'bundix/commandline'                                    
                                                                
bundix_cli = Bundix::CommandLine.new.tap(&:parse_options)       
bundix = Bundix.new(bundix_cli.options)                         
cache = bundix.parse_gemset                                     
lock = bundix.parse_lockfile                                    
dep_cache = bundix.build_depcache(lock)                         
                                                                
unhandled_platforms = lock.specs.flat_map do |spec|             
  dep_cache.fetch(spec.name).platforms.reject do |platform_name|
    Bundix::PLATFORM_MAPPING.key? platform_name.to_s            
  end                                                           
end                                                             
                                                                
puts unhandled_platforms.sort.uniq.to_a                         
$ ./bundix-unhandled-platforms.rb
truffleruby

And, FWIW:

$ nix-shell --run 'command -v ruby bundler bundix' -p ruby bundler bundix
/nix/store/rwp5fpzqssf5m9dzbgbwsfgdzw8xajra-ruby-2.5.5/bin/ruby
/nix/store/q3m22q8z2rsq1hjy6lsv4amavyf872lw-bundler-1.17.2/bin/bundle
/nix/store/xxa511193snkcjdcj8di4l1yslris4k3-bundix-2.4.1/bin/bundix

Happy to provide any additional information on my environment if it would be helpful.


I am not sure what action Bundix should take in response to an unrecognized platform -- ignore it? Issue an exception? Auto-generate a hash? E.g.:

# bundix.rb

PLATFORM_MAPPING = Hash.new do |platform_mapping, platform_name|
  case platform_name_s = platform_name.to_s
  when /(\w+)_(\d+)/
    version = $2.chars.join('.')
    platform_mapping[platform_name_s] = {:engine => $1, :version => version}
  else
    platform_mapping[platform_name_s] = {:engine => platform_name_s}
  end
end

tomeon avatar Jun 25 '19 16:06 tomeon

I also faced a similar error when trying to create a Rails environment. nix-shell version: 2.19.3

Command:

$ nix-shell \
 -p "ruby.withPackages (ps: with ps; [ rails ])" \
 -p bundix \
 --run "rails new blog --skip-bundle && cd blog && bundle lock && bundix"

Error:

/nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:100:in `serialize': Cannot convert to nix: nil (RuntimeError)
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:69:in `sub'
        from (erb):1:in `block in serialize'
        from (erb):1:in `each'
        from (erb):1:in `each_with_index'
        from (erb):1:in `serialize'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `eval'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `result'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:85:in `serialize'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:69:in `sub'
        from (erb):2:in `block in serialize'
        from (erb):2:in `each'
        from (erb):2:in `serialize'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `eval'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `result'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:83:in `serialize'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:69:in `sub'
        from (erb):2:in `block in serialize'
        from (erb):2:in `each'
        from (erb):2:in `serialize'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `eval'
        from /nix/store/mqvgyyxws079dwijpslhgmm5ylmx880a-ruby-3.1.4/lib/ruby/3.1.0/erb.rb:905:in `result'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:83:in `serialize'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/nixer.rb:20:in `serialize'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/commandline.rb:153:in `object2nix'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/commandline.rb:159:in `save_gemset'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/commandline.rb:37:in `run'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/lib/bundix/commandline.rb:22:in `run'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/lib/ruby/gems/3.1.0/gems/bundix-2.5.0/bin/bundix:5:in `<top (required)>'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/bin/.bundix-wrapped:18:in `load'
        from /nix/store/2xpdl61qc2pzf4s4hk5a70299amdxs3p-bundix-2.5.2/bin/.bundix-wrapped:18:in `<main>'

Has this problem been ignored for a long time?

whtsht avatar Jan 27 '24 10:01 whtsht

This bug currently prevents bundix from running on freshly generated rails apps.

quickdudley avatar Apr 07 '24 20:04 quickdudley

@quickdudley I have pushed up a fix in my fork. Feel free to give it a try

inscapist avatar Apr 09 '24 16:04 inscapist

Thanks you @inscapist ! Your fork fixed my problem (I couldn't start a rails new app).

Might I be so bold as to suggest raising the priority of this issue, as it's morphed into something that breaks a key use case, and we seem to have a fix. Then maybe close #12 a bit later?

  • EDIT: I tried to post an alternate workaround for other noobs, but it was rubbish, so I'm deleting it with this edit.

For other confused noobs wondering how I eventually solved my problem and got Rails working, I used instructions and software from https://github.com/inscapist/ruby-nix to generate a flake.nix, which I meant I could later run nix develop and get a shell with binaries running from /nix/store/.../bin/some-bin.

nagi avatar Jun 29 '24 01:06 nagi