Add nixredo-whichdo; Put do file discovery into nix
parent
fc8781a2e0
commit
dd8952be85
58
builder.nix
58
builder.nix
|
@ -1,32 +1,42 @@
|
||||||
builderArgs:
|
buildArgs@{ lib ? import ./lib.nix {}, nixpkgs ? <nixpkgs>, pkgs ? import nixpkgs {} }:
|
||||||
let
|
let
|
||||||
|
inherit (lib) searchPath whichdo d1 d2;
|
||||||
|
|
||||||
myself = { nixpkgs ? <nixpkgs>, pkgs ? import nixpkgs {}, rargs, cwd }:
|
resolve = path: let
|
||||||
builder:
|
builder = (whichdo path);
|
||||||
|
in if builder == "" then throw "No rule to build ${path}"
|
||||||
|
else runBuilder (d1 path builder) (d2 path builder) builder;
|
||||||
|
|
||||||
|
runBuilder = d1: d2: builder:
|
||||||
|
with pkgs.lib;
|
||||||
with builtins;
|
with builtins;
|
||||||
let
|
let
|
||||||
resolveLocal = arg: let
|
# Funktionalise pkgs; our main entry point to resolve default*nix build scripts.
|
||||||
fullPath = cwd + "/" + arg + ".nix";
|
funcPkgs = { __functor = self: arg: resolve arg; } // pkgs;
|
||||||
recurse = myself { rargs = [ (toString arg) (toString arg) ]; inherit cwd; };
|
|
||||||
in recurse fullPath;
|
|
||||||
funcPkgs = { __functor = self: arg: resolveLocal arg; } // pkgs;
|
|
||||||
|
|
||||||
_builder = if (tryEval (import builder)).success
|
_builder = if (tryEval (let
|
||||||
then import builder
|
# Needs to be done as nix chokes on empty files rn.
|
||||||
else ''
|
content = readFile builder;
|
||||||
#!/bin/sh
|
in assert content != "" && (! (hasPrefix "#!" content)); import builder)).success
|
||||||
${builder} $1 $2 $out >$out
|
then import builder
|
||||||
'';
|
else ''
|
||||||
|
#!/bin/sh
|
||||||
|
${/. + builder} $d1 $d2 $out >$out
|
||||||
|
'';
|
||||||
__builder = if isFunction _builder then _builder funcPkgs
|
__builder = if isFunction _builder then _builder funcPkgs
|
||||||
else _builder;
|
else _builder;
|
||||||
|
|
||||||
args = { stdenv = pkgs.stdenvNoCC; } // (if isString __builder
|
args = { stdenv = pkgs.stdenvNoCC; } // (if isString __builder
|
||||||
then { builder = __builder; }
|
then { builder = __builder; }
|
||||||
else __builder);
|
else __builder);
|
||||||
in (args.deriver or args.stdenv.mkDerivation) ({
|
|
||||||
name = pkgs.lib.strings.sanitizeDerivationName (builtins.elemAt rargs 0);
|
drv = (args.deriver or args.stdenv.mkDerivation) ({
|
||||||
buildCommand = args.builder;
|
name = pkgs.lib.strings.sanitizeDerivationName d1;
|
||||||
passAsFile = [ "buildCommand" ];
|
buildCommand = args.builder;
|
||||||
preferLocalBuild = true;
|
passAsFile = [ "buildCommand" ];
|
||||||
allowSubstitutes = false;
|
preferLocalBuild = true;
|
||||||
} // (removeAttrs args [ "builder" "system" "deriver" "stdenv" ])); # myself
|
allowSubstitutes = false;
|
||||||
in myself builderArgs
|
inherit d1 d2;
|
||||||
|
} // (removeAttrs args [ "builder" "system" "deriver" "stdenv" ]));
|
||||||
|
in drv; # myself
|
||||||
|
in resolve
|
||||||
|
|
|
@ -5,10 +5,13 @@ stdenv.mkDerivation {
|
||||||
phases = [ "installPhase" "fixupPhase" ];
|
phases = [ "installPhase" "fixupPhase" ];
|
||||||
jq = "${jq}/bin/jq";
|
jq = "${jq}/bin/jq";
|
||||||
buildernix = ./builder.nix;
|
buildernix = ./builder.nix;
|
||||||
|
libnix = ./lib.nix;
|
||||||
|
|
||||||
|
files = [ ./nixredo ./nixredo-deps ./nixredo-whichdo ];
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
for f in ${./nixredo} ${./nixredo-deps}; do
|
for f in $files; do
|
||||||
_f=$out/bin/nixredo''${f##*-nixredo}
|
_f=$out/bin/nixredo''${f##*-nixredo}
|
||||||
cp $f $_f
|
cp $f $_f
|
||||||
substituteAllInPlace $_f
|
substituteAllInPlace $_f
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
{ lib ? import <nixpkgs/lib> }:
|
||||||
|
let
|
||||||
|
inherit (builtins) length genList pathExists;
|
||||||
|
inherit (lib) take splitString concatStringsSep last foldl foldr head
|
||||||
|
tail singleton removePrefix hasSuffix removeSuffix flatten crossLists reverseList;
|
||||||
|
butlast = list: take (length list - 1) list;
|
||||||
|
dirname = path: let _p = (butlast (splitString "/" path)); in if _p != [] then concatStringsSep "/" _p else "./";
|
||||||
|
basename = path: (last (splitString "/" path));
|
||||||
|
|
||||||
|
doFileSuffix = "do";
|
||||||
|
|
||||||
|
genPatterns = path: let
|
||||||
|
fn = basename path;
|
||||||
|
in (map (x: "default." + x)
|
||||||
|
(foldr (a: b: let x = (head b); in [ (a + "." + x) ] ++ b)
|
||||||
|
[ doFileSuffix ]
|
||||||
|
(tail (splitString "." fn))));
|
||||||
|
|
||||||
|
searchPath = path:
|
||||||
|
let
|
||||||
|
pathlist = (splitString "/" path);
|
||||||
|
pat = (last pathlist);
|
||||||
|
doFile = path + "." + doFileSuffix;
|
||||||
|
patlist = genPatterns pat;
|
||||||
|
foldedpaths = foldr (a: b:
|
||||||
|
let
|
||||||
|
h = if length b == 0 then "" else head b;
|
||||||
|
in [ (h + a + "/") ] ++ b) [] (tail (reverseList pathlist));
|
||||||
|
pths = crossLists (p: pat: p + pat) [ foldedpaths patlist ];
|
||||||
|
in [ doFile ] ++ pths;
|
||||||
|
|
||||||
|
cwd = "/home/spacefrogg/tmp";
|
||||||
|
path = cwd + "/foo/bar/baz.def.c";
|
||||||
|
|
||||||
|
whichdo = path: let
|
||||||
|
pathlist = searchPath path;
|
||||||
|
in foldl (res: p: if res == "" then if pathExists p then p else res else res) "" pathlist;
|
||||||
|
|
||||||
|
d1 = path: pat: let
|
||||||
|
dir = (dirname pat) + "/";
|
||||||
|
in removePrefix dir path;
|
||||||
|
|
||||||
|
d2 = path: pat: let
|
||||||
|
dir = (dirname pat) + "/";
|
||||||
|
_path = removePrefix dir path;
|
||||||
|
_pat = removeSuffix ".${doFileSuffix}" (removePrefix "${dir}default" pat);
|
||||||
|
_out = removeSuffix _pat _path;
|
||||||
|
in if _out == "" then _path else _out;
|
||||||
|
|
||||||
|
self = {
|
||||||
|
inherit dirname basename searchPath cwd path doFileSuffix whichdo d1 d2;
|
||||||
|
};
|
||||||
|
|
||||||
|
in self
|
37
nixredo
37
nixredo
|
@ -2,25 +2,18 @@
|
||||||
exec >&2
|
exec >&2
|
||||||
[ "${NIXREDO_ROOT-x}" != x ] || { printf "Set NIXREDO_ROOT. Set empty to use global nix store\n"; exit 127; }
|
[ "${NIXREDO_ROOT-x}" != x ] || { printf "Set NIXREDO_ROOT. Set empty to use global nix store\n"; exit 127; }
|
||||||
if [ $# -eq 0 ]; then set -- all; fi
|
if [ $# -eq 0 ]; then set -- all; fi
|
||||||
if [ -e "$1.nix" ]; then
|
set -e
|
||||||
set -e
|
set -- "$1" "$1" "$1.redo.tmp"
|
||||||
set -- "$1" "$1" "$1.redo.tmp"
|
f=$(realpath -s "$1")
|
||||||
f=$(realpath "$1.nix")
|
out=$(nix -vL --show-trace build ${NIXREDO_ROOT:+--store "$NIXREDO_ROOT"} \
|
||||||
out=$(nix -vL --show-trace build ${NIXREDO_ROOT:+--store "$NIXREDO_ROOT"} \
|
--option auto-optimise-store true --option substituters daemon \
|
||||||
--option auto-optimise-store true --option substituters daemon \
|
--impure --json --no-link \
|
||||||
--impure --json --no-link \
|
--expr " import @buildernix@ { lib = import @libnix@ {}; } \"$f\"" |
|
||||||
--expr "import @buildernix@ { cwd = \"$PWD/\"; rargs = [ \"$1\" \"$1\" ];} \"$f\"" |
|
@jq@ -r '.[0].outputs.out')
|
||||||
@jq@ -r '.[0].outputs.out')
|
[ -n "$out" ] || exit 127
|
||||||
[ -n "$out" ] || exit 127
|
rm -rf "$3"
|
||||||
rm -rf "$3"
|
ln -s "${NIXREDO_ROOT+$NIXREDO_ROOT}$out" "$3"
|
||||||
ln -s "${NIXREDO_ROOT+$NIXREDO_ROOT}$out" "$3"
|
# ln "${NIXREDO_ROOT+$NIXREDO_ROOT/}$out" "$3"
|
||||||
# ln "${NIXREDO_ROOT+$NIXREDO_ROOT/}$out" "$3"
|
# chmod +w "$3"
|
||||||
# chmod +w "$3"
|
# touch "$3"
|
||||||
# touch "$3"
|
mv "$3" "$1"
|
||||||
mv "$3" "$1"
|
|
||||||
elif [ -e "$1" ]; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
printf "Error: No rule to build %s\n" "$1"
|
|
||||||
exit 127
|
|
||||||
fi
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
f=$(realpath -s "$1")
|
||||||
|
nix eval --impure --expr "with import @libnix@ {}; /. + (whichdo \"$f\")"
|
Loading…
Reference in New Issue