diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix index 1fdf4c3883da..1b0a62c2e8e7 100644 --- a/nixos/modules/system/activation/top-level.nix +++ b/nixos/modules/system/activation/top-level.nix @@ -74,7 +74,9 @@ let baseSystemAssertWarn else (pkgs.replaceDependencies.override { - nix = config.nix.package; + replaceDirectDependencies = pkgs.replaceDirectDependencies.override { + nix = config.nix.package; + }; }) { drv = baseSystemAssertWarn; inherit replacements cutoffPackages; diff --git a/pkgs/build-support/replace-dependencies.nix b/pkgs/build-support/replace-dependencies.nix index 2af6d19c268d..af0a2c05d623 100644 --- a/pkgs/build-support/replace-dependencies.nix +++ b/pkgs/build-support/replace-dependencies.nix @@ -1,7 +1,7 @@ { - runCommandLocal, - nix, lib, + runCommandLocal, + replaceDirectDependencies, }: # Replace some dependencies in the requisites tree of drv, propagating the change all the way up the tree, even within other replacements, without a full rebuild. @@ -43,15 +43,13 @@ let inherit (builtins) unsafeDiscardStringContext appendContext; inherit (lib) trace - substring stringLength - concatStringsSep - mapAttrsToList listToAttrs attrValues mapAttrs filter hasAttr + mapAttrsToList all ; inherit (lib.attrsets) mergeAttrsList; @@ -90,21 +88,6 @@ let echo }) > $out '' ).outPath; - rewriteHashes = - drv: rewrites: - if rewrites == { } then - drv - else - let - drvName = substring 33 (stringLength (baseNameOf drv)) (baseNameOf drv); - in - runCommandLocal drvName { nixStore = "${nix}/bin/nix-store"; } '' - $nixStore --dump ${drv} | sed 's|${baseNameOf drv}|'$(basename $out)'|g' | sed -e ${ - concatStringsSep " -e " ( - mapAttrsToList (name: value: "'s|${baseNameOf name}|${baseNameOf value}|g'") rewrites - ) - } | $nixStore --restore $out - ''; knownDerivations = [ drv ] ++ map ({ newDependency, ... }: newDependency) replacements; referencesMemo = listToAttrs ( @@ -162,7 +145,13 @@ let }) rewrittenReferences ); in - rewriteHashes storePathOrKnownDerivationMemo.${drv} rewrites + replaceDirectDependencies { + drv = storePathOrKnownDerivationMemo.${drv}; + replacements = mapAttrsToList (name: value: { + oldDependency = name; + newDependency = value; + }) rewrites; + } ) relevantReferences // listToAttrs ( map (drv: { diff --git a/pkgs/build-support/replace-direct-dependencies.nix b/pkgs/build-support/replace-direct-dependencies.nix new file mode 100644 index 000000000000..b579a097c442 --- /dev/null +++ b/pkgs/build-support/replace-direct-dependencies.nix @@ -0,0 +1,25 @@ +{ + lib, + runCommandLocal, + nix, +}: + +# Replace some direct dependencies of drv, not recursing into the dependency tree. +# You likely want to use replaceDependencies instead, unless you plan to implement your own recursion mechanism. +{ drv, replacements ? [ ] }: +let inherit (lib) all stringLength substring concatStringsSep; +in assert all ({ oldDependency, newDependency }: + stringLength oldDependency == stringLength newDependency) replacements; +if replacements == [ ] then + drv +else + let drvName = substring 33 (stringLength (baseNameOf drv)) (baseNameOf drv); + in runCommandLocal drvName { nixStore = "${nix}/bin/nix-store"; } '' + $nixStore --dump ${drv} | sed 's|${ + baseNameOf drv + }|'$(basename $out)'|g' | sed -e ${ + concatStringsSep " -e " (map ({ oldDependency, newDependency }: + "'s|${baseNameOf oldDependency}|${baseNameOf newDependency}|g'") + replacements) + } | $nixStore --restore $out + '' diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 93df75b3b5b9..bcc9af48f461 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1319,6 +1319,8 @@ with pkgs; replaceVars = callPackage ../build-support/replace-vars { }; + replaceDirectDependencies = callPackage ../build-support/replace-direct-dependencies.nix { }; + nukeReferences = callPackage ../build-support/nuke-references { inherit (darwin) signingUtils; };