{ 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) isStorePath substring stringLength optionalString escapeShellArgs concatMap ; in if replacements == [ ] then drv else let drvName = if isStorePath drv then # Reconstruct the name from the actual store path if available. substring 33 (stringLength (baseNameOf drv)) (baseNameOf drv) else if drv ? drvAttrs.name then # Try to get the name from the derivation arguments otherwise (for floating or deferred derivations). drv.drvAttrs.name + ( let outputName = drv.outputName or "out"; in optionalString (outputName != "out") "-${outputName}" ) else throw "cannot reconstruct the derivation name from ${drv}"; in runCommandLocal drvName { nativeBuildInputs = [ nix.out ]; } '' createRewriteScript() { while [ $# -ne 0 ]; do oldBasename="$(basename "$1")" newBasename="$(basename "$2")" shift 2 if [ ''${#oldBasename} -ne ''${#newBasename} ]; then echo "cannot rewrite $oldBasename to $newBasename: length does not match" >&2 exit 1 fi echo "s|$oldBasename|$newBasename|g" >> rewrite.sed done } createRewriteScript ${ escapeShellArgs ( [ drv (placeholder "out") ] ++ concatMap ( { oldDependency, newDependency }: [ oldDependency newDependency ] ) replacements ) } nix-store --dump ${drv} | sed -f rewrite.sed | nix-store --restore $out ''