nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at 21.05 97 lines 3.3 kB view raw
1{ stdenv, lib, resholve }: 2 3{ pname 4, src 5, version 6, passthru ? { } 7, solutions 8, ... 9}@attrs: 10let 11 inherit stdenv; 12 /* These functions break up the work of partially validating the 13 * 'solutions' attrset and massaging it into env/cli args. 14 * 15 * Note: some of the left-most args do not *have* to be passed as 16 * deep as they are, but I've done so to provide more error context 17 */ 18 19 # for brevity / line length 20 spaces = l: builtins.concatStringsSep " " l; 21 semicolons = l: builtins.concatStringsSep ";" l; 22 23 /* Throw a fit with dotted attr path context */ 24 nope = path: msg: 25 throw "${builtins.concatStringsSep "." path}: ${msg}"; 26 27 /* Special-case directive value representations by type */ 28 makeDirective = solution: env: name: val: 29 if builtins.isInt val then builtins.toString val 30 else if builtins.isString val then name 31 else if true == val then name 32 else if false == val then "" # omit! 33 else if null == val then "" # omit! 34 else if builtins.isList val then "${name}:${semicolons val}" 35 else nope [ solution env name ] "unexpected type: ${builtins.typeOf val}"; 36 37 /* Build fake/fix/keep directives from Nix types */ 38 makeDirectives = solution: env: val: 39 lib.mapAttrsToList (makeDirective solution env) val; 40 41 /* Special-case value representation by type/name */ 42 makeEnvVal = solution: env: val: 43 if env == "inputs" then lib.makeBinPath val 44 else if builtins.isString val then val 45 else if builtins.isList val then spaces val 46 else if builtins.isAttrs val then spaces (makeDirectives solution env val) 47 else nope [ solution env ] "unexpected type: ${builtins.typeOf val}"; 48 49 /* Shell-format each env value */ 50 shellEnv = solution: env: value: 51 lib.escapeShellArg (makeEnvVal solution env value); 52 53 /* Build a single ENV=val pair */ 54 makeEnv = solution: env: value: 55 "RESHOLVE_${lib.toUpper env}=${shellEnv solution env value}"; 56 57 /* Discard attrs claimed by makeArgs */ 58 removeCliArgs = value: 59 removeAttrs value [ "scripts" "flags" ]; 60 61 /* Verify required arguments are present */ 62 validateSolution = { scripts, inputs, interpreter, ... }: true; 63 64 /* Pull out specific solution keys to build ENV=val pairs */ 65 makeEnvs = solution: value: 66 spaces (lib.mapAttrsToList (makeEnv solution) (removeCliArgs value)); 67 68 /* Pull out specific solution keys to build CLI argstring */ 69 makeArgs = { flags ? [ ], scripts, ... }: 70 spaces (flags ++ scripts); 71 72 /* Build a single resholve invocation */ 73 makeInvocation = solution: value: 74 if validateSolution value then 75 "${makeEnvs solution value} resholve --overwrite ${makeArgs value}" 76 else throw "invalid solution"; # shouldn't trigger for now 77 78 /* Build resholve invocation for each solution. */ 79 makeCommands = solutions: 80 lib.mapAttrsToList makeInvocation solutions; 81 82 self = (stdenv.mkDerivation ((removeAttrs attrs [ "solutions" ]) 83 // { 84 inherit pname version src; 85 buildInputs = [ resholve ]; 86 87 # enable below for verbose debug info if needed 88 # supports default python.logging levels 89 # LOGLEVEL="INFO"; 90 preFixup = '' 91 pushd "$out" 92 ${builtins.concatStringsSep "\n" (makeCommands solutions)} 93 popd 94 ''; 95 })); 96in 97lib.extendDerivation true passthru self