mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2025-02-16 15:17:18 +02: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
4 changed files with 68 additions and 20 deletions
|
@ -15,7 +15,20 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
EvalSettings evalSettings {
|
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);
|
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
||||||
|
|
|
@ -45,8 +45,9 @@ static Strings parseNixPath(const std::string & s)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalSettings::EvalSettings(bool & readOnlyMode)
|
EvalSettings::EvalSettings(bool & readOnlyMode, EvalSettings::LookupPathHooks lookupPathHooks)
|
||||||
: readOnlyMode{readOnlyMode}
|
: readOnlyMode{readOnlyMode}
|
||||||
|
, lookupPathHooks{lookupPathHooks}
|
||||||
{
|
{
|
||||||
auto var = getEnv("NIX_PATH");
|
auto var = getEnv("NIX_PATH");
|
||||||
if (var) nixPath = parseNixPath(*var);
|
if (var) nixPath = parseNixPath(*var);
|
||||||
|
|
|
@ -5,9 +5,40 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
class Store;
|
||||||
|
|
||||||
struct EvalSettings : Config
|
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;
|
bool & readOnlyMode;
|
||||||
|
|
||||||
|
@ -17,6 +48,8 @@ struct EvalSettings : Config
|
||||||
|
|
||||||
static std::string resolvePseudoUrl(std::string_view url);
|
static std::string resolvePseudoUrl(std::string_view url);
|
||||||
|
|
||||||
|
LookupPathHooks lookupPathHooks;
|
||||||
|
|
||||||
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation", R"(
|
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation", R"(
|
||||||
Enable built-in functions that allow executing native code.
|
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);
|
auto i = lookupPathResolved.find(value);
|
||||||
if (i != lookupPathResolved.end()) return i->second;
|
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)) {
|
if (EvalSettings::isPseudoUrl(value)) {
|
||||||
try {
|
try {
|
||||||
auto accessor = fetchers::downloadTarball(
|
auto accessor = fetchers::downloadTarball(
|
||||||
EvalSettings::resolvePseudoUrl(value)).accessor;
|
EvalSettings::resolvePseudoUrl(value)).accessor;
|
||||||
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
||||||
res = { store->toRealPath(storePath) };
|
return finish(store->toRealPath(storePath));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
.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:")) {
|
if (auto colPos = value.find(':'); colPos != value.npos) {
|
||||||
experimentalFeatureSettings.require(Xp::Flakes);
|
auto scheme = value.substr(0, colPos);
|
||||||
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
|
auto rest = value.substr(colPos + 1);
|
||||||
debug("fetching flake search path element '%s''", value);
|
if (auto * hook = get(settings.lookupPathHooks, scheme)) {
|
||||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first;
|
auto res = (*hook)(store, rest);
|
||||||
res = { store->toRealPath(storePath) };
|
if (res)
|
||||||
|
return finish(std::move(*res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
{
|
||||||
auto path = absPath(value);
|
auto path = absPath(value);
|
||||||
|
|
||||||
/* Allow access to paths in the search path. */
|
/* Allow access to paths in the search path. */
|
||||||
|
@ -2800,22 +2806,17 @@ std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Pa
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathExists(path))
|
if (pathExists(path))
|
||||||
res = { path };
|
return finish(std::move(path));
|
||||||
else {
|
else {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)
|
.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)
|
||||||
});
|
});
|
||||||
res = std::nullopt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
debug("failed to resolve search path element '%s'", value);
|
||||||
debug("resolved search path element '%s' to '%s'", value, *res);
|
return std::nullopt;
|
||||||
else
|
|
||||||
debug("failed to resolve search path element '%s'", value);
|
|
||||||
|
|
||||||
lookupPathResolved.emplace(value, res);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue