mirror of
https://github.com/NixOS/nix.git
synced 2024-11-25 16:23:02 +00:00
Factor out flake:...
lookup path from evaluator
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
parent
88f9d8ccb1
commit
52730d38e2
@ -15,7 +15,20 @@
|
||||
namespace nix {
|
||||
|
||||
EvalSettings evalSettings {
|
||||
settings.readOnlyMode
|
||||
settings.readOnlyMode,
|
||||
{
|
||||
{
|
||||
"flake",
|
||||
[](ref<Store> store, std::string_view rest) {
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
// FIXME `parseFlakeRef` should take a `std::string_view`.
|
||||
auto flakeRef = parseFlakeRef(std::string { rest }, {}, true, false);
|
||||
debug("fetching flake search path element '%s''", rest);
|
||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
|
||||
return store->toRealPath(storePath);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
||||
|
@ -45,8 +45,9 @@ static Strings parseNixPath(const std::string & s)
|
||||
return res;
|
||||
}
|
||||
|
||||
EvalSettings::EvalSettings(bool & readOnlyMode)
|
||||
EvalSettings::EvalSettings(bool & readOnlyMode, EvalSettings::LookupPathHooks lookupPathHooks)
|
||||
: readOnlyMode{readOnlyMode}
|
||||
, lookupPathHooks{lookupPathHooks}
|
||||
{
|
||||
auto var = getEnv("NIX_PATH");
|
||||
if (var) nixPath = parseNixPath(*var);
|
||||
|
@ -5,9 +5,40 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
class Store;
|
||||
|
||||
struct EvalSettings : Config
|
||||
{
|
||||
EvalSettings(bool & readOnlyMode);
|
||||
/**
|
||||
* Function used to interpet look path entries of a given scheme.
|
||||
*
|
||||
* The argument is the non-scheme part of the lookup path entry (see
|
||||
* `LookupPathHooks` below).
|
||||
*
|
||||
* The return value is (a) whether the entry was valid, and, if so,
|
||||
* what does it map to.
|
||||
*
|
||||
* @todo Return (`std::optional` of) `SourceAccssor` or something
|
||||
* more structured instead of mere `std::string`?
|
||||
*/
|
||||
using LookupPathHook = std::optional<std::string>(ref<Store> store, std::string_view);
|
||||
|
||||
/**
|
||||
* Map from "scheme" to a `LookupPathHook`.
|
||||
*
|
||||
* Given a lookup path value (i.e. either the whole thing, or after
|
||||
* the `<key>=`) in the form of:
|
||||
*
|
||||
* ```
|
||||
* <scheme>:<arbitrary string>
|
||||
* ```
|
||||
*
|
||||
* if `<scheme>` is a key in this map, then `<arbitrary string>` is
|
||||
* passed to the hook that is the value in this map.
|
||||
*/
|
||||
using LookupPathHooks = std::map<std::string, std::function<LookupPathHook>>;
|
||||
|
||||
EvalSettings(bool & readOnlyMode, LookupPathHooks lookupPathHooks = {});
|
||||
|
||||
bool & readOnlyMode;
|
||||
|
||||
@ -17,6 +48,8 @@ struct EvalSettings : Config
|
||||
|
||||
static std::string resolvePseudoUrl(std::string_view url);
|
||||
|
||||
LookupPathHooks lookupPathHooks;
|
||||
|
||||
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation", R"(
|
||||
Enable built-in functions that allow executing native code.
|
||||
|
||||
|
@ -2760,14 +2760,18 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||
auto i = lookupPathResolved.find(value);
|
||||
if (i != lookupPathResolved.end()) return i->second;
|
||||
|
||||
std::optional<std::string> res;
|
||||
auto finish = [&](std::string res) {
|
||||
debug("resolved search path element '%s' to '%s'", value, res);
|
||||
lookupPathResolved.emplace(value, res);
|
||||
return res;
|
||||
};
|
||||
|
||||
if (EvalSettings::isPseudoUrl(value)) {
|
||||
try {
|
||||
auto accessor = fetchers::downloadTarball(
|
||||
EvalSettings::resolvePseudoUrl(value)).accessor;
|
||||
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
||||
res = { store->toRealPath(storePath) };
|
||||
return finish(store->toRealPath(storePath));
|
||||
} catch (Error & e) {
|
||||
logWarning({
|
||||
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
||||
@ -2775,15 +2779,17 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||
}
|
||||
}
|
||||
|
||||
else if (hasPrefix(value, "flake:")) {
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
|
||||
debug("fetching flake search path element '%s''", value);
|
||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
|
||||
res = { store->toRealPath(storePath) };
|
||||
if (auto colPos = value.find(':'); colPos != value.npos) {
|
||||
auto scheme = value.substr(0, colPos);
|
||||
auto rest = value.substr(colPos + 1);
|
||||
if (auto * hook = get(settings.lookupPathHooks, scheme)) {
|
||||
auto res = (*hook)(store, rest);
|
||||
if (res)
|
||||
return finish(std::move(*res));
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
{
|
||||
auto path = absPath(value);
|
||||
|
||||
/* Allow access to paths in the search path. */
|
||||
@ -2800,22 +2806,17 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||
}
|
||||
|
||||
if (pathExists(path))
|
||||
res = { path };
|
||||
return finish(std::move(path));
|
||||
else {
|
||||
logWarning({
|
||||
.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)
|
||||
});
|
||||
res = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (res)
|
||||
debug("resolved search path element '%s' to '%s'", value, *res);
|
||||
else
|
||||
debug("failed to resolve search path element '%s'", value);
|
||||
debug("failed to resolve search path element '%s'", value);
|
||||
return std::nullopt;
|
||||
|
||||
lookupPathResolved.emplace(value, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user