Overriding the version of a package without overrideAttrs

I’m trying to install a pre-release version of the mindustry package (derivation), but the source isn’t exposed in the derivation’s attribute set.

The way I’d usually do this would be something like:

package.overrideAttrs (old: rec {
  version = "135";
  src = fetFromGitHub (old.src // {
    ref = "v{version}";
  };
})

Except the derivation for mindustry looks roughly like that:

let
  pname = "mindustry";
  version = "v126.2";
  Mindustry = fetchFromGitHub {
    # ...
  };
  someDeps = fetchFromGitHub {
    # ...
  };
  moreDeps = fetchFromGitHub {
    # ...
  };
in mkDerivation {
  inherit pname version;
  buildInputs = [
    # ...
  ];
  buildPhase = with lib; ''
    # Use ${Mindustry}, ${someDeps} and ${moreDeps}
  '';
}

I’d like to avoid copying all the build scripts and just change the version, because I don’t want to maintain them in my configuration, and I’m okay pening a PR on nixpkgs. But I’m wondering what would be the best way to go about this ? I originally thought I’d add a version or usePreRelease argument to the package function, defaulting to a stable version or false (respectively), but I’ve never seen this elsewhere in nixpkgs so I’m not sure it’s the right idea.

(Mentioning @fgaz @petabyteboy since they’re the package maintainers).

1 Like

As the source is manually referenced in the unpackPhase (which should be overridable), my immediate thought on how to try go about solving this without changing anything in upstream nixpkgs would be to use builtins.replaceStrings (or some other string substitution/manipulation function) to replace the ${Mindustry} reference with your own.

That’s ugly if it works, but it’d be great if it did because this is not an uncommon issue. Presumably nix resolves the path before your string substitution though?

Presumably nix resolves the path before your string substitution though?

Presumably, and that does complicate how to actually go about doing it. Still shouldn’t be impossible given that there’s a lot simple static string surrounding it, and the source path itself should look pretty much the same as any other (barring the hash of course).

A simpler approach in this specific case — with the added downside of downloading Mindustry twice — would be to append:

rm -r Mindustry
cp -r ${yourSource} Mindustry
etc

Since there’s no way to grab directly, I’d have to have a fetchFromGitHub for the “old” sources in my override and update the shas everytime I update the nixpkgs’ revision I override from ? I’d rather just make an environment with the dependencies and just launch the jar that way if I’m not making this available upstream (which I’m ready to do, a bunch of mods and servers require the pre-release to work).

No, that’s not needed, as you can get the old source path with both builtins.substring and builtins.match (more robust):

nix-repl> mindustry.unpackPhase
"cp -r /nix/store/vvg8djscvvnyvrg0bvsk3mpxgh6z5zis-source Mindustry\ncp -r /nix/store/szggpmqbdylg9d1mizw1qsl54psizxv0-source Arc\nchmod -R u+w -- Mindustry Arc\ncp /nix/store/i0nfwi39a5bg845clqaa5w15dcp41kxy-source/stb_image.h Arc/arc-core/csrc/\ncp -r /nix/store/ms3hx2qwhrx68mh28qif3jpagfiys19g-source Arc/arc-core/csrc/soloud\nchmod -R u+w -- Arc\n"

nix-repl> builtins.substring 6 50 mindustry.unpackPhase
"/nix/store/vvg8djscvvnyvrg0bvsk3mpxgh6z5zis-source"

nix-repl> builtins.match ".*cp -r (/nix/store/.{32}-source) Mindustry.*" mindustry.unpackPhase
[ "/nix/store/vvg8djscvvnyvrg0bvsk3mpxgh6z5zis-source" ]

And then replace that with your own:

nix-repl> builtins.replaceStrings [(builtins.head (builtins.match ".*cp -r (/nix/store/.{32}-source) Mindustry.*" mindustry.unpackPhase))] ["yourSourceHere"] mindustry.unpackPhase
"cp -r yourSourceHere Mindustry\ncp -r /nix/store/szggpmqbdylg9d1mizw1qsl54psizxv0-source Arc\nchmod -R u+w -- Mindustry Arc\ncp /nix/store/i0nfwi39a5bg845clqaa5w15dcp41kxy-source/stb_image.h Arc/arc-core/csrc/\ncp -r /nix/store/ms3hx2qwhrx68mh28qif3jpagfiys19g-source Arc/arc-core/csrc/soloud\nchmod -R u+w -- Arc\n"
1 Like