at 22.05-pre 74 lines 2.9 kB view raw
1{ lib, resholve, binlore }: 2 3rec { 4 /* These functions break up the work of partially validating the 5 'solutions' attrset and massaging it into env/cli args. 6 7 Note: some of the left-most args do not *have* to be passed as 8 deep as they are, but I've done so to provide more error context 9 */ 10 11 # for brevity / line length 12 spaces = l: builtins.concatStringsSep " " l; 13 semicolons = l: builtins.concatStringsSep ";" l; 14 15 /* Throw a fit with dotted attr path context */ 16 nope = path: msg: 17 throw "${builtins.concatStringsSep "." path}: ${msg}"; 18 19 /* Special-case directive value representations by type */ 20 makeDirective = solution: env: name: val: 21 if builtins.isInt val then builtins.toString val 22 else if builtins.isString val then name 23 else if true == val then name 24 else if false == val then "" # omit! 25 else if null == val then "" # omit! 26 else if builtins.isList val then "${name}:${semicolons val}" 27 else nope [ solution env name ] "unexpected type: ${builtins.typeOf val}"; 28 29 /* Build fake/fix/keep directives from Nix types */ 30 makeDirectives = solution: env: val: 31 lib.mapAttrsToList (makeDirective solution env) val; 32 33 /* Special-case value representation by type/name */ 34 makeEnvVal = solution: env: val: 35 if env == "inputs" then lib.makeBinPath val 36 else if builtins.isString val then val 37 else if builtins.isList val then spaces val 38 else if builtins.isAttrs val then spaces (makeDirectives solution env val) 39 else nope [ solution env ] "unexpected type: ${builtins.typeOf val}"; 40 41 /* Shell-format each env value */ 42 shellEnv = solution: env: value: 43 lib.escapeShellArg (makeEnvVal solution env value); 44 45 /* Build a single ENV=val pair */ 46 makeEnv = solution: env: value: 47 "RESHOLVE_${lib.toUpper env}=${shellEnv solution env value}"; 48 49 /* Discard attrs claimed by makeArgs */ 50 removeCliArgs = value: 51 removeAttrs value [ "scripts" "flags" ]; 52 53 /* Verify required arguments are present */ 54 validateSolution = { scripts, inputs, interpreter, ... }: true; 55 56 /* Pull out specific solution keys to build ENV=val pairs */ 57 makeEnvs = solution: value: 58 spaces (lib.mapAttrsToList (makeEnv solution) (removeCliArgs value)); 59 60 /* Pull out specific solution keys to build CLI argstring */ 61 makeArgs = { flags ? [ ], scripts, ... }: 62 spaces (flags ++ scripts); 63 64 /* Build a single resholve invocation */ 65 makeInvocation = solution: value: 66 if validateSolution value then 67 # we pass resholve a directory 68 "RESHOLVE_LORE=${binlore.collect { drvs = value.inputs; } } ${makeEnvs solution value} ${resholve}/bin/resholve --overwrite ${makeArgs value}" 69 else throw "invalid solution"; # shouldn't trigger for now 70 71 /* Build resholve invocation for each solution. */ 72 makeCommands = solutions: 73 lib.mapAttrsToList makeInvocation solutions; 74}