diff --git a/fn.nix b/fn.nix index 8fd80df..a8e75df 100644 --- a/fn.nix +++ b/fn.nix @@ -8,7 +8,7 @@ rec { fileContentsOr = a: b: (ifelse (pathIsRegularFile a) a b); - cwd = toString ./.; + cwd = builtins.getEnv "PWD"; # lst (string PATH) (string FILETYPE) (bool RETURNFULLPATH) lst = { p ? cwd, t ? "regular", b ? false }: (lists.forEach @@ -25,18 +25,37 @@ rec { (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: ifelse ((elem true (hasAttrs [["meta" "broken"]] p)) && (p.meta.broken == true)) - (warn "Package ${p.name} is marked as broken." true) - false; + 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 != []; } + # 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); - # Those two lines are quite magical 🧙 - depsBrokenRec = p: (b: b == true) (ifelse (depsBroken p) true - (map (p: depsBrokenRec 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) + ); pkgFilter = ld: (filter (p: ( ifelse (isBroken p)