mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-08-17 02:10:31 +03:00
simplify graph methods & add more tests for fileSystem
This commit is contained in:
parent
4f2a64a66f
commit
df26fb319f
@ -11,7 +11,15 @@ A collection of tools needed to interact with graphs (i.e. A dependencyTree)
|
||||
|
||||
# Params
|
||||
|
||||
- graph :: { ${path} :: [ [ string ] ] }
|
||||
- Graph :: {
|
||||
${name}.${version} :: {
|
||||
dependencies = {
|
||||
${dep.name}.version = String;
|
||||
};
|
||||
dev :: Bool;
|
||||
};
|
||||
};
|
||||
|
||||
GenericGraph; An AttrSet of nodeIds, pointing to neighboring nodes. (could be cyclic).
|
||||
|
||||
- roots :: [ String ]
|
||||
@ -102,46 +110,60 @@ A collection of tools needed to interact with graphs (i.e. A dependencyTree)
|
||||
}
|
||||
}
|
||||
*/
|
||||
getFileSystem = pdefs: pdefs':
|
||||
getFileSystem = graph: sanitizedGraph:
|
||||
l.foldl' (
|
||||
/*
|
||||
set :: {
|
||||
sanitziedGraphEntry :: {
|
||||
name ::
|
||||
version ::
|
||||
dev ::
|
||||
isRoot ? :: true;
|
||||
key :: [];
|
||||
}
|
||||
|
||||
*/
|
||||
res: set: let
|
||||
filteredSet = l.filterAttrs (_: value: value.info.initialState == "dist") pdefs.${set.name};
|
||||
res: sanitizedGraphEntry: let
|
||||
/*
|
||||
|
||||
filteredSet :: graph
|
||||
|
||||
Example:
|
||||
|
||||
All versions of "next" that are in the dist state.
|
||||
|
||||
*/
|
||||
distVersions = l.filterAttrs (_version: e: e.info.initialState == "dist") graph.${sanitizedGraphEntry.name};
|
||||
in
|
||||
res
|
||||
// l.foldl' (
|
||||
acc: version: let
|
||||
entry = filteredSet.${version};
|
||||
// l.foldlAttrs (
|
||||
acc: version: entry: let
|
||||
pdef = graph.${sanitizedGraphEntry.name}.${version};
|
||||
in
|
||||
acc
|
||||
// l.foldl' (res: path:
|
||||
if entry.info.allPaths.${path}
|
||||
// l.foldlAttrs (fileSystem: path: pathInfo:
|
||||
if pathInfo
|
||||
then
|
||||
res
|
||||
// {
|
||||
${path} = {
|
||||
source = entry.dist;
|
||||
bins =
|
||||
l.mapAttrs' (name: target: {
|
||||
name = (builtins.dirOf path) + "/.bin/" + name;
|
||||
value = path + "/" + target;
|
||||
})
|
||||
pdefs.${set.name}.${version}.bins;
|
||||
};
|
||||
}
|
||||
else res) {} (l.attrNames (entry.info.allPaths))
|
||||
) {} (l.attrNames filteredSet)
|
||||
fileSystem
|
||||
// getFileSystemInfo path pdef entry
|
||||
else fileSystem) {} (entry.info.allPaths)
|
||||
) {}
|
||||
distVersions
|
||||
) {}
|
||||
pdefs';
|
||||
sanitizedGraph;
|
||||
|
||||
getFileSystemInfo = path: pdef: entry: let
|
||||
info = {
|
||||
${path} = {
|
||||
source = entry.dist;
|
||||
bins =
|
||||
l.mapAttrs' (name: target: {
|
||||
name = (builtins.dirOf path) + "/.bin/" + name;
|
||||
value = path + "/" + target;
|
||||
})
|
||||
pdef.bins;
|
||||
};
|
||||
};
|
||||
in
|
||||
info;
|
||||
in {
|
||||
inherit
|
||||
sanitizeGraph
|
||||
|
@ -152,20 +152,12 @@
|
||||
rinfo = info // {inherit fileSystem;};
|
||||
name = plent.name or lock.name;
|
||||
|
||||
fileSystem = graphUtils.getFileSystem pdefs (info.pdefs' {
|
||||
graph = pdefs;
|
||||
root = {
|
||||
inherit name;
|
||||
inherit (plent) version;
|
||||
};
|
||||
fileSystem = graphUtils.getFileSystem pdefs (utils.getSanitizedGraph {
|
||||
inherit plent pdefs;
|
||||
});
|
||||
fileSystemProd = graphUtils.getFileSystem pdefs (info.pdefs' {
|
||||
graph = pdefs;
|
||||
root = {
|
||||
inherit name;
|
||||
inherit (plent) version;
|
||||
};
|
||||
opt = {
|
||||
fileSystemProd = graphUtils.getFileSystem pdefs (utils.getSanitizedGraph {
|
||||
inherit pdefs plent;
|
||||
filterTree = {
|
||||
dev = false;
|
||||
};
|
||||
});
|
||||
|
@ -66,7 +66,6 @@ in {
|
||||
specialArgs
|
||||
;
|
||||
})
|
||||
fileSystem
|
||||
pdefs
|
||||
;
|
||||
};
|
||||
|
@ -72,12 +72,42 @@
|
||||
# One source drv must potentially be installed in multiple other (nested) locations
|
||||
options.info.allPaths = l.mkOption {
|
||||
type = t.attrsOf t.bool;
|
||||
};
|
||||
options.info.pdefs' = l.mkOption {
|
||||
type = t.raw;
|
||||
description = ''
|
||||
In case of conflicting versions a dependency must be installed in multiple nested locations.
|
||||
|
||||
In this example: Because the root "node_modules/ansi-regex" is a different version.
|
||||
The current version must be installed privately if anyone depdends on it.
|
||||
|
||||
{
|
||||
"node_modules/cliui/node_modules/ansi-regex" = true;
|
||||
"node_modules/wrap-ansi/node_modules/ansi-regex" = true;
|
||||
"node_modules/yargs/node_modules/ansi-regex" = true;
|
||||
};
|
||||
|
||||
npm usually already resolved this, can be manually adjusted via this option.
|
||||
'';
|
||||
};
|
||||
options.info.fileSystem = l.mkOption {
|
||||
type = t.raw;
|
||||
type = t.nullOr t.raw;
|
||||
default = null;
|
||||
description = ''
|
||||
A json serializable attribute-set.
|
||||
Holds all directories and bin symlinks realized the build script.
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
{
|
||||
"node_modules/tap-dot" = {
|
||||
bins = {
|
||||
"node_modules/.bin/tap-dot" = "node_modules/tap-dot/bin/dot";
|
||||
};
|
||||
source = «derivation tap-dot.drv»;
|
||||
};
|
||||
# ..
|
||||
}
|
||||
```
|
||||
'';
|
||||
};
|
||||
|
||||
/*
|
||||
@ -135,6 +165,16 @@ in {
|
||||
*/
|
||||
pdefs = {
|
||||
type = t.attrsOf (t.attrsOf (t.submodule pdefEntryOptions));
|
||||
description = ''
|
||||
Also known as 'graph'.
|
||||
|
||||
Holds all information, including cyclic references.
|
||||
|
||||
Use this structure to access meta information from the lockfile.
|
||||
Such as bins, path etc.
|
||||
|
||||
Can be JSON serialized.
|
||||
'';
|
||||
};
|
||||
|
||||
/*
|
||||
@ -143,24 +183,24 @@ in {
|
||||
${nodePath} :: Derivation
|
||||
}
|
||||
*/
|
||||
fileSystem = {
|
||||
type = t.nullOr (t.attrsOf (t.submodule {
|
||||
options.source = l.mkOption {
|
||||
type = t.nullOr dreamTypes.drvPartOrPackage;
|
||||
};
|
||||
options.bins = optBins;
|
||||
}));
|
||||
# options.bins = l.mkOption {
|
||||
# type = t.attrsOf (t.submodule {
|
||||
# options.name = l.mkOption {
|
||||
# type = t.str;
|
||||
# };
|
||||
# options.target = l.mkOption {
|
||||
# type = t.str;
|
||||
# };
|
||||
# });
|
||||
# };
|
||||
# }));
|
||||
# default = null;
|
||||
};
|
||||
# TODO: Make lazy enough. then replace info.fileSystem with this
|
||||
# fileSystem = {
|
||||
# type = t.nullOr (t.attrsOf (t.submodule {
|
||||
# options.source = l.mkOption {
|
||||
# type = t.nullOr dreamTypes.drvPartOrPackage;
|
||||
# };
|
||||
# options.bins = optBins;
|
||||
# }));
|
||||
# options.bins = l.mkOption {
|
||||
# type = t.attrsOf (t.submodule {
|
||||
# options.name = l.mkOption {
|
||||
# type = t.str;
|
||||
# };
|
||||
# options.target = l.mkOption {
|
||||
# type = t.str;
|
||||
# };
|
||||
# });
|
||||
# };
|
||||
# }));
|
||||
# };
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
{lib}: let
|
||||
l = lib // builtins;
|
||||
# cfg = config.WIP-nodejs-builder-v3;
|
||||
|
||||
nodejsLockUtils = import ../../../lib/internal/nodejsLockUtils.nix {inherit lib;};
|
||||
graphUtils = import ../../../lib/internal/graphUtils.nix {inherit lib;};
|
||||
@ -19,15 +18,42 @@
|
||||
path == ""
|
||||
then "source"
|
||||
else "dist";
|
||||
};
|
||||
|
||||
pdefs' = {
|
||||
graph,
|
||||
root ? {
|
||||
name = plent.name or "nixpkgs-docs-example";
|
||||
version = plent.version;
|
||||
},
|
||||
opt ? {},
|
||||
/**
|
||||
A Convinient wrapper around sanitizeGraph
|
||||
which allows to pass options such as { dev=false; }
|
||||
|
||||
*/
|
||||
getSanitizedGraph = {
|
||||
# The lockfile entry; One depdency used as a root.
|
||||
plent,
|
||||
# The dependency 'graph'. See: sanitizeGraph
|
||||
pdefs,
|
||||
/**
|
||||
Drops dependencies including their subtree connection by filter attribute.
|
||||
|
||||
for example:
|
||||
|
||||
```
|
||||
filterTree = {
|
||||
dev = false;
|
||||
};
|
||||
```
|
||||
|
||||
Will filter out all dev dependencies including all children below dev-dependencies.
|
||||
|
||||
Which will result in a prod only tree.
|
||||
*/
|
||||
filterTree ? {},
|
||||
}:
|
||||
let
|
||||
root = {
|
||||
name = plent.name;
|
||||
version = plent.version;
|
||||
};
|
||||
graph = pdefs;
|
||||
in
|
||||
graphUtils.sanitizeGraph {
|
||||
inherit root graph;
|
||||
pred = (
|
||||
@ -39,10 +65,9 @@
|
||||
else value == e.${name}
|
||||
)
|
||||
true
|
||||
opt
|
||||
filterTree
|
||||
);
|
||||
};
|
||||
};
|
||||
in {
|
||||
inherit getInfo;
|
||||
inherit getInfo getSanitizedGraph;
|
||||
}
|
||||
|
212
tests/nix-unit/test_graph_utils/fileSystem.nix
Normal file
212
tests/nix-unit/test_graph_utils/fileSystem.nix
Normal file
@ -0,0 +1,212 @@
|
||||
{lib ? import <nixpkgs/lib>, ...}: let
|
||||
utils = import ../../../lib/internal/graphUtils.nix {inherit lib;};
|
||||
in {
|
||||
test_simple = let
|
||||
graph = {
|
||||
"a"."1" = {
|
||||
dist = "<Dist Derivation>";
|
||||
dependencies = {};
|
||||
dev = false;
|
||||
bins = {
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/a" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
sanitizedGraph = utils.sanitizeGraph {
|
||||
inherit graph;
|
||||
root = {
|
||||
name = "a";
|
||||
version = "1";
|
||||
};
|
||||
};
|
||||
|
||||
fileSystem = utils.getFileSystem graph sanitizedGraph;
|
||||
in {
|
||||
expr = fileSystem;
|
||||
expected = {
|
||||
"node_modules/a" = {
|
||||
bins = {};
|
||||
source = "<Dist Derivation>";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
test_cyclic_dependency = let
|
||||
graph = {
|
||||
"a"."1" = {
|
||||
dist = "<A Derivation>";
|
||||
dependencies = {
|
||||
b.version = "1";
|
||||
};
|
||||
dev = false;
|
||||
bins = {};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/a" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
"b"."1" = {
|
||||
dist = "<B Derivation>";
|
||||
dependencies = {
|
||||
a.version = "1";
|
||||
};
|
||||
dev = false;
|
||||
bins = {};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/b" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
sanitizedGraph = utils.sanitizeGraph {
|
||||
inherit graph;
|
||||
root = {
|
||||
name = "a";
|
||||
version = "1";
|
||||
};
|
||||
};
|
||||
|
||||
fileSystem = utils.getFileSystem graph sanitizedGraph;
|
||||
in {
|
||||
expr = fileSystem;
|
||||
expected = {
|
||||
"node_modules/a" = {
|
||||
bins = {};
|
||||
source = "<A Derivation>";
|
||||
};
|
||||
"node_modules/b" = {
|
||||
bins = {};
|
||||
source = "<B Derivation>";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
test_bin_conflict = let
|
||||
graph = {
|
||||
"a"."1" = {
|
||||
dist = "<A Derivation>";
|
||||
dependencies = {
|
||||
b.version = "1";
|
||||
c.version = "1";
|
||||
};
|
||||
dev = false;
|
||||
bins = {
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/a" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
"b"."1" = {
|
||||
dist = "<B Derivation>";
|
||||
dependencies = {
|
||||
c.version = "2";
|
||||
d.version = "1";
|
||||
};
|
||||
dev = false;
|
||||
bins = {
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/b" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
"d"."1" = {
|
||||
dist = "<D Derivation>";
|
||||
dependencies = {
|
||||
c.version = "2";
|
||||
};
|
||||
dev = false;
|
||||
bins = {
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/d" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
"c"."1" = {
|
||||
dist = "<C1 Derivation>";
|
||||
dependencies = {
|
||||
};
|
||||
dev = false;
|
||||
bins = {
|
||||
c-cli = "cli.js";
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/c" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
"c"."2" = {
|
||||
dist = "<C2 Derivation>";
|
||||
dependencies = {
|
||||
};
|
||||
dev = false;
|
||||
bins = {
|
||||
c-cli = "cli.js";
|
||||
};
|
||||
info = {
|
||||
initialState = "dist";
|
||||
allPaths = {
|
||||
"node_modules/b/node_modules/c" = true;
|
||||
"node_modules/d/node_modules/c" = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
sanitizedGraph = utils.sanitizeGraph {
|
||||
inherit graph;
|
||||
root = {
|
||||
name = "a";
|
||||
version = "1";
|
||||
};
|
||||
};
|
||||
|
||||
fileSystem = utils.getFileSystem graph sanitizedGraph;
|
||||
in {
|
||||
expr = fileSystem;
|
||||
expected = {
|
||||
"node_modules/a" = {
|
||||
bins = {};
|
||||
source = "<A Derivation>";
|
||||
};
|
||||
"node_modules/b" = {
|
||||
bins = {};
|
||||
source = "<B Derivation>";
|
||||
};
|
||||
"node_modules/b/node_modules/c" = {
|
||||
bins = {"node_modules/b/node_modules/.bin/c-cli" = "node_modules/b/node_modules/c/cli.js";};
|
||||
source = "<C2 Derivation>";
|
||||
};
|
||||
"node_modules/c" = {
|
||||
bins = {"node_modules/.bin/c-cli" = "node_modules/c/cli.js";};
|
||||
source = "<C1 Derivation>";
|
||||
};
|
||||
"node_modules/d" = {
|
||||
bins = {};
|
||||
source = "<D Derivation>";
|
||||
};
|
||||
"node_modules/d/node_modules/c" = {
|
||||
bins = {"node_modules/d/node_modules/.bin/c-cli" = "node_modules/d/node_modules/c/cli.js";};
|
||||
source = "<C2 Derivation>";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user