symlinkJoin: documentation & tests for stripPrefix
This commit is contained in:
@@ -466,6 +466,29 @@ rec {
|
||||
...
|
||||
|
||||
|
||||
To create a directory structure from a specific subdirectory of input `paths` instead of their full trees,
|
||||
you can either append the subdirectory path to each input path, or use the `stripPrefix` argument to
|
||||
remove the common prefix during linking.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
# create symlinks of tmpfiles.d rules from multiple packages
|
||||
symlinkJoin { name = "tmpfiles.d"; paths = [ pkgs.lvm2 pkgs.nix ]; stripPrefix = "/lib/tmpfiles.d"; }
|
||||
|
||||
|
||||
This creates a derivation with a directory structure like the following:
|
||||
|
||||
|
||||
/nix/store/m5s775yicb763hfa133jwml5hwmwzv14-tmpfiles.d
|
||||
|-- lvm2.conf -> /nix/store/k6js0l5f0zpvrhay49579fj939j77p2w-lvm2-2.03.29/lib/tmpfiles.d/lvm2.conf
|
||||
`-- nix-daemon.conf -> /nix/store/z4v2s3s3y79fmabhps5hakb3c5dwaj5a-nix-1.33.7/lib/tmpfiles.d/nix-daemon.conf
|
||||
|
||||
|
||||
By default, packages that don't contain the specified subdirectory are silently skipped.
|
||||
Set `failOnMissing = true` to make the build fail if any input package is missing the subdirectory
|
||||
(this is the default behavior when not using stripPrefix).
|
||||
|
||||
symlinkJoin and linkFarm are similar functions, but they output
|
||||
derivations with different structure.
|
||||
|
||||
@@ -495,9 +518,12 @@ rec {
|
||||
, failOnMissing ? stripPrefix == ""
|
||||
, ...
|
||||
}:
|
||||
# Ensure no partial paths used, it will be confusing considering
|
||||
# most of the time symlinkJoin is used with packages.
|
||||
assert (stripPrefix == "" || (hasPrefix "/" stripPrefix) && stripPrefix != "/");
|
||||
assert lib.assertMsg (stripPrefix != "" -> (hasPrefix "/" stripPrefix && stripPrefix != "/")) ''
|
||||
stripPrefix must be either an empty string (disable stripping behavior), or relative path prefixed with /.
|
||||
|
||||
Ensure that the path starts with / and specifies path to the subdirectory.
|
||||
'';
|
||||
|
||||
let
|
||||
mapPaths = f: paths: map (path:
|
||||
if path == null then null
|
||||
@@ -510,14 +536,12 @@ rec {
|
||||
paths = mapPaths (path: "${path}${stripPrefix}") paths;
|
||||
passAsFile = [ "paths" ];
|
||||
}; # pass the defaults
|
||||
ignoreMissing = optionalString (!failOnMissing) "test -d $i && ";
|
||||
ignoreError = optionalString (!failOnMissing) " || true";
|
||||
in
|
||||
runCommand name args
|
||||
''
|
||||
mkdir -p $out
|
||||
for i in $(cat $pathsPath); do
|
||||
${ignoreMissing}${lndir}/bin/lndir -silent $i $out${ignoreError}
|
||||
${optionalString (!failOnMissing) "if test -d $i; then "}${lndir}/bin/lndir -silent $i $out${optionalString (!failOnMissing) "; fi"}
|
||||
done
|
||||
${postBuild}
|
||||
'';
|
||||
|
||||
@@ -19,6 +19,7 @@ in
|
||||
recurseIntoAttrs {
|
||||
concat = callPackage ./concat-test.nix {};
|
||||
linkFarm = callPackage ./link-farm.nix {};
|
||||
symlinkJoin = recurseIntoAttrs (callPackage ./symlink-join.nix {});
|
||||
overriding = callPackage ../test-overriding.nix {};
|
||||
inherit references;
|
||||
writeCBin = callPackage ./writeCBin.nix {};
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
{
|
||||
symlinkJoin,
|
||||
writeTextFile,
|
||||
runCommand,
|
||||
testers,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (testers) testEqualContents testBuildFailure;
|
||||
|
||||
foo = writeTextFile {
|
||||
name = "foo";
|
||||
text = "foo";
|
||||
destination = "/etc/test.d/foo";
|
||||
};
|
||||
|
||||
bar = writeTextFile {
|
||||
name = "bar";
|
||||
text = "bar";
|
||||
destination = "/etc/test.d/bar";
|
||||
};
|
||||
|
||||
baz = writeTextFile {
|
||||
name = "baz";
|
||||
text = "baz";
|
||||
destination = "/var/lib/arbitrary/baz";
|
||||
};
|
||||
|
||||
qux = writeTextFile {
|
||||
name = "qux";
|
||||
text = "qux";
|
||||
};
|
||||
|
||||
emulatedSymlinkJoinFooBarStrip = runCommand "symlinkJoin-strip-foo-bar" { } ''
|
||||
mkdir $out
|
||||
ln -s ${foo}/etc/test.d/foo $out/
|
||||
ln -s ${bar}/etc/test.d/bar $out/
|
||||
'';
|
||||
in
|
||||
{
|
||||
symlinkJoin = testEqualContents {
|
||||
assertion = "symlinkJoin";
|
||||
actual = symlinkJoin {
|
||||
name = "symlinkJoin";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
];
|
||||
};
|
||||
expected = runCommand "symlinkJoin-foo-bar-baz" { } ''
|
||||
mkdir -p $out/{var/lib/arbitrary,etc/test.d}
|
||||
ln -s {${foo},${bar}}/etc/test.d/* $out/etc/test.d
|
||||
ln -s ${baz}/var/lib/arbitrary/baz $out/var/lib/arbitrary/
|
||||
'';
|
||||
};
|
||||
|
||||
symlinkJoin-strip-paths = testEqualContents {
|
||||
assertion = "symlinkJoin-strip-paths";
|
||||
actual = symlinkJoin {
|
||||
name = "symlinkJoinPrefix";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
];
|
||||
stripPrefix = "/etc/test.d";
|
||||
};
|
||||
expected = emulatedSymlinkJoinFooBarStrip;
|
||||
};
|
||||
|
||||
symlinkJoin-strip-paths-skip-missing = testEqualContents {
|
||||
assertion = "symlinkJoin-strip-paths-skip-missing";
|
||||
actual = symlinkJoin {
|
||||
name = "symlinkJoinPrefix";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
];
|
||||
stripPrefix = "/etc/test.d";
|
||||
};
|
||||
expected = emulatedSymlinkJoinFooBarStrip;
|
||||
};
|
||||
|
||||
symlinkJoin-strip-paths-skip-not-directories = testEqualContents {
|
||||
assertion = "symlinkJoin-strip-paths-skip-not-directories";
|
||||
actual = symlinkJoin {
|
||||
name = "symlinkJoinPrefix";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
qux
|
||||
];
|
||||
stripPrefix = "/etc/test.d";
|
||||
};
|
||||
expected = emulatedSymlinkJoinFooBarStrip;
|
||||
};
|
||||
|
||||
symlinkJoin-fails-on-missing =
|
||||
runCommand "symlinkJoin-fails-on-missing"
|
||||
{
|
||||
failed = testBuildFailure (symlinkJoin {
|
||||
name = "symlinkJoin-fail";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
];
|
||||
stripPrefix = "/etc/test.d";
|
||||
failOnMissing = true;
|
||||
});
|
||||
}
|
||||
''
|
||||
grep -e "-baz/etc/test.d: No such file or directory" $failed/testBuildFailure.log
|
||||
touch $out
|
||||
'';
|
||||
|
||||
symlinkJoin-fails-on-file =
|
||||
runCommand "symlinkJoin-fails-on-file"
|
||||
{
|
||||
failed = testBuildFailure (symlinkJoin {
|
||||
name = "symlinkJoin-fail";
|
||||
paths = [
|
||||
foo
|
||||
bar
|
||||
qux
|
||||
];
|
||||
stripPrefix = "/etc/test.d";
|
||||
failOnMissing = true;
|
||||
});
|
||||
}
|
||||
''
|
||||
grep -e "-qux/etc/test.d: Not a directory" $failed/testBuildFailure.log
|
||||
touch $out
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user