Skip to content

Commit

Permalink
Merge pull request #9063 from obsidiansystems/libfetchers-prep
Browse files Browse the repository at this point in the history
Introduce `libnixflake`
  • Loading branch information
Ericson2314 committed Jun 27, 2024
2 parents ed12926 + 7181d1f commit 7e66f0d
Show file tree
Hide file tree
Showing 26 changed files with 233 additions and 72 deletions.
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);

/**
* 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;

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

0 comments on commit 7e66f0d

Please sign in to comment.