Skip to content

Commit

Permalink
No global settings in libnixfetchers and libnixflake
Browse files Browse the repository at this point in the history
Progress on NixOS#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
52bfccf.
  • Loading branch information
Ericson2314 committed Jul 8, 2024
1 parent cfe3ee3 commit 41e812e
Show file tree
Hide file tree
Showing 50 changed files with 402 additions and 272 deletions.
2 changes: 1 addition & 1 deletion src/libcmd/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ ref<EvalState> EvalCommand::getEvalState()
#else
std::make_shared<EvalState>(
#endif
lookupPath, getEvalStore(), evalSettings, getStore())
lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore())
;

evalState->repair = repair;
Expand Down
20 changes: 16 additions & 4 deletions src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "fetch-settings.hh"
#include "eval-settings.hh"
#include "common-eval-args.hh"
#include "shared.hh"
Expand All @@ -7,6 +8,7 @@
#include "fetchers.hh"
#include "registry.hh"
#include "flake/flakeref.hh"
#include "flake/settings.hh"
#include "store-api.hh"
#include "command.hh"
#include "tarball.hh"
Expand All @@ -16,6 +18,10 @@

namespace nix {

fetchers::Settings fetchSettings;

static GlobalConfig::Register rFetchSettings(&fetchSettings);

EvalSettings evalSettings {
settings.readOnlyMode,
{
Expand All @@ -24,7 +30,7 @@ EvalSettings evalSettings {
[](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);
auto flakeRef = parseFlakeRef(fetchSettings, 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);
Expand All @@ -35,6 +41,12 @@ EvalSettings evalSettings {

static GlobalConfig::Register rEvalSettings(&evalSettings);


flake::Settings flakeSettings;

static GlobalConfig::Register rFlakeSettings(&flakeSettings);


CompatibilitySettings compatibilitySettings {};

static GlobalConfig::Register rCompatibilitySettings(&compatibilitySettings);
Expand Down Expand Up @@ -171,8 +183,8 @@ MixEvalArgs::MixEvalArgs()
.category = category,
.labels = {"original-ref", "resolved-ref"},
.handler = {[&](std::string _from, std::string _to) {
auto from = parseFlakeRef(_from, absPath("."));
auto to = parseFlakeRef(_to, absPath("."));
auto from = parseFlakeRef(fetchSettings, _from, absPath("."));
auto to = parseFlakeRef(fetchSettings, _to, absPath("."));
fetchers::Attrs extraAttrs;
if (to.subdir != "") extraAttrs["dir"] = to.subdir;
fetchers::overrideRegistry(from.input, to.input, extraAttrs);
Expand Down Expand Up @@ -230,7 +242,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas

else if (hasPrefix(s, "flake:")) {
experimentalFeatureSettings.require(Xp::Flakes);
auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
auto flakeRef = parseFlakeRef(fetchSettings, std::string(s.substr(6)), {}, true, false);
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first;
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
}
Expand Down
15 changes: 15 additions & 0 deletions src/libcmd/common-eval-args.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,32 @@
namespace nix {

class Store;

namespace fetchers { struct Settings; }

class EvalState;
struct EvalSettings;
struct CompatibilitySettings;
class Bindings;
struct SourcePath;

namespace flake { struct Settings; }

/**
* @todo Get rid of global setttings variables
*/
extern fetchers::Settings fetchSettings;

/**
* @todo Get rid of global setttings variables
*/
extern EvalSettings evalSettings;

/**
* @todo Get rid of global setttings variables
*/
extern flake::Settings flakeSettings;

/**
* Settings that control behaviors that have changed since Nix 2.3.
*/
Expand Down
3 changes: 2 additions & 1 deletion src/libcmd/installable-flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
flake::LockFlags lockFlagsApplyConfig = lockFlags;
// FIXME why this side effect?
lockFlagsApplyConfig.applyNixConfig = true;
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlagsApplyConfig));
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(
flakeSettings, *state, flakeRef, lockFlagsApplyConfig));
}
return _lockedFlake;
}
Expand Down
3 changes: 2 additions & 1 deletion src/libcmd/installable-flake.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
///@file

#include "common-eval-args.hh"
#include "installable-value.hh"

namespace nix {
Expand Down Expand Up @@ -80,7 +81,7 @@ struct InstallableFlake : InstallableValue
*/
static inline FlakeRef defaultNixpkgsFlakeRef()
{
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
return FlakeRef::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", "nixpkgs"}});
}

ref<eval_cache::EvalCache> openEvalCache(
Expand Down
19 changes: 12 additions & 7 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ MixFlakeOptions::MixFlakeOptions()
lockFlags.writeLockFile = false;
lockFlags.inputOverrides.insert_or_assign(
flake::parseInputPath(inputPath),
parseFlakeRef(flakeRef, absPath(getCommandBaseDir()), true));
parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir()), true));
}},
.completer = {[&](AddCompletions & completions, size_t n, std::string_view prefix) {
if (n == 0) {
Expand Down Expand Up @@ -170,14 +170,15 @@ MixFlakeOptions::MixFlakeOptions()
.handler = {[&](std::string flakeRef) {
auto evalState = getEvalState();
auto flake = flake::lockFlake(
flakeSettings,
*evalState,
parseFlakeRef(flakeRef, absPath(getCommandBaseDir())),
parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir())),
{ .writeLockFile = false });
for (auto & [inputName, input] : flake.lockFile.root->inputs) {
auto input2 = flake.lockFile.findInput({inputName}); // resolve 'follows' nodes
if (auto input3 = std::dynamic_pointer_cast<const flake::LockedNode>(input2)) {
overrideRegistry(
fetchers::Input::fromAttrs({{"type","indirect"}, {"id", inputName}}),
fetchers::Input::fromAttrs(fetchSettings, {{"type","indirect"}, {"id", inputName}}),
input3->lockedRef.input,
{});
}
Expand Down Expand Up @@ -338,10 +339,11 @@ void completeFlakeRefWithFragment(
auto flakeRefS = std::string(prefix.substr(0, hash));

// TODO: ideally this would use the command base directory instead of assuming ".".
auto flakeRef = parseFlakeRef(expandTilde(flakeRefS), absPath("."));
auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), absPath("."));

auto evalCache = openEvalCache(*evalState,
std::make_shared<flake::LockedFlake>(lockFlake(*evalState, flakeRef, lockFlags)));
std::make_shared<flake::LockedFlake>(lockFlake(
flakeSettings, *evalState, flakeRef, lockFlags)));

auto root = evalCache->getRoot();

Expand Down Expand Up @@ -403,7 +405,7 @@ void completeFlakeRef(AddCompletions & completions, ref<Store> store, std::strin
Args::completeDir(completions, 0, prefix);

/* Look for registry entries that match the prefix. */
for (auto & registry : fetchers::getRegistries(store)) {
for (auto & registry : fetchers::getRegistries(fetchSettings, store)) {
for (auto & entry : registry->entries) {
auto from = entry.from.to_string();
if (!hasPrefix(prefix, "flake:") && hasPrefix(from, "flake:")) {
Expand Down Expand Up @@ -534,7 +536,8 @@ Installables SourceExprCommand::parseInstallables(
}

try {
auto [flakeRef, fragment] = parseFlakeRefWithFragment(std::string { prefix }, absPath(getCommandBaseDir()));
auto [flakeRef, fragment] = parseFlakeRefWithFragment(
fetchSettings, std::string { prefix }, absPath(getCommandBaseDir()));
result.push_back(make_ref<InstallableFlake>(
this,
getEvalState(),
Expand Down Expand Up @@ -851,6 +854,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
std::vector<FlakeRef> res;
for (auto i : rawInstallables)
res.push_back(parseFlakeRefWithFragment(
fetchSettings,
expandTilde(i),
absPath(getCommandBaseDir())).first);
return res;
Expand All @@ -873,6 +877,7 @@ std::vector<FlakeRef> InstallableCommand::getFlakeRefsForCompletion()
{
return {
parseFlakeRefWithFragment(
fetchSettings,
expandTilde(_installable),
absPath(getCommandBaseDir())).first
};
Expand Down
4 changes: 2 additions & 2 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -690,14 +690,14 @@ void NixRepl::loadFlake(const std::string & flakeRefS)
if (flakeRefS.empty())
throw Error("cannot use ':load-flake' without a path specified. (Use '.' for the current working directory.)");

auto flakeRef = parseFlakeRef(flakeRefS, absPath("."), true);
auto flakeRef = parseFlakeRef(fetchSettings, flakeRefS, absPath("."), true);
if (evalSettings.pureEval && !flakeRef.input.isLocked())
throw Error("cannot use ':load-flake' on locked flake reference '%s' (use --impure to override)", flakeRefS);

Value v;

flake::callFlake(*state,
flake::lockFlake(*state, flakeRef,
flake::lockFlake(flakeSettings, *state, flakeRef,
flake::LockFlags {
.updateLockFile = false,
.useRegistries = !evalSettings.pureEval,
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr-c/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ libexprc_CXXFLAGS += $(INCLUDE_libutil) $(INCLUDE_libutilc) \
$(INCLUDE_libstore) $(INCLUDE_libstorec) \
$(INCLUDE_libexpr) $(INCLUDE_libexprc)

libexprc_LIBS = libutil libutilc libstore libstorec libexpr
libexprc_LIBS = libutil libutilc libstore libstorec libfetchers libexpr

libexprc_LDFLAGS += $(THREAD_LDFLAGS)

Expand Down
2 changes: 2 additions & 0 deletions src/libexpr-c/nix_api_expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,14 @@ EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c
static_cast<std::align_val_t>(alignof(EvalState)));
auto * p2 = static_cast<EvalState *>(p);
new (p) EvalState {
.fetchSettings = nix::fetchers::Settings{},
.settings = nix::EvalSettings{
nix::settings.readOnlyMode,
},
.state = nix::EvalState(
nix::LookupPath::parse(lookupPath),
store->ptr,
p2->fetchSettings,
p2->settings),
};
loadConfFile(p2->settings);
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr-c/nix_api_expr_internal.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#ifndef NIX_API_EXPR_INTERNAL_H
#define NIX_API_EXPR_INTERNAL_H

#include "fetch-settings.hh"
#include "eval.hh"
#include "eval-settings.hh"
#include "attr-set.hh"
#include "nix_api_value.h"

struct EvalState
{
nix::fetchers::Settings fetchSettings;
nix::EvalSettings settings;
nix::EvalState state;
};
Expand Down
1 change: 0 additions & 1 deletion src/libexpr/eval-settings.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "users.hh"
#include "config-global.hh"
#include "globals.hh"
#include "profiles.hh"
#include "eval.hh"
Expand Down
4 changes: 3 additions & 1 deletion src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,11 @@ static constexpr size_t BASE_ENV_SIZE = 128;
EvalState::EvalState(
const LookupPath & _lookupPath,
ref<Store> store,
const fetchers::Settings & fetchSettings,
const EvalSettings & settings,
std::shared_ptr<Store> buildStore)
: settings{settings}
: fetchSettings{fetchSettings}
, settings{settings}
, sWith(symbols.create("<with>"))
, sOutPath(symbols.create("outPath"))
, sDrvPath(symbols.create("drvPath"))
Expand Down
7 changes: 5 additions & 2 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace nix {
constexpr size_t maxPrimOpArity = 8;

class Store;
namespace fetchers { struct Settings; }
struct EvalSettings;
class EvalState;
class StorePath;
Expand All @@ -43,7 +44,7 @@ namespace eval_cache {
/**
* Function that implements a primop.
*/
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
using PrimOpFun = void(EvalState & state, const PosIdx pos, Value * * args, Value & v);

/**
* Info about a primitive operation, and its implementation
Expand Down Expand Up @@ -84,7 +85,7 @@ struct PrimOp
/**
* Implementation of the primop.
*/
std::function<std::remove_pointer<PrimOpFun>::type> fun;
std::function<PrimOpFun> fun;

/**
* Optional experimental for this to be gated on.
Expand Down Expand Up @@ -162,6 +163,7 @@ struct DebugTrace {
class EvalState : public std::enable_shared_from_this<EvalState>
{
public:
const fetchers::Settings & fetchSettings;
const EvalSettings & settings;
SymbolTable symbols;
PosTable positions;
Expand Down Expand Up @@ -353,6 +355,7 @@ public:
EvalState(
const LookupPath & _lookupPath,
ref<Store> store,
const fetchers::Settings & fetchSettings,
const EvalSettings & settings,
std::shared_ptr<Store> buildStore = nullptr);
~EvalState();
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/primops/fetchMercurial.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
attrs.insert_or_assign("name", std::string(name));
if (ref) attrs.insert_or_assign("ref", *ref);
if (rev) attrs.insert_or_assign("rev", rev->gitRev());
auto input = fetchers::Input::fromAttrs(std::move(attrs));
auto input = fetchers::Input::fromAttrs(state.fetchSettings, std::move(attrs));

auto [storePath, input2] = input.fetchToStore(state.store);

Expand Down
8 changes: 4 additions & 4 deletions src/libexpr/primops/fetchTree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static void fetchTree(
Value & v,
const FetchTreeParams & params = FetchTreeParams{}
) {
fetchers::Input input;
fetchers::Input input { state.fetchSettings };
NixStringContext context;
std::optional<std::string> type;
if (params.isFetchGit) type = "git";
Expand Down Expand Up @@ -148,7 +148,7 @@ static void fetchTree(
"attribute 'name' isn’t supported in call to 'fetchTree'"
).atPos(pos).debugThrow();

input = fetchers::Input::fromAttrs(std::move(attrs));
input = fetchers::Input::fromAttrs(state.fetchSettings, std::move(attrs));
} else {
auto url = state.coerceToString(pos, *args[0], context,
"while evaluating the first argument passed to the fetcher",
Expand All @@ -161,13 +161,13 @@ static void fetchTree(
if (!attrs.contains("exportIgnore") && (!attrs.contains("submodules") || !*fetchers::maybeGetBoolAttr(attrs, "submodules"))) {
attrs.emplace("exportIgnore", Explicit<bool>{true});
}
input = fetchers::Input::fromAttrs(std::move(attrs));
input = fetchers::Input::fromAttrs(state.fetchSettings, std::move(attrs));
} else {
if (!experimentalFeatureSettings.isEnabled(Xp::Flakes))
state.error<EvalError>(
"passing a string argument to 'fetchTree' requires the 'flakes' experimental feature"
).atPos(pos).debugThrow();
input = fetchers::Input::fromURL(url);
input = fetchers::Input::fromURL(state.fetchSettings, url);
}
}

Expand Down
9 changes: 2 additions & 7 deletions src/libfetchers/fetch-settings.cc
Original file line number Diff line number Diff line change
@@ -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);

}
Loading

0 comments on commit 41e812e

Please sign in to comment.