about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--corepkgs/fetchurl.nix15
-rw-r--r--src/libstore/builtins.cc17
-rw-r--r--tests/fetchurl.nix6
-rw-r--r--tests/fetchurl.sh24
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