Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Merge pull request #138080 from abathur/resholve_0.6.0

authored by

Sandro and committed by
GitHub
0dd7492c 621fa8b6

+630 -167
+52
pkgs/development/misc/resholve/README.md
··· 84 84 | fake | attrset | [directives](#controlling-resolution-with-directives) | 85 85 | fix | attrset | [directives](#controlling-resolution-with-directives) | 86 86 | keep | attrset | [directives](#controlling-resolution-with-directives) | 87 + | lore | string | [lore directory](#controlling-nested-resolution-with-lore) | 88 + | execers | list | [execer lore directive](#controlling-nested-resolution-with-lore) | 89 + | wrappers | list | [wrapper lore directive](#controlling-nested-resolution-with-lore) | 87 90 88 91 ## Controlling resolution with directives 89 92 ··· 156 159 "~/.bashrc" = true; 157 160 }; 158 161 ``` 162 + 163 + ## Controlling nested resolution with lore 164 + 165 + Initially, resolution of commands in the arguments to command-executing 166 + commands was limited to one level for a hard-coded list of builtins and 167 + external commands. resholve can now resolve these recursively. 168 + 169 + This feature combines information (_lore_) that the resholve Nix API 170 + obtains via binlore ([nixpkgs](../../tools/analysis/binlore), [repo](https://github.com/abathur/resholve)), 171 + with some rules (internal to resholve) for locating sub-executions in 172 + some of the more common commands. 173 + 174 + - "execer" lore identifies whether an executable can, cannot, 175 + or might execute its arguments. Every "can" or "might" verdict requires 176 + either built-in rules for finding the executable, or human triage. 177 + - "wrapper" lore maps shell exec wrappers to the programs they exec so 178 + that resholve can substitute an executable's verdict for its wrapper's. 179 + 180 + There will be more mechanisms for controlling this process in the future 181 + (and your reports/experiences will play a role in shaping them...) For now, 182 + the main lever is the ability to substitute your own lore. This is how you'd 183 + do it piecemeal: 184 + 185 + ``` 186 + # --execer 'cannot:${openssl.bin}/bin/openssl can:${openssl.bin}/bin/c_rehash' 187 + execer = [ 188 + /* 189 + This is the same verdict binlore will 190 + come up with. It's a no-op just to demo 191 + how to fiddle lore via the Nix API. 192 + */ 193 + "cannot:${openssl.bin}/bin/openssl" 194 + # different verdict, but not used 195 + "can:${openssl.bin}/bin/c_rehash" 196 + ]; 197 + 198 + # --wrapper '${gnugrep}/bin/egrep:${gnugrep}/bin/grep' 199 + execer = [ 200 + /* 201 + This is the same verdict binlore will 202 + come up with. It's a no-op just to demo 203 + how to fiddle lore via the Nix API. 204 + */ 205 + "${gnugrep}/bin/egrep:${gnugrep}/bin/grep" 206 + ]; 207 + ``` 208 + 209 + The format is fairly simple to generate--you can script your own generator if 210 + you need to modify the lore.
+13 -4
pkgs/development/misc/resholve/default.nix
··· 1 1 { callPackage 2 - , doCheck ? true 2 + , ... 3 3 }: 4 4 5 + let 6 + source = callPackage ./source.nix { }; 7 + deps = callPackage ./deps.nix { }; 8 + in 5 9 rec { 6 - resholve = callPackage ./resholve.nix { inherit doCheck; }; 7 - resholvePackage = 8 - callPackage ./resholve-package.nix { inherit resholve; }; 10 + resholve = callPackage ./resholve.nix { 11 + inherit (source) rSrc; 12 + inherit (source) version; 13 + inherit (deps.oil) oildev; 14 + }; 15 + resholvePackage = callPackage ./resholve-package.nix { 16 + inherit resholve; 17 + }; 9 18 }
+7 -109
pkgs/development/misc/resholve/deps.nix
··· 1 - { lib, stdenv 2 - , python27Packages 3 - , fetchFromGitHub 4 - , makeWrapper 5 - , # re2c deps 6 - autoreconfHook 7 - , # py-yajl deps 8 - git 9 - , # oil deps 10 - readline 11 - , cmark 12 - , file 13 - , glibcLocales 14 - , oilPatches ? [ ] 1 + { callPackage 2 + , ... 15 3 }: 16 4 17 5 /* 18 - Notes on specific dependencies: 19 - - if/when python2.7 is removed from nixpkgs, this may need to figure 6 + Notes on specific dependencies: 7 + - if/when python2.7 is removed from nixpkgs, this may need to figure 20 8 out how to build oil's vendored python2 21 - - I'm not sure if glibcLocales is worth the addition here. It's to fix 9 + - I'm not sure if glibcLocales is worth the addition here. It's to fix 22 10 a libc test oil runs. My oil fork just disabled the libc tests, but 23 11 I haven't quite decided if that's the right long-term call, so I 24 12 didn't add a patch for it here yet. 25 13 */ 26 14 27 15 rec { 28 - # had to add this as well; 1.3 causes a break here; sticking 29 - # to oil's official 1.0.3 dep for now. 30 - re2c = stdenv.mkDerivation rec { 31 - pname = "re2c"; 32 - version = "1.0.3"; 33 - sourceRoot = "${src.name}/re2c"; 34 - src = fetchFromGitHub { 35 - owner = "skvadrik"; 36 - repo = "re2c"; 37 - rev = version; 38 - sha256 = "0grx7nl9fwcn880v5ssjljhcb9c5p2a6xpwil7zxpmv0rwnr3yqi"; 39 - }; 40 - nativeBuildInputs = [ autoreconfHook ]; 41 - preCheck = '' 42 - patchShebangs run_tests.sh 43 - ''; 44 - }; 45 - 46 - py-yajl = python27Packages.buildPythonPackage rec { 47 - pname = "oil-pyyajl-unstable"; 48 - version = "2019-12-05"; 49 - src = fetchFromGitHub { 50 - owner = "oilshell"; 51 - repo = "py-yajl"; 52 - rev = "eb561e9aea6e88095d66abcc3990f2ee1f5339df"; 53 - sha256 = "17hcgb7r7cy8r1pwbdh8di0nvykdswlqj73c85k6z8m0filj3hbh"; 54 - fetchSubmodules = true; 55 - }; 56 - # just for submodule IIRC 57 - nativeBuildInputs = [ git ]; 58 - }; 59 - 60 - # resholve's primary dependency is this developer build of the oil shell. 61 - oildev = python27Packages.buildPythonPackage rec { 62 - pname = "oildev-unstable"; 63 - version = "2021-02-26"; 64 - 65 - src = fetchFromGitHub { 66 - owner = "oilshell"; 67 - repo = "oil"; 68 - rev = "11c6bd3ca0e126862c7a1f938c8510779837affa"; 69 - hash = "sha256-UTQywtx+Dn1/qx5uocqgGn7oFYW4R5DbuiRNF8t/BzY="; 70 - 71 - /* 72 - It's not critical to drop most of these; the primary target is 73 - the vendored fork of Python-2.7.13, which is ~ 55M and over 3200 74 - files, dozens of which get interpreter script patches in fixup. 75 - */ 76 - extraPostFetch = '' 77 - rm -rf Python-2.7.13 benchmarks metrics py-yajl rfc gold web testdata services demo devtools cpp 78 - ''; 79 - }; 80 - 81 - # TODO: not sure why I'm having to set this for nix-build... 82 - # can anyone tell if I'm doing something wrong? 83 - SOURCE_DATE_EPOCH = 315532800; 84 - 85 - # These aren't, strictly speaking, nix/nixpkgs specific, but I've 86 - # had hell upstreaming them. Pulling from resholve source and 87 - # passing in from resholve.nix 88 - patches = oilPatches; 89 - 90 - buildInputs = [ readline cmark py-yajl ]; 91 - 92 - nativeBuildInputs = [ re2c file makeWrapper ]; 93 - 94 - propagatedBuildInputs = with python27Packages; [ six typing ]; 95 - 96 - doCheck = true; 97 - 98 - preBuild = '' 99 - build/dev.sh all 100 - ''; 101 - 102 - postPatch = '' 103 - patchShebangs asdl build core doctools frontend native oil_lang 104 - ''; 105 - 106 - _NIX_SHELL_LIBCMARK = "${cmark}/lib/libcmark${stdenv.hostPlatform.extensions.sharedLibrary}"; 107 - 108 - # See earlier note on glibcLocales 109 - LOCALE_ARCHIVE = lib.optionalString (stdenv.buildPlatform.libc == "glibc") "${glibcLocales}/lib/locale/locale-archive"; 110 - 111 - meta = { 112 - description = "A new unix shell"; 113 - homepage = "https://www.oilshell.org/"; 114 - license = with lib.licenses; [ 115 - psfl # Includes a portion of the python interpreter and standard library 116 - asl20 # Licence for Oil itself 117 - ]; 118 - }; 119 - }; 16 + # binlore = callPackage ./binlore.nix { }; 17 + oil = callPackage ./oildev.nix { }; 120 18 }
+121
pkgs/development/misc/resholve/oildev.nix
··· 1 + { lib 2 + , stdenv 3 + , python27Packages 4 + , callPackage 5 + , fetchFromGitHub 6 + , makeWrapper 7 + , # re2c deps 8 + autoreconfHook 9 + , # py-yajl deps 10 + git 11 + , # oil deps 12 + readline 13 + , cmark 14 + , file 15 + , glibcLocales 16 + }: 17 + 18 + rec { 19 + re2c = stdenv.mkDerivation rec { 20 + pname = "re2c"; 21 + version = "1.0.3"; 22 + sourceRoot = "${src.name}/re2c"; 23 + src = fetchFromGitHub { 24 + owner = "skvadrik"; 25 + repo = "re2c"; 26 + rev = version; 27 + sha256 = "0grx7nl9fwcn880v5ssjljhcb9c5p2a6xpwil7zxpmv0rwnr3yqi"; 28 + }; 29 + nativeBuildInputs = [ autoreconfHook ]; 30 + preCheck = '' 31 + patchShebangs run_tests.sh 32 + ''; 33 + }; 34 + 35 + py-yajl = python27Packages.buildPythonPackage rec { 36 + pname = "oil-pyyajl-unstable"; 37 + version = "2019-12-05"; 38 + src = fetchFromGitHub { 39 + owner = "oilshell"; 40 + repo = "py-yajl"; 41 + rev = "eb561e9aea6e88095d66abcc3990f2ee1f5339df"; 42 + sha256 = "17hcgb7r7cy8r1pwbdh8di0nvykdswlqj73c85k6z8m0filj3hbh"; 43 + fetchSubmodules = true; 44 + }; 45 + # just for submodule IIRC 46 + nativeBuildInputs = [ git ]; 47 + }; 48 + 49 + oildev = python27Packages.buildPythonPackage rec { 50 + pname = "oildev-unstable"; 51 + version = "2021-07-14"; 52 + 53 + src = fetchFromGitHub { 54 + owner = "oilshell"; 55 + repo = "oil"; 56 + # rev == present HEAD of release/0.8.12 57 + rev = "799c0703d1da86cb80d1f5b163edf9369ad77cf1"; 58 + hash = "sha256-QNSISr719ycZ1Z0quxHWzCb3IvHGj9TpogaYz20hDM4="; 59 + 60 + /* 61 + It's not critical to drop most of these; the primary target is 62 + the vendored fork of Python-2.7.13, which is ~ 55M and over 3200 63 + files, dozens of which get interpreter script patches in fixup. 64 + */ 65 + extraPostFetch = '' 66 + rm -rf Python-2.7.13 benchmarks metrics py-yajl rfc gold web testdata services demo devtools cpp 67 + ''; 68 + }; 69 + 70 + # TODO: not sure why I'm having to set this for nix-build... 71 + # can anyone tell if I'm doing something wrong? 72 + SOURCE_DATE_EPOCH = 315532800; 73 + 74 + # patch to support a python package, pass tests on macOS, etc. 75 + patchSrc = fetchFromGitHub { 76 + owner = "abathur"; 77 + repo = "nix-py-dev-oil"; 78 + rev = "v0.8.12"; 79 + hash = "sha256-/EvwxL201lGsioL0lIhzM8VTghe6FuVbc3PBJgY8c8E="; 80 + }; 81 + patches = [ 82 + "${patchSrc}/0001-add_setup_py.patch" 83 + "${patchSrc}/0002-add_MANIFEST_in.patch" 84 + "${patchSrc}/0004-disable-internal-py-yajl-for-nix-built.patch" 85 + "${patchSrc}/0006-disable_failing_libc_tests.patch" 86 + "${patchSrc}/0007-namespace_via_init.patch" 87 + ]; 88 + 89 + buildInputs = [ readline cmark py-yajl ]; 90 + 91 + nativeBuildInputs = [ re2c file makeWrapper ]; 92 + 93 + propagatedBuildInputs = with python27Packages; [ six typing ]; 94 + 95 + doCheck = true; 96 + 97 + preBuild = '' 98 + build/dev.sh all 99 + ''; 100 + 101 + postPatch = '' 102 + patchShebangs asdl build core doctools frontend native oil_lang 103 + ''; 104 + 105 + # TODO: this may be obsolete? 106 + _NIX_SHELL_LIBCMARK = "${cmark}/lib/libcmark${stdenv.hostPlatform.extensions.sharedLibrary}"; 107 + 108 + # See earlier note on glibcLocales TODO: verify needed? 109 + LOCALE_ARCHIVE = lib.optionalString (stdenv.buildPlatform.libc == "glibc") "${glibcLocales}/lib/locale/locale-archive"; 110 + 111 + # not exhaustive; just a spot-check for now 112 + pythonImportsCheck = [ "oil" "oil._devbuild" ]; 113 + 114 + meta = { 115 + license = with lib.licenses; [ 116 + psfl # Includes a portion of the python interpreter and standard library 117 + asl20 # Licence for Oil itself 118 + ]; 119 + }; 120 + }; 121 + }
+20 -10
pkgs/development/misc/resholve/resholve-package.nix
··· 1 - { stdenv, lib, resholve }: 1 + { stdenv, lib, resholve, binlore }: 2 2 3 3 { pname 4 4 , src ··· 10 10 let 11 11 inherit stdenv; 12 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 - */ 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 18 19 19 # for brevity / line length 20 20 spaces = l: builtins.concatStringsSep " " l; ··· 72 72 /* Build a single resholve invocation */ 73 73 makeInvocation = solution: value: 74 74 if validateSolution value then 75 - "${makeEnvs solution value} resholve --overwrite ${makeArgs value}" 75 + # we pass resholve a directory 76 + "RESHOLVE_LORE=${binlore.collect { drvs = value.inputs; } } ${makeEnvs solution value} resholve --overwrite ${makeArgs value}" 76 77 else throw "invalid solution"; # shouldn't trigger for now 77 78 78 79 /* Build resholve invocation for each solution. */ ··· 87 88 # enable below for verbose debug info if needed 88 89 # supports default python.logging levels 89 90 # LOGLEVEL="INFO"; 91 + /* 92 + subshell/PS4/set -x and : command to output resholve envs 93 + and invocation. Extra context makes it clearer what the 94 + Nix API is doing, makes nix-shell debugging easier, etc. 95 + */ 90 96 preFixup = '' 91 - pushd "$out" 92 - ${builtins.concatStringsSep "\n" (makeCommands solutions)} 93 - popd 97 + ( 98 + cd "$out" 99 + PS4=$'\x1f'"\033[33m[resholve context]\033[0m " 100 + set -x 101 + : changing directory to $PWD 102 + ${builtins.concatStringsSep "\n" (makeCommands solutions)} 103 + ) 94 104 ''; 95 105 })); 96 106 in
+9 -44
pkgs/development/misc/resholve/resholve.nix
··· 2 2 , callPackage 3 3 , python27Packages 4 4 , installShellFiles 5 - , fetchFromGitHub 6 - , file 7 - , findutils 8 - , gettext 9 - , bats 10 - , bash 11 - , doCheck ? true 5 + , rSrc 6 + , version 7 + , oildev 8 + , binlore 12 9 }: 13 - let 14 - version = "0.5.1"; 15 - rSrc = fetchFromGitHub { 16 - owner = "abathur"; 17 - repo = "resholve"; 18 - rev = "v${version}"; 19 - hash = "sha256-+9MjvO1H+A3Ol2to5tWqdpNR7osQsYcbkX9avAqyrKw="; 20 - }; 21 - deps = callPackage ./deps.nix { 22 - /* 23 - resholve needs to patch Oil, but trying to avoid adding 24 - them all *to* nixpkgs, since they aren't specific to 25 - nix/nixpkgs. 26 - */ 27 - oilPatches = [ 28 - "${rSrc}/0001-add_setup_py.patch" 29 - "${rSrc}/0002-add_MANIFEST_in.patch" 30 - "${rSrc}/0003-fix_codegen_shebang.patch" 31 - "${rSrc}/0004-disable-internal-py-yajl-for-nix-built.patch" 32 - "${rSrc}/0005_revert_libc_locale.patch" 33 - "${rSrc}/0006_disable_failing_libc_tests.patch" 34 - "${rSrc}/0007_restore_root_init_py.patch" 35 - ]; 36 - }; 37 - in 10 + 38 11 python27Packages.buildPythonApplication { 39 12 pname = "resholve"; 40 13 inherit version; 41 14 src = rSrc; 42 15 format = "other"; 16 + dontBuild = true; 43 17 44 18 nativeBuildInputs = [ installShellFiles ]; 45 19 46 - propagatedBuildInputs = [ deps.oildev python27Packages.configargparse ]; 20 + propagatedBuildInputs = [ oildev python27Packages.configargparse ]; 47 21 48 22 patchPhase = '' 49 23 for file in resholve; do ··· 56 30 installManPage resholve.1 57 31 ''; 58 32 59 - inherit doCheck; 60 - checkInputs = [ bats ]; 61 - RESHOLVE_PATH = "${lib.makeBinPath [ file findutils gettext ]}"; 62 - 63 - checkPhase = '' 64 - # explicit interpreter for test suite 65 - export INTERP="${bash}/bin/bash" PATH="$out/bin:$PATH" 66 - patchShebangs . 67 - ./test.sh 68 - ''; 69 - 70 33 # Do not propagate Python; may be obsoleted by nixos/nixpkgs#102613 71 34 # for context on why, see abathur/resholve#20 72 35 postFixup = '' 73 36 rm $out/nix-support/propagated-build-inputs 74 37 ''; 38 + 39 + passthru.tests = callPackage ./test.nix { inherit rSrc; inherit binlore; }; 75 40 76 41 meta = with lib; { 77 42 description = "Resolve external shell-script dependencies";
+19
pkgs/development/misc/resholve/source.nix
··· 1 + { fetchFromGitHub 2 + , ... 3 + }: 4 + 5 + rec { 6 + version = "0.6.0"; 7 + rSrc = 8 + # local build -> `make ci`; `make clean` to restore 9 + # return to remote source 10 + # if builtins.pathExists ./.local 11 + # then ./. 12 + # else 13 + fetchFromGitHub { 14 + owner = "abathur"; 15 + repo = "resholve"; 16 + rev = "v${version}"; 17 + hash = "sha256-GfhhU9f5kiYcuYTPKWXCIkAGsz7GhAUGjAmIZ8Ww5X4="; 18 + }; 19 + }
+227
pkgs/development/misc/resholve/test.nix
··· 1 + { lib 2 + , stdenv 3 + , callPackage 4 + , resholve 5 + , resholvePackage 6 + , shunit2 7 + , coreutils 8 + , gnused 9 + , gnugrep 10 + , findutils 11 + , jq 12 + , bash 13 + , bats 14 + , libressl 15 + , openssl 16 + , python27 17 + , file 18 + , gettext 19 + , rSrc 20 + , runDemo ? false 21 + , binlore 22 + }: 23 + 24 + let 25 + inherit (callPackage ./default.nix { }) 26 + resholve resholvePackage; 27 + 28 + # ourCoreutils = coreutils.override { singleBinary = false; }; 29 + 30 + /* 31 + TODO: wrapped copy of find so that we can eventually test 32 + our ability to see through wrappers. Unused for now. 33 + Note: grep can serve the negative case; grep doesn't match, and 34 + egrep is a shell wrapper for grep. 35 + */ 36 + # wrapfind = runCommand "wrapped-find" { } '' 37 + # source ${makeWrapper}/nix-support/setup-hook 38 + # makeWrapper ${findutils}/bin/find $out/bin/wrapped-find 39 + # ''; 40 + /* TODO: 41 + unrelated, but is there already a function (or would 42 + there be demand for one?) along the lines of: 43 + wrap = { drv, executable(s?), args ? { } }: that: 44 + - generates a sane output name 45 + - sources makewrapper 46 + - retargets real executable if already wrapped 47 + - wraps the executable 48 + 49 + I wonder because my first thought here was overrideAttrs, 50 + but I realized rebuilding just for a custom wrapper is an 51 + ongoing waste of time. If it is a common pattern in the 52 + wild, it would be a nice QoL improvement. 53 + */ 54 + 55 + in 56 + rec { 57 + re_shunit2 = with shunit2; 58 + resholvePackage { 59 + inherit pname src version installPhase; 60 + solutions = { 61 + shunit = { 62 + interpreter = "none"; 63 + scripts = [ "bin/shunit2" ]; 64 + inputs = [ coreutils gnused gnugrep findutils ]; 65 + # resholve's Nix API is analogous to the CLI flags 66 + # documented in 'man resholve' 67 + fake = { 68 + # "missing" functions shunit2 expects the user to declare 69 + function = [ 70 + "oneTimeSetUp" 71 + "oneTimeTearDown" 72 + "setUp" 73 + "tearDown" 74 + "suite" 75 + "noexec" 76 + ]; 77 + # shunit2 is both bash and zsh compatible, and in 78 + # some zsh-specific code it uses this non-bash builtin 79 + builtin = [ "setopt" ]; 80 + }; 81 + fix = { 82 + # stray absolute path; make it resolve from coreutils 83 + "/usr/bin/od" = true; 84 + }; 85 + keep = { 86 + # dynamically defined in shunit2:_shunit_mktempFunc 87 + eval = [ "shunit_condition_" "_shunit_test_" "_shunit_prepForSourcing" ]; 88 + 89 + # variables invoked as commands; long-term goal is to 90 + # resolve the *variable*, but that is complexish, so 91 + # this is where we are... 92 + "$__SHUNIT_CMD_ECHO_ESC" = true; 93 + "$_SHUNIT_LINENO_" = true; 94 + "$SHUNIT_CMD_TPUT" = true; 95 + }; 96 + }; 97 + }; 98 + }; 99 + module1 = resholvePackage { 100 + pname = "testmod1"; 101 + version = "unreleased"; 102 + 103 + src = rSrc; 104 + setSourceRoot = "sourceRoot=$(echo */tests/nix/libressl)"; 105 + 106 + installPhase = '' 107 + mkdir -p $out/{bin,submodule} 108 + install libressl.sh $out/bin/libressl.sh 109 + install submodule/helper.sh $out/submodule/helper.sh 110 + ''; 111 + 112 + solutions = { 113 + libressl = { 114 + # submodule to demonstrate 115 + scripts = [ "bin/libressl.sh" "submodule/helper.sh" ]; 116 + interpreter = "none"; 117 + inputs = [ jq module2 libressl.bin ]; 118 + }; 119 + }; 120 + 121 + is_it_okay_with_arbitrary_envs = "shonuff"; 122 + }; 123 + module2 = resholvePackage { 124 + pname = "testmod2"; 125 + version = "unreleased"; 126 + 127 + src = rSrc; 128 + setSourceRoot = "sourceRoot=$(echo */tests/nix/openssl)"; 129 + 130 + installPhase = '' 131 + mkdir -p $out/bin 132 + install openssl.sh $out/bin/openssl.sh 133 + install profile $out/profile 134 + ''; 135 + 136 + solutions = { 137 + openssl = { 138 + fix = { 139 + aliases = true; 140 + }; 141 + scripts = [ "bin/openssl.sh" ]; 142 + interpreter = "none"; 143 + inputs = [ re_shunit2 openssl.bin ]; 144 + execer = [ 145 + /* 146 + This is the same verdict binlore will 147 + come up with. It's a no-op just to demo 148 + how to fiddle lore via the Nix API. 149 + */ 150 + "cannot:${openssl.bin}/bin/openssl" 151 + # different verdict, but not used 152 + "can:${openssl.bin}/bin/c_rehash" 153 + ]; 154 + }; 155 + profile = { 156 + scripts = [ "profile" ]; 157 + interpreter = "none"; 158 + inputs = [ ]; 159 + }; 160 + }; 161 + }; 162 + module3 = resholvePackage { 163 + pname = "testmod3"; 164 + version = "unreleased"; 165 + 166 + src = rSrc; 167 + setSourceRoot = "sourceRoot=$(echo */tests/nix/future_perfect_tense)"; 168 + 169 + installPhase = '' 170 + mkdir -p $out/bin 171 + install conjure.sh $out/bin/conjure.sh 172 + ''; 173 + 174 + solutions = { 175 + conjure = { 176 + scripts = [ "bin/conjure.sh" ]; 177 + interpreter = "${bash}/bin/bash"; 178 + inputs = [ module1 ]; 179 + }; 180 + }; 181 + }; 182 + 183 + cli = stdenv.mkDerivation { 184 + name = "resholve-test"; 185 + src = rSrc; 186 + installPhase = '' 187 + mkdir $out 188 + cp *.ansi $out/ 189 + ''; 190 + doCheck = true; 191 + buildInputs = [ resholve ]; 192 + checkInputs = [ coreutils bats python27 ]; 193 + # LOGLEVEL="DEBUG"; 194 + 195 + # default path 196 + RESHOLVE_PATH = "${lib.makeBinPath [ bash file findutils gettext ]}"; 197 + # but separate packages for combining as needed 198 + PKG_FILE = "${lib.makeBinPath [ file ]}"; 199 + PKG_FINDUTILS = "${lib.makeBinPath [ findutils ]}"; 200 + PKG_GETTEXT = "${lib.makeBinPath [ gettext ]}"; 201 + PKG_COREUTILS = "${lib.makeBinPath [ coreutils ]}"; 202 + RESHOLVE_LORE = "${binlore.collect { drvs = [ bash file findutils gettext coreutils ]; } }"; 203 + 204 + # explicit interpreter for demo suite; maybe some better way... 205 + INTERP = "${bash}/bin/bash"; 206 + 207 + checkPhase = '' 208 + patchShebangs . 209 + mkdir empty_lore 210 + touch empty_lore/{execers,wrappers} 211 + export EMPTY_LORE=$PWD/empty_lore 212 + printf "\033[33m============================= resholve test suite ===================================\033[0m\n" > test.ansi 213 + if ./test.sh &>> test.ansi; then 214 + cat test.ansi 215 + else 216 + cat test.ansi && exit 1 217 + fi 218 + '' + lib.optionalString runDemo '' 219 + printf "\033[33m============================= resholve demo ===================================\033[0m\n" > demo.ansi 220 + if ./demo &>> demo.ansi; then 221 + cat demo.ansi 222 + else 223 + cat demo.ansi && exit 1 224 + fi 225 + ''; 226 + }; 227 + }
+112
pkgs/development/tools/analysis/binlore/default.nix
··· 1 + { lib 2 + , fetchFromGitHub 3 + , runCommand 4 + , yallback 5 + , yara 6 + }: 7 + 8 + /* TODO/CAUTION: 9 + 10 + I don't want to discourage use, but I'm not sure how stable 11 + the API is. Have fun, but be prepared to track changes! :) 12 + 13 + For _now_, binlore is basically a thin wrapper around 14 + `<invoke yara> | <postprocess with yallback>` with support 15 + for running it on a derivation, saving the result in the 16 + store, and aggregating results from a set of packages. 17 + 18 + In the longer term, I suspect there are more uses for this 19 + general pattern (i.e., run some analysis tool that produces 20 + a deterministic output and cache the result per package...). 21 + 22 + I'm not sure how that'll look and if it'll be the case that 23 + binlore automatically collects all of them, or if you'll be 24 + configuring which "kind(s)" of lore it generates. Nailing 25 + that down will almost certainly mean reworking the API. 26 + 27 + */ 28 + 29 + let 30 + src = fetchFromGitHub { 31 + owner = "abathur"; 32 + repo = "binlore"; 33 + rev = "v0.1.3"; 34 + hash = "sha256-+rgv8gAQ3ptOpL/EhbKr/jq+k/4Lpn06/2qON+Ps2wE="; 35 + }; 36 + /* 37 + binlore has one one more yallbacks responsible for 38 + routing the appropriate lore to a named file in the 39 + appropriate format. At some point I might try to do 40 + something fancy with this, but for now the answer to 41 + *all* questions about the lore are: the bare minimum 42 + to get resholve over the next feature hump in time to 43 + hopefully slip this feature in before the branch-off. 44 + */ 45 + # TODO: feeling really uninspired on the API 46 + loreDef = { 47 + # YARA rule file 48 + rules = (src + /execers.yar); 49 + # output filenames; "types" of lore 50 + types = [ "execers" "wrappers" ]; 51 + # shell rule callbacks; see github.com/abathur/yallback 52 + yallback = (src + /execers.yall); 53 + # TODO: 54 + # - echo for debug, can be removed at some point 55 + # - I really just wanted to put the bit after the pipe 56 + # in here, but I'm erring on the side of flexibility 57 + # since this form will make it easier to pilot other 58 + # uses of binlore. 59 + callback = lore: drv: overrides: '' 60 + if [[ -d "${drv}/bin" ]]; then 61 + echo generating binlore for $drv by running: 62 + echo "${yara}/bin/yara ${lore.rules} ${drv}/bin | ${yallback}/bin/yallback ${lore.yallback}" 63 + else 64 + echo "failed to generate binlore for $drv (${drv}/bin doesn't exist)" 65 + fi 66 + '' + 67 + /* 68 + Override lore for some packages. Unsure, but for now: 69 + 1. start with the ~name (pname-version) 70 + 2. remove characters from the end until we find a match 71 + in overrides/ 72 + 3. execute the override script with the list of expected 73 + lore types 74 + */ 75 + '' 76 + i=''${#identifier} 77 + filter= 78 + while [[ $i > 0 ]] && [[ -z "$filter" ]]; do 79 + if [[ -f "${overrides}/''${identifier:0:$i}" ]]; then 80 + filter="${overrides}/''${identifier:0:$i}" 81 + echo using "${overrides}/''${identifier:0:$i}" to generate overriden binlore for $drv 82 + break 83 + fi 84 + ((i--)) || true # don't break build 85 + done # || true # don't break build 86 + if [[ -d "${drv}/bin" ]]; then 87 + ${yara}/bin/yara ${lore.rules} ${drv}/bin | ${yallback}/bin/yallback ${lore.yallback} "$filter" 88 + fi 89 + ''; 90 + }; 91 + overrides = (src + /overrides); 92 + 93 + in rec { 94 + collect = { lore ? loreDef, drvs }: (runCommand "more-binlore" { } '' 95 + mkdir $out 96 + for lorefile in ${toString lore.types}; do 97 + cat ${lib.concatMapStrings (x: x + "/$lorefile ") (map (make lore) (map lib.getBin drvs))} > $out/$lorefile 98 + done 99 + ''); 100 + # TODO: echo for debug, can be removed at some point 101 + make = lore: drv: runCommand "${drv.name}-binlore" { 102 + identifier = drv.name; 103 + drv = drv; 104 + } ('' 105 + mkdir $out 106 + touch $out/{${builtins.concatStringsSep "," lore.types}} 107 + 108 + ${lore.callback lore drv overrides} 109 + 110 + echo binlore for $drv written to $out 111 + ''); 112 + }
+34
pkgs/development/tools/analysis/yallback/default.nix
··· 1 + { lib 2 + , stdenv 3 + , fetchFromGitHub 4 + , makeWrapper 5 + , coreutils 6 + , bashInteractive 7 + }: 8 + 9 + stdenv.mkDerivation rec { 10 + version = "0.1.0"; 11 + pname = "yallback"; 12 + src = fetchFromGitHub { 13 + owner = "abathur"; 14 + repo = "yallback"; 15 + rev = "v${version}"; 16 + hash = "sha256-FaPqpxstKMhqLPFLIdenHgwzDE3gspBbJUSY95tblgI="; 17 + }; 18 + 19 + buildInputs = [ coreutils bashInteractive ]; 20 + nativeBuildInputs = [ makeWrapper ]; 21 + 22 + installPhase = '' 23 + install -Dv yallback $out/bin/yallback 24 + wrapProgram $out/bin/yallback --prefix PATH : ${lib.makeBinPath [ coreutils ]} 25 + ''; 26 + 27 + meta = with lib; { 28 + description = "Callbacks for YARA rule matches"; 29 + homepage = "https://github.com/abathur/yallback"; 30 + license = licenses.mit; 31 + maintainers = with maintainers; [ abathur ]; 32 + platforms = platforms.all; 33 + }; 34 + }
+12
pkgs/tools/misc/arch-install-scripts/default.nix
··· 52 52 53 53 # packages resholve should resolve executables from 54 54 inputs = [ coreutils gawk util-linux ]; 55 + 56 + # TODO: no good way to resolve mount/umount in Nix builds for now 57 + # see https://github.com/abathur/resholve/issues/29 58 + fake = { 59 + external = [ "mount" "umount" ]; 60 + }; 61 + 62 + # TODO: remove the execer lore override below after 63 + # https://github.com/abathur/binlore/issues/1 64 + execer = [ 65 + "cannot:${util-linux}/bin/unshare" 66 + ]; 55 67 }; 56 68 }; 57 69
+4
pkgs/top-level/all-packages.nix
··· 3632 3632 3633 3633 biblatex-check = callPackage ../tools/typesetting/biblatex-check { }; 3634 3634 3635 + binlore = callPackage ../development/tools/analysis/binlore { }; 3636 + 3635 3637 birdfont = callPackage ../tools/misc/birdfont { }; 3636 3638 xmlbird = callPackage ../tools/misc/birdfont/xmlbird.nix { stdenv = gccStdenv; }; 3637 3639 ··· 10579 10581 yafaray-core = callPackage ../tools/graphics/yafaray-core { }; 10580 10582 10581 10583 yajsv = callPackage ../tools/misc/yajsv { }; 10584 + 10585 + yallback = callPackage ../development/tools/analysis/yallback { }; 10582 10586 10583 10587 yapf = with python3Packages; toPythonApplication yapf; 10584 10588