How to override a pacakge built with `bundlerApp`

I’d like to make asciidoctor use a custom build of ruby. If I go to nixpkgs and apply this:

diff --git i/pkgs/tools/typesetting/asciidoctor/default.nix w/pkgs/tools/typesetting/asciidoctor/default.nix
index f875cc26311..a5e5b0d9657 100644
--- i/pkgs/tools/typesetting/asciidoctor/default.nix
+++ w/pkgs/tools/typesetting/asciidoctor/default.nix
@@ -1,6 +1,7 @@
 { lib, bundlerApp, makeWrapper,
   # Optional dependencies, can be null
   epubcheck, kindlegen,
+  myRuby,
   bundlerUpdateScript
 }:
 
@@ -16,6 +17,8 @@ let
       "asciidoctor-epub3"
     ];
 
+    ruby = myRuby;
+
     buildInputs = [ makeWrapper ];
 
     postBuild = ''
diff --git i/pkgs/top-level/all-packages.nix w/pkgs/top-level/all-packages.nix
index 9b9ecaece81..ea4643bf309 100644
--- i/pkgs/top-level/all-packages.nix
+++ w/pkgs/top-level/all-packages.nix
@@ -9785,6 +9785,19 @@ in
     ruby_2_6
     ruby_2_7;
 
