about summary refs log tree commit diff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-05-05T15·09+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-05-05T15·09+0200
commit9451ef3731904090d7c8476137960a3fb9d4679d (patch)
treee1963c47fbba25a17f5a72670d774d28db229f1a /src/libexpr/parser.y
parent35d30d67ebcca90c3120eeaa7f38baee8805c670 (diff)
Allow URLs in the Nix search path
E.g. to install "hello" from the latest Nixpkgs:

  $ nix-build '<nixpkgs>' -A hello -I nixpkgs=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz

Or to install a specific version of NixOS:

  $ nixos-rebuild switch -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/63def04891a0abc328b1b0b3a78ec02c58f48583.tar.gz
Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 664d6692f51e..e3f2f09b20bd 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -527,6 +527,8 @@ formal
 #include <unistd.h>
 
 #include <eval.hh>
+#include <download.hh>
+#include <store-api.hh>
 
 
 namespace nix {
@@ -599,6 +601,15 @@ Expr * EvalState::parseExprFromString(const string & s, const Path & basePath)
 }
 
 
+bool isUri(const string & s)
+{
+    size_t pos = s.find("://");
+    if (pos == string::npos) return false;
+    string scheme(s, 0, pos);
+    return scheme == "http" || scheme == "https";
+}
+
+
 void EvalState::addToSearchPath(const string & s, bool warn)
 {
     size_t pos = s.find('=');
@@ -611,6 +622,9 @@ void EvalState::addToSearchPath(const string & s, bool warn)
         path = string(s, pos + 1);
     }
 
+    if (isUri(path))
+        path = downloadFileCached(path, true);
+
     path = absPath(path);
     if (pathExists(path)) {
         debug(format("adding path ‘%1%’ to the search path") % path);
@@ -629,16 +643,17 @@ Path EvalState::findFile(const string & path)
 
 Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos & pos)
 {
-    foreach (SearchPath::iterator, i, searchPath) {
+    for (auto & i : searchPath) {
+        assert(!isUri(i.second));
         Path res;
-        if (i->first.empty())
-            res = i->second + "/" + path;
+        if (i.first.empty())
+            res = i.second + "/" + path;
         else {
-            if (path.compare(0, i->first.size(), i->first) != 0 ||
-                (path.size() > i->first.size() && path[i->first.size()] != '/'))
+            if (path.compare(0, i.first.size(), i.first) != 0 ||
+                (path.size() > i.first.size() && path[i.first.size()] != '/'))
                 continue;
-            res = i->second +
-                (path.size() == i->first.size() ? "" : "/" + string(path, i->first.size()));
+            res = i.second +
+                (path.size() == i.first.size() ? "" : "/" + string(path, i.first.size()));
         }
         if (pathExists(res)) return canonPath(res);
     }