Change:
Using with , currently does not allow me to replace a string that contains spaces. Steps to reproduce the behavior: the code below: It gives the following error: I tried quoting it, escaping the spaces... but none of them seemed to work. The I did succeeds. If applicable, add screenshots to help explain your problem. Add any other context about the problem here. I posted this in the NixOS matrix room a while ago (but I forgot to submit an issue): !$ People showed me some bash magic I couldn't understand, I think they might be helpful and worth checking out. <!-- Please @ people who are in the list of the offending package or module. If in doubt, check for whoever last touched something. -- (git blame) cc (people in the original conversation) Please run and paste the result. (I'm sorry if I described anything incorrectly, I'm a not a native English speaker and I am still trying to improve my language skills) Add a :+1: [reaction] to [issues you find important]. [reaction]: [issues you find important]:
Should be fixed with , please give it a try :)
Wonderful! It worked for me

Discussion:
# See: https://github.com/NixOS/nixpkgs/issues/213408 pkgs.substitute { src = "${systemd}/example/sysctl.d/50-coredump.conf"; <del> replacements = [ </del> <ins> substitutions = [ </ins> "--replace" "${systemd}" "${pkgs.symlinkJoin { name = "systemd"; paths = [ systemd ]; }}"

<del> { stdenvNoCC }: </del> <ins> { lib, stdenvNoCC }: /* This is a wrapper around `substitute` in the stdenv. Attribute arguments: - `name` (optional): The name of the resulting derivation - `src`: The path to the file to substitute - `substitutions`: The list of substitution arguments to pass See https://nixos.org/manual/nixpkgs/stable/#fun-substitute - `replacements`: Deprecated version of `substitutions` that doesn't support spaces in arguments. Example: ```nix { substitute }: substitute { src = ./greeting.txt; substitutions = [ "--replace" "world" "paul" ]; } ``` See ../../test/substitute for tests */ </ins> args: <del> # This is a wrapper around `substitute` in the stdenv. # The `replacements` attribute should be a list of list of arguments # to `substitute`, such as `[ "--replace" "sourcetext" "replacementtext" ]` stdenvNoCC.mkDerivation ({ </del> <ins> let </ins> name = if args ? name then args.name else baseNameOf (toString args.src); <ins> deprecationReplacement = lib.pipe args.replacements [ lib.toList (map (lib.splitString " ")) lib.concatLists (lib.concatMapStringsSep " " lib.strings.escapeNixString) ]; optionalDeprecationWarning = # substitutions is only available starting 24.05. # TODO: Remove support for replacements sometime after the next release lib.warnIf (args ? replacements && lib.isInOldestRelease 2405) '' pkgs.substitute: For "${name}", `replacements` is used, which is deprecated since it doesn't support arguments with spaces. Use `substitutions` instead: substitutions = [ ${deprecationReplacement} ];''; in optionalDeprecationWarning stdenvNoCC.mkDerivation ({ inherit name; </ins> builder = ./substitute.sh; inherit (args) src; preferLocalBuild = true; allowSubstitutes = false; <del> } // args // { replacements = args.replacements; }) </del> <ins> } // args // lib.optionalAttrs (args ? substitutions) { substitutions = assert lib.assertMsg (lib.isList args.substitutions) '' pkgs.substitute: For "${name}", `substitutions` is passed, which is expected to be a list, but it's a ${builtins.typeOf args.substitutions} instead.''; lib.escapeShellArgs args.substitutions; }) </ins>

mkdir -p $out/$dir fi <del> substitute $src $target $replacements </del> <ins> substitutionsList=($replacements) if [[ -v substitutions ]]; then eval "substitutionsList+=($substitutions)" fi substitute $src $target "${substitutionsList[@]}" </ins> if test -n "$isExecutable"; then chmod +x $target

patches = [ (substitute { src = ./libamplsolver-sharedlib.patch; <del> replacements = [ "--replace" "@sharedlibext@" "${stdenv.hostPlatform.extensions.sharedLibrary}" ]; </del> <ins> substitutions = [ "--replace" "@sharedlibext@" "${stdenv.hostPlatform.extensions.sharedLibrary}" ]; </ins> }) ];

