aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/src/release-notes/rl-next.md12
-rw-r--r--src/libcmd/common-eval-args.cc40
-rw-r--r--src/libexpr/eval.cc20
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/libexpr/parser.y20
-rw-r--r--src/libexpr/primops/fetchTree.cc2
-rw-r--r--src/libstore/filetransfer.cc18
-rw-r--r--src/libstore/filetransfer.hh5
-rw-r--r--tests/flakes/flakes.sh6
9 files changed, 91 insertions, 36 deletions
diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md
index c1f4de76f..f9a0063ee 100644
--- a/doc/manual/src/release-notes/rl-next.md
+++ b/doc/manual/src/release-notes/rl-next.md
@@ -2,3 +2,15 @@
* The `repeat` and `enforce-determinism` options have been removed
since they had been broken under many circumstances for a long time.
+
+* You can now use [flake references] in the [old command line interface], e.g.
+
+ [flake references]: ../command-ref/new-cli/nix3-flake.md#flake-references
+ [old command line interface]: ../command-ref/main-commands.md
+
+ ```
+ # nix-build flake:nixpkgs -A hello
+ # nix-build -I nixpkgs=flake:github:NixOS/nixpkgs/nixos-22.05 \
+ '<nixpkgs>' -A hello
+ # NIX_PATH=nixpkgs=flake:nixpkgs nix-build '<nixpkgs>' -A hello
+ ```
diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc
index dc0de4b9f..67fc501c9 100644
--- a/src/libcmd/common-eval-args.cc
+++ b/src/libcmd/common-eval-args.cc
@@ -85,6 +85,23 @@ MixEvalArgs::MixEvalArgs()
-I nixpkgs=channel:nixos-21.05
-I nixpkgs=https://nixos.org/channels/nixos-21.05/nixexprs.tar.xz
```
+
+ You can also fetch source trees using flake URLs and add them to the
+ search path. For instance,
+
+ ```
+ -I nixpkgs=flake:nixpkgs
+ ```
+
+ specifies that the prefix `nixpkgs` shall refer to the source tree
+ downloaded from the `nixpkgs` entry in the flake registry. Similarly,
+
+ ```
+ -I nixpkgs=flake:github:NixOS/nixpkgs/nixos-22.05
+ ```
+
+ makes `<nixpkgs>` refer to a particular branch of the
+ `NixOS/nixpkgs` repository on GitHub.
)",
.category = category,
.labels = {"path"},
@@ -142,14 +159,25 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
Path lookupFileArg(EvalState & state, std::string_view s)
{
- if (isUri(s)) {
- return state.store->toRealPath(
- fetchers::downloadTarball(
- state.store, resolveUri(s), "source", false).first.storePath);
- } else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
+ if (EvalSettings::isPseudoUrl(s)) {
+ auto storePath = fetchers::downloadTarball(
+ state.store, EvalSettings::resolvePseudoUrl(s), "source", false).first.storePath;
+ return state.store->toRealPath(storePath);
+ }
+
+ else if (hasPrefix(s, "flake:")) {
+ settings.requireExperimentalFeature(Xp::Flakes);
+ auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
+ auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
+ return state.store->toRealPath(storePath);
+ }
+
+ else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
Path p(s.substr(1, s.size() - 2));
return state.findFile(p);
- } else
+ }
+
+ else
return absPath(std::string(s));
}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index b67ed853e..6955aacbf 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -402,7 +402,8 @@ static Strings parseNixPath(const std::string & s)
}
if (*p == ':') {
- if (isUri(std::string(start2, s.end()))) {
+ auto prefix = std::string(start2, s.end());
+ if (EvalSettings::isPseudoUrl(prefix) || hasPrefix(prefix, "flake:")) {
++p;
while (p != s.end() && *p != ':') ++p;
}
@@ -2583,6 +2584,23 @@ Strings EvalSettings::getDefaultNixPath()
return res;
}
+bool EvalSettings::isPseudoUrl(std::string_view s)
+{
+ if (s.compare(0, 8, "channel:") == 0) return true;
+ size_t pos = s.find("://");
+ if (pos == std::string::npos) return false;
+ std::string scheme(s, 0, pos);
+ return scheme == "http" || scheme == "https" || scheme == "file" || scheme == "channel" || scheme == "git" || scheme == "s3" || scheme == "ssh";
+}
+
+std::string EvalSettings::resolvePseudoUrl(std::string_view url)
+{
+ if (hasPrefix(url, "channel:"))
+ return "https://nixos.org/channels/" + std::string(url.substr(8)) + "/nixexprs.tar.xz";
+ else
+ return std::string(url);
+}
+
EvalSettings evalSettings;
static GlobalConfig::Register rEvalSettings(&evalSettings);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index f07f15d43..cf307d820 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -590,6 +590,10 @@ struct EvalSettings : Config
static Strings getDefaultNixPath();
+ static bool isPseudoUrl(std::string_view s);
+
+ static std::string resolvePseudoUrl(std::string_view url);
+
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation",
"Whether builtin functions that allow executing native code should be enabled."};
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 7c9b5a2db..fbf865719 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -643,6 +643,7 @@ formal
#include "filetransfer.hh"
#include "fetchers.hh"
#include "store-api.hh"
+#include "flake/flake.hh"
namespace nix {
@@ -805,17 +806,28 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
std::pair<bool, std::string> res;
- if (isUri(elem.second)) {
+ if (EvalSettings::isPseudoUrl(elem.second)) {
try {
- res = { true, store->toRealPath(fetchers::downloadTarball(
- store, resolveUri(elem.second), "source", false).first.storePath) };
+ auto storePath = fetchers::downloadTarball(
+ store, EvalSettings::resolvePseudoUrl(elem.second), "source", false).first.storePath;
+ res = { true, store->toRealPath(storePath) };
} catch (FileTransferError & e) {
logWarning({
.msg = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second)
});
res = { false, "" };
}
- } else {
+ }
+
+ else if (hasPrefix(elem.second, "flake:")) {
+ settings.requireExperimentalFeature(Xp::Flakes);
+ auto flakeRef = parseFlakeRef(elem.second.substr(6), {}, true, false);
+ debug("fetching flake search path element '%s''", elem.second);
+ auto storePath = flakeRef.resolve(store).fetchTree(store).first.storePath;
+ res = { true, store->toRealPath(storePath) };
+ }
+
+ else {
auto path = absPath(elem.second);
if (pathExists(path))
res = { true, path };
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index 84e7f5c02..680446787 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -220,8 +220,6 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
} else
url = state.forceStringNoCtx(*args[0], pos);
- url = resolveUri(*url);
-
state.checkURI(*url);
if (name == "")
diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc
index 2ff411e18..756bd4423 100644
--- a/src/libstore/filetransfer.cc
+++ b/src/libstore/filetransfer.cc
@@ -33,14 +33,6 @@ FileTransferSettings fileTransferSettings;
static GlobalConfig::Register rFileTransferSettings(&fileTransferSettings);
-std::string resolveUri(std::string_view uri)
-{
- if (uri.compare(0, 8, "channel:") == 0)
- return "https://nixos.org/channels/" + std::string(uri.substr(8)) + "/nixexprs.tar.xz";
- else
- return std::string(uri);
-}
-
struct curlFileTransfer : public FileTransfer
{
CURLM * curlm = 0;
@@ -873,14 +865,4 @@ FileTransferError::FileTransferError(FileTransfer::Error error, std::optional<st
err.msg = hf;
}
-bool isUri(std::string_view s)
-{
- if (s.compare(0, 8, "channel:") == 0) return true;
- size_t pos = s.find("://");
- if (pos == std::string::npos) return false;
- std::string scheme(s, 0, pos);
- return scheme == "http" || scheme == "https" || scheme == "file" || scheme == "channel" || scheme == "git" || scheme == "s3" || scheme == "ssh";
-}
-
-
}
diff --git a/src/libstore/filetransfer.hh b/src/libstore/filetransfer.hh
index 40e7cf52c..07d58f53a 100644
--- a/src/libstore/filetransfer.hh
+++ b/src/libstore/filetransfer.hh
@@ -125,9 +125,4 @@ public:
FileTransferError(FileTransfer::Error error, std::optional<std::string> response, const Args & ... args);
};
-bool isUri(std::string_view s);
-
-/* Resolve deprecated 'channel:<foo>' URLs. */
-std::string resolveUri(std::string_view uri);
-
}
diff --git a/tests/flakes/flakes.sh b/tests/flakes/flakes.sh
index 8cdc320fb..5ef4d0a7a 100644
--- a/tests/flakes/flakes.sh
+++ b/tests/flakes/flakes.sh
@@ -473,3 +473,9 @@ nix store delete $(nix store add-path $badFlakeDir)
[[ $(nix path-info $(nix store add-path $flake1Dir)) =~ flake1 ]]
[[ $(nix path-info path:$(nix store add-path $flake1Dir)) =~ simple ]]
+
+# Test fetching flakerefs in the legacy CLI.
+[[ $(nix-instantiate --eval flake:flake3 -A x) = 123 ]]
+[[ $(nix-instantiate --eval flake:git+file://$flake3Dir -A x) = 123 ]]
+[[ $(nix-instantiate -I flake3=flake:flake3 --eval '<flake3>' -A x) = 123 ]]
+[[ $(NIX_PATH=flake3=flake:flake3 nix-instantiate --eval '<flake3>' -A x) = 123 ]]