How to override this derivation?

tl;dr: Sometimes overrideAttrs doesn’t seem to override everything and old version-specific attributes are left behind leading to build failures. What to do in this case?


Whenever a new version of SoftMaker Office is going to be released, the old version goes on special for like 20 bucks, so I grabbed a cheap license. Of course, this license is only valid for the old version of SoftMaker Office, so in my personal overlay I’m trying to override the version-specific attributes, to downgrade to my licensed version.

However, it seems like you cannot override the softmaker-office derivation in this way. Consider the following Nix expression:

# test1.nix
with import (fetchTarball { url = "https://nixos.org/channels/nixos-unstable/nixexprs.tar.xz"; }) {};

let
  version = "976";
  edition = "2018";
in softmaker-office.overrideAttrs (oldAttrs: {
  pname = "softmaker-office";
  inherit version edition;
  suiteName = "SoftMaker Office";
  src = fetchurl {
    url = "https://www.softmaker.net/down/softmaker-office-${edition}-${version}-amd64.tgz";
    sha256 = "0s8kzpc6w2cjkfqmhb2p1pkmkiq9vk9gnc7z2992kijaf9bwk3qz";
  };
  archive = "office${edition}.tar.lzma";
})

When I instantiate this expression and search for the version number that I wanted to override, there are still matches:

$ nix show-derivation $(nix-instantiate test1.nix) | grep -c 2021 
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
3

Of course this derivation fails to build, because now there is a mix of different editions all over the place. Taking a look at the derivation in softmaker_office.nix in the nixpkgs tree I find that this derivation is created by calling a generic.nix package with appropriate arguments. In fact, when I write a derivation which uses that, it works:

# test2.nix
with import <nixpkgs> {};

let
  version = "976";
  edition = "2018";
in callPackage <nixpkgs/pkgs/applications/office/softmaker/generic.nix> {
  pname = "softmaker-office";
  inherit version edition;
  suiteName = "SoftMaker Office";
  src = fetchurl {
    url = "https://www.softmaker.net/down/softmaker-office-${edition}-${version}-amd64.tgz";
    sha256 = "0s8kzpc6w2cjkfqmhb2p1pkmkiq9vk9gnc7z2992kijaf9bwk3qz";
  };
  archive = "office${edition}.tar.lzma";
}

Instantiating shows no reference to the wrong edition:

$ nix show-derivation $(nix-instantiate test2.nix) | grep -c 2021
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
0

This however is really bad, because this depends on NIX_PATH and I want this to work even if my NIX_PATH is empty. How can I override this derivation without depending on NIX_PATH?

overrideAttrs overrides the attributes passed to the mkDerivation correctly but it does not change the original scope. The phases in the expression refer to values from the scope so your changes do not apply to them.

One possible fix would be changing the interpolation of Nix variable ${src} to a use of $src environment variable. The environment variables are only set by the builder from the attributes passed to mkDerivation so your changes would manifest there. The same would have to be done for other variables you would like to tweak like archive or edition.

Alternately, since values are passed as function arguments through callPackage, it would be nicer to override them using override but that might not be possible when there are two nested callPackage calls. Not completely sure about this but would expect override to only work for the outer one in all-packages.nix.

Finally, you do not need to use angle bracket paths, "${<nixpkgs>}/pkgs/applications/office/softmaker/generic.nix" or "${fetchTarball { url = "https://nixos.org/channels/nixos-unstable/nixexprs.tar.xz"; }}/pkgs/applications/office/softmaker/generic.nix" should work just as well.

Hm, that’s what I suspected, that there needs to be an upstream change in nixpkgs to support this.

Thanks for the hint with the path, though. In fact, the package set has an attribute path that resolves to the store path where nixpkgs is unpacked. So in my overlay I can do something like this:

(self: super: {
  "${self.path}/pkgs/applications/office/softmaker/generic.nix";
})

Maintainer here. The problem with softmaker-office/freeoffice is that people often want to override it, though for another reason, namely because upstream replaces tarballs (even of older versions) when newer versions become available. So, there is often a window between them releasing a new version and me noticing/updating the derivation. Since upstream does not want to fix this, I asked them permission to make the tarballs available from some other location (e.g. archive.org), but unfortunately progress has been stuck for almost 6 months:

https://forum.softmaker.com/viewtopic.php?f=320&t=19327

Anyway, I think a reasonable solution in this case may be to make version/edition/sha256 arguments of the outer derivation (with default values), so that the version/hash could be overridden with override rather than messing around with overrideAttrs.

Let me know if that is an acceptable solution and I’ll do a PR.

Could you please share how other people override it? Because overrideAttrs doesn’t work and the callPackage "path" approach is pretty ugly (in my opinion).

That sounds good, but src would have to be overridable as well for the moving URL you mentioned.

I would guess the latter :wink: .

I am not sure I follow. Passing a different edition, version and sha256 would then also use the URL with those values in fetchURL. E.g. with the proposed change (I’ll do a draft PR in a minute),

softmaker-office.override {
  officeVersion = {
    edition = "2018";
    version = "976";
    sha256 = "0j6zm0cbxrcgm7glk84hvvbp4z0ys6v8bkwwhl5r7dbphyi72fw8";
  };
}

gives me the latest Softmaker Office 2018 release.

Or do you want to use a different URL altogether?

@hmenke in case you want to try: softmaker-office, freeoffice: make it easy to override versions by danieldk · Pull Request #96163 · NixOS/nixpkgs · GitHub

Well, you mentioned that you’d want to host the upstream tarballs on something like archive.org eventually to work around the unpredictable hash changes.

This looks really good. I wanted to run nixpkgs-review but that doesn’t seem to work for draft PRs.

1 Like