1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-03 15:40:59 +01:00

No global settings in libnixfetchers and libnixflake

Progress on #5638

There are still a global fetcher and eval settings, but they are pushed
down into `libnixcmd`, which is a lot less bad a place for this sort of
thing.

Continuing process pioneered in
52bfccf8d8.
This commit is contained in:
John Ericson 2024-07-01 13:37:30 -04:00
parent b57c361097
commit 3fc77f281e
50 changed files with 401 additions and 271 deletions

View file

@ -1,14 +1,9 @@
#include "fetch-settings.hh"
#include "config-global.hh"
namespace nix {
namespace nix::fetchers {
FetchSettings::FetchSettings()
Settings::Settings()
{
}
FetchSettings fetchSettings;
static GlobalConfig::Register rFetchSettings(&fetchSettings);
}

View file

@ -9,11 +9,11 @@
#include <sys/types.h>
namespace nix {
namespace nix::fetchers {
struct FetchSettings : public Config
struct Settings : public Config
{
FetchSettings();
Settings();
Setting<StringMap> accessTokens{this, {}, "access-tokens",
R"(
@ -84,9 +84,14 @@ struct FetchSettings : public Config
`narHash` attribute is specified,
e.g. `github:NixOS/patchelf/7c2f768bf9601268a4e71c2ebe91e2011918a70f?narHash=sha256-PPXqKY2hJng4DBVE0I4xshv/vGLUskL7jl53roB8UdU%3D`.
)"};
Setting<std::string> flakeRegistry{this, "https://channels.nixos.org/flake-registry.json", "flake-registry",
R"(
Path or URI of the global flake registry.
When empty, disables the global flake registry.
)",
{}, true, Xp::Flakes};
};
// FIXME: don't use a global variable.
extern FetchSettings fetchSettings;
}

View file

@ -35,9 +35,11 @@ nlohmann::json dumpRegisterInputSchemeInfo() {
return res;
}
Input Input::fromURL(const std::string & url, bool requireTree)
Input Input::fromURL(
const Settings & settings,
const std::string & url, bool requireTree)
{
return fromURL(parseURL(url), requireTree);
return fromURL(settings, parseURL(url), requireTree);
}
static void fixupInput(Input & input)
@ -49,10 +51,12 @@ static void fixupInput(Input & input)
input.getLastModified();
}
Input Input::fromURL(const ParsedURL & url, bool requireTree)
Input Input::fromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree)
{
for (auto & [_, inputScheme] : *inputSchemes) {
auto res = inputScheme->inputFromURL(url, requireTree);
auto res = inputScheme->inputFromURL(settings, url, requireTree);
if (res) {
experimentalFeatureSettings.require(inputScheme->experimentalFeature());
res->scheme = inputScheme;
@ -64,7 +68,7 @@ Input Input::fromURL(const ParsedURL & url, bool requireTree)
throw Error("input '%s' is unsupported", url.url);
}
Input Input::fromAttrs(Attrs && attrs)
Input Input::fromAttrs(const Settings & settings, Attrs && attrs)
{
auto schemeName = ({
auto schemeNameOpt = maybeGetStrAttr(attrs, "type");
@ -78,7 +82,7 @@ Input Input::fromAttrs(Attrs && attrs)
// but not all of them. Doing this is to support those other
// operations which are supposed to be robust on
// unknown/uninterpretable inputs.
Input input;
Input input { settings };
input.attrs = attrs;
fixupInput(input);
return input;
@ -99,7 +103,7 @@ Input Input::fromAttrs(Attrs && attrs)
if (name != "type" && allowedAttrs.count(name) == 0)
throw Error("input attribute '%s' not supported by scheme '%s'", name, schemeName);
auto res = inputScheme->inputFromAttrs(attrs);
auto res = inputScheme->inputFromAttrs(settings, attrs);
if (!res) return raw();
res->scheme = inputScheme;
fixupInput(*res);

View file

@ -17,6 +17,8 @@ namespace nix::fetchers {
struct InputScheme;
struct Settings;
/**
* The `Input` object is generated by a specific fetcher, based on
* user-supplied information, and contains
@ -28,6 +30,12 @@ struct Input
{
friend struct InputScheme;
const Settings * settings;
Input(const Settings & settings)
: settings{&settings}
{ }
std::shared_ptr<InputScheme> scheme; // note: can be null
Attrs attrs;
@ -42,16 +50,22 @@ public:
*
* The URL indicate which sort of fetcher, and provides information to that fetcher.
*/
static Input fromURL(const std::string & url, bool requireTree = true);
static Input fromURL(
const Settings & settings,
const std::string & url, bool requireTree = true);
static Input fromURL(const ParsedURL & url, bool requireTree = true);
static Input fromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree = true);
/**
* Create an `Input` from a an `Attrs`.
*
* The URL indicate which sort of fetcher, and provides information to that fetcher.
*/
static Input fromAttrs(Attrs && attrs);
static Input fromAttrs(
const Settings & settings,
Attrs && attrs);
ParsedURL toURL() const;
@ -146,9 +160,13 @@ struct InputScheme
virtual ~InputScheme()
{ }
virtual std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const = 0;
virtual std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree) const = 0;
virtual std::optional<Input> inputFromAttrs(const Attrs & attrs) const = 0;
virtual std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const = 0;
/**
* What is the name of the scheme?

View file

@ -164,7 +164,9 @@ static const Hash nullRev{HashAlgorithm::SHA1};
struct GitInputScheme : InputScheme
{
std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const override
std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree) const override
{
if (url.scheme != "git" &&
url.scheme != "git+http" &&
@ -190,7 +192,7 @@ struct GitInputScheme : InputScheme
attrs.emplace("url", url2.to_string());
return inputFromAttrs(attrs);
return inputFromAttrs(settings, attrs);
}
@ -222,7 +224,9 @@ struct GitInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const override
{
for (auto & [name, _] : attrs)
if (name == "verifyCommit"
@ -238,7 +242,7 @@ struct GitInputScheme : InputScheme
throw BadURL("invalid Git branch/tag name '%s'", *ref);
}
Input input;
Input input{settings};
input.attrs = attrs;
auto url = fixGitURL(getStrAttr(attrs, "url"));
parseURL(url);
@ -366,13 +370,13 @@ struct GitInputScheme : InputScheme
/* URL of the repo, or its path if isLocal. Never a `file` URL. */
std::string url;
void warnDirty() const
void warnDirty(const Settings & settings) const
{
if (workdirInfo.isDirty) {
if (!fetchSettings.allowDirty)
if (!settings.allowDirty)
throw Error("Git tree '%s' is dirty", url);
if (fetchSettings.warnDirty)
if (settings.warnDirty)
warn("Git tree '%s' is dirty", url);
}
}
@ -653,7 +657,7 @@ struct GitInputScheme : InputScheme
attrs.insert_or_assign("exportIgnore", Explicit<bool>{ exportIgnore });
attrs.insert_or_assign("submodules", Explicit<bool>{ true });
attrs.insert_or_assign("allRefs", Explicit<bool>{ true });
auto submoduleInput = fetchers::Input::fromAttrs(std::move(attrs));
auto submoduleInput = fetchers::Input::fromAttrs(*input.settings, std::move(attrs));
auto [submoduleAccessor, submoduleInput2] =
submoduleInput.getAccessor(store);
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string() + "»");
@ -711,7 +715,7 @@ struct GitInputScheme : InputScheme
// TODO: fall back to getAccessorFromCommit-like fetch when submodules aren't checked out
// attrs.insert_or_assign("allRefs", Explicit<bool>{ true });
auto submoduleInput = fetchers::Input::fromAttrs(std::move(attrs));
auto submoduleInput = fetchers::Input::fromAttrs(*input.settings, std::move(attrs));
auto [submoduleAccessor, submoduleInput2] =
submoduleInput.getAccessor(store);
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string() + "»");
@ -743,7 +747,7 @@ struct GitInputScheme : InputScheme
verifyCommit(input, repo);
} else {
repoInfo.warnDirty();
repoInfo.warnDirty(*input.settings);
if (repoInfo.workdirInfo.headRev) {
input.attrs.insert_or_assign("dirtyRev",

View file

@ -31,7 +31,9 @@ struct GitArchiveInputScheme : InputScheme
{
virtual std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const = 0;
std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const override
std::optional<Input> inputFromURL(
const fetchers::Settings & settings,
const ParsedURL & url, bool requireTree) const override
{
if (url.scheme != schemeName()) return {};
@ -90,7 +92,7 @@ struct GitArchiveInputScheme : InputScheme
if (ref && rev)
throw BadURL("URL '%s' contains both a commit hash and a branch/tag name %s %s", url.url, *ref, rev->gitRev());
Input input;
Input input{settings};
input.attrs.insert_or_assign("type", std::string { schemeName() });
input.attrs.insert_or_assign("owner", path[0]);
input.attrs.insert_or_assign("repo", path[1]);
@ -119,12 +121,14 @@ struct GitArchiveInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const fetchers::Settings & settings,
const Attrs & attrs) const override
{
getStrAttr(attrs, "owner");
getStrAttr(attrs, "repo");
Input input;
Input input{settings};
input.attrs = attrs;
return input;
}
@ -168,18 +172,20 @@ struct GitArchiveInputScheme : InputScheme
return input;
}
std::optional<std::string> getAccessToken(const std::string & host) const
std::optional<std::string> getAccessToken(const fetchers::Settings & settings, const std::string & host) const
{
auto tokens = fetchSettings.accessTokens.get();
auto tokens = settings.accessTokens.get();
if (auto token = get(tokens, host))
return *token;
return {};
}
Headers makeHeadersWithAuthTokens(const std::string & host) const
Headers makeHeadersWithAuthTokens(
const fetchers::Settings & settings,
const std::string & host) const
{
Headers headers;
auto accessToken = getAccessToken(host);
auto accessToken = getAccessToken(settings, host);
if (accessToken) {
auto hdr = accessHeaderFromToken(*accessToken);
if (hdr)
@ -295,7 +301,7 @@ struct GitArchiveInputScheme : InputScheme
locking. FIXME: in the future, we may want to require a Git
tree hash instead of a NAR hash. */
return input.getRev().has_value()
&& (fetchSettings.trustTarballsFromGitForges ||
&& (input.settings->trustTarballsFromGitForges ||
input.getNarHash().has_value());
}
@ -352,7 +358,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
: "https://%s/api/v3/repos/%s/%s/commits/%s",
host, getOwner(input), getRepo(input), *input.getRef());
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
auto json = nlohmann::json::parse(
readFile(
@ -369,7 +375,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
{
auto host = getHost(input);
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
// If we have no auth headers then we default to the public archive
// urls so we do not run into rate limits.
@ -389,7 +395,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
void clone(const Input & input, const Path & destDir) const override
{
auto host = getHost(input);
Input::fromURL(fmt("git+https://%s/%s/%s.git",
Input::fromURL(*input.settings, fmt("git+https://%s/%s/%s.git",
host, getOwner(input), getRepo(input)))
.applyOverrides(input.getRef(), input.getRev())
.clone(destDir);
@ -426,7 +432,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
auto url = fmt("https://%s/api/v4/projects/%s%%2F%s/repository/commits?ref_name=%s",
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), *input.getRef());
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
auto json = nlohmann::json::parse(
readFile(
@ -456,7 +462,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
input.getRev()->to_string(HashFormat::Base16, false));
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
return DownloadUrl { url, headers };
}
@ -464,7 +470,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
{
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
// FIXME: get username somewhere
Input::fromURL(fmt("git+https://%s/%s/%s.git",
Input::fromURL(*input.settings, fmt("git+https://%s/%s/%s.git",
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")))
.applyOverrides(input.getRef(), input.getRev())
.clone(destDir);
@ -496,7 +502,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
auto base_url = fmt("https://%s/%s/%s",
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"));
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
std::string refUri;
if (ref == "HEAD") {
@ -543,14 +549,14 @@ struct SourceHutInputScheme : GitArchiveInputScheme
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
input.getRev()->to_string(HashFormat::Base16, false));
Headers headers = makeHeadersWithAuthTokens(host);
Headers headers = makeHeadersWithAuthTokens(*input.settings, host);
return DownloadUrl { url, headers };
}
void clone(const Input & input, const Path & destDir) const override
{
auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
Input::fromURL(fmt("git+https://%s/%s/%s",
Input::fromURL(*input.settings, fmt("git+https://%s/%s/%s",
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")))
.applyOverrides(input.getRef(), input.getRev())
.clone(destDir);

View file

@ -8,7 +8,9 @@ std::regex flakeRegex("[a-zA-Z][a-zA-Z0-9_-]*", std::regex::ECMAScript);
struct IndirectInputScheme : InputScheme
{
std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const override
std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree) const override
{
if (url.scheme != "flake") return {};
@ -41,7 +43,7 @@ struct IndirectInputScheme : InputScheme
// FIXME: forbid query params?
Input input;
Input input{settings};
input.attrs.insert_or_assign("type", "indirect");
input.attrs.insert_or_assign("id", id);
if (rev) input.attrs.insert_or_assign("rev", rev->gitRev());
@ -65,13 +67,15 @@ struct IndirectInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const override
{
auto id = getStrAttr(attrs, "id");
if (!std::regex_match(id, flakeRegex))
throw BadURL("'%s' is not a valid flake ID", id);
Input input;
Input input{settings};
input.attrs = attrs;
return input;
}

View file

@ -45,7 +45,9 @@ static std::string runHg(const Strings & args, const std::optional<std::string>
struct MercurialInputScheme : InputScheme
{
std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const override
std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree) const override
{
if (url.scheme != "hg+http" &&
url.scheme != "hg+https" &&
@ -68,7 +70,7 @@ struct MercurialInputScheme : InputScheme
attrs.emplace("url", url2.to_string());
return inputFromAttrs(attrs);
return inputFromAttrs(settings, attrs);
}
std::string_view schemeName() const override
@ -88,7 +90,9 @@ struct MercurialInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const override
{
parseURL(getStrAttr(attrs, "url"));
@ -97,7 +101,7 @@ struct MercurialInputScheme : InputScheme
throw BadURL("invalid Mercurial branch/tag name '%s'", *ref);
}
Input input;
Input input{settings};
input.attrs = attrs;
return input;
}
@ -182,10 +186,10 @@ struct MercurialInputScheme : InputScheme
/* This is an unclean working tree. So copy all tracked
files. */
if (!fetchSettings.allowDirty)
if (!input.settings->allowDirty)
throw Error("Mercurial tree '%s' is unclean", actualUrl);
if (fetchSettings.warnDirty)
if (input.settings->warnDirty)
warn("Mercurial tree '%s' is unclean", actualUrl);
input.attrs.insert_or_assign("ref", chomp(runHg({ "branch", "-R", actualUrl })));

View file

@ -7,14 +7,16 @@ namespace nix::fetchers {
struct PathInputScheme : InputScheme
{
std::optional<Input> inputFromURL(const ParsedURL & url, bool requireTree) const override
std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & url, bool requireTree) const override
{
if (url.scheme != "path") return {};
if (url.authority && *url.authority != "")
throw Error("path URL '%s' should not have an authority ('%s')", url.url, *url.authority);
Input input;
Input input{settings};
input.attrs.insert_or_assign("type", "path");
input.attrs.insert_or_assign("path", url.path);
@ -54,11 +56,13 @@ struct PathInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const override
{
getStrAttr(attrs, "path");
Input input;
Input input{settings};
input.attrs = attrs;
return input;
}

View file

@ -1,7 +1,7 @@
#include "fetch-settings.hh"
#include "registry.hh"
#include "tarball.hh"
#include "users.hh"
#include "config-global.hh"
#include "globals.hh"
#include "store-api.hh"
#include "local-fs-store.hh"
@ -11,12 +11,13 @@
namespace nix::fetchers {
std::shared_ptr<Registry> Registry::read(
const Settings & settings,
const Path & path, RegistryType type)
{
auto registry = std::make_shared<Registry>(type);
auto registry = std::make_shared<Registry>(settings, type);
if (!pathExists(path))
return std::make_shared<Registry>(type);
return std::make_shared<Registry>(settings, type);
try {
@ -36,8 +37,8 @@ std::shared_ptr<Registry> Registry::read(
auto exact = i.find("exact");
registry->entries.push_back(
Entry {
.from = Input::fromAttrs(jsonToAttrs(i["from"])),
.to = Input::fromAttrs(std::move(toAttrs)),
.from = Input::fromAttrs(settings, jsonToAttrs(i["from"])),
.to = Input::fromAttrs(settings, std::move(toAttrs)),
.extraAttrs = extraAttrs,
.exact = exact != i.end() && exact.value()
});
@ -106,10 +107,10 @@ static Path getSystemRegistryPath()
return settings.nixConfDir + "/registry.json";
}
static std::shared_ptr<Registry> getSystemRegistry()
static std::shared_ptr<Registry> getSystemRegistry(const Settings & settings)
{
static auto systemRegistry =
Registry::read(getSystemRegistryPath(), Registry::System);
Registry::read(settings, getSystemRegistryPath(), Registry::System);
return systemRegistry;
}
@ -118,25 +119,24 @@ Path getUserRegistryPath()
return getConfigDir() + "/nix/registry.json";
}
std::shared_ptr<Registry> getUserRegistry()
std::shared_ptr<Registry> getUserRegistry(const Settings & settings)
{
static auto userRegistry =
Registry::read(getUserRegistryPath(), Registry::User);
Registry::read(settings, getUserRegistryPath(), Registry::User);
return userRegistry;
}
std::shared_ptr<Registry> getCustomRegistry(const Path & p)
std::shared_ptr<Registry> getCustomRegistry(const Settings & settings, const Path & p)
{
static auto customRegistry =
Registry::read(p, Registry::Custom);
Registry::read(settings, p, Registry::Custom);
return customRegistry;
}
static std::shared_ptr<Registry> flagRegistry =
std::make_shared<Registry>(Registry::Flag);
std::shared_ptr<Registry> getFlagRegistry()
std::shared_ptr<Registry> getFlagRegistry(const Settings & settings)
{
static auto flagRegistry =
std::make_shared<Registry>(settings, Registry::Flag);
return flagRegistry;
}
@ -145,30 +145,15 @@ void overrideRegistry(
const Input & to,
const Attrs & extraAttrs)
{
flagRegistry->add(from, to, extraAttrs);
getFlagRegistry(*from.settings)->add(from, to, extraAttrs);
}
struct RegistrySettings : Config
{
Setting<std::string> flakeRegistry{this, "https://channels.nixos.org/flake-registry.json", "flake-registry",
R"(
Path or URI of the global flake registry.
When empty, disables the global flake registry.
)",
{}, true, Xp::Flakes};
};
RegistrySettings registrySettings;
static GlobalConfig::Register rRegistrySettings(&registrySettings);
static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, ref<Store> store)
{
static auto reg = [&]() {
auto path = registrySettings.flakeRegistry.get();
auto path = settings.flakeRegistry.get();
if (path == "") {
return std::make_shared<Registry>(Registry::Global); // empty registry
return std::make_shared<Registry>(settings, Registry::Global); // empty registry
}
if (!hasPrefix(path, "/")) {
@ -178,19 +163,19 @@ static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
path = store->toRealPath(storePath);
}
return Registry::read(path, Registry::Global);
return Registry::read(settings, path, Registry::Global);
}();
return reg;
}
Registries getRegistries(ref<Store> store)
Registries getRegistries(const Settings & settings, ref<Store> store)
{
Registries registries;
registries.push_back(getFlagRegistry());
registries.push_back(getUserRegistry());
registries.push_back(getSystemRegistry());
registries.push_back(getGlobalRegistry(store));
registries.push_back(getFlagRegistry(settings));
registries.push_back(getUserRegistry(settings));
registries.push_back(getSystemRegistry(settings));
registries.push_back(getGlobalRegistry(settings, store));
return registries;
}
@ -207,7 +192,7 @@ std::pair<Input, Attrs> lookupInRegistries(
n++;
if (n > 100) throw Error("cycle detected in flake registry for '%s'", input.to_string());
for (auto & registry : getRegistries(store)) {
for (auto & registry : getRegistries(*input.settings, store)) {
// FIXME: O(n)
for (auto & entry : registry->entries) {
if (entry.exact) {

View file

@ -10,6 +10,8 @@ namespace nix::fetchers {
struct Registry
{
const Settings & settings;
enum RegistryType {
Flag = 0,
User = 1,
@ -29,11 +31,13 @@ struct Registry
std::vector<Entry> entries;
Registry(RegistryType type)
: type(type)
Registry(const Settings & settings, RegistryType type)
: settings{settings}
, type{type}
{ }
static std::shared_ptr<Registry> read(
const Settings & settings,
const Path & path, RegistryType type);
void write(const Path & path);
@ -48,13 +52,13 @@ struct Registry
typedef std::vector<std::shared_ptr<Registry>> Registries;
std::shared_ptr<Registry> getUserRegistry();
std::shared_ptr<Registry> getUserRegistry(const Settings & settings);
std::shared_ptr<Registry> getCustomRegistry(const Path & p);
std::shared_ptr<Registry> getCustomRegistry(const Settings & settings, const Path & p);
Path getUserRegistryPath();
Registries getRegistries(ref<Store> store);
Registries getRegistries(const Settings & settings, ref<Store> store);
void overrideRegistry(
const Input & from,

View file

@ -214,12 +214,14 @@ struct CurlInputScheme : InputScheme
static const std::set<std::string> specialParams;
std::optional<Input> inputFromURL(const ParsedURL & _url, bool requireTree) const override
std::optional<Input> inputFromURL(
const Settings & settings,
const ParsedURL & _url, bool requireTree) const override
{
if (!isValidURL(_url, requireTree))
return std::nullopt;
Input input;
Input input{settings};
auto url = _url;
@ -267,9 +269,11 @@ struct CurlInputScheme : InputScheme
};
}
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
std::optional<Input> inputFromAttrs(
const Settings & settings,
const Attrs & attrs) const override
{
Input input;
Input input{settings};
input.attrs = attrs;
//input.locked = (bool) maybeGetStrAttr(input.attrs, "hash");
@ -349,7 +353,7 @@ struct TarballInputScheme : CurlInputScheme
result.accessor->setPathDisplay("«" + input.to_string() + "»");
if (result.immutableUrl) {
auto immutableInput = Input::fromURL(*result.immutableUrl);
auto immutableInput = Input::fromURL(*input.settings, *result.immutableUrl);
// FIXME: would be nice to support arbitrary flakerefs
// here, e.g. git flakes.
if (immutableInput.getType() != "tarball")