From 0f6231702fc1ccde0130bcbf297ff415d17b06d8 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 4 Sep 2020 17:19:55 +0200 Subject: lib/generators.toPretty: Only quote attribute names if necessary --- lib/generators.nix | 2 +- lib/tests/misc.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index abd237eb7d37..800ef5be4fcd 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -227,7 +227,7 @@ rec { else "{ " + libStr.concatStringsSep " " (libAttr.mapAttrsToList (name: value: - "${toPretty args name} = ${toPretty args value};") v) + "${libStr.escapeNixIdentifier name} = ${toPretty args value};") v) + " }" else if isFunction v then let fna = lib.functionArgs v; diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index b066f577f323..7d7380e8b74b 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -469,7 +469,7 @@ runTests { function = "<λ>"; functionArgs = "<λ:{(arg),foo}>"; list = "[ 3 4 ${function} [ false ] ]"; - attrs = "{ \"foo\" = null; \"foo bar\" = \"baz\"; }"; + attrs = "{ foo = null; \"foo bar\" = \"baz\"; }"; drv = "<δ:test>"; }; }; -- cgit v1.2.3 From 4811f54e94756d8a83ee9fb439e56675033923ae Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 4 Sep 2020 17:23:28 +0200 Subject: lib/generators.toPretty: Wrap in a go function As a preparation to the following commit --- lib/generators.nix | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index 800ef5be4fcd..e6b9b6b66c8b 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -204,7 +204,7 @@ rec { will use fn to convert val to a pretty printed representation. (This means fn is type Val -> String.) */ allowPrettyValues ? false - }@args: v: with builtins; + }@args: let go = v: with builtins; let isPath = v: typeOf v == "path"; in if isInt v then toString v else if isFloat v then "~${toString v}" @@ -214,7 +214,7 @@ rec { else if null == v then "null" else if isPath v then toString v else if isList v then "[ " - + libStr.concatMapStringsSep " " (toPretty args) v + + libStr.concatMapStringsSep " " go v + " ]" else if isAttrs v then # apply pretty values if allowed @@ -227,7 +227,7 @@ rec { else "{ " + libStr.concatStringsSep " " (libAttr.mapAttrsToList (name: value: - "${libStr.escapeNixIdentifier name} = ${toPretty args value};") v) + "${libStr.escapeNixIdentifier name} = ${go value};") v) + " }" else if isFunction v then let fna = lib.functionArgs v; @@ -237,6 +237,7 @@ rec { in if fna == {} then "<λ>" else "<λ:{${showFnas}}>" else abort "generators.toPretty: should never happen (v = ${v})"; + in go; # PLIST handling toPlist = {}: v: let -- cgit v1.2.3 From 47f2eb89c16a74881c6e1a3b18290bf3d0f94a60 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 4 Sep 2020 17:46:12 +0200 Subject: lib/generators.toPretty: Implement multiline printing --- lib/generators.nix | 25 +++++++++++++++---------- lib/tests/misc.nix | 26 +++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index e6b9b6b66c8b..23a74c757f8a 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -203,9 +203,14 @@ rec { /* If this option is true, attrsets like { __pretty = fn; val = …; } will use fn to convert val to a pretty printed representation. (This means fn is type Val -> String.) */ - allowPrettyValues ? false - }@args: let go = v: with builtins; + allowPrettyValues ? false, + /* If this option is true, the output is indented with newlines for attribute sets and lists */ + multiline ? true + }@args: let + go = indent: v: with builtins; let isPath = v: typeOf v == "path"; + introSpace = if multiline then "\n${indent} " else " "; + outroSpace = if multiline then "\n${indent}" else " "; in if isInt v then toString v else if isFloat v then "~${toString v}" else if isString v then ''"${libStr.escape [''"''] v}"'' @@ -213,9 +218,9 @@ rec { else if false == v then "false" else if null == v then "null" else if isPath v then toString v - else if isList v then "[ " - + libStr.concatMapStringsSep " " go v - + " ]" + else if isList v then "[" + introSpace + + libStr.concatMapStringsSep introSpace (go (indent + " ")) v + + outroSpace + "]" else if isAttrs v then # apply pretty values if allowed if attrNames v == [ "__pretty" "val" ] && allowPrettyValues @@ -224,11 +229,11 @@ rec { else if v ? type && v.type == "derivation" then "<δ:${v.name}>" # "<δ:${concatStringsSep "," (builtins.attrNames v)}>" - else "{ " - + libStr.concatStringsSep " " (libAttr.mapAttrsToList + else "{" + introSpace + + libStr.concatStringsSep introSpace (libAttr.mapAttrsToList (name: value: - "${libStr.escapeNixIdentifier name} = ${go value};") v) - + " }" + "${libStr.escapeNixIdentifier name} = ${go (indent + " ") value};") v) + + outroSpace + "}" else if isFunction v then let fna = lib.functionArgs v; showFnas = concatStringsSep "," (libAttr.mapAttrsToList @@ -237,7 +242,7 @@ rec { in if fna == {} then "<λ>" else "<λ:{${showFnas}}>" else abort "generators.toPretty: should never happen (v = ${v})"; - in go; + in go ""; # PLIST handling toPlist = {}: v: let diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 7d7380e8b74b..4fed8ef01c94 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -446,7 +446,7 @@ runTests { }; testToPretty = { - expr = mapAttrs (const (generators.toPretty {})) rec { + expr = mapAttrs (const (generators.toPretty { multiline = false; })) rec { int = 42; float = 0.1337; bool = true; @@ -474,6 +474,30 @@ runTests { }; }; + testToPrettyMultiline = { + expr = mapAttrs (const (generators.toPretty { })) rec { + list = [ 3 4 [ false ] ]; + attrs = { foo = null; bar.foo = "baz"; }; + }; + expected = rec { + list = '' + [ + 3 + 4 + [ + false + ] + ]''; + attrs = '' + { + bar = { + foo = "baz"; + }; + foo = null; + }''; + }; + }; + testToPrettyAllowPrettyValues = { expr = generators.toPretty { allowPrettyValues = true; } { __pretty = v: "«" + v + "»"; val = "foo"; }; -- cgit v1.2.3 From 073e9b2aed0f855ce26bd3a26dab044c0c17c817 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 17 Sep 2020 17:58:04 +0200 Subject: lib/generators.toPretty: Improved string printing, handling newlines --- lib/generators.nix | 14 +++++++++++++- lib/tests/misc.nix | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index 23a74c757f8a..81bedd13d80a 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -213,7 +213,19 @@ rec { outroSpace = if multiline then "\n${indent}" else " "; in if isInt v then toString v else if isFloat v then "~${toString v}" - else if isString v then ''"${libStr.escape [''"''] 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 else if true == v then "true" else if false == v then "false" else if null == v then "null" diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 4fed8ef01c94..813a8e7f815f 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -450,7 +450,9 @@ runTests { int = 42; float = 0.1337; bool = true; + emptystring = ""; string = ''fno"rd''; + newlinestring = "\n"; path = /. + "/foo"; null_ = null; function = x: x; @@ -463,7 +465,9 @@ runTests { int = "42"; float = "~0.133700"; bool = "true"; + emptystring = ''""''; string = ''"fno\"rd"''; + newlinestring = "\"\\n\""; path = "/foo"; null_ = "null"; function = "<λ>"; @@ -478,6 +482,16 @@ runTests { expr = mapAttrs (const (generators.toPretty { })) rec { list = [ 3 4 [ false ] ]; attrs = { foo = null; bar.foo = "baz"; }; + newlinestring = "\n"; + multilinestring = '' + hello + there + test + ''; + multilinestring' = '' + hello + there + test''; }; expected = rec { list = '' @@ -495,6 +509,19 @@ runTests { }; foo = null; }''; + newlinestring = "''\n \n''"; + multilinestring = '' + ''' + hello + there + test + '''''; + multilinestring' = '' + ''' + hello + there + test'''''; + }; }; -- cgit v1.2.3 From d0be9e98109428e67e4b7fab3e49728cc6633073 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 17 Sep 2020 18:08:44 +0200 Subject: =?UTF-8?q?lib/generators.toPretty:=20Switch=20away=20from=20?= =?UTF-8?q?=CE=B4=20and=20=CE=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - These symbols can be confusing for those not familiar with them - There's no harm in making these more obvious - Terminals may not print them correctly either Also changes the function argument printing slightly to be more obvious --- lib/generators.nix | 12 +++++------- lib/tests/misc.nix | 13 ++++++++----- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index 81bedd13d80a..205092a2681b 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -237,10 +237,8 @@ rec { # apply pretty values if allowed if attrNames v == [ "__pretty" "val" ] && allowPrettyValues then v.__pretty v.val - # TODO: there is probably a better representation? else if v ? type && v.type == "derivation" then - "<δ:${v.name}>" - # "<δ:${concatStringsSep "," (builtins.attrNames v)}>" + "" else "{" + introSpace + libStr.concatStringsSep introSpace (libAttr.mapAttrsToList (name: value: @@ -248,11 +246,11 @@ rec { + outroSpace + "}" else if isFunction v then let fna = lib.functionArgs v; - showFnas = concatStringsSep "," (libAttr.mapAttrsToList - (name: hasDefVal: if hasDefVal then "(${name})" else name) + showFnas = concatStringsSep ", " (libAttr.mapAttrsToList + (name: hasDefVal: if hasDefVal then name + "?" else name) fna); - in if fna == {} then "<λ>" - else "<λ:{${showFnas}}>" + in if fna == {} then "" + else "" else abort "generators.toPretty: should never happen (v = ${v})"; in go ""; diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 813a8e7f815f..2456b52c099c 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -445,7 +445,10 @@ runTests { expected = builtins.toJSON val; }; - testToPretty = { + testToPretty = + let + deriv = derivation { name = "test"; builder = "/bin/sh"; system = builtins.currentSystem; }; + in { expr = mapAttrs (const (generators.toPretty { multiline = false; })) rec { int = 42; float = 0.1337; @@ -459,7 +462,7 @@ runTests { functionArgs = { arg ? 4, foo }: arg; list = [ 3 4 function [ false ] ]; attrs = { foo = null; "foo bar" = "baz"; }; - drv = derivation { name = "test"; system = builtins.currentSystem; }; + drv = deriv; }; expected = rec { int = "42"; @@ -470,11 +473,11 @@ runTests { newlinestring = "\"\\n\""; path = "/foo"; null_ = "null"; - function = "<λ>"; - functionArgs = "<λ:{(arg),foo}>"; + function = ""; + functionArgs = ""; list = "[ 3 4 ${function} [ false ] ]"; attrs = "{ foo = null; \"foo bar\" = \"baz\"; }"; - drv = "<δ:test>"; + drv = ""; }; }; -- cgit v1.2.3 From 05e4d371ef5c3819b969d34eb76ed7e4b3c99027 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 17 Sep 2020 18:14:18 +0200 Subject: lib/generators.toPretty: Print [] and {} compactly --- lib/generators.nix | 7 +++++-- lib/tests/misc.nix | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index 205092a2681b..716ae77973f4 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -230,13 +230,16 @@ rec { else if false == v then "false" else if null == v then "null" else if isPath v then toString v - else if isList v then "[" + introSpace + else if isList v then + if v == [] then "[ ]" + else "[" + introSpace + libStr.concatMapStringsSep introSpace (go (indent + " ")) v - + outroSpace + "]" + + outroSpace + "]" else if isAttrs v then # apply pretty values if allowed if attrNames v == [ "__pretty" "val" ] && allowPrettyValues then v.__pretty v.val + else if v == {} then "{ }" else if v ? type && v.type == "derivation" then "" else "{" + introSpace diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 2456b52c099c..f60e6ad17870 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -461,7 +461,9 @@ runTests { function = x: x; functionArgs = { arg ? 4, foo }: arg; list = [ 3 4 function [ false ] ]; + emptylist = []; attrs = { foo = null; "foo bar" = "baz"; }; + emptyattrs = {}; drv = deriv; }; expected = rec { @@ -476,7 +478,9 @@ runTests { function = ""; functionArgs = ""; list = "[ 3 4 ${function} [ false ] ]"; + emptylist = "[ ]"; attrs = "{ foo = null; \"foo bar\" = \"baz\"; }"; + emptyattrs = "{ }"; drv = ""; }; }; -- cgit v1.2.3 From 15c5ba9d28dbdcebd3320864b62fdc7f2b37defd Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 17 Sep 2020 18:18:50 +0200 Subject: lib/generators.toPretty: functors should print as functions Not attribute sets. So move the function case forward --- lib/generators.nix | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/generators.nix b/lib/generators.nix index 716ae77973f4..501a23599f45 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -235,6 +235,13 @@ rec { else "[" + introSpace + libStr.concatMapStringsSep introSpace (go (indent + " ")) v + outroSpace + "]" + else if isFunction v then + let fna = lib.functionArgs v; + showFnas = concatStringsSep ", " (libAttr.mapAttrsToList + (name: hasDefVal: if hasDefVal then name + "?" else name) + fna); + in if fna == {} then "" + else "" else if isAttrs v then # apply pretty values if allowed if attrNames v == [ "__pretty" "val" ] && allowPrettyValues @@ -247,13 +254,6 @@ rec { (name: value: "${libStr.escapeNixIdentifier name} = ${go (indent + " ") value};") v) + outroSpace + "}" - else if isFunction v then - let fna = lib.functionArgs v; - showFnas = concatStringsSep ", " (libAttr.mapAttrsToList - (name: hasDefVal: if hasDefVal then name + "?" else name) - fna); - in if fna == {} then "" - else "" else abort "generators.toPretty: should never happen (v = ${v})"; in go ""; -- cgit v1.2.3