forked from lix-project/lix
nix-shell/nix-build: Support .drv files again
Fixes #1663. Also handle '!<output-name>' (#1694).
This commit is contained in:
parent
0fc3e581e0
commit
90948a4e3a
|
@ -1,6 +1,7 @@
|
||||||
#include "get-drvs.hh"
|
#include "get-drvs.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "eval-inline.hh"
|
#include "eval-inline.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
@ -15,6 +16,33 @@ DrvInfo::DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPathWithOutputs)
|
||||||
|
: state(&state), attrs(nullptr), attrPath("")
|
||||||
|
{
|
||||||
|
auto spec = parseDrvPathWithOutputs(drvPathWithOutputs);
|
||||||
|
|
||||||
|
drvPath = spec.first;
|
||||||
|
|
||||||
|
auto drv = store->derivationFromPath(drvPath);
|
||||||
|
|
||||||
|
name = storePathToName(drvPath);
|
||||||
|
|
||||||
|
if (spec.second.size() > 1)
|
||||||
|
throw Error("building more than one derivation output is not supported, in '%s'", drvPathWithOutputs);
|
||||||
|
|
||||||
|
outputName =
|
||||||
|
spec.second.empty()
|
||||||
|
? get(drv.env, "outputName", "out")
|
||||||
|
: *spec.second.begin();
|
||||||
|
|
||||||
|
auto i = drv.outputs.find(outputName);
|
||||||
|
if (i == drv.outputs.end())
|
||||||
|
throw Error("derivation '%s' does not have output '%s'", drvPath, outputName);
|
||||||
|
|
||||||
|
outPath = i->second.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string DrvInfo::queryName() const
|
string DrvInfo::queryName() const
|
||||||
{
|
{
|
||||||
if (name == "" && attrs) {
|
if (name == "" && attrs) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
|
|
||||||
DrvInfo(EvalState & state) : state(&state) { };
|
DrvInfo(EvalState & state) : state(&state) { };
|
||||||
DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs);
|
DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs);
|
||||||
|
DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPathWithOutputs);
|
||||||
|
|
||||||
string queryName() const;
|
string queryName() const;
|
||||||
string querySystem() const;
|
string querySystem() const;
|
||||||
|
|
|
@ -263,6 +263,8 @@ void mainWrapped(int argc, char * * argv)
|
||||||
if (runEnv)
|
if (runEnv)
|
||||||
setenv("IN_NIX_SHELL", pure ? "pure" : "impure", 1);
|
setenv("IN_NIX_SHELL", pure ? "pure" : "impure", 1);
|
||||||
|
|
||||||
|
DrvInfos drvs;
|
||||||
|
|
||||||
/* Parse the expressions. */
|
/* Parse the expressions. */
|
||||||
std::vector<Expr *> exprs;
|
std::vector<Expr *> exprs;
|
||||||
|
|
||||||
|
@ -272,6 +274,8 @@ void mainWrapped(int argc, char * * argv)
|
||||||
for (auto i : left) {
|
for (auto i : left) {
|
||||||
if (fromArgs)
|
if (fromArgs)
|
||||||
exprs.push_back(state.parseExprFromString(i, absPath(".")));
|
exprs.push_back(state.parseExprFromString(i, absPath(".")));
|
||||||
|
else if (store->isStorePath(i) && std::regex_match(i, std::regex(".*\\.drv(!.*)?")))
|
||||||
|
drvs.push_back(DrvInfo(state, store, i));
|
||||||
else
|
else
|
||||||
/* If we're in a #! script, interpret filenames
|
/* If we're in a #! script, interpret filenames
|
||||||
relative to the script. */
|
relative to the script. */
|
||||||
|
@ -280,8 +284,6 @@ void mainWrapped(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evaluate them into derivations. */
|
/* Evaluate them into derivations. */
|
||||||
DrvInfos drvs;
|
|
||||||
|
|
||||||
if (attrPaths.empty()) attrPaths = {""};
|
if (attrPaths.empty()) attrPaths = {""};
|
||||||
|
|
||||||
for (auto e : exprs) {
|
for (auto e : exprs) {
|
||||||
|
|
|
@ -2,6 +2,8 @@ source common.sh
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
|
rm -f $TEST_ROOT/result*
|
||||||
|
|
||||||
# Test whether read-only evaluation works when referring to the
|
# Test whether read-only evaluation works when referring to the
|
||||||
# ‘drvPath’ attribute.
|
# ‘drvPath’ attribute.
|
||||||
echo "evaluating c..."
|
echo "evaluating c..."
|
||||||
|
@ -28,7 +30,7 @@ echo "output path is $outPath"
|
||||||
[ "$(cat "$outPath"/file)" = "success" ]
|
[ "$(cat "$outPath"/file)" = "success" ]
|
||||||
|
|
||||||
# Test nix-build on a derivation with multiple outputs.
|
# Test nix-build on a derivation with multiple outputs.
|
||||||
nix-build multiple-outputs.nix -A a -o $TEST_ROOT/result
|
outPath1=$(nix-build multiple-outputs.nix -A a -o $TEST_ROOT/result)
|
||||||
[ -e $TEST_ROOT/result-first ]
|
[ -e $TEST_ROOT/result-first ]
|
||||||
(! [ -e $TEST_ROOT/result-second ])
|
(! [ -e $TEST_ROOT/result-second ])
|
||||||
nix-build multiple-outputs.nix -A a.all -o $TEST_ROOT/result
|
nix-build multiple-outputs.nix -A a.all -o $TEST_ROOT/result
|
||||||
|
@ -37,6 +39,17 @@ nix-build multiple-outputs.nix -A a.all -o $TEST_ROOT/result
|
||||||
[ "$(cat $TEST_ROOT/result-second/link/file)" = "first" ]
|
[ "$(cat $TEST_ROOT/result-second/link/file)" = "first" ]
|
||||||
hash1=$(nix-store -q --hash $TEST_ROOT/result-second)
|
hash1=$(nix-store -q --hash $TEST_ROOT/result-second)
|
||||||
|
|
||||||
|
outPath2=$(nix-build $(nix-instantiate multiple-outputs.nix -A a) --no-out-link)
|
||||||
|
[[ $outPath1 = $outPath2 ]]
|
||||||
|
|
||||||
|
outPath2=$(nix-build $(nix-instantiate multiple-outputs.nix -A a.first) --no-out-link)
|
||||||
|
[[ $outPath1 = $outPath2 ]]
|
||||||
|
|
||||||
|
outPath2=$(nix-build $(nix-instantiate multiple-outputs.nix -A a.second) --no-out-link)
|
||||||
|
[[ $(cat $outPath2/file) = second ]]
|
||||||
|
|
||||||
|
[[ $(nix-build $(nix-instantiate multiple-outputs.nix -A a.all) --no-out-link | wc -l) -eq 2 ]]
|
||||||
|
|
||||||
# Delete one of the outputs and rebuild it. This will cause a hash
|
# Delete one of the outputs and rebuild it. This will cause a hash
|
||||||
# rewrite.
|
# rewrite.
|
||||||
nix-store --delete $TEST_ROOT/result-second --ignore-liveness
|
nix-store --delete $TEST_ROOT/result-second --ignore-liveness
|
||||||
|
|
|
@ -2,7 +2,7 @@ source common.sh
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
nix-build dependencies.nix -o $TEST_ROOT/result
|
outPath=$(nix-build dependencies.nix -o $TEST_ROOT/result)
|
||||||
test "$(cat $TEST_ROOT/result/foobar)" = FOOBAR
|
test "$(cat $TEST_ROOT/result/foobar)" = FOOBAR
|
||||||
|
|
||||||
# The result should be retained by a GC.
|
# The result should be retained by a GC.
|
||||||
|
@ -17,3 +17,9 @@ test -e $target/foobar
|
||||||
rm $TEST_ROOT/result
|
rm $TEST_ROOT/result
|
||||||
nix-store --gc
|
nix-store --gc
|
||||||
if test -e $target/foobar; then false; fi
|
if test -e $target/foobar; then false; fi
|
||||||
|
|
||||||
|
outPath2=$(nix-build $(nix-instantiate dependencies.nix) --no-out-link)
|
||||||
|
[[ $outPath = $outPath2 ]]
|
||||||
|
|
||||||
|
outPath2=$(nix-build $(nix-instantiate dependencies.nix)!out --no-out-link)
|
||||||
|
[[ $outPath = $outPath2 ]]
|
||||||
|
|
|
@ -10,6 +10,13 @@ output=$(nix-shell --pure shell.nix -A shellDrv --run \
|
||||||
|
|
||||||
[ "$output" = " - foo - bar" ]
|
[ "$output" = " - foo - bar" ]
|
||||||
|
|
||||||
|
# Test nix-shell on a .drv
|
||||||
|
[[ $(nix-shell --pure $(nix-instantiate shell.nix -A shellDrv) --run \
|
||||||
|
'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]]
|
||||||
|
|
||||||
|
[[ $(nix-shell --pure $(nix-instantiate shell.nix -A shellDrv) --run \
|
||||||
|
'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]]
|
||||||
|
|
||||||
# Test nix-shell -p
|
# Test nix-shell -p
|
||||||
output=$(NIX_PATH=nixpkgs=shell.nix nix-shell --pure -p foo bar --run 'echo "$(foo) $(bar)"')
|
output=$(NIX_PATH=nixpkgs=shell.nix nix-shell --pure -p foo bar --run 'echo "$(foo) $(bar)"')
|
||||||
[ "$output" = "foo bar" ]
|
[ "$output" = "foo bar" ]
|
||||||
|
|
Loading…
Reference in a new issue