diff --git a/pkgs/build-support/my-env-run/default.nix b/pkgs/build-support/my-env-run/default.nix new file mode 100644 index 000000000000..0fedd0b8c6d3 --- /dev/null +++ b/pkgs/build-support/my-env-run/default.nix @@ -0,0 +1,6 @@ +{ writeScript, bash, myEnvFun }: args: + +let env = myEnvFun args; in writeScript "envrun-${args.name}" '' + #!${bash}/bin/bash + ${env}/bin/load-env-${args.name} +'' diff --git a/pkgs/misc/nix-run/default.nix b/pkgs/misc/nix-run/default.nix new file mode 100644 index 000000000000..ef83ec2a1f3d --- /dev/null +++ b/pkgs/misc/nix-run/default.nix @@ -0,0 +1,72 @@ +{ stdenv, bash, writeScript }: + +let + + nix-run = writeScript "nix-run" '' + #!${bash}/bin/bash + + # Runs nix-build and executes the result + # All arguments before "--" are given to nix-build, + # and all arguments after "--" are given to the + # executed command. stdin is redirected to the executed + # command. + + out=$(mktemp) + rm "$out" + + # parse args into args1 and args2, separated by -- + # args1 goes to nix-build, args2 goes to the built command + args1=("$@") + args2=() + for i in "''${!args1[@]}"; do + if [ "''${args1[$i]}" == "--" ]; then + args2=("''${args1[@]:$((i+1))}") + args1=("''${args1[@]:0:$((i))}") + break + fi + done + + if nix-build -o "$out" "''${args1[@]}" >/dev/null; then + target=$(readlink -m "$out") + unlink "$out" + if test -f "$target" && test -x "$target"; then + exec "$target" "''${args2[@]}" <&0 + else + echo "nix-run: No executable target produced by nix-build" + exit 1 + fi + else + echo "nix-run: nix-build failed" + exit 1 + fi + ''; + +in stdenv.mkDerivation { + name = "nix-run"; + phases = [ "installPhase" ]; + installPhase = '' + mkdir -p $out/bin + ln -s ${nix-run} $out/bin/nix-run + ''; + meta = { + description = '' + Wrapper around nix-build that automatically executes the binary + produced by the provided Nix expression. + ''; + longDescription = '' + nix-run invokes nix-build with any options given to it. It then + expects one executable file to be produced by nix-build. If this + is the case, that file is executed with any options that is given + to nix-run after a -- option separator. If no + executable file is produced by nix-build, nix-run will exit with + an error. An example invocation of nix-run is nix-run -A + myattr mynix.nix -- -o opt. nix-run will then build the + attribute myattr from the Nix expression given + in the file mynix.nix. If a single executable + file is produced, that file is executed with the option + -o opt. + ''; + maintainers = [ stdenv.lib.maintainers.rickynils ]; + platforms = stdenv.lib.platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1bae1e14df7a..47b8be12fa8e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10352,6 +10352,12 @@ let inherit (stdenv) mkDerivation; }; + myEnvRun = import ../build-support/my-env-run { + inherit writeScript bash myEnvFun; + }; + + nix-run = callPackage ../misc/nix-run { }; + # patoline requires a rather large ocaml compilation environment. # this is why it is build as an environment and not just a normal package. # remark : the emacs mode is also installed, but you have to adjust your load-path.