# this patch is from debian: # https://sources.debian.org/data/main/b/binutils/2.38-3/debian/patches/mips64-default-n64.diff (if stdenv.targetPlatform.isMusl <del> then substitute { src = ./mips64-default-n64.patch; replacements = [ "--replace" "gnuabi64" "muslabi64" ]; } </del> <ins> then substitute { src = ./mips64-default-n64.patch; substitutions = [ "--replace" "gnuabi64" "muslabi64" ]; } </ins> else ./mips64-default-n64.patch) # On PowerPC, when generating assembly code, GCC generates a `.machine` # custom instruction which instructs the assembler to generate code for this

# this patch is from debian: # https://sources.debian.org/data/main/b/binutils/2.38-3/debian/patches/mips64-default-n64.diff (if stdenv.targetPlatform.isMusl <del> then substitute { src = ./mips64-default-n64.patch; replacements = [ "--replace" "gnuabi64" "muslabi64" ]; } </del> <ins> then substitute { src = ./mips64-default-n64.patch; substitutions = [ "--replace" "gnuabi64" "muslabi64" ]; } </ins> else ./mips64-default-n64.patch) # This patch fixes a bug in 2.40 on MinGW, which breaks DXVK when cross-building from Darwin. # See https://sourceware.org/bugzilla/show_bug.cgi?id=30079

patches = [(substitute { src = ./disable-git-version.patch; <del> replacements = [ "--subst-var-by" "version" version ]; </del> <ins> substitutions = [ "--subst-var-by" "version" version ]; </ins> })]; depsHash = "sha256-0P/BcjNnbDN25DguRcCyzPuUG7bouxEx1ySodIbSwvg=";

auto-patchelf-hook = callPackage ./auto-patchelf-hook { }; systemd = callPackage ./systemd { }; <ins> substitute = recurseIntoAttrs (callPackage ./substitute { }); </ins> }

<ins> { substitute, testers, runCommand }: let # Ofborg doesn't allow any traces on stderr, # so mock `lib` to not trace warnings, # because substitute gives a deprecation warning substituteSilent = substitute.override (prevArgs: { lib = prevArgs.lib.extend (finalLib: prevLib: { trivial = prevLib.trivial // { warn = msg: value: value; }; }); }); in { substitutions = testers.testEqualContents { assertion = "substitutions-spaces"; actual = substitute { src = builtins.toFile "source" '' Hello world! ''; substitutions = [ "--replace-fail" "Hello world!" "Yo peter!" ]; }; expected = builtins.toFile "expected" '' Yo peter! ''; }; legacySingleReplace = testers.testEqualContents { assertion = "substitute-single-replace"; actual = substituteSilent { src = builtins.toFile "source" '' Hello world! ''; replacements = [ "--replace-fail" "world" "paul" ]; }; expected = builtins.toFile "expected" '' Hello paul! ''; }; legacyString = testers.testEqualContents { assertion = "substitute-string"; actual = substituteSilent { src = builtins.toFile "source" '' Hello world! ''; # Not great that this works at all, but is supported replacements = "--replace-fail world string"; }; expected = builtins.toFile "expected" '' Hello string! ''; }; legacySingleArg = testers.testEqualContents { assertion = "substitute-single-arg"; actual = substituteSilent { src = builtins.toFile "source" '' Hello world! ''; # Not great that this works at all, but is supported replacements = [ "--replace-fail world list" ]; }; expected = builtins.toFile "expected" '' Hello list! ''; }; legacyVar = testers.testEqualContents { assertion = "substitute-var"; actual = substituteSilent { src = builtins.toFile "source" '' @greeting@ @name@! ''; # Not great that this works at all, but is supported replacements = [ "--subst-var name" "--subst-var-by greeting Yo" ]; name = "peter"; }; expected = builtins.toFile "expected" '' Yo peter! ''; }; } </ins>