bundix
bundix copied to clipboard
Serialization of Nil object crashes the CLI
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.
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
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?
This bug currently prevents bundix from running on freshly generated rails apps.
@quickdudley I have pushed up a fix in my fork. Feel free to give it a try
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.