style: Switch to nixfmt from nixpkgs-fmt

Most of the ecosystem has moved to this formatter,
and many people configured their editors to autoformat it with this formatter.

Closes: https://git.snix.dev/snix/snix/issues/62
Change-Id: Icf39e7836c91fc2ae49fbe22a40a639105bfb0bd
Reviewed-on: https://cl.snix.dev/c/snix/+/30671
Reviewed-by: Florian Klink <flokli@flokli.de>
Tested-by: besadii
Autosubmit: Ilan Joselevich <personal@ilanjoselevich.com>
This commit is contained in:
Ilan Joselevich 2025-08-09 21:08:41 +02:00
parent 3443e6bd08
commit 91d02d8c84
136 changed files with 39952 additions and 11007 deletions

View file

@ -32,25 +32,30 @@ let
map
match
readDir
substring;
substring
;
argsWithPath = args: parts:
let meta.locatedAt = parts;
in meta // (if isAttrs args then args else args meta);
argsWithPath =
args: parts:
let
meta.locatedAt = parts;
in
meta // (if isAttrs args then args else args meta);
readDirVisible = path:
readDirVisible =
path:
let
children = readDir path;
# skip hidden files, except for those that contain special instructions to readTree
isVisible = f: f == ".skip-subtree" || f == ".skip-tree" || (substring 0 1 f) != ".";
names = filter isVisible (attrNames children);
in
listToAttrs (map
(name: {
listToAttrs (
map (name: {
inherit name;
value = children.${name};
})
names);
}) names
);
# Create a mark containing the location of this attribute and
# a list of all child attribute names added by readTree.
@ -60,39 +65,48 @@ let
};
# Create a label from a target's tree location.
mkLabel = target:
let label = concatStringsSep "/" target.__readTree;
in if target ? __subtarget
then "${label}:${target.__subtarget}"
else label;
mkLabel =
target:
let
label = concatStringsSep "/" target.__readTree;
in
if target ? __subtarget then "${label}:${target.__subtarget}" else label;
# Merge two attribute sets, but place attributes in `passthru` via
# `overrideAttrs` for derivation targets that support it.
merge = a: b:
if a ? overrideAttrs
then
a.overrideAttrs
(prev: {
passthru = (prev.passthru or { }) // b;
})
else a // b;
merge =
a: b:
if a ? overrideAttrs then
a.overrideAttrs (prev: {
passthru = (prev.passthru or { }) // b;
})
else
a // b;
# Import a file and enforce our calling convention
importFile = args: scopedArgs: path: parts: filter:
importFile =
args: scopedArgs: path: parts: filter:
let
importedFile =
if scopedArgs != { } && builtins ? scopedImport # For snix
then builtins.scopedImport scopedArgs path
else import path;
if
scopedArgs != { } && builtins ? scopedImport # For snix
then
builtins.scopedImport scopedArgs path
else
import path;
pathType = builtins.typeOf importedFile;
in
if pathType != "lambda"
then throw "readTree: trying to import ${toString path}, but its a ${pathType}, you need to make it a function like { depot, pkgs, ... }"
else importedFile (filter parts (argsWithPath args parts));
if pathType != "lambda" then
throw "readTree: trying to import ${toString path}, but its a ${pathType}, you need to make it a function like { depot, pkgs, ... }"
else
importedFile (filter parts (argsWithPath args parts));
nixFileName = file:
let res = match "(.*)\\.nix" file;
in if res == null then null else head res;
nixFileName =
file:
let
res = match "(.*)\\.nix" file;
in
if res == null then null else head res;
# Internal implementation of readTree, which handles things like the
# skipping of trees and subtrees.
@ -105,7 +119,15 @@ let
# The higher-level `readTree` method assembles the final attribute
# set out of these results at the top-level, and the internal
# `children` implementation unwraps and processes nested trees.
readTreeImpl = { args, initPath, rootDir, parts, argsFilter, scopedArgs }:
readTreeImpl =
{
args,
initPath,
rootDir,
parts,
argsFilter,
scopedArgs,
}:
let
dir = readDirVisible initPath;
@ -123,9 +145,10 @@ let
joinChild = c: initPath + ("/" + c);
self =
if rootDir
then { __readTree = [ ]; }
else importFile (args // { here = result; }) scopedArgs initPath parts argsFilter;
if rootDir then
{ __readTree = [ ]; }
else
importFile (args // { here = result; }) scopedArgs initPath parts argsFilter;
# Import subdirectories of the current one, unless any skip
# instructions exist.
@ -134,88 +157,93 @@ let
# should be ignored, but its content is not inspected by
# readTree
filterDir = f: dir."${f}" == "directory";
filteredChildren = map
(c: {
name = c;
value = readTreeImpl {
inherit argsFilter scopedArgs;
args = args;
initPath = (joinChild c);
rootDir = false;
parts = (parts ++ [ c ]);
};
})
(filter filterDir (attrNames dir));
filteredChildren = map (c: {
name = c;
value = readTreeImpl {
inherit argsFilter scopedArgs;
args = args;
initPath = (joinChild c);
rootDir = false;
parts = (parts ++ [ c ]);
};
}) (filter filterDir (attrNames dir));
# Remove skipped children from the final set, and unwrap the
# result set.
children =
if skipSubtree then [ ]
else map ({ name, value }: { inherit name; value = value.ok; }) (filter (child: child.value ? ok) filteredChildren);
if skipSubtree then
[ ]
else
map (
{ name, value }:
{
inherit name;
value = value.ok;
}
) (filter (child: child.value ? ok) filteredChildren);
# Import Nix files
nixFiles =
if skipSubtree then [ ]
else filter (f: f != null) (map nixFileName (attrNames dir));
nixChildren = map
(c:
let
p = joinChild (c + ".nix");
childParts = parts ++ [ c ];
imported = importFile (args // { here = result; }) scopedArgs p childParts argsFilter;
in
{
name = c;
value =
if isAttrs imported
then merge imported (marker childParts { })
else imported;
})
nixFiles;
nixFiles = if skipSubtree then [ ] else filter (f: f != null) (map nixFileName (attrNames dir));
nixChildren = map (
c:
let
p = joinChild (c + ".nix");
childParts = parts ++ [ c ];
imported = importFile (args // { here = result; }) scopedArgs p childParts argsFilter;
in
{
name = c;
value = if isAttrs imported then merge imported (marker childParts { }) else imported;
}
) nixFiles;
nodeValue = if dir ? "default.nix" then self else { };
allChildren = listToAttrs (
if dir ? "default.nix"
then children
else nixChildren ++ children
);
allChildren = listToAttrs (if dir ? "default.nix" then children else nixChildren ++ children);
result =
if isAttrs nodeValue
then merge nodeValue (allChildren // (marker parts allChildren))
else nodeValue;
if isAttrs nodeValue then
merge nodeValue (allChildren // (marker parts allChildren))
else
nodeValue;
in
if skipTree
then { skip = true; }
else {
ok = result;
};
if skipTree then
{ skip = true; }
else
{
ok = result;
};
# Top-level implementation of readTree itself.
readTree = args:
readTree =
args:
let
tree = readTreeImpl args;
in
if tree ? skip
then throw "Top-level folder has a .skip-tree marker and could not be read by readTree!"
else tree.ok;
if tree ? skip then
throw "Top-level folder has a .skip-tree marker and could not be read by readTree!"
else
tree.ok;
# Helper function to fetch subtargets from a target. This is a
# temporary helper to warn on the use of the `meta.targets`
# attribute, which is deprecated in favour of `meta.ci.targets`.
subtargets = node:
let targets = (node.meta.targets or [ ]) ++ (node.meta.ci.targets or [ ]);
in if node ? meta.targets then
subtargets =
node:
let
targets = (node.meta.targets or [ ]) ++ (node.meta.ci.targets or [ ]);
in
if node ? meta.targets then
builtins.trace ''
Warning: The meta.targets attribute is deprecated.
Please move the subtargets of //${mkLabel node} to the
meta.ci.targets attribute.

''
targets else targets;
'' targets
else
targets;
# Function which can be used to find all readTree targets within an
# attribute set.
@ -231,23 +259,29 @@ let
#
# eligible: Function to determine whether the given derivation
# should be included in the build.
gather = eligible: node:
gather =
eligible: node:
if node ? __readTree then
# Include the node itself if it is eligible.
# Include the node itself if it is eligible.
(if eligible node then [ node ] else [ ])
# Include eligible children of the node
++ concatMap (gather eligible) (map (attr: node."${attr}") node.__readTreeChildren)
# Include specified sub-targets of the node
++ filter eligible (map
(k: (node."${k}" or { }) // {
# Keep the same tree location, but explicitly mark this
# node as a subtarget.
__readTree = node.__readTree;
__readTreeChildren = [ ];
__subtarget = k;
})
(subtargets node))
else [ ];
++ filter eligible (
map (
k:
(node."${k}" or { })
// {
# Keep the same tree location, but explicitly mark this
# node as a subtarget.
__readTree = node.__readTree;
__readTreeChildren = [ ];
__subtarget = k;
}
) (subtargets node)
)
else
[ ];
# Determine whether a given value is a derivation.
# Copied from nixpkgs/lib for cases where lib is not available yet.
@ -256,12 +290,14 @@ in
{
inherit gather mkLabel;
__functor = _:
{ path
, args
, filter ? (_parts: x: x)
, scopedArgs ? { }
, rootDir ? true
__functor =
_:
{
path,
args,
filter ? (_parts: x: x),
scopedArgs ? { },
rootDir ? true,
}:
readTree {
inherit args scopedArgs rootDir;
@ -285,43 +321,56 @@ in
# which should be able to access the restricted folder.
#
# reason: Textual explanation for the restriction (included in errors)
restrictFolder = { folder, exceptions ? [ ], reason }: parts: args:
if (elemAt parts 0) == folder || elem parts exceptions
then args
else args // {
depot = args.depot // {
"${folder}" = throw ''
Access to targets under //${folder} is not permitted from
other repository paths. Specific exceptions are configured
at the top-level.
restrictFolder =
{
folder,
exceptions ? [ ],
reason,
}:
parts: args:
if (elemAt parts 0) == folder || elem parts exceptions then
args
else
args
// {
depot = args.depot // {
"${folder}" = throw ''
Access to targets under //${folder} is not permitted from
other repository paths. Specific exceptions are configured
at the top-level.
${reason}
At location: ${builtins.concatStringsSep "." parts}
'';
${reason}
At location: ${builtins.concatStringsSep "." parts}
'';
};
};
};
# This definition of fix is identical to <nixpkgs>.lib.fix, but is
# provided here for cases where readTree is used before nixpkgs can
# be imported.
#
# It is often required to create the args attribute set.
fix = f: let x = f x; in x;
fix =
f:
let
x = f x;
in
x;
# Takes an attribute set and adds a meta.ci.targets attribute to it
# which contains all direct children of the attribute set which are
# derivations.
#
# Type: attrs -> attrs
drvTargets = attrs:
attrs // {
drvTargets =
attrs:
attrs
// {
# preserve .meta from original attrs
meta = (attrs.meta or { }) // {
# preserve .meta.ci (except .targets) from original attrs
ci = (attrs.meta.ci or { }) // {
targets = builtins.filter
(x: isDerivation attrs."${x}")
(builtins.attrNames attrs);
targets = builtins.filter (x: isDerivation attrs."${x}") (builtins.attrNames attrs);
};
};
};

View file

@ -1,18 +1,26 @@
{ depot, lib, pkgs, ... }:
{
depot,
lib,
pkgs,
...
}:
let
inherit (lib) partition optionalAttrs any;
inherit (builtins) tryEval;
it = msg: asserts:
it =
msg: asserts:
let
results = partition (a: a.ok) asserts;
in
{
_it = msg;
} // optionalAttrs (results.right != [ ]) {
}
// optionalAttrs (results.right != [ ]) {
passes = map (result: result.test) results.right;
} // optionalAttrs (results.wrong != [ ]) {
}
// optionalAttrs (results.wrong != [ ]) {
fails = map (result: result.test) results.wrong;
};
@ -21,16 +29,18 @@ let
ok = a == b;
};
assertThrows = test: value:
assertThrows =
test: value:
let
value' = tryEval value;
in
{
inherit test;
ok = ! value'.success;
ok = !value'.success;
};
runTestsuite = name: its:
runTestsuite =
name: its:
let
fails = any (it': it' ? fails) its;
in
@ -42,11 +52,14 @@ let
inherit its;
}
(
if fails then ''
jq '.its' < .attrs.json
'' else ''
jq '.its' < .attrs.json > $out
''
if fails then
''
jq '.its' < .attrs.json
''
else
''
jq '.its' < .attrs.json > $out
''
);
tree-ex = depot.nix.readTree {
@ -55,25 +68,14 @@ let
};
example = it "corresponds to the README example" [
(assertEq "third_party attrset"
(lib.isAttrs tree-ex.third_party
&& (! lib.isDerivation tree-ex.third_party))
true)
(assertEq "third_party attrset other attribute"
tree-ex.third_party.favouriteColour
"orange")
(assertEq "rustpkgs attrset aho-corasick"
tree-ex.third_party.rustpkgs.aho-corasick
"aho-corasick")
(assertEq "rustpkgs attrset serde"
tree-ex.third_party.rustpkgs.serde
"serde")
(assertEq "tools cheddear"
"cheddar"
tree-ex.tools.cheddar)
(assertEq "tools roquefort"
tree-ex.tools.roquefort
"roquefort")
(assertEq "third_party attrset" (
lib.isAttrs tree-ex.third_party && (!lib.isDerivation tree-ex.third_party)
) true)
(assertEq "third_party attrset other attribute" tree-ex.third_party.favouriteColour "orange")
(assertEq "rustpkgs attrset aho-corasick" tree-ex.third_party.rustpkgs.aho-corasick "aho-corasick")
(assertEq "rustpkgs attrset serde" tree-ex.third_party.rustpkgs.serde "serde")
(assertEq "tools cheddear" "cheddar" tree-ex.tools.cheddar)
(assertEq "tools roquefort" tree-ex.tools.roquefort "roquefort")
];
tree-tl = depot.nix.readTree {
@ -82,65 +84,64 @@ let
};
traversal-logic = it "corresponds to the traversal logic in the README" [
(assertEq "skip-tree/a is read"
tree-tl.skip-tree.a
"a is read normally")
(assertEq "skip-tree does not contain b"
(builtins.attrNames tree-tl.skip-tree)
[ "__readTree" "__readTreeChildren" "a" ])
(assertEq "skip-tree children list does not contain b"
tree-tl.skip-tree.__readTreeChildren
[ "a" ])
(assertEq "skip-tree/a is read" tree-tl.skip-tree.a "a is read normally")
(assertEq "skip-tree does not contain b" (builtins.attrNames tree-tl.skip-tree) [
"__readTree"
"__readTreeChildren"
"a"
])
(assertEq "skip-tree children list does not contain b" tree-tl.skip-tree.__readTreeChildren [ "a" ])
(assertEq "skip subtree default.nix is read"
tree-tl.skip-subtree.but
"the default.nix is still read")
(assertEq "skip subtree a/default.nix is skipped"
(tree-tl.skip-subtree ? a)
false)
(assertEq "skip subtree b/c.nix is skipped"
(tree-tl.skip-subtree ? b)
false)
(assertEq "skip subtree default.nix is read" tree-tl.skip-subtree.but
"the default.nix is still read"
)
(assertEq "skip subtree a/default.nix is skipped" (tree-tl.skip-subtree ? a) false)
(assertEq "skip subtree b/c.nix is skipped" (tree-tl.skip-subtree ? b) false)
(assertEq "skip subtree a/default.nix would be read without .skip-subtree"
(tree-tl.no-skip-subtree.a)
"am I subtree yet?")
(assertEq "skip subtree b/c.nix would be read without .skip-subtree"
(tree-tl.no-skip-subtree.b.c)
"cool")
"am I subtree yet?"
)
(assertEq "skip subtree b/c.nix would be read without .skip-subtree" (tree-tl.no-skip-subtree.b.c
) "cool")
(assertEq "default.nix attrset is merged with siblings"
tree-tl.default-nix.no
"siblings should be read")
(assertEq "default.nix means sibling isnt read"
(tree-tl.default-nix ? sibling)
false)
(assertEq "default.nix attrset is merged with siblings" tree-tl.default-nix.no
"siblings should be read"
)
(assertEq "default.nix means sibling isnt read" (tree-tl.default-nix ? sibling) false)
(assertEq "default.nix means subdirs are still read and merged into default.nix"
(tree-tl.default-nix.subdir.a)
"but Im picked up")
"but Im picked up"
)
(assertEq "default.nix can be not an attrset"
tree-tl.default-nix.no-merge
"Im not merged with any children")
(assertEq "default.nix is not an attrset -> children are not merged"
(tree-tl.default-nix.no-merge ? subdir)
false)
(assertEq "default.nix can be not an attrset" tree-tl.default-nix.no-merge
"Im not merged with any children"
)
(assertEq "default.nix is not an attrset -> children are not merged" (
tree-tl.default-nix.no-merge ? subdir
) false)
(assertEq "default.nix can contain a derivation"
(lib.isDerivation tree-tl.default-nix.can-be-drv)
true)
(assertEq "default.nix can contain a derivation" (lib.isDerivation tree-tl.default-nix.can-be-drv)
true
)
(assertEq "Even if default.nix is a derivation, children are traversed and merged"
tree-tl.default-nix.can-be-drv.subdir.a
"Picked up through the drv")
(assertEq "default.nix drv is not changed by readTree"
tree-tl.default-nix.can-be-drv
(import ./test-tree-traversal/default-nix/can-be-drv/default.nix { }))
"Picked up through the drv"
)
(assertEq "default.nix drv is not changed by readTree" tree-tl.default-nix.can-be-drv (
import ./test-tree-traversal/default-nix/can-be-drv/default.nix { }
))
(assertEq "`here` argument represents the attrset a given file is part of"
(builtins.removeAttrs tree-tl.here-arg [ "__readTree" "__readTreeChildren" "subdir" ])
(builtins.removeAttrs tree-tl.here-arg [
"__readTree"
"__readTreeChildren"
"subdir"
])
{
attr1 = "foo";
attr2 = "foo";
attr3 = "sibl1";
})
}
)
];
# these each call readTree themselves because the throws have to happen inside assertThrows
@ -149,7 +150,8 @@ let
(depot.nix.readTree {
path = ./test-wrong-not-a-function;
args = { };
}).not-a-function)
}).not-a-function
)
# cant test for that, assertThrows cant catch this error
# (assertThrows "this file is a function but doesnt have dots"
# (depot.nix.readTree {} ./test-wrong-no-dots).no-dots-in-function)
@ -160,22 +162,36 @@ let
args = { };
};
assertMarkerByPath = path:
assertMarkerByPath =
path:
assertEq "${lib.concatStringsSep "." path} is marked correctly"
(lib.getAttrFromPath path read-markers).__readTree
path;
markers = it "marks nodes correctly" [
(assertMarkerByPath [ "directory-marked" ])
(assertMarkerByPath [ "directory-marked" "nested" ])
(assertMarkerByPath [ "file-children" "one" ])
(assertMarkerByPath [ "file-children" "two" ])
(assertEq "nix file children are marked correctly"
read-markers.file-children.__readTreeChildren [ "one" "two" ])
(assertEq "directory children are marked correctly"
read-markers.directory-marked.__readTreeChildren [ "nested" ])
(assertEq "absence of children is marked"
read-markers.directory-marked.nested.__readTreeChildren [ ])
(assertMarkerByPath [
"directory-marked"
"nested"
])
(assertMarkerByPath [
"file-children"
"one"
])
(assertMarkerByPath [
"file-children"
"two"
])
(assertEq "nix file children are marked correctly" read-markers.file-children.__readTreeChildren [
"one"
"two"
])
(assertEq "directory children are marked correctly" read-markers.directory-marked.__readTreeChildren
[ "nested" ]
)
(assertEq "absence of children is marked" read-markers.directory-marked.nested.__readTreeChildren
[ ]
)
];
in

View file

@ -1,3 +1,4 @@
{ ... }:
{ }
{
}

View file

@ -1,3 +1,4 @@
{ ... }:
{ }
{
}

View file

@ -1,3 +1,4 @@
{ ... }:
{ }
{
}

View file

@ -1,3 +1,4 @@
{ ... }:
{ }
{
}

View file

@ -3,5 +3,8 @@ derivation {
name = "im-a-drv";
system = builtins.currentSystem;
builder = "/bin/sh";
args = [ "-c" ''echo "" > $out'' ];
args = [
"-c"
''echo "" > $out''
];
}

View file

@ -1,4 +1,5 @@
{ here, ... }: {
{ here, ... }:
{
attr1 = "foo";
attr2 = here.attr1;

View file

@ -1,2 +1 @@
{ here, ... }:
here.sibl1
{ here, ... }: here.sibl1

View file

@ -1,3 +1,3 @@
{}:
{ }:
"This is a function, but readTree wants to pass a bunch of arguments, and not having dots means we depend on exactly which arguments."