-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathfiles.nix
69 lines (65 loc) · 1.89 KB
/
files.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# file related operations
{ lib
, stdenv
, writeScript
}:
rec {
# Takes a (string) filepath and creates a derivation for that file (and for
# that file only)
singleOut = base: file:
let
basePrefix = (builtins.toString base) + "/";
pred = path: type:
let
actual = lib.strings.removePrefix basePrefix path;
expected = file;
in
(expected == actual) ||
(type == "directory" && (lib.strings.hasPrefix actual expected));
# TODO: even though we're doing a lot of cleaning, there's still some
# 'does-file-exist' happening
src = lib.cleanSourceWith
{ filter = pred; src = lib.cleanSource base; };
name = # Makes the file name derivation friendly
lib.stringAsChars
(x:
if x == "/" then "_"
else if builtins.isNull (builtins.match "[a-zA-Z0-9.+=-_?]" x)
then ""
else x
) file;
in stdenv.mkDerivation {
inherit name src;
builder = writeScript (name + "-single-out")
# TODO: make sure the file actually exists and that there's only one
''
echo "Singling out file ${file}"
source $stdenv/setup
mkdir -p $out
echo "Running: cp $src/${file} $out/${file}"
echo "Listing $src"
ls $src/**/*
mkdir -p $(dirname $out/${file})
cp $src/${file} $out/${file}
echo "Done: Singling out file ${file}"
'';
};
doesFileExist = base: filename:
lib.lists.elem filename (listFilesInDir base);
listFilesInDir = dir:
let
go = dir: dirName:
lib.lists.concatLists
(
lib.attrsets.mapAttrsToList
(path: ty:
if ty == "directory"
then
go "${dir}/${path}" "${dirName}${path}/"
else
[ "${dirName}${path}" ]
)
(builtins.readDir dir)
);
in go dir "";
}