+  myRuby = ruby.override {
+    rubygemsSupport = true;
+    JitSupport = false;
+    useRailsExpress = false;
+    zlibSupport = true;
+    opensslSupport = true;
+    gdbmSupport = false;
+    cursesSupport = false;
+    docSupport = false;
+    yamlSupport = false;
+    fiddleSupport = false;
+  };
+
   rubyMinimal = ruby.override {
     # gem support is minimal overhead
     rubygemsSupport = true;

It works. But If I discard that diff and use this overlay:

self: super:

{
  asciidoctor = self.asciidoctor.override {
    ruby = self.ruby.override {
      rubygemsSupport = true;
      JitSupport = false;
      useRailsExpress = false;
      zlibSupport = true;
      opensslSupport = true;
      gdbmSupport = false;
      cursesSupport = false;
      docSupport = false;
      yamlSupport = false;
      fiddleSupport = false;
    };
  };
}

It fails with:

error: while evaluating the attribute 'asciidoctor.override' at /home/doron/.config/nixpkgs/overlays/test.nix:5:3:
infinite recursion encountered, at undefined position

The infinite recursion is because you’re trying to override self.asciidoctor and assign the results back to asciidoctor. You need to override super.asciidoctor instead.

Also asciidoctor doesn’t take ruby directly. You’ll need to do something like

self: super:

{
  asciidoctor = super.asciidoctor.override {
    bundlerApp = self.bundlerApp.override {
      ruby = self.ruby.override {
        …
      };
    };
  };
}

OK that makes sense - once more the subtlety of self vs super proves it self. But, @lilyball It feels as if this doesn’t make a difference:

I’ve applied this overlay to showcase it:

self: super:

{
  myRuby = super.ruby.override {
    rubygemsSupport = true;
    JitSupport = false;
    useRailsExpress = false;
    zlibSupport = true;
    opensslSupport = true;
    gdbmSupport = false;
    cursesSupport = false;
    docSupport = false;
    yamlSupport = false;
    fiddleSupport = false;
  };
  myAsciidoctor = super.asciidoctor.override {
    bundlerApp = self.bundlerApp.override {
      ruby = self.myRuby;
    };
  };
}

And then I built myAsciidoctor and I think it used a different ruby then the one I told it to. According to:

nix show-derivation -f. myAsciidoctor.bundler.ruby

vs:

nix show-derivation -f. myRuby
Example part of the diff:
{																		{
  "/nix/store/m4af426cldnkib7m60vywimgcfq2j3sn-ruby-2.6.6.drv": {									     |	  "/nix/store/ww4l5dlnc7wr647j0fr58b4gz52xdpyn-ruby-2.6.6.drv": {
    "outputs": {																    "outputs": {
      "devdoc": {															     <
        "path": "/nix/store/ysgz3b9d0cpb1scsjib75lg7jz04gw1q-ruby-2.6.6-devdoc"								     <
      },																     <
      "out": {																	      "out": {
        "path": "/nix/store/vkrhmj35dqfcih95agbpa88j2xk7lnzp-ruby-2.6.6"								     |	        "path": "/nix/store/v608yw4zr37pfn9nmab0qi5pw4ra5w5c-ruby-2.6.6"
      }																		      }
    },																		    },
    "inputSrcs": [																    "inputSrcs": [
      "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh",									     |	      "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
      "/nix/store/wq7zxvl223s5s97y3dhc3gkyk5d6dw0w-rbconfig.rb"										     <
    ],																		    ],
    "inputDrvs": {																    "inputDrvs": {
      "/nix/store/0rmjkqyallafgy9pq9yzakm4zq4sbrkh-openssl-1.1.1g.drv": [									      "/nix/store/0rmjkqyallafgy9pq9yzakm4zq4sbrkh-openssl-1.1.1g.drv": [
        "dev"																	        "dev"
      ],																	      ],
      "/nix/store/4k3a2124489wh1qfv5k69jlvnf3g13nf-ncurses-6.2.drv": [									     |	      "/nix/store/1kb6yv5nsly2acdlfqmvbchbd81w5rn6-remove-references-to.drv": [
        "dev"																     <
      ],																     <
      "/nix/store/4ld134xz2gdws19ip8n47jjk0vjbhzav-libyaml-0.2.4.drv": [								     <
        "out"																	        "out"
      ],																	      ],
      "/nix/store/5chp9cailjvpgnmpw671x7f9pnvla2cd-bison-3.5.4.drv": [										      "/nix/store/5chp9cailjvpgnmpw671x7f9pnvla2cd-bison-3.5.4.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/5rimw6hxjnw7dn39f3y17ggdvmax95id-libffi-3.3.drv": [									     |	      "/nix/store/7972f43hfz2av5slvb4gxivp7vhyk7aq-gcc-wrapper-9.3.0.drv": [
        "dev"																     |	        "out"
      ],																	      ],
      "/nix/store/9prnmsy7bnyksnvv848fam5xn72ds4a0-rubygems.drv": [										      "/nix/store/9prnmsy7bnyksnvv848fam5xn72ds4a0-rubygems.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/adhv49di569bbaimp324an2ww8q04mhv-readline-6.3p08.drv": [								     <
        "dev"																     <
      ],																     <
      "/nix/store/d5fdhfsf7jbjwycy3wc8mn6hxj9xgaq0-stdenv-linux.drv": [										      "/nix/store/d5fdhfsf7jbjwycy3wc8mn6hxj9xgaq0-stdenv-linux.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/dgbvm6a2nynz8gfn6j4fw8yis1pmfsfl-source.drv": [									     <
        "out"																     <
      ],																     <
      "/nix/store/dl7kzk37ifpz8ymjawyy8rcm736k29x1-autoconf-2.69.drv": [									      "/nix/store/dl7kzk37ifpz8ymjawyy8rcm736k29x1-autoconf-2.69.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/i50g0b0kfv4271152qw8ypqqq9zi1gm2-ruby-2.6.6.drv": [									     |	      "/nix/store/fq9mgi95qvzlr08i0zq20c296v3j647k-ruby-2.6.6.tar.gz.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/igfr0giijrg2whpaxq98nmgm77bzprvn-zlib-1.2.11.drv": [										      "/nix/store/igfr0giijrg2whpaxq98nmgm77bzprvn-zlib-1.2.11.drv": [
        "dev"																	        "dev"
      ],																	      ],
      "/nix/store/lgr9qxwqnqc0r3msz0h895hqhq2ydvwk-source.drv": [									     <
        "out"																     <
      ],																     <
      "/nix/store/p56113z64rryp7hp0gyddlai8jr3dxkn-source.drv": [										      "/nix/store/p56113z64rryp7hp0gyddlai8jr3dxkn-source.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/pqgz70sbzmmmrc2f74yk4wk8fcfwrp97-bash-4.4-p23.drv": [										      "/nix/store/pqgz70sbzmmmrc2f74yk4wk8fcfwrp97-bash-4.4-p23.drv": [
        "out"																	        "out"
      ],																	      ],
      "/nix/store/w0gpyavsybcb0wl05b6wddhyby0fa4cl-hook.drv": [											      "/nix/store/w0gpyavsybcb0wl05b6wddhyby0fa4cl-hook.drv": [
        "out"																	        "out"
      ],																     <
      "/nix/store/ywpz012gmfhfhzvbj9abg2m6a5vk1wls-gdbm-1.18.1.drv": [									     <
        "out"																     <
      ],																     <
      "/nix/store/z0h9fs0nlskk43mp45yxycflbpvpmjb6-groff-1.22.4.drv": [									     <
        "out"																     <
      ]																		      ]
    },																		    },
    "platform": "x86_64-linux",															    "platform": "x86_64-linux",
    "builder": "/nix/store/n313xks5ym0s0a5v8a5285rmnmvy6ms9-bash-4.4-p23/bin/bash",								    "builder": "/nix/store/n313xks5ym0s0a5v8a5285rmnmvy6ms9-bash-4.4-p23/bin/bash",
    "args": [																	    "args": [
      "-e",																	      "-e",
      "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"										      "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
    ],																		    ],
    "env": {																	    "env": {
      "NROFF": "/nix/store/b6a7ji8d947zm2h2q925b8h9kjhf3591-groff-1.22.4/bin/nroff",							     <
      "buildFlags": "",																      "buildFlags": "",
      "buildInputs": "/nix/store/adlqzc4wi496i7kg5y171hk5hb0z3q3q-autoconf-2.69 /nix/store/ljah2d66anmgnpjrw79pdh21d7izd6ly-libffi-3.3-dev   |	      "buildInputs": "/nix/store/adlqzc4wi496i7kg5y171hk5hb0z3q3q-autoconf-2.69 /nix/store/0gc02jwnylkyr4rx7hyx97f76ii9v6cx-zlib-1.2.11-dev
      "builder": "/nix/store/n313xks5ym0s0a5v8a5285rmnmvy6ms9-bash-4.4-p23/bin/bash",								      "builder": "/nix/store/n313xks5ym0s0a5v8a5285rmnmvy6ms9-bash-4.4-p23/bin/bash",
      "configureFlags": "--enable-shared --enable-pthread --with-soname=ruby_v2_6_6 --with-baseruby=/nix/store/v2vn13x6s1b51xr9ij79na2crgxq  |	      "configureFlags": "--enable-shared --enable-pthread --with-soname=ruby_v2_6_6 --disable-jit-support --disable-install-doc",
      "depsBuildBuild": "",															      "depsBuildBuild": "",
      "depsBuildBuildPropagated": "",														      "depsBuildBuildPropagated": "",
      "depsBuildTarget": "",															      "depsBuildTarget": "",
      "depsBuildTargetPropagated": "",														      "depsBuildTargetPropagated": "",
      "depsHostHost": "",															      "depsHostHost": "",
      "depsHostHostPropagated": "",														      "depsHostHostPropagated": "",
      "depsTargetTarget": "",															      "depsTargetTarget": "",
      "depsTargetTargetPropagated": "",														      "depsTargetTargetPropagated": "",
      "devdoc": "/nix/store/ysgz3b9d0cpb1scsjib75lg7jz04gw1q-ruby-2.6.6-devdoc",							     <
      "doCheck": "",																      "doCheck": "",
      "doInstallCheck": "",															      "doInstallCheck": "",
      "enableParallelBuilding": "1",														      "enableParallelBuilding": "1",
      "enableParallelChecking": "1",														      "enableParallelChecking": "1",
      "installFlags": "install-doc",													     |	      "installFlags": "",
      "name": "ruby-2.6.6",															      "name": "ruby-2.6.6",
      "nativeBuildInputs": "/nix/store/vp7dr6h8jhj9vnm5rvmbchk1wwwh01kl-hook /nix/store/0jcwbn7cqirazankplg9mn28jpijxa9x-bison-3.5.4 /nix/s  |	      "nativeBuildInputs": "/nix/store/vp7dr6h8jhj9vnm5rvmbchk1wwwh01kl-hook /nix/store/0jcwbn7cqirazankplg9mn28jpijxa9x-bison-3.5.4",
      "out": "/nix/store/vkrhmj35dqfcih95agbpa88j2xk7lnzp-ruby-2.6.6",									     |	      "out": "/nix/store/v608yw4zr37pfn9nmab0qi5pw4ra5w5c-ruby-2.6.6",
      "outputs": "out devdoc",														     |	      "outputs": "out",
      "patches": "/nix/store/8xizavnghyyiblsinw9paqm0jcxfdcpq-source/patches/ruby/2.6/head/railsexpress/01-fix-broken-tests-caused-by-ad.pa  |	      "patches": "",
      "pname": "ruby",																      "pname": "ruby",
      "postInstall": "# Remove unnecessary groff reference from runtime closure, since it's big\nsed -i '/NROFF/d' $out/lib/ruby/*/*/rbconf  |	      "postInstall": "# Remove unnecessary groff reference from runtime closure, since it's big\nsed -i '/NROFF/d' $out/lib/ruby/*/*/rbconf
      "postPatch": "sed -i configure.ac -e '/config.guess/d'\ncp --remove-destination /nix/store/90djdksdw2v570m4z9c7dynmrprw4ag3-source/co	      "postPatch": "sed -i configure.ac -e '/config.guess/d'\ncp --remove-destination /nix/store/90djdksdw2v570m4z9c7dynmrprw4ag3-source/co
      "postUnpack": "rm -rf $sourceRoot/{lib,test}/rubygems*\ncp -r /nix/store/2ab93by4ic0l95kpclaabsnckfxzf0nl-rubygems/lib/rubygems* $sou	      "postUnpack": "rm -rf $sourceRoot/{lib,test}/rubygems*\ncp -r /nix/store/2ab93by4ic0l95kpclaabsnckfxzf0nl-rubygems/lib/rubygems* $sou
      "preConfigure": "configureFlagsArray+=(\"--with-ridir=$devdoc/share/ri\")\n",							     |	      "preConfigure": "",
      "preInstall": "# Ruby installs gems here itself now.\nmkdir -pv \"$out/lib/ruby/gems/2.6.0\"\nexport GEM_HOME=\"$out/lib/ruby/gems/2.	      "preInstall": "# Ruby installs gems here itself now.\nmkdir -pv \"$out/lib/ruby/gems/2.6.0\"\nexport GEM_HOME=\"$out/lib/ruby/gems/2.
      "propagatedBuildInputs": "",														      "propagatedBuildInputs": "",
      "propagatedNativeBuildInputs": "",													      "propagatedNativeBuildInputs": "",
      "src": "/nix/store/njiqb0dhad3sn9a40pam36xwfpk8bkr2-source",									     |	      "src": "/nix/store/n7hy5f4a6sya87x4i4sn7a56w9c20wc5-ruby-2.6.6.tar.gz",
      "stdenv": "/nix/store/2p8fmj0yrvhbjdy25ac87jvccg7lygrg-stdenv-linux",									      "stdenv": "/nix/store/2p8fmj0yrvhbjdy25ac87jvccg7lygrg-stdenv-linux",
      "strictDeps": "",																      "strictDeps": "",
      "system": "x86_64-linux",															      "system": "x86_64-linux",
      "version": "2.6.6"															      "version": "2.6.6"
    }																		    }
  }																		  }
}																		}

However, this works:

self: super:

{
  ruby = super.ruby.override {
    # rubyMinimal disables too much features required by asciidoctor
    rubygemsSupport = true;
    JitSupport = false;
    useRailsExpress = false;
    zlibSupport = true;
    opensslSupport = true;
    gdbmSupport = false;
    cursesSupport = false;
    docSupport = false;
    yamlSupport = false;
    fiddleSupport = false;
  };
}

But that’s overriding all rubys, not only the one used by a bundlerApp, so it’s not an answer to the original question.

Looks like I was wrong, bundlerApp repeats the ruby argument but defaults it to the ruby provided to the bundlerApp derivation itself. However overriding it on bundlerApp doesn’t actually work because bundlerApp defers to a separate bundled-common package which won’t get the override that way.

Given that, try asciidoctor.override (old: { ruby = self.myRuby; }) after all. That should not only override ruby on bundlerApp but also provide the same definition to the bundled-common package.

Also FWIW, asciidoctor.bundler.ruby just tells you the ruby used for the bundler tool, which is meaningless here. Look at asciidoctor.ruby instead, that will tell you the version of ruby actually used by the gem itself.

This:

self: super:

{
  myRuby = super.ruby.override {
    ...
  };
  asciidoctor = super.asciidoctor.override (old: {
    ruby = self.myRuby;
  });
}

Fails with:

error: while evaluating anonymous function at /var/src/nixpkgs/lib/customisation.nix:77:32, called from /home/doron/.config/nixpkgs/overlays/test.nix:17:17:
while evaluating 'makeOverridable' at /var/src/nixpkgs/lib/customisation.nix:67:24, called from /var/src/nixpkgs/lib/customisation.nix:77:41:
anonymous function at /var/src/nixpkgs/pkgs/tools/typesetting/asciidoctor/default.nix:1:1 called with unexpected argument 'ruby', at /var/src/nixpkgs/lib/customisation.nix:69:16

I could be wrong but I thought @volth may have had some thoughts on ruby infrastructure and having it better support this type of thing…

Oh shoot, you’re right, bundlerApp doesn’t have its own independent makeOverridable call. Not that it would actually work in this case anyway now that I think about it, because asciidoctor is pulled in with callPackage so override is overriding its arguments and there’s no way to “unwrap” an override.

I feel like bundlerApp should have its own variant of overrideAttrs (ideally something standardized by the various language platform helpers).

We could also make a change to bundler-app/default.nix to allow overriding ruby on bundlerApp itself to work, which is to explicitly pass the ruby argument to bundled-common even if it wasn’t given directly to bundlerApp.

At this point I think what you need to do looks like

self: super:

{
  myRuby = super.ruby.override {
    …
  };
  asciidoctor = super.asciidoctor.override (_: {
    bundlerApp = super.bundlerApp.override (_: {
      ruby = self.myRuby;
      callPackage = self.newScope { ruby = self.myRuby; };
    });
  });
}

This should pass the new ruby through to bundled-common as well.