-------------- ongoing crimes
Change-Id: Iedd51025b3a5a25b6570983726f8a237c53f5192
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "lix/libcmd/built-path.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libexpr/get-drvs.hh"
|
||||
#include "lix/libutil/types.hh"
|
||||
#include "lix/libutil/json-fwd.hh"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "lix/libcmd/command.hh"
|
||||
#include "lix/libflakes/init.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libstore/local-fs-store.hh"
|
||||
#include "lix/libstore/derivations.hh"
|
||||
@@ -119,6 +120,8 @@ ref<eval_cache::CachingEvaluator> EvalCommand::getEvaluator()
|
||||
startReplOnEvalErrors ? AbstractNixRepl::runSimple : nullptr
|
||||
);
|
||||
|
||||
flake::initFlakes(evalState.get());
|
||||
|
||||
evalState->repair = repair;
|
||||
}
|
||||
return ref<eval_cache::CachingEvaluator>::unsafeFromPtr(evalState);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "lix/libutil/args.hh"
|
||||
#include "lix/libcmd/common-eval-args.hh"
|
||||
#include "lix/libstore/path.hh"
|
||||
#include "lix/libexpr/flake/lockfile.hh"
|
||||
#include "lix/libflakes/expr/lockfile.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libfetchers/registry.hh"
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libcmd/command.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "lix/libcmd/common-eval-args.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/get-drvs.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "lix/libexpr/attr-path.hh"
|
||||
#include "lix/libcmd/common-eval-args.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libexpr/eval-cache.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "lix/libcmd/installables.hh"
|
||||
#include "lix/libexpr/eval-cache.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "lix/libexpr/eval-settings.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libmain/shared.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libexpr/eval-cache.hh"
|
||||
#include "lix/libfetchers/registry.hh"
|
||||
#include "lix/libstore/build-result.hh"
|
||||
|
||||
@@ -45,6 +45,7 @@ libcmd = library(
|
||||
liblixstore,
|
||||
liblixfetchers,
|
||||
liblixexpr,
|
||||
liblixflakes,
|
||||
liblixmain,
|
||||
liblix_doc,
|
||||
boehm,
|
||||
@@ -76,6 +77,7 @@ liblixcmd = declare_dependency(
|
||||
dependencies : [
|
||||
liblixutil,
|
||||
liblixstore,
|
||||
liblixflakes,
|
||||
kj,
|
||||
],
|
||||
link_with : libcmd,
|
||||
|
||||
+2
-2
@@ -22,8 +22,8 @@
|
||||
#include "lix/libexpr/get-drvs.hh"
|
||||
#include "lix/libstore/derivations.hh"
|
||||
#include "lix/libstore/globals.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libexpr/flake/lockfile.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libflakes/expr/lockfile.hh"
|
||||
#include "lix/libcmd/editor-for.hh"
|
||||
#include "lix/libutil/finally.hh"
|
||||
#include "lix/libcmd/markdown.hh"
|
||||
|
||||
@@ -6,8 +6,7 @@ renameInGlobalScope: false
|
||||
Load, parse and return the Nix expression in the file *path*.
|
||||
|
||||
The value *path* can be a path, a string, or an attribute set with an
|
||||
`__toString` attribute or a `outPath` attribute (as derivations or flake
|
||||
inputs typically have).
|
||||
`__toString` attribute or a `outPath` attribute (as derivations typically have).
|
||||
|
||||
If *path* is a directory, the file `default.nix` in that directory
|
||||
is loaded.
|
||||
|
||||
@@ -6,48 +6,12 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
|
||||
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
|
||||
static Strings parseNixPath(const std::string & s)
|
||||
{
|
||||
Strings res;
|
||||
|
||||
auto p = s.begin();
|
||||
|
||||
while (p != s.end()) {
|
||||
auto start = p;
|
||||
auto start2 = p;
|
||||
|
||||
while (p != s.end() && *p != ':') {
|
||||
if (*p == '=') start2 = p + 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (p == s.end()) {
|
||||
if (p != start) res.push_back(std::string(start, p));
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == ':') {
|
||||
auto prefix = std::string(start2, s.end());
|
||||
if (EvalSettings::isPseudoUrl(prefix) || prefix.starts_with("flake:")) {
|
||||
++p;
|
||||
while (p != s.end() && *p != ':') ++p;
|
||||
}
|
||||
res.push_back(std::string(start, p));
|
||||
if (p == s.end()) break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
EvalSettings::EvalSettings()
|
||||
{
|
||||
auto var = getEnv("NIX_PATH");
|
||||
if (var) nixPath.setDefault(parseNixPath(*var));
|
||||
//auto var = getEnv("NIX_PATH");
|
||||
// TODO(flakes): move that allowed prefix and parse it from eval plugins.
|
||||
//if (var) nixPath.setDefault(parseNixPath(*var, ));
|
||||
}
|
||||
|
||||
Strings EvalSettings::getDefaultNixPath()
|
||||
|
||||
+83
-25
@@ -21,7 +21,7 @@
|
||||
#include "lix/libexpr/print.hh"
|
||||
#include "lix/libexpr/gc-small-vector.hh"
|
||||
#include "lix/libfetchers/fetch-to-store.hh"
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libutil/exit.hh"
|
||||
#include "lix/libutil/json.hh"
|
||||
#include "symbol-table.hh"
|
||||
@@ -318,14 +318,16 @@ EvalBuiltins::EvalBuiltins(
|
||||
EvalPaths::EvalPaths(
|
||||
AsyncIoRoot & aio,
|
||||
const ref<Store> & store,
|
||||
SearchPath searchPath,
|
||||
SearchPath initialSearchPath,
|
||||
bool pureEval,
|
||||
EvalErrorContext & errors
|
||||
)
|
||||
: store(store)
|
||||
, searchPath_(std::move(searchPath))
|
||||
, searchPath_(std::move(initialSearchPath))
|
||||
, pureEval(pureEval)
|
||||
, errors(errors)
|
||||
{
|
||||
if (evalSettings.restrictEval || evalSettings.pureEval) {
|
||||
if (evalSettings.restrictEval || pureEval) {
|
||||
allowedPaths = AllowedPath{.allowAllChildren = false};
|
||||
|
||||
for (auto & i : searchPath_.elements) {
|
||||
@@ -349,6 +351,70 @@ EvalPaths::EvalPaths(
|
||||
}
|
||||
}
|
||||
|
||||
/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
|
||||
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
|
||||
static Strings parseNixPath(const std::string & s, const std::set<std::string> & allowedPrefixes)
|
||||
{
|
||||
Strings res;
|
||||
|
||||
auto p = s.begin();
|
||||
|
||||
while (p != s.end()) {
|
||||
auto start = p;
|
||||
auto start2 = p;
|
||||
|
||||
while (p != s.end() && *p != ':') {
|
||||
if (*p == '=') start2 = p + 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (p == s.end()) {
|
||||
if (p != start) res.push_back(std::string(start, p));
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == ':') {
|
||||
auto prefix = std::string(start2, s.end());
|
||||
|
||||
auto matchesAllowedPrefixes = std::any_of(
|
||||
allowedPrefixes.begin(),
|
||||
allowedPrefixes.end(),
|
||||
[&](const std::string & allowedPrefix) {
|
||||
return prefix.starts_with(allowedPrefix);
|
||||
}
|
||||
);
|
||||
if (EvalSettings::isPseudoUrl(prefix) || matchesAllowedPrefixes) {
|
||||
++p;
|
||||
while (p != s.end() && *p != ':') ++p;
|
||||
}
|
||||
res.push_back(std::string(start, p));
|
||||
if (p == s.end()) break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void EvalPaths::parseAndConfigureEnvironmentNixPath(std::string const & value)
|
||||
{
|
||||
if (!pureEval) {
|
||||
for (auto & elem : parseNixPath(value, allowedNixPathPrefixes)) {
|
||||
searchPath_.elements.emplace_back(SearchPath::Elem::parse(elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EvalPaths::configureSettingNixPath(std::list<std::string> const & values)
|
||||
{
|
||||
if (!pureEval) {
|
||||
for (auto & elem : values) {
|
||||
searchPath_.elements.emplace_back(SearchPath::Elem::parse(elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Evaluator::Evaluator(
|
||||
AsyncIoRoot & aio,
|
||||
const SearchPath & _searchPath,
|
||||
@@ -357,16 +423,7 @@ Evaluator::Evaluator(
|
||||
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl
|
||||
)
|
||||
: s(symbols)
|
||||
, paths(aio, store, [&] {
|
||||
SearchPath searchPath;
|
||||
if (!evalSettings.pureEval) {
|
||||
for (auto & i : _searchPath.elements)
|
||||
searchPath.elements.emplace_back(SearchPath::Elem {i});
|
||||
for (auto & i : evalSettings.nixPath.get())
|
||||
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
|
||||
}
|
||||
return searchPath;
|
||||
}(), errors)
|
||||
, paths(aio, store, _searchPath, evalSettings.pureEval, errors)
|
||||
, builtins(mem, symbols, paths.searchPath(), store->config().storeDir)
|
||||
, repair(NoRepair)
|
||||
, store(store)
|
||||
@@ -392,6 +449,11 @@ Evaluator::Evaluator(
|
||||
box_ptr<EvalState> Evaluator::begin(AsyncIoRoot & aio)
|
||||
{
|
||||
assert(!activeEval);
|
||||
if (auto envNixPath = getEnvNonEmpty("NIX_PATH")) {
|
||||
paths.parseAndConfigureEnvironmentNixPath(*envNixPath);
|
||||
} else {
|
||||
paths.configureSettingNixPath(evalSettings.nixPath);
|
||||
}
|
||||
return box_ptr<EvalState>::unsafeFromNonnull(
|
||||
std::unique_ptr<EvalState>(new EvalState(aio, *this))
|
||||
);
|
||||
@@ -2972,7 +3034,12 @@ try {
|
||||
|
||||
std::optional<std::string> res;
|
||||
|
||||
if (EvalSettings::isPseudoUrl(value)) {
|
||||
for (auto & responder : searchPathResponders) {
|
||||
if (responder.canResolve(value))
|
||||
res = TRY_AWAIT(responder.resolve(value, store));
|
||||
}
|
||||
|
||||
if (!res && EvalSettings::isPseudoUrl(value)) {
|
||||
try {
|
||||
auto storePath = TRY_AWAIT(fetchers::downloadTarball(
|
||||
store, EvalSettings::resolvePseudoUrl(value), "source", false)).tree.storePath;
|
||||
@@ -2984,16 +3051,7 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
else if (value.starts_with("flake:")) {
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
|
||||
debug("fetching flake search path element '%s''", value);
|
||||
auto storePath =
|
||||
TRY_AWAIT(TRY_AWAIT(flakeRef.resolve(store)).fetchTree(store)).first.storePath;
|
||||
res = {store->toRealPath(storePath)};
|
||||
}
|
||||
|
||||
else {
|
||||
else if (!res) {
|
||||
auto path = absPath(value);
|
||||
if (pathExists(path))
|
||||
res = { path };
|
||||
|
||||
+28
-1
@@ -320,20 +320,47 @@ struct EvalErrorContext
|
||||
|
||||
class EvalPaths
|
||||
{
|
||||
struct Responder {
|
||||
std::function<bool (std::string const &)> canResolve;
|
||||
std::function<kj::Promise<Result<std::optional<std::string>>> (std::string const &, ref<Store>)> resolve;
|
||||
};
|
||||
|
||||
ref<Store> store;
|
||||
std::set<std::string> allowedNixPathPrefixes;
|
||||
std::vector<Responder> searchPathResponders;
|
||||
SearchPath searchPath_;
|
||||
bool pureEval;
|
||||
EvalErrorContext & errors;
|
||||
|
||||
public:
|
||||
EvalPaths(
|
||||
AsyncIoRoot & aio,
|
||||
const ref<Store> & store,
|
||||
SearchPath searchPath,
|
||||
SearchPath initialSearchPath,
|
||||
bool pureEval,
|
||||
EvalErrorContext & errors
|
||||
);
|
||||
|
||||
void parseAndConfigureEnvironmentNixPath(std::string const & value);
|
||||
void configureSettingNixPath(std::list<std::string> const & value);
|
||||
|
||||
const SearchPath & searchPath() const { return searchPath_; }
|
||||
|
||||
std::string resolvePseudoUrl(std::string_view url) {
|
||||
if (url.starts_with("channel:"))
|
||||
return "https://channels.nixos.org/" + std::string(url.substr(8)) + "/nixexprs.tar.xz";
|
||||
else
|
||||
return std::string(url);
|
||||
}
|
||||
|
||||
bool registerAllowedNixPathPrefix(const std::string & allowedPrefix) {
|
||||
auto [_, added] = allowedNixPathPrefixes.insert(allowedPrefix);
|
||||
return added;
|
||||
}
|
||||
void registerSearchPathResolver(std::function<bool (std::string const &)> eligible, std::function<kj::Promise<Result<std::optional<std::string>>> (std::string const & value, ref<Store> store)> resolver) {
|
||||
searchPathResponders.push_back({.canResolve=eligible,.resolve=resolver});
|
||||
}
|
||||
|
||||
private:
|
||||
struct AllowedPath
|
||||
{
|
||||
|
||||
@@ -19,12 +19,4 @@ void prim_getContext(EvalState & state, Value * * args, Value & v);
|
||||
void prim_hasContext(EvalState & state, Value * * args, Value & v);
|
||||
void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args, Value & v);
|
||||
|
||||
namespace flake {
|
||||
|
||||
void prim_flakeRefToString(EvalState & state, Value * * args, Value & v);
|
||||
void prim_getFlake(EvalState & state, Value * * args, Value & v);
|
||||
void prim_parseFlakeRef(EvalState & state, Value * * args, Value & v);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ foreach header : [ 'imported-drv-to-derivation.nix', 'fetchurl.nix' ]
|
||||
install_dir : includedir / 'lix/libexpr',
|
||||
)
|
||||
endforeach
|
||||
subdir('flake')
|
||||
|
||||
libexpr_setting_definitions = files(
|
||||
# keep-sorted start
|
||||
@@ -79,7 +78,6 @@ builtin_definitions = files(
|
||||
'builtins/filter.md',
|
||||
'builtins/filterSource.md',
|
||||
'builtins/findFile.md',
|
||||
'builtins/flakeRefToString.md',
|
||||
'builtins/floor.md',
|
||||
'builtins/foldlStrict.md',
|
||||
'builtins/fromJSON.md',
|
||||
@@ -90,7 +88,6 @@ builtin_definitions = files(
|
||||
'builtins/getAttr.md',
|
||||
'builtins/getContext.md',
|
||||
'builtins/getEnv.md',
|
||||
'builtins/getFlake.md',
|
||||
'builtins/groupBy.md',
|
||||
'builtins/hasAttr.md',
|
||||
'builtins/hasContext.md',
|
||||
@@ -116,7 +113,6 @@ builtin_definitions = files(
|
||||
'builtins/match.md',
|
||||
'builtins/mul.md',
|
||||
'builtins/parseDrvName.md',
|
||||
'builtins/parseFlakeRef.md',
|
||||
'builtins/partition.md',
|
||||
'builtins/path.md',
|
||||
'builtins/pathExists.md',
|
||||
@@ -207,10 +203,6 @@ libexpr_sources = files(
|
||||
'eval-error.cc',
|
||||
'eval-settings.cc',
|
||||
'eval.cc',
|
||||
'flake/config.cc',
|
||||
'flake/flake.cc',
|
||||
'flake/flakeref.cc',
|
||||
'flake/lockfile.cc',
|
||||
'function-trace.cc',
|
||||
'gc-alloc.cc',
|
||||
'get-drvs.cc',
|
||||
@@ -242,9 +234,6 @@ libexpr_headers = files(
|
||||
'eval-inline.hh',
|
||||
'eval-settings.hh',
|
||||
'eval.hh',
|
||||
'flake/flake.hh',
|
||||
'flake/flakeref.hh',
|
||||
'flake/lockfile.hh',
|
||||
'function-trace.hh',
|
||||
'gc-alloc.hh',
|
||||
'gc-small-vector.hh',
|
||||
|
||||
@@ -12,7 +12,6 @@ Pure evaluation mode ensures that the result of Nix expressions is fully determi
|
||||
|
||||
Access is nonetheless allowed to (absolute) paths in the Nix store that are returned by builtins like [`builtins.filterSource`](@docroot@/language/builtins.md#builtins-filterSource), [`builtins.fetchTarball`](@docroot@/language/builtins.md#builtins-fetchTarball) and similar.
|
||||
- Impure fetches such as not specifying a commit ID for `builtins.fetchGit` or not specifying a hash for `builtins.fetchTarball` are rejected.
|
||||
- In flakes, access to relative paths outside of the root of the flake's source tree (often, a git repository) is rejected.
|
||||
- The evaluator ignores `NIX_PATH`, `-I` and the `nix-path` setting. Thus, [`builtins.nixPath`](@docroot@/language/builtin-constants.md#builtins-nixPath) is an empty list.
|
||||
- The builtins [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem) and [`builtins.currentTime`](@docroot@/language/builtin-constants.md#builtins-currentTime) are absent from `builtins`.
|
||||
- [`builtins.getEnv`](@docroot@/language/builtin-constants.md#builtins-currentSystem) always returns empty string for any variable.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libutil/logging.hh"
|
||||
#include "lix/libutil/json.hh"
|
||||
#include "lix/libutil/users.hh"
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/eval-settings.hh"
|
||||
#include "lix/libexpr/extra-primops.hh"
|
||||
#include "lix/libexpr/flake/lockfile.hh"
|
||||
#include "lix/libexpr/primops.hh"
|
||||
#include "lix/libflakes/expr/lockfile.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
@@ -994,6 +995,12 @@ void prim_getFlake(EvalState & state, Value * * args, Value & v)
|
||||
v);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_getFlake(PrimOp{{
|
||||
.name = "getFlake",
|
||||
.arity = 1,
|
||||
.fun = prim_getFlake,
|
||||
}});
|
||||
|
||||
void prim_parseFlakeRef(
|
||||
EvalState & state,
|
||||
Value * * args,
|
||||
@@ -1015,6 +1022,12 @@ void prim_parseFlakeRef(
|
||||
v.mkAttrs(binds);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_parseFlakeRef(PrimOp{{
|
||||
.name = "parseFlakeRef",
|
||||
.arity = 1,
|
||||
.fun = prim_parseFlakeRef,
|
||||
}});
|
||||
|
||||
void prim_flakeRefToString(
|
||||
EvalState & state,
|
||||
Value * * args,
|
||||
@@ -1053,6 +1066,12 @@ void prim_flakeRefToString(
|
||||
v.mkString(flakeRef.to_string());
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_flakeRefToString(PrimOp{{
|
||||
.name = "flakeRefToString",
|
||||
.arity = 1,
|
||||
.fun = prim_flakeRefToString,
|
||||
}});
|
||||
|
||||
}
|
||||
|
||||
Fingerprint LockedFlake::getFingerprint() const
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libutil/types.hh"
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libexpr/flake/lockfile.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libflakes/expr/lockfile.hh"
|
||||
#include "lix/libexpr/value.hh"
|
||||
|
||||
namespace nix {
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
#include "lix/libutil/regex.hh"
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "lix/libexpr/flake/lockfile.hh"
|
||||
#include "lix/libflakes/expr/lockfile.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libutil/error.hh"
|
||||
#include "lix/libutil/json.hh"
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libutil/json-fwd.hh"
|
||||
|
||||
namespace nix {
|
||||
@@ -1,8 +1,8 @@
|
||||
libexpr_generated_headers += custom_target(
|
||||
libflakes_generated_headers += custom_target(
|
||||
command : [ 'bash', '-c', 'echo \'R"__NIX_STR(\' | cat - @INPUT@ && echo \')__NIX_STR"\'' ],
|
||||
input : 'call-flake.nix',
|
||||
output : '@PLAINNAME@.gen.hh',
|
||||
capture : true,
|
||||
install : true,
|
||||
install_dir : includedir / 'lix/libexpr/flake',
|
||||
install_dir : includedir / 'lix/libflakes/expr',
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
namespace nix {
|
||||
class EvalState;
|
||||
struct Value;
|
||||
|
||||
namespace flake {
|
||||
void prim_flakeRefToString(EvalState & state, Value * * args, Value & v);
|
||||
void prim_getFlake(EvalState & state, Value * * args, Value & v);
|
||||
void prim_parseFlakeRef(EvalState & state, Value * * args, Value & v);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "lix/libflakes/init.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
|
||||
// TODO: register the builtins
|
||||
// register the setting for flakes (eval-cache)?
|
||||
|
||||
namespace nix::flake {
|
||||
void initFlakes(Evaluator * eval)
|
||||
{
|
||||
// We inform the evaluator about Flakes during NIX_PATH processing.
|
||||
eval->paths.registerAllowedNixPathPrefix("flake:");
|
||||
eval->paths.registerSearchPathResolver([&](std::string const & value) {
|
||||
return value.starts_with("flake:");
|
||||
}, [&](std::string const & value, ref<Store> store) -> kj::Promise<Result<std::optional<std::string>>> {
|
||||
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
|
||||
debug("fetching flake search path element '%s'", value);
|
||||
auto storePath =
|
||||
TRY_AWAIT(TRY_AWAIT(flakeRef.resolve(store)).fetchTree(store)).first.storePath;
|
||||
|
||||
co_return {store->toRealPath(storePath)};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
namespace nix {
|
||||
class Evaluator;
|
||||
|
||||
namespace flake {
|
||||
void initFlakes(Evaluator * eval);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Lix libflakes
|
||||
Description: Lix Package Manager (libflakes)
|
||||
Version: @PACKAGE_VERSION@
|
||||
# dependencies on boost is omitted since it is optional (only required by some headers)
|
||||
Requires: lix-base lix-util lix-store lix-fetchers @BOEHM_IF_FOUND@
|
||||
Libs: -L${libdir} -llixflakes
|
||||
@@ -0,0 +1,157 @@
|
||||
libflakes_generated_headers = []
|
||||
|
||||
subdir('expr')
|
||||
|
||||
# libflakes_setting_definitions = files(
|
||||
# # keep-sorted start
|
||||
# # keep-sorted end
|
||||
# )
|
||||
# libflakes_settings_header = custom_target(
|
||||
# command : [
|
||||
# python.full_path(),
|
||||
# '@SOURCE_ROOT@/lix/code-generation/build_settings.py',
|
||||
# '--kernel', host_machine.system(),
|
||||
# '--header', '@OUTPUT@',
|
||||
# '--experimental-features', '@SOURCE_ROOT@/lix/libutil/experimental-features',
|
||||
# '@INPUT@',
|
||||
# ],
|
||||
# input : libflakes_setting_definitions,
|
||||
# output : 'libflakes-settings.gen.inc',
|
||||
# install : true,
|
||||
# install_dir : includedir / 'lix/libflakes',
|
||||
# )
|
||||
|
||||
builtin_definitions = files(
|
||||
# keep-sorted start
|
||||
'builtins/flakeRefToString.md',
|
||||
'builtins/getFlake.md',
|
||||
'builtins/parseFlakeRef.md',
|
||||
# keep-sorted end
|
||||
)
|
||||
builtins_gen = custom_target(
|
||||
command : [
|
||||
python.full_path(),
|
||||
'@SOURCE_ROOT@/lix/code-generation/build_builtins.py',
|
||||
'--header', '@OUTPUT0@',
|
||||
'--docs', '@OUTPUT1@',
|
||||
'--experimental-features', '@SOURCE_ROOT@/lix/libutil/experimental-features',
|
||||
'@INPUT@'
|
||||
],
|
||||
input : builtin_definitions,
|
||||
output : [
|
||||
'register-builtins.gen.inc',
|
||||
'builtins.md',
|
||||
],
|
||||
)
|
||||
register_builtins_header = builtins_gen[0]
|
||||
builtins_md = builtins_gen[1]
|
||||
|
||||
libflakes_sources = files(
|
||||
# keep-sorted start
|
||||
'expr/config.cc',
|
||||
'expr/flake.cc',
|
||||
'expr/flakeref.cc',
|
||||
'expr/lockfile.cc',
|
||||
'init.cc',
|
||||
# keep-sorted end
|
||||
)
|
||||
|
||||
libflakes_headers = files(
|
||||
# keep-sorted start
|
||||
'expr/flake.hh',
|
||||
'expr/flakeref.hh',
|
||||
'expr/lockfile.hh',
|
||||
'init.hh'
|
||||
# keep-sorted end
|
||||
)
|
||||
|
||||
dependencies = [
|
||||
liblixutil,
|
||||
liblixstore,
|
||||
liblixfetchers,
|
||||
liblixexpr,
|
||||
boehm,
|
||||
boost,
|
||||
kj,
|
||||
nlohmann_json,
|
||||
toml11,
|
||||
]
|
||||
|
||||
libflakes_temp = library(
|
||||
is_static ? 'lixflakes_temp' : 'lixflakes',
|
||||
libflakes_sources,
|
||||
# libflakes_settings_header,
|
||||
libflakes_generated_headers,
|
||||
register_builtins_header,
|
||||
dependencies : dependencies,
|
||||
# for shared.hh
|
||||
include_directories : [
|
||||
'../libmain',
|
||||
],
|
||||
cpp_pch : cpp_pch,
|
||||
install : not is_static,
|
||||
# FIXME(Qyriad): is this right?
|
||||
install_rpath : libdir,
|
||||
)
|
||||
# FIXME: remove when https://git.lix.systems/lix-project/lix/issues/359 is fixed.
|
||||
# FIXME: replace by prelink when https://github.com/mesonbuild/meson/pull/14846 is widely available.
|
||||
if is_static
|
||||
libflakes_prelink = custom_target(
|
||||
'lixflakes-prelink',
|
||||
output : 'lixflakes-prelink.o',
|
||||
input : libflakes_temp,
|
||||
command : [
|
||||
cxx.cmd_array(),
|
||||
'-r',
|
||||
'-o',
|
||||
'@OUTPUT@',
|
||||
is_darwin ? '-Wl,-force_load' : '-Wl,--whole-archive',
|
||||
'@INPUT@',
|
||||
],
|
||||
)
|
||||
libflakes = library(
|
||||
'lixflakes',
|
||||
[libflakes_prelink],
|
||||
dependencies : dependencies,
|
||||
install : true,
|
||||
)
|
||||
else
|
||||
libflakes = libflakes_temp
|
||||
endif
|
||||
|
||||
install_headers(
|
||||
libflakes_headers,
|
||||
subdir : 'lix/libflakes',
|
||||
preserve_path : true,
|
||||
)
|
||||
|
||||
liblixflakes = declare_dependency(
|
||||
include_directories : include_directories('../..'),
|
||||
# sources : libflakes_settings_header,
|
||||
dependencies : [
|
||||
liblixutil,
|
||||
liblixexpr,
|
||||
liblixfetchers,
|
||||
boehm,
|
||||
boost,
|
||||
kj,
|
||||
],
|
||||
link_with : libflakes,
|
||||
)
|
||||
|
||||
meson.override_dependency('lix-flakes', liblixflakes)
|
||||
|
||||
# FIXME: not using the pkg-config module because it creates way too many deps
|
||||
# while meson migration is in progress, and we want to not include boost here
|
||||
configure_file(
|
||||
input : 'lix-flakes.pc.in',
|
||||
output : 'lix-flakes.pc',
|
||||
install_dir : libdir / 'pkgconfig',
|
||||
configuration : {
|
||||
'prefix' : prefix,
|
||||
'libdir' : libdir,
|
||||
'includedir' : includedir,
|
||||
'PACKAGE_VERSION' : meson.project_version(),
|
||||
'BOEHM_IF_FOUND' : boehm.found() ? 'bdw-gc' : '',
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
extern "C" void nix_plugin_entry()
|
||||
{
|
||||
// 1. register an allowed prefix for NIX_PATH parsing
|
||||
// 2. register a search path resolver
|
||||
}
|
||||
@@ -22,6 +22,8 @@ subdir('libstore')
|
||||
subdir('libfetchers')
|
||||
# libexpr depends on all of the above
|
||||
subdir('libexpr')
|
||||
# libflakes depends on all of the above
|
||||
subdir('libflakes')
|
||||
# libmain depends on libutil and libstore
|
||||
subdir('libmain')
|
||||
# libcmd depends on everything
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/eval-inline.hh" // IWYU pragma: keep
|
||||
#include "lix/libexpr/eval-settings.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libexpr/get-drvs.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libstore/derivations.hh"
|
||||
|
||||
@@ -172,6 +172,7 @@ nix = executable(
|
||||
liblixstore,
|
||||
liblixfetchers,
|
||||
liblixexpr,
|
||||
liblixflakes,
|
||||
liblixmain,
|
||||
liblixcmd,
|
||||
boehm,
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include "lix/libstore/derivations.hh"
|
||||
#include "lix/libutil/archive.hh"
|
||||
#include "lix/libstore/builtins/buildenv.hh"
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "lix/libutil/regex.hh"
|
||||
#include "user-env.hh"
|
||||
#include "lix/libstore/profiles.hh"
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
#include "lix/libmain/common-args.hh"
|
||||
#include "lix/libmain/shared.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/flake/flake.hh"
|
||||
#include "lix/libflakes/expr/flake.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libutil/url-parts.hh"
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "lix/libexpr/flake/flakeref.hh"
|
||||
#include "lix/libflakes/expr/flakeref.hh"
|
||||
#include "tests/libexpr.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
class FlakeRefTest : public LibExprTest {};
|
||||
|
||||
|
||||
/* ----------- tests for flake/flakeref.hh --------------------------------------------------*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* to_string
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(to_string, doesntReencodeUrl) {
|
||||
TEST_F(FlakeRefTest, doesntReencodeUrl) {
|
||||
auto s = "http://localhost:8181/test/+3d.tar.gz";
|
||||
auto flakeref = parseFlakeRef(s);
|
||||
auto parsed = flakeref.to_string();
|
||||
+36
-1
@@ -207,7 +207,6 @@ libexpr_tests_sources = files(
|
||||
'libexpr/attr-path.cc',
|
||||
'libexpr/derived-path.cc',
|
||||
'libexpr/error_traces.cc',
|
||||
'libexpr/flakeref.cc',
|
||||
'libexpr/json.cc',
|
||||
'libexpr/primops.cc',
|
||||
'libexpr/search-path.cc',
|
||||
@@ -247,6 +246,42 @@ test(
|
||||
verbose : false,
|
||||
)
|
||||
|
||||
libflakes_tests_sources = files(
|
||||
'libflakes/flakeref.cc',
|
||||
)
|
||||
|
||||
libflakes_tester = executable(
|
||||
'liblixflakes-tests',
|
||||
libflakes_tests_sources,
|
||||
dependencies : [
|
||||
libasanoptions,
|
||||
liblixexpr_test_support,
|
||||
liblixstore_test_support,
|
||||
liblixstore,
|
||||
liblixutil,
|
||||
liblixexpr,
|
||||
liblixfetchers,
|
||||
liblixflakes,
|
||||
rapidcheck,
|
||||
gtest,
|
||||
nlohmann_json,
|
||||
kj
|
||||
],
|
||||
cpp_pch : cpp_pch
|
||||
)
|
||||
|
||||
test(
|
||||
'libflakes-unit-tests',
|
||||
libflakes_tester,
|
||||
args : tests_args,
|
||||
env : default_test_env + {
|
||||
'_NIX_TEST_UNIT_DATA': meson.project_source_root() / 'tests/unit/libflakes/data',
|
||||
},
|
||||
suite : 'check',
|
||||
protocol : 'gtest',
|
||||
verbose : false,
|
||||
)
|
||||
|
||||
libcmd_tester = executable(
|
||||
'liblixcmd-tests',
|
||||
files('libcmd/args.cc'),
|
||||
|
||||
Reference in New Issue
Block a user