summaryrefslogtreecommitdiffstats
path: root/lib/generators.nix
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2022-11-07 13:01:13 +0100
committerpennae <82953136+pennae@users.noreply.github.com>2022-12-08 17:52:52 +0100
commit0b661ce32af9baa07da56b3f48fcd3ef5611b66c (patch)
tree71056af5bcad19b694c5fcf980ba5180f9574f0f /lib/generators.nix
parent0fa7b1b004788881733dc117edd7699f77384166 (diff)
lib/generators.toPretty: escape strings properly
Diffstat (limited to 'lib/generators.nix')
-rw-r--r--lib/generators.nix24
1 files changed, 13 insertions, 11 deletions
diff --git a/lib/generators.nix b/lib/generators.nix
index 9620b8b27b9b..06823d215e36 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -297,17 +297,19 @@ rec {
else if isFloat v then "~${toString v}"
else if isString v then
let
- # Separate a string into its lines
- newlineSplits = filter (v: ! isList v) (builtins.split "\n" v);
- # For a '' string terminated by a \n, which happens when the closing '' is on a new line
- multilineResult = "''" + introSpace + concatStringsSep introSpace (lib.init newlineSplits) + outroSpace + "''";
- # For a '' string not terminated by a \n, which happens when the closing '' is not on a new line
- multilineResult' = "''" + introSpace + concatStringsSep introSpace newlineSplits + "''";
- # For single lines, replace all newlines with their escaped representation
- singlelineResult = "\"" + libStr.escape [ "\"" ] (concatStringsSep "\\n" newlineSplits) + "\"";
- in if multiline && length newlineSplits > 1 then
- if lib.last newlineSplits == "" then multilineResult else multilineResult'
- else singlelineResult
+ lines = filter (v: ! isList v) (builtins.split "\n" v);
+ escapeSingleline = libStr.escape [ "\\" "\"" "\${" ];
+ escapeMultiline = libStr.replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
+ singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
+ multilineResult = let
+ escapedLines = map escapeMultiline lines;
+ # The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
+ # indentation level. Otherwise, '' is appended to the last line.
+ lastLine = lib.last escapedLines;
+ in "''" + introSpace + concatStringsSep introSpace (lib.init escapedLines)
+ + (if lastLine == "" then outroSpace else introSpace + lastLine) + "''";
+ in
+ if multiline && length lines > 1 then multilineResult else singlelineResult
else if true == v then "true"
else if false == v then "false"
else if null == v then "null"