From 6525da6321a7272faa0c2b1c15ffd3501888e9b9 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 3 Jan 2020 05:22:11 +0100 Subject: lib/types: Allow paths as submodule values --- lib/tests/modules.sh | 3 +-- lib/types.nix | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index f69befd15c64..65b482ec194d 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -174,8 +174,7 @@ checkConfigOutput "true" config.submodule.inner ./declare-submoduleWith-modules. checkConfigOutput "true" config.submodule.outer ./declare-submoduleWith-modules.nix ## Paths should be allowed as values and work as expected -# Temporarily disabled until https://github.com/NixOS/nixpkgs/pull/76861 -#checkConfigOutput "true" config.submodule.enable ./declare-submoduleWith-path.nix +checkConfigOutput "true" config.submodule.enable ./declare-submoduleWith-path.nix cat < Date: Fri, 10 Jan 2020 21:24:31 +0100 Subject: lib.commitIdFromGitRepo: support git-worktree lib.commitIdFromGitRepo now resolves the refs from the parent repository in case the supplied path is a file containing the path to said repository. this adds support for git-worktree and things alike. see gitrepository-layout(5). this also: - adds a new boolean function lib.pathIsRegularFile to check whether a path is a regular file - patches lib.revisionWithDefault and the revision and versionSuffix attributes in config.system.nixos in order to support git-worktrees --- lib/default.nix | 2 +- lib/sources.nix | 34 ++++++++++++++++++++++++++++------ lib/trivial.nix | 2 +- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/default.nix b/lib/default.nix index 9f7a088d792d..77dda17f3b4f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -100,7 +100,7 @@ let inherit (sources) pathType pathIsDirectory cleanSourceFilter cleanSource sourceByRegex sourceFilesBySuffices commitIdFromGitRepo cleanSourceWith pathHasContext - canCleanSource; + canCleanSource pathIsRegularFile; inherit (modules) evalModules unifyModuleSyntax applyIfFunction mergeModules mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions diff --git a/lib/sources.nix b/lib/sources.nix index 51bcf5559e32..0fd172c42b77 100644 --- a/lib/sources.nix +++ b/lib/sources.nix @@ -9,6 +9,9 @@ rec { # Returns true if the path exists and is a directory, false otherwise pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false; + # Returns true if the path exists and is a regular file, false otherwise + pathIsRegularFile = p: if builtins.pathExists p then (pathType p) == "regular" else false; + # Bring in a path as a source, filtering out all Subversion and CVS # directories, as well as backup files (*~). cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! ( @@ -110,24 +113,43 @@ rec { with builtins; let fileName = toString path + "/" + file; packedRefsName = toString path + "/packed-refs"; - in if lib.pathExists fileName + in if pathIsRegularFile path + # Resolve git worktrees. See gitrepository-layout(5) + then + let m = match "^gitdir: (.*)$" (lib.fileContents path); + in if m == null + then throw ("File contains no gitdir reference: " + path) + else + let gitDir = lib.head m; + commonDir' = if pathIsRegularFile "${gitDir}/commondir" + then lib.fileContents "${gitDir}/commondir" + else gitDir; + commonDir = if lib.hasPrefix "/" commonDir' + then commonDir' + else toString (/. + "${gitDir}/${commonDir'}"); + refFile = lib.removePrefix "${commonDir}/" "${gitDir}/${file}"; + in readCommitFromFile refFile commonDir + + else if pathIsRegularFile fileName + # Sometimes git stores the commitId directly in the file but + # sometimes it stores something like: «ref: refs/heads/branch-name» then let fileContent = lib.fileContents fileName; - # Sometimes git stores the commitId directly in the file but - # sometimes it stores something like: «ref: refs/heads/branch-name» matchRef = match "^ref: (.*)$" fileContent; - in if matchRef == null + in if matchRef == null then fileContent else readCommitFromFile (lib.head matchRef) path + + else if pathIsRegularFile packedRefsName # Sometimes, the file isn't there at all and has been packed away in the # packed-refs file, so we have to grep through it: - else if lib.pathExists packedRefsName then let fileContent = readFile packedRefsName; matchRef = match (".*\n([^\n ]*) " + file + "\n.*") fileContent; - in if matchRef == null + in if matchRef == null then throw ("Could not find " + file + " in " + packedRefsName) else lib.head matchRef + else throw ("Not a .git directory: " + path); in readCommitFromFile "HEAD"; diff --git a/lib/trivial.nix b/lib/trivial.nix index 3a25e31fb052..940ec1a3d59e 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -191,7 +191,7 @@ rec { let revisionFile = "${toString ./..}/.git-revision"; gitRepo = "${toString ./..}/.git"; - in if lib.pathIsDirectory gitRepo + in if builtins.pathExists gitRepo then lib.commitIdFromGitRepo gitRepo else if lib.pathExists revisionFile then lib.fileContents revisionFile else default; -- cgit v1.2.3 From b0c2c96cbe12c5a3a280ffd2634ebe0c8507e8b0 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 11 Jan 2020 08:54:42 +0100 Subject: lib/types: improve loaOf warning Not all modules use name attribute as the name of the submodule, for example, environment.etc uses target. We will need to maintain a list of exceptions. --- lib/types.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/types.nix b/lib/types.nix index e86f6d364761..cbbea00058d0 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -340,18 +340,22 @@ rec { let padWidth = stringLength (toString (length def.value)); unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i; + nameAttrs = { + "environment.etc" = "target"; + }; + nameAttr = nameAttrs.${option} or "name"; res = { inherit (def) file; value = listToAttrs ( imap1 (elemIdx: elem: - { name = elem.name or (unnamed elemIdx); + { name = elem.${nameAttr} or (unnamed elemIdx); value = elem; }) def.value); }; option = concatStringsSep "." loc; sample = take 3 def.value; - list = concatMapStrings (x: ''{ name = "${x.name or "unnamed"}"; ...} '') sample; - set = concatMapStrings (x: ''${x.name or "unnamed"} = {...}; '') sample; + list = concatMapStrings (x: ''{ ${nameAttr} = "${x.${nameAttr} or "unnamed"}"; ...} '') sample; + set = concatMapStrings (x: ''${x.${nameAttr} or "unnamed"} = {...}; '') sample; msg = '' In file ${def.file} a list is being assigned to the option config.${option}. -- cgit v1.2.3 From 6fc46fbb177e22d467c9d92d0fac8581afa81246 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 11 Jan 2020 13:32:30 +0100 Subject: lib/types: only show ... in loaOf warning when necessary --- lib/types.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/types.nix b/lib/types.nix index cbbea00058d0..6eebc20829c6 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -354,6 +354,7 @@ rec { }; option = concatStringsSep "." loc; sample = take 3 def.value; + more = lib.optionalString (length def.value > 3) "... "; list = concatMapStrings (x: ''{ ${nameAttr} = "${x.${nameAttr} or "unnamed"}"; ...} '') sample; set = concatMapStrings (x: ''${x.${nameAttr} or "unnamed"} = {...}; '') sample; msg = '' @@ -363,10 +364,10 @@ rec { See https://git.io/fj2zm for more information. Do ${option} = - { ${set}...} + { ${set}${more}} instead of ${option} = - [ ${list}...] + [ ${list}${more}] ''; in lib.warn msg res -- cgit v1.2.3 From 13633bd21ac92dce92f920fd68578f5e430c6c0d Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 11 Jan 2020 15:02:57 +0100 Subject: lib/types: improve loaOf message even more Now we suggest correct names for all options in Nixpkgs and also home-manager at the time of writing. --- lib/types.nix | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/types.nix b/lib/types.nix index 6eebc20829c6..a090af78acda 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -340,23 +340,80 @@ rec { let padWidth = stringLength (toString (length def.value)); unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i; - nameAttrs = { - "environment.etc" = "target"; - }; - nameAttr = nameAttrs.${option} or "name"; + anyString = placeholder "name"; + nameAttrs = [ + { path = [ "environment" "etc" ]; + name = "target"; + } + { path = [ "containers" anyString "bindMounts" ]; + name = "mountPoint"; + } + { path = [ "programs" "ssh" "knownHosts" ]; + # hostNames is actually a list so we would need to handle it only when singleton + name = "hostNames"; + } + { path = [ "fileSystems" ]; + name = "mountPoint"; + } + { path = [ "boot" "specialFileSystems" ]; + name = "mountPoint"; + } + { path = [ "services" "znapzend" "zetup" ]; + name = "dataset"; + } + { path = [ "services" "znapzend" "zetup" anyString "destinations" ]; + name = "label"; + } + { path = [ "services" "geoclue2" "appConfig" ]; + name = "desktopID"; + } + { path = [ "home-manager" "users" anyString "programs" "ssh" "matchBlocks" ]; + name = "host"; # https://github.com/rycee/home-manager/blob/e8dbc3561373b68d12decb3c0d7c1ba245f138f7/modules/programs/ssh.nix#L265 + } + { path = [ "home-manager" "users" anyString "home" "file" ]; + name = "target"; # https://github.com/rycee/home-manager/blob/0e9b7aab3c6c27bf020402e0e2ef20b65c040552/modules/files.nix#L33 + } + { path = [ "home-manager" "users" anyString "xdg" "configFile" ]; + name = "target"; # https://github.com/rycee/home-manager/blob/54de0e1d79a1370e57a8f23bef89f99f9b92ab67/modules/misc/xdg.nix#L41 + } + { path = [ "home-manager" "users" anyString "xdg" "dataFile" ]; + name = "target"; # https://github.com/rycee/home-manager/blob/54de0e1d79a1370e57a8f23bef89f99f9b92ab67/modules/misc/xdg.nix#L58 + } + ]; + matched = let + equals = a: b: b == anyString || a == b; + fallback = { name = "name"; }; + in findFirst ({ path, ... }: all (v: v == true) (zipListsWith equals loc path)) fallback nameAttrs; + nameAttr = matched.name; + nameValueOld = value: + if isList value then + if length value > 0 then + "[ " + concatMapStringsSep " " escapeNixString value + " ]" + else + "[ ]" + else + escapeNixString value; + nameValueNew = value: unnamed: + if isList value then + if length value > 0 then + head value + else + unnamed + else + value; res = { inherit (def) file; value = listToAttrs ( imap1 (elemIdx: elem: - { name = elem.${nameAttr} or (unnamed elemIdx); + { name = nameValueNew (elem.${nameAttr} or (unnamed elemIdx)) (unnamed elemIdx); value = elem; }) def.value); }; option = concatStringsSep "." loc; sample = take 3 def.value; more = lib.optionalString (length def.value > 3) "... "; - list = concatMapStrings (x: ''{ ${nameAttr} = "${x.${nameAttr} or "unnamed"}"; ...} '') sample; - set = concatMapStrings (x: ''${x.${nameAttr} or "unnamed"} = {...}; '') sample; + list = concatMapStrings (x: ''{ ${nameAttr} = ${nameValueOld (x.${nameAttr} or "unnamed")}; ...} '') sample; + set = concatMapStrings (x: ''${nameValueNew (x.${nameAttr} or "unnamed") "unnamed"} = {...}; '') sample; msg = '' In file ${def.file} a list is being assigned to the option config.${option}. -- cgit v1.2.3