I’ve been trying to get bundlerEnv to use a newer version of bundler, and have been going down many rabbitholes.
Here’s the bundler.nix that I’d like to use in place of the older bundler version (2.1.4)
{ buildRubyGem, makeWrapper, ruby, coreutils }:
buildRubyGem rec {
inherit ruby;
name = "${gemName}-${version}";
gemName = "bundler";
version = "2.2.11";
source.sha256 = "1izx6wsjdm6mnbxazgz1z5qbhwrrisbq0np2nmx4ij6lrqjy18jf";
dontPatchShebangs = true;
postFixup = ''
sed -i -e "s/activate_bin_path/bin_path/g" $out/bin/bundle
# silence an annoying warning about sudo being needed
sed -i -e '/if sudo_needed/I,+2 d' $out/lib/ruby/gems/${ruby.version.libDir}/gems/${name}/lib/bundler.rb
'';
}
One option is to add this as an overlay to override pkgs.bundler, but that seems to cause an awful lot of rebuilds from source for any other packages that happen to use ruby.
Can anyone see a good reason that isn’t already the case? I’m basically doing the monkeys-on-typewriters approach to fixing this, I can’t say I’ve got a good understanding on what’s going on with nix/bundlerEnv.
And is there a way of using that newer version of bundler short of getting that fix upstreamed into nixpkgs?
The following is written chronologically during the hours i spent working on this:
From looking through the code shouldn’t bundlerEnv use the bundler included in the gemset?
I foolishly thought this before trying it out on my own project that uses bundlerEnv and bundix. I have still not gotten it to work that well.
If the gemset contains a specification for bundler bundlerEnv will use that but if you use bundix it will delete that specification the next time you run it, unless you manually add bundler to the Gemfile.lock file, which will be deleted by bundler the next time you run it.
After looking some more at the code and commit history for bundlerEnv it is clear that there are some gaps left from when bundlerEnv was split into multiple components. The code that determines the version of bundler used is all over the place.
basicEnv will use the default bundler or if found the bundler in the gemset and bundlerEnv is just basicEnv most of the time. But if pname attribute is set on bundlerEnv then it will always use the bundler it is called with for generating bin stubs.
So that means that if you use pname and want to use a different bundler you have to specify it in two places:
My personal opinion is that either there should be a top level bundlerCommon that bundlerApp and bundlerEnv take as argument or the callPackage ../bundled-common {} should be replaced with import ../bundled-common { inherit stdenv runCommand ruby lib rsync defaultGemConfig buildRubyGem buildEnv makeWrapper bundler; } so that you have the option of overriding all the arguments to ../bundled-common.
As for the gemset bundler I think bundlerEnv should be changed to use the bundler found by basicEnv so that it will use the gemset bundler if someone else uses that functionality.
I will try and put these changes into a PR later today.