2020-10-09 15:55:37 +02:00
|
|
|
{
|
|
|
|
stdenv
|
2022-09-01 16:27:29 +02:00
|
|
|
, lib
|
2020-10-09 15:55:37 +02:00
|
|
|
}:
|
|
|
|
|
2022-09-01 16:27:29 +02:00
|
|
|
with lib;
|
2020-07-27 11:14:33 +02:00
|
|
|
|
2020-10-09 15:55:37 +02:00
|
|
|
let
|
2020-07-27 11:14:33 +02:00
|
|
|
gen = rec {
|
|
|
|
# genAttrSets "a" ["hello" "world"]
|
|
|
|
# [ { a = "hello"; } { a = "world"; } ]
|
|
|
|
genAttrSets = (name: arr: (map (x: {${name}=x; })) arr);
|
|
|
|
|
|
|
|
# addAttrSets "a" [1 2] {e=4;}
|
|
|
|
# [ { a = 1; e = 4; } { a = 2; e = 4; } ]
|
|
|
|
addAttrSets = (name: arr: set: (map (x: set // {${name}=x; })) arr);
|
|
|
|
|
|
|
|
# attrToList {a=1;}
|
|
|
|
# [ { name = "a"; value = 1; } ]
|
|
|
|
attrToList = (set: map (name: {name=name; value=set.${name};} ) (builtins.attrNames set));
|
|
|
|
|
|
|
|
# mergeConfig [{e=1;}] {name="a"; value=[1 2]
|
|
|
|
# [ { a = 1; e = 1; } { a = 2; e = 1; } ]
|
2020-10-09 15:55:37 +02:00
|
|
|
mergeConfig = (arr: new: flatten ( map (x: addAttrSets new.name new.value x) arr));
|
2020-07-27 11:14:33 +02:00
|
|
|
|
|
|
|
# genConfigs {a=[1 2]; b=[3 4];}
|
|
|
|
# [ { a = 1; b = 3; } { a = 1; b = 4; } { a = 2; b = 3; } { a = 2; b = 4; } ]
|
2020-10-09 15:55:37 +02:00
|
|
|
genConfigs = (config: foldl mergeConfig [{}] (attrToList config));
|
2020-07-27 11:14:33 +02:00
|
|
|
|
|
|
|
# Generate multiple app versions by override with each config
|
2020-07-29 18:38:39 +02:00
|
|
|
genApp = (app: configs: map (conf: app.override conf // {conf=conf;}) configs);
|
2020-07-27 11:14:33 +02:00
|
|
|
|
|
|
|
# Generate app version from an array of apps
|
|
|
|
genApps = (apps: configs:
|
2020-10-09 15:55:37 +02:00
|
|
|
flatten (map (app: genApp app configs) apps));
|
|
|
|
|
|
|
|
/* Returns the path of the executable of a stage */
|
|
|
|
stageProgram = stage:
|
|
|
|
if stage ? programPath
|
|
|
|
then "${stage}${stage.programPath}"
|
|
|
|
else "${stage}";
|
2020-07-27 11:14:33 +02:00
|
|
|
|
2020-10-15 18:48:50 +02:00
|
|
|
/* Given a trebuchet, returns the experiment */
|
2020-11-20 15:34:14 +01:00
|
|
|
getExperimentStage = drv:
|
|
|
|
if (drv ? isExperiment) && drv.isExperiment then drv
|
|
|
|
else getExperimentStage drv.nextStage;
|
2020-11-13 19:06:31 +01:00
|
|
|
|
|
|
|
# Computes the exponentiation operation
|
|
|
|
pow = x: n: fold (a: b: a*b) 1 (map (a: x) (range 1 n));
|
|
|
|
|
|
|
|
# Generates a list of exponents from a to b inclusive, and raises base to
|
|
|
|
# each element of the list.
|
|
|
|
expRange = base: a: b: (map (ex: pow base ex) (range a b));
|
|
|
|
|
2021-01-28 15:00:43 +01:00
|
|
|
# Generates a range from start to end (inclusive) by multiplying start by 2.
|
|
|
|
range2 = start: end:
|
|
|
|
let
|
|
|
|
_range2 = s: e: if (s > e) then [] else [ s ] ++ (_range2 (s * 2) e);
|
|
|
|
in
|
|
|
|
_range2 start end;
|
|
|
|
|
2020-11-13 19:06:31 +01:00
|
|
|
# Generates a list of integers by halving number N until it reaches 1. Is
|
|
|
|
# sorted from the smallest to largest.
|
2020-11-16 11:58:43 +01:00
|
|
|
halfList = N:
|
2020-11-13 19:06:31 +01:00
|
|
|
let
|
|
|
|
_divList = n: if (n == 0) then [] else (_divList (n / 2)) ++ [ n ];
|
|
|
|
in
|
|
|
|
_divList N;
|
|
|
|
|
2020-11-16 11:59:11 +01:00
|
|
|
# A list of all divisors of n, sorted in increased order:
|
|
|
|
divisors = n: filter (x: (mod n x == 0)) (range 1 n);
|
|
|
|
|
2020-11-13 19:06:31 +01:00
|
|
|
# Generates a set given a list of keys, where all values are null.
|
|
|
|
genNullAttr = l: genAttrs l (name: null);
|
|
|
|
|
|
|
|
# From the keys in the lis l, generates a set with the values in the set a,
|
|
|
|
# if they don't exist, they are not taken. Values set to null are removed.
|
|
|
|
optionalInherit = l: a: filterAttrs (n: v: v!=null)
|
|
|
|
(overrideExisting (genNullAttr l) a);
|
|
|
|
|
2021-04-16 11:49:37 +02:00
|
|
|
# Given a float f, truncates it and returns the resulting the integer
|
|
|
|
floatTruncate = f: let
|
|
|
|
strFloat = toString f;
|
|
|
|
slices = splitString "." strFloat;
|
|
|
|
front = elemAt slices 0;
|
|
|
|
in
|
|
|
|
toInt front;
|
|
|
|
|
2021-03-31 16:38:09 +02:00
|
|
|
# Returns the given gitCommit if not null, or the one stored in the
|
|
|
|
# gitTable for the branch gitBranch.
|
2021-04-01 17:45:37 +02:00
|
|
|
findCommit = {gitCommit ? null, gitTable ? null, gitBranch}:
|
|
|
|
assert (gitCommit == null) -> (gitTable != null);
|
|
|
|
assert (gitTable == null) -> (gitCommit != null);
|
|
|
|
if (gitCommit != null) then gitCommit
|
|
|
|
else
|
|
|
|
assert (assertMsg (gitTable ? "${gitBranch}")
|
|
|
|
''
|
|
|
|
The git branch "${gitBranch}" was not found in the gitTable.
|
|
|
|
Is the gitTable outdated?
|
|
|
|
'');
|
|
|
|
gitTable."${gitBranch}";
|
|
|
|
|
|
|
|
# Custom wrapper around fetchGit to be able to quickly specify apps
|
|
|
|
# and change the repository source for all at once. Returns an
|
|
|
|
# attributte set with the `src` as well as the selected gitCommit,
|
|
|
|
# gitBranch and gitURL.
|
|
|
|
fetchGarlicApp = {
|
|
|
|
gitBranch,
|
|
|
|
appName ? null,
|
|
|
|
gitURL ? null,
|
|
|
|
gitCommit ? null,
|
|
|
|
gitTable ? null
|
|
|
|
}:
|
|
|
|
assert (appName == null) -> (gitURL != null);
|
|
|
|
assert (gitURL == null) -> (appName != null);
|
|
|
|
let
|
|
|
|
_gitURL = if (gitURL != null) then gitURL
|
|
|
|
else "ssh://git@bscpm03.bsc.es/garlic/apps/${appName}.git";
|
|
|
|
_gitCommit = findCommit {
|
|
|
|
inherit gitCommit gitTable gitBranch;
|
|
|
|
};
|
|
|
|
_gitBranch = gitBranch;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
src = builtins.fetchGit {
|
|
|
|
url = _gitURL;
|
|
|
|
ref = _gitBranch;
|
|
|
|
rev = _gitCommit;
|
|
|
|
};
|
|
|
|
gitBranch = _gitBranch;
|
|
|
|
gitCommit = _gitCommit;
|
|
|
|
|
|
|
|
# The gitURL is not stored in the derivation, as we dont really
|
|
|
|
# care of where the source comes from, as long as is the same
|
|
|
|
# commit.
|
|
|
|
gitURL = _gitURL;
|
|
|
|
};
|
2020-07-27 11:14:33 +02:00
|
|
|
};
|
|
|
|
in
|
|
|
|
gen
|