summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFrederik Rietdijk <fridh@fridh.nl>2020-01-13 16:08:59 +0100
committerFrederik Rietdijk <fridh@fridh.nl>2020-01-13 16:08:59 +0100
commited1b0d0bac6438fbfcb2dca77493edcbe3384114 (patch)
treed9ddecb505723c8c45ca2837e08e121f41b49fd2 /lib
parent960f062825d22e328828766f4910b702f81ddade (diff)
parentde66fc6a2a2483f4bbbb759c55176643df6e38ba (diff)
Merge master into staging-next
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix2
-rw-r--r--lib/sources.nix34
-rwxr-xr-xlib/tests/modules.sh3
-rw-r--r--lib/trivial.nix2
-rw-r--r--lib/types.nix80
5 files changed, 103 insertions, 18 deletions
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/tests/modules.sh b/lib/tests/modules.sh
index c8340ff7f157..8cd632a439cd 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
# Check that disabledModules works recursively and correctly
checkConfigOutput "true" config.enable ./disable-recursive/main.nix
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;
diff --git a/lib/types.nix b/lib/types.nix
index e86f6d364761..ab325fd20091 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -340,18 +340,80 @@ rec {
let
padWidth = stringLength (toString (length def.value));
unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i;
+ 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.name or (unnamed elemIdx);
+ { name = nameValueNew (elem.${nameAttr} or (unnamed elemIdx)) (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;
+ more = lib.optionalString (length def.value > 3) "... ";
+ 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}.
@@ -359,10 +421,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
@@ -430,14 +492,16 @@ rec {
else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);
allModules = defs: modules ++ imap1 (n: { value, file }:
- # Annotate the value with the location of its definition for better error messages
- coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value
+ if isAttrs value || isFunction value then
+ # Annotate the value with the location of its definition for better error messages
+ coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value
+ else value
) defs;
in
mkOptionType rec {
name = "submodule";
- check = x: isAttrs x || isFunction x;
+ check = x: isAttrs x || isFunction x || path.check x;
merge = loc: defs:
(evalModules {
modules = allModules defs;