-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathflake.nix
98 lines (89 loc) · 2.82 KB
/
flake.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# SPDX-FileCopyrightText: 2022 The Standard Authors
# SPDX-FileCopyrightText: 2022 Michael Fellinger <https://manveru.dev/>
#
# SPDX-License-Identifier: MIT
{
inputs.nixlib.url = "github:nix-community/nixpkgs.lib";
outputs = {nixlib, ...}: let
l = nixlib.lib // builtins;
pretty = l.generators.toPretty {};
/*
A source inclusion helper.
With incl, you can specify what files should become part of the
input hashing function of nix.
That means, that only if that hash changes, a rebuild is triggered.
By only including the sources that are an actual ingredient to your
build process, you can greatly reduce the need for arbitrary builds.
Slightly less effective than language native build caching. But hey,
it's 100% polyglot.
You can use this function independently of the rest of std.
*/
incl = debug: src: allowedPaths: let
src' = l.unsafeDiscardStringContext (toString src);
normalizedPaths =
l.map (
path: let
path' = l.unsafeDiscardStringContext (toString path);
in
if l.hasPrefix l.storeDir path'
then path'
else src' + "/${path'}"
)
allowedPaths;
patterns =
l.traceIf debug "allowedPaths: ${pretty normalizedPaths}"
l.traceIf
debug "src: \"${src'}\""
mkInclusive
normalizedPaths;
filter =
l.traceIf debug "patterns: ${pretty patterns}"
(isIncluded debug)
patterns;
in
l.cleanSourceWith {
name = "incl";
inherit src filter;
};
mkInclusive = paths:
l.foldl' (
sum: path: {
prefixes = sum.prefixes ++ [path];
}
) {
prefixes = [];
}
paths;
isIncluded = debug: patterns: _path: _type: let
traceCandidate = l.traceIf debug "candidate ${_type}: ${_path}";
in
traceCandidate (
# add file or recurse into node ?
l.any (
pre: let
contains = _type == "directory" && l.hasPrefix "${_path}/" pre;
hit = pre == _path;
prefix = l.hasPrefix "${pre}/" _path;
in
l.traceIf (debug && (hit || prefix || contains)) (
if contains && !(hit || prefix)
then "\trecurse as container for: ${pre}"
else if _type == "directory"
then "\trecurse on prefix: ${pre}"
else if _type == "regular" && hit
then "\tinclude on hit: ${pre}"
else if _type == "regular" && prefix
then "\tinclude on prefix: ${pre}/"
else "\tfile type '${_type}' - will fail"
)
hit
|| prefix
|| contains
)
patterns.prefixes
);
in {
debug = false;
__functor = {debug, ...}: incl debug;
};
}