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
open Ast
open Nix_unparse
open Nix_emit_node
let emit_pipeline ?(rel_root="..") (p : Ast.pipeline_result) =
let import_lines = List.filter_map (fun stmt ->
let s = unparse_import_stmt stmt in
if s = "" then None else Some s
) p.p_imports in
let node_names = List.map fst p.p_exprs in
let nodes =
p.p_exprs
|> List.map (fun (name, expr) ->
let deps = match List.assoc_opt name p.p_deps with Some d -> d | None -> [] in
let runtime = match List.assoc_opt name p.p_runtimes with Some r -> r | None -> "T" in
let serializer = match List.assoc_opt name p.p_serializers with Some s -> s | None -> Ast.mk_expr (Ast.Var "default") in
let deserializer = match List.assoc_opt name p.p_deserializers with Some d -> d | None -> Ast.mk_expr (Ast.Var "default") in
let env_vars = match List.assoc_opt name p.p_env_vars with Some vars -> vars | None -> [] in
let runtime_args = match List.assoc_opt name p.p_args with Some args -> args | None -> [] in
let functions = match List.assoc_opt name p.p_functions with Some f -> f | None -> [] in
let includes = match List.assoc_opt name p.p_includes with Some f -> f | None -> [] in
let noop = match List.assoc_opt name p.p_noops with Some b -> b | None -> false in
let script = match List.assoc_opt name p.p_scripts with Some s -> s | None -> None in
let shell = match List.assoc_opt name p.p_shells with Some s -> s | None -> None in
let shell_args = match List.assoc_opt name p.p_shell_args with Some args -> args | None -> [] in
emit_node (name, expr) deps node_names import_lines runtime serializer deserializer env_vars runtime_args functions includes noop script shell shell_args)
|> String.concat "\n"
in
let final_copy =
node_names
|> List.map (fun n -> Printf.sprintf " cp -r ${%s} $out/%s" n n)
|> String.concat "\n"
in
Printf.sprintf {|
{ system ? builtins.currentSystem }:
let
# Pull exact pinned inputs from the project flake.
# The flake.lock guarantees reproducibility.
# Note: toString is required to convert the path to a string
# that builtins.getFlake accepts.
flake = builtins.getFlake (toString %s/.);
pkgs = if (builtins.hasAttr "legacyPackages" flake && builtins.hasAttr system flake.legacyPackages.${system})
then flake.legacyPackages.${system}
else flake.inputs.nixpkgs.legacyPackages.${system};
tBin = let
base = (flake.inputs.t-lang or flake).packages.${system}.default;
in if builtins.pathExists %s/dune-project then
base.overrideAttrs (old: { src = sources; })
else base;
stdenv = pkgs.stdenv;
# Filter out _pipeline/, .git/, and other non-source directories
sources = builtins.filterSource
(path: type:
let baseName = builtins.baseNameOf path;
in !(baseName == "_pipeline" || baseName == ".git" || baseName == ".direnv" || baseName == "_build"))
%s/.;
toml = if builtins.pathExists %s/tproject.toml then builtins.fromTOML (builtins.readFile %s/tproject.toml) else {};
rPackagesList = (toml.r-dependencies or {}).packages or [];
r-env = pkgs.rWrapper.override {
packages = (builtins.map (p: pkgs.rPackages.${p}) rPackagesList);
};
pyDeps = toml.py-dependencies or toml.python-dependencies or {};
pyVersion = pyDeps.version or "python3";
pyPackagesList = pyDeps.packages or [];
py-env = pkgs.${pyVersion}.withPackages (ps: (builtins.map (p: ps.${p}) pyPackagesList));
# Additional Tools & LaTeX
additionalTools = (toml.additional-tools or {}).packages or [];
latexPkgs = (toml.latex or {}).packages or [];
latexCombined = if latexPkgs == [] then null
else pkgs.texlive.combine (builtins.listToAttrs (builtins.map (name: { name = name; value = pkgs.texlive.${name}; }) (["scheme-small"] ++ latexPkgs)));
globalBuildInputs = (builtins.map (p: pkgs.${p}) additionalTools)
++ (if latexCombined == null then [] else [ latexCombined ]);
in
rec {
%s
pipeline_output = stdenv.mkDerivation {
name = "pipeline_output";
buildInputs = [ tBin %s ] ++ globalBuildInputs;
buildCommand = ''
mkdir -p $out
%s
'';
};
}
|} rel_root rel_root rel_root rel_root rel_root nodes (String.concat " " node_names) final_copy