nixos/fn.nix

72 lines
3 KiB
Nix

{ lib }:
with builtins;
with lib;
rec {
ifelse = a: b: c: if a then b else c;
fileContentsOr = a: b: (ifelse
(pathIsRegularFile a)
a b);
cwd = builtins.getEnv "PWD";
# lst (string PATH) (string FILETYPE) (bool RETURNFULLPATH)
lst = { p ? cwd, t ? "regular", b ? false }: (lists.forEach
(attrNames
(filterAttrs (n: v: v == t)
(readDir p)))
(v: ((optionalString b "${p}/") + v)));
lsf = p: (lst { p = p; });
lsd = p: (lst { p = p; t = "directory"; b = true; });
lsfRec = p: b: flatten ((map (np: lsfRec np b) (lsd p)) ++ (lst { p = p; b = b; }));
hasAttrs = aList: d: (map
(a:
(ifelse (isList a)
(hasAttrByPath a d)
(hasAttr a d)))
aList);
# Not sure how list operations are implemented in Nix
# This might be a tad bit inefficient.
# TODO: look for better implementation (map is a builtin function so checking that probably won't help)
# Sequentially checks elements of list (l) for condition (cond) and executes do on first match.
meetsConDo = cond: do: l: ifelse (l == []) false
(let
h = (head l);
t = (tail l);
in ifelse (cond h) (do h)
(meetsConDo (cond) (do) (t)));
deps = p: ifelse (isAttrs p) (filter (p: isAttrs p)
(p.buildInputs ++ p.nativeBuildInputs ++ p.propagatedBuildInputs ++ p.propagatedNativeBuildInputs)
) [];
importFilter = l: p: filter (n: elem (nameFromURL (toString n) ".") l) p;
depsRec = ld: ifelse (ld == []) [] ((toList ld) ++ (depsRec (lists.unique (lists.flatten (map (d: deps d) (toList ld))))));
isBroken = p: meetsConDo (s: ((hasAttrByPath s.path p) && (s.check (getAttrFromPath s.path p)))) (s: s.msg)
[
{ path = ["meta" "broken"]; msg = (warn "Package ${p.name} is marked as broken." true); check = m: m; }
{ path = ["meta" "knownVulnerabilities" ]; msg = (warn "Package ${p.name} has known Vulnerabilities.." true); check = m: m != []; }
{ path = ["name"]; msg = (warn "${p.name}: python2 is depricated." false); check = m: (strings.hasInfix "python2" m) || (strings.hasInfix "python-2" m); }
# not sure if the following test creates false positives (AFAIK every derivation/package needs to have an outPath)
# , definitely should catch all corner cases/everything that fails to evaluate.
{ path = [ "outPath" ]; msg = (warn "Package ${p.name} has no outPath" true); check = m: !(tryEval m).success; }
];
depsBroken = p: lists.any (p: (isBroken p)) (deps p);
# No more magic 🧙 here 😢
# But at least it now (hopefully) checks ONLY dependencies (and all of them at that).
depsBrokenRec = p: (meetsConDo
(p: ifelse (depsBroken p) true (depsBrokenRec (deps p)))
(p: true) (deps p)
);
sopsHelper = template: names: options: let
nameList = map template names;
in listToAttrs (map (nameEntry: {name = nameEntry; value = options;}) nameList);
pkgFilter = ld: (filter
(p: (
ifelse (isBroken p)
false
(ifelse (depsBrokenRec p)
(warn "Dependency of ${p.name} is marked as broken." false)
true)
))
ld);
}