Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce libnixflake #9063

Merged
merged 3 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ makefiles = \
src/libfetchers/local.mk \
src/libmain/local.mk \
src/libexpr/local.mk \
src/libflake/local.mk \
src/libcmd/local.mk \
src/nix/local.mk \
src/libutil-c/local.mk \
Expand Down Expand Up @@ -45,7 +46,8 @@ makefiles += \
tests/unit/libstore-support/local.mk \
tests/unit/libfetchers/local.mk \
tests/unit/libexpr/local.mk \
tests/unit/libexpr-support/local.mk
tests/unit/libexpr-support/local.mk \
tests/unit/libflake/local.mk
endif

ifeq ($(ENABLE_FUNCTIONAL_TESTS), yes)
Expand Down
20 changes: 10 additions & 10 deletions maintainers/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,6 @@
''^src/libexpr/eval-settings\.hh$''
''^src/libexpr/eval\.cc$''
''^src/libexpr/eval\.hh$''
''^src/libexpr/flake/config\.cc$''
''^src/libexpr/flake/flake\.cc$''
''^src/libexpr/flake/flake\.hh$''
''^src/libexpr/flake/flakeref\.cc$''
''^src/libexpr/flake/flakeref\.hh$''
''^src/libexpr/flake/lockfile\.cc$''
''^src/libexpr/flake/lockfile\.hh$''
''^src/libexpr/flake/url-name\.cc$''
''^src/libexpr/function-trace\.cc$''
''^src/libexpr/gc-small-vector\.hh$''
''^src/libexpr/get-drvs\.cc$''
Expand Down Expand Up @@ -127,6 +119,14 @@
''^src/libfetchers/tarball\.hh$''
''^src/libfetchers/git\.cc$''
''^src/libfetchers/mercurial\.cc$''
''^src/libflake/flake/config\.cc$''
''^src/libflake/flake/flake\.cc$''
''^src/libflake/flake/flake\.hh$''
''^src/libflake/flake/flakeref\.cc$''
''^src/libflake/flake/flakeref\.hh$''
''^src/libflake/flake/lockfile\.cc$''
''^src/libflake/flake/lockfile\.hh$''
''^src/libflake/flake/url-name\.cc$''
''^src/libmain/common-args\.cc$''
''^src/libmain/common-args\.hh$''
''^src/libmain/loggers\.cc$''
Expand Down Expand Up @@ -436,8 +436,6 @@
''^tests/unit/libexpr/derived-path\.cc''
''^tests/unit/libexpr/error_traces\.cc''
''^tests/unit/libexpr/eval\.cc''
''^tests/unit/libexpr/flake/flakeref\.cc''
''^tests/unit/libexpr/flake/url-name\.cc''
''^tests/unit/libexpr/json\.cc''
''^tests/unit/libexpr/main\.cc''
''^tests/unit/libexpr/primops\.cc''
Expand All @@ -446,6 +444,8 @@
''^tests/unit/libexpr/value/context\.cc''
''^tests/unit/libexpr/value/print\.cc''
''^tests/unit/libfetchers/public-key\.cc''
''^tests/unit/libflake/flakeref\.cc''
''^tests/unit/libflake/url-name\.cc''
''^tests/unit/libstore-support/tests/derived-path\.cc''
''^tests/unit/libstore-support/tests/derived-path\.hh''
''^tests/unit/libstore-support/tests/nix_api_store\.hh''
Expand Down
15 changes: 14 additions & 1 deletion src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/libcmd/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ libcmd_DIR := $(d)

libcmd_SOURCES := $(wildcard $(d)/*.cc)

libcmd_CXXFLAGS += $(INCLUDE_libutil) $(INCLUDE_libstore) $(INCLUDE_libfetchers) $(INCLUDE_libexpr) $(INCLUDE_libmain)
libcmd_CXXFLAGS += $(INCLUDE_libutil) $(INCLUDE_libstore) $(INCLUDE_libfetchers) $(INCLUDE_libexpr) $(INCLUDE_libflake) $(INCLUDE_libmain)

libcmd_LDFLAGS = $(EDITLINE_LIBS) $(LOWDOWN_LIBS) $(THREAD_LDFLAGS)

libcmd_LIBS = libstore libutil libexpr libmain libfetchers
libcmd_LIBS = libutil libstore libfetchers libflake libexpr libmain

$(eval $(call install-file-in, $(buildprefix)$(d)/nix-cmd.pc, $(libdir)/pkgconfig, 0644))
3 changes: 2 additions & 1 deletion src/libexpr/eval-settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
35 changes: 34 additions & 1 deletion src/libexpr/eval-settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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>>;
Ericson2314 marked this conversation as resolved.
Show resolved Hide resolved

EvalSettings(bool & readOnlyMode, LookupPathHooks lookupPathHooks = {});

bool & readOnlyMode;

Expand All @@ -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.
Expand Down
36 changes: 18 additions & 18 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "url.hh"
#include "fetch-to-store.hh"
#include "tarball.hh"
#include "flake/flakeref.hh"
#include "parser-tab.hh"

#include <algorithm>
Expand Down Expand Up @@ -2760,30 +2759,36 @@ 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)
});
}
}

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. */
Expand All @@ -2800,22 +2805,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;
}


Expand Down
3 changes: 0 additions & 3 deletions src/libexpr/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ libexpr_SOURCES := \
$(wildcard $(d)/*.cc) \
$(wildcard $(d)/value/*.cc) \
$(wildcard $(d)/primops/*.cc) \
$(wildcard $(d)/flake/*.cc) \
$(d)/lexer-tab.cc \
$(d)/parser-tab.cc
# Not just for this library itself, but also for downstream libraries using this library
Expand Down Expand Up @@ -45,8 +44,6 @@ $(eval $(call install-file-in, $(buildprefix)$(d)/nix-expr.pc, $(libdir)/pkgconf

$(foreach i, $(wildcard src/libexpr/value/*.hh), \
$(eval $(call install-file-in, $(i), $(includedir)/nix/value, 0644)))
$(foreach i, $(wildcard src/libexpr/flake/*.hh), \
$(eval $(call install-file-in, $(i), $(includedir)/nix/flake, 0644)))

$(d)/primops.cc: $(d)/imported-drv-to-derivation.nix.gen.hh

Expand Down
25 changes: 0 additions & 25 deletions src/libfetchers/fetch-settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,6 @@ struct FetchSettings : public Config
Setting<bool> warnDirty{this, true, "warn-dirty",
"Whether to warn about dirty Git/Mercurial trees."};

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};

Setting<bool> useRegistries{this, true, "use-registries",
"Whether to use flake registries to resolve flake references.",
{}, true, Xp::Flakes};

Setting<bool> acceptFlakeConfig{this, false, "accept-flake-config",
"Whether to accept nix configuration from a flake without prompting.",
{}, true, Xp::Flakes};

Setting<std::string> commitLockFileSummary{
this, "", "commit-lock-file-summary",
R"(
The commit summary to use when committing changed flake lock files. If
empty, the summary is generated based on the action performed.
)",
{"commit-lockfile-summary"}, true, Xp::Flakes};

Setting<bool> trustTarballsFromGitForges{
this, true, "trust-tarballs-from-git-forges",
R"(
Expand All @@ -108,7 +84,6 @@ struct FetchSettings : public Config
`narHash` attribute is specified,
e.g. `github:NixOS/patchelf/7c2f768bf9601268a4e71c2ebe91e2011918a70f?narHash=sha256-PPXqKY2hJng4DBVE0I4xshv/vGLUskL7jl53roB8UdU%3D`.
)"};

};

// FIXME: don't use a global variable.
Expand Down
20 changes: 17 additions & 3 deletions src/libfetchers/registry.cc
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#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"

#include "fetch-settings.hh"

#include <nlohmann/json.hpp>

namespace nix::fetchers {
Expand Down Expand Up @@ -149,10 +148,25 @@ void overrideRegistry(
flagRegistry->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 auto reg = [&]() {
auto path = fetchSettings.flakeRegistry.get();
auto path = registrySettings.flakeRegistry.get();
if (path == "") {
return std::make_shared<Registry>(Registry::Global); // empty registry
}
Expand Down
12 changes: 12 additions & 0 deletions src/libflake/flake-settings.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "flake-settings.hh"
#include "config-global.hh"

namespace nix {

FlakeSettings::FlakeSettings() {}

FlakeSettings flakeSettings;

static GlobalConfig::Register rFlakeSettings(&flakeSettings);

}
Loading
Loading