diff options
-rw-r--r-- | corepkgs/fetchurl.nix | 15 | ||||
-rw-r--r-- | src/libstore/builtins.cc | 17 | ||||
-rw-r--r-- | tests/fetchurl.nix | 6 | ||||
-rw-r--r-- | tests/fetchurl.sh | 24 |
4 files changed, 46 insertions, 16 deletions
diff --git a/corepkgs/fetchurl.nix b/corepkgs/fetchurl.nix index 9ecb2225ba67..5e0ad9da3c68 100644 --- a/corepkgs/fetchurl.nix +++ b/corepkgs/fetchurl.nix @@ -1,12 +1,19 @@ with import <nix/config.nix>; -{system ? builtins.currentSystem, url, outputHash ? "", outputHashAlgo ? "", md5 ? "", sha1 ? "", sha256 ? "", executable ? false}: +{ system ? builtins.currentSystem +, url +, outputHash ? "" +, outputHashAlgo ? "" +, md5 ? "", sha1 ? "", sha256 ? "" +, executable ? false +, unpack ? false +, name ? baseNameOf (toString url) +}: assert (outputHash != "" && outputHashAlgo != "") || md5 != "" || sha1 != "" || sha256 != ""; derivation { - name = baseNameOf (toString url); builder = "builtin:fetchurl"; # New-style output content requirements. @@ -14,9 +21,9 @@ derivation { if sha256 != "" then "sha256" else if sha1 != "" then "sha1" else "md5"; outputHash = if outputHash != "" then outputHash else if sha256 != "" then sha256 else if sha1 != "" then sha1 else md5; - outputHashMode = if executable then "recursive" else "flat"; + outputHashMode = if unpack || executable then "recursive" else "flat"; - inherit system url executable; + inherit name system url executable unpack; # No need to double the amount of network traffic preferLocalBuild = true; diff --git a/src/libstore/builtins.cc b/src/libstore/builtins.cc index 2a4396308399..fefad63bd1bb 100644 --- a/src/libstore/builtins.cc +++ b/src/libstore/builtins.cc @@ -1,5 +1,7 @@ #include "builtins.hh" #include "download.hh" +#include "store-api.hh" +#include "archive.hh" namespace nix { @@ -20,12 +22,21 @@ void builtinFetchurl(const BasicDerivation & drv) auto out = drv.env.find("out"); if (out == drv.env.end()) throw Error("attribute ‘url’ missing"); - writeFile(out->second, data.data); + + Path storePath = out->second; + assertStorePath(storePath); + + auto unpack = drv.env.find("unpack"); + if (unpack != drv.env.end() && unpack->second == "1") { + StringSource source(data.data); + restorePath(storePath, source); + } else + writeFile(storePath, data.data); auto executable = drv.env.find("executable"); if (executable != drv.env.end() && executable->second == "1") { - if (chmod(out->second.c_str(), 0755) == -1) - throw SysError(format("making ‘%1%’ executable") % out->second); + if (chmod(storePath.c_str(), 0755) == -1) + throw SysError(format("making ‘%1%’ executable") % storePath); } } diff --git a/tests/fetchurl.nix b/tests/fetchurl.nix deleted file mode 100644 index 2abcc039a832..000000000000 --- a/tests/fetchurl.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ filename, sha256 }: - -import <nix/fetchurl.nix> { - url = "file://${filename}"; - inherit sha256; -} diff --git a/tests/fetchurl.sh b/tests/fetchurl.sh index 6acc87eafca8..495d42a2568a 100644 --- a/tests/fetchurl.sh +++ b/tests/fetchurl.sh @@ -2,8 +2,26 @@ source common.sh clearStore -hash=$(nix-hash --flat --type sha256 ./fetchurl.nix) +hash=$(nix-hash --flat --type sha256 ./fetchurl.sh) -outPath=$(nix-build ./fetchurl.nix --argstr filename $(pwd)/fetchurl.nix --argstr sha256 $hash --no-out-link) +outPath=$(nix-build '<nix/fetchurl.nix>' --argstr url file://$(pwd)/fetchurl.sh --argstr sha256 $hash --no-out-link) -cmp $outPath fetchurl.nix +cmp $outPath fetchurl.sh + +rm -rf $TEST_ROOT/archive +mkdir -p $TEST_ROOT/archive +cp ./fetchurl.sh $TEST_ROOT/archive +chmod +x $TEST_ROOT/archive/fetchurl.sh +ln -s foo $TEST_ROOT/archive/symlink +nar=$TEST_ROOT/archive.nar +nix-store --dump $TEST_ROOT/archive > $nar + +hash=$(nix-hash --flat --type sha256 $nar) + +outPath=$(nix-build '<nix/fetchurl.nix>' --argstr url file://$nar --argstr sha256 $hash \ + --arg unpack true --argstr name xyzzy --no-out-link) + +echo $outPath | grep -q 'xyzzy' + +test -x $outPath/fetchurl.sh +test -L $outPath/symlink |