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

Move value-only methods to InstallableValue #7757

Merged
merged 1 commit into from
Mar 24, 2023
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
11 changes: 11 additions & 0 deletions src/libcmd/command-installable-value.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "command-installable-value.hh"

namespace nix {

void InstallableValueCommand::run(ref<Store> store, ref<Installable> installable)
{
auto installableValue = InstallableValue::require(installable);
run(store, installableValue);
}

}
13 changes: 13 additions & 0 deletions src/libcmd/command-installable-value.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "installable-value.hh"
#include "command.hh"

namespace nix {

struct InstallableValueCommand : InstallableCommand
{
virtual void run(ref<Store> store, ref<InstallableValue> installable) = 0;

void run(ref<Store> store, ref<Installable> installable) override;
};

}
44 changes: 44 additions & 0 deletions src/libcmd/installable-value.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "installable-value.hh"
#include "eval-cache.hh"

namespace nix {

std::vector<ref<eval_cache::AttrCursor>>
InstallableValue::getCursors(EvalState & state)
{
auto evalCache =
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
[&]() { return toValue(state).first; });
return {evalCache->getRoot()};
}

ref<eval_cache::AttrCursor>
InstallableValue::getCursor(EvalState & state)
{
/* Although getCursors should return at least one element, in case it doesn't,
bound check to avoid an undefined behavior for vector[0] */
return getCursors(state).at(0);
}

static UsageError nonValueInstallable(Installable & installable)
{
return UsageError("installable '%s' does not correspond to a Nix language value", installable.what());
}

InstallableValue & InstallableValue::require(Installable & installable)
{
auto * castedInstallable = dynamic_cast<InstallableValue *>(&installable);
if (!castedInstallable)
throw nonValueInstallable(installable);
return *castedInstallable;
}

ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
{
auto castedInstallable = installable.dynamic_pointer_cast<InstallableValue>();
if (!castedInstallable)
throw nonValueInstallable(*installable);
return ref { castedInstallable };
}

}
30 changes: 30 additions & 0 deletions src/libcmd/installable-value.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,41 @@

namespace nix {

struct App
{
std::vector<DerivedPath> context;
Path program;
// FIXME: add args, sandbox settings, metadata, ...
};

struct UnresolvedApp
{
App unresolved;
App resolve(ref<Store> evalStore, ref<Store> store);
};

struct InstallableValue : Installable
{
ref<EvalState> state;

InstallableValue(ref<EvalState> state) : state(state) {}

virtual std::pair<Value *, PosIdx> toValue(EvalState & state) = 0;

/* Get a cursor to each value this Installable could refer to. However
if none exists, throw exception instead of returning empty vector. */
virtual std::vector<ref<eval_cache::AttrCursor>>
getCursors(EvalState & state);

/* Get the first and most preferred cursor this Installable could refer
to, or throw an exception if none exists. */
virtual ref<eval_cache::AttrCursor>
getCursor(EvalState & state);

UnresolvedApp toApp(EvalState & state);

static InstallableValue & require(Installable & installable);
static ref<InstallableValue> require(ref<Installable> installable);
};

}
17 changes: 0 additions & 17 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,23 +364,6 @@ DerivedPathWithInfo Installable::toDerivedPath()
return std::move(buildables[0]);
}

std::vector<ref<eval_cache::AttrCursor>>
Installable::getCursors(EvalState & state)
{
auto evalCache =
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
[&]() { return toValue(state).first; });
return {evalCache->getRoot()};
}

ref<eval_cache::AttrCursor>
Installable::getCursor(EvalState & state)
{
/* Although getCursors should return at least one element, in case it doesn't,
bound check to avoid an undefined behavior for vector[0] */
return getCursors(state).at(0);
}

static StorePath getDeriver(
ref<Store> store,
const Installable & i,
Expand Down
30 changes: 0 additions & 30 deletions src/libcmd/installables.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,6 @@ struct SourceExprCommand;

namespace eval_cache { class EvalCache; class AttrCursor; }

struct App
{
std::vector<DerivedPath> context;
Path program;
// FIXME: add args, sandbox settings, metadata, ...
};

struct UnresolvedApp
{
App unresolved;
App resolve(ref<Store> evalStore, ref<Store> store);
};

enum class Realise {
/* Build the derivation. Postcondition: the
derivation outputs exist. */
Expand Down Expand Up @@ -92,30 +79,13 @@ struct Installable

DerivedPathWithInfo toDerivedPath();

UnresolvedApp toApp(EvalState & state);

virtual std::pair<Value *, PosIdx> toValue(EvalState & state)
{
throw Error("argument '%s' cannot be evaluated", what());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notes: this is the main motivation, remove default implementation of an error


/* Return a value only if this installable is a store path or a
symlink to it. */
virtual std::optional<StorePath> getStorePath()
{
return {};
}

/* Get a cursor to each value this Installable could refer to. However
if none exists, throw exception instead of returning empty vector. */
virtual std::vector<ref<eval_cache::AttrCursor>>
getCursors(EvalState & state);

/* Get the first and most preferred cursor this Installable could refer
to, or throw an exception if none exists. */
virtual ref<eval_cache::AttrCursor>
getCursor(EvalState & state);

virtual FlakeRef nixpkgsFlakeRef() const
{
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
Expand Down
3 changes: 2 additions & 1 deletion src/nix/app.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "installables.hh"
#include "installable-derived-path.hh"
#include "installable-value.hh"
#include "store-api.hh"
#include "eval-inline.hh"
#include "eval-cache.hh"
Expand Down Expand Up @@ -40,7 +41,7 @@ std::string resolveString(
return rewriteStrings(toResolve, rewrites);
}

UnresolvedApp Installable::toApp(EvalState & state)
UnresolvedApp InstallableValue::toApp(EvalState & state)
{
auto cursor = getCursor(state);
auto attrPath = cursor->getAttrPath();
Expand Down
6 changes: 3 additions & 3 deletions src/nix/bundle.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "command.hh"
#include "installable-flake.hh"
#include "command-installable-value.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
Expand All @@ -8,7 +8,7 @@

using namespace nix;

struct CmdBundle : InstallableCommand
struct CmdBundle : InstallableValueCommand
{
std::string bundler = "github:NixOS/bundlers";
std::optional<Path> outLink;
Expand Down Expand Up @@ -70,7 +70,7 @@ struct CmdBundle : InstallableCommand
return res;
}

void run(ref<Store> store, ref<Installable> installable) override
void run(ref<Store> store, ref<InstallableValue> installable) override
{
auto evalState = getEvalState();

Expand Down
6 changes: 3 additions & 3 deletions src/nix/edit.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "command.hh"
#include "command-installable-value.hh"
#include "shared.hh"
#include "eval.hh"
#include "attr-path.hh"
Expand All @@ -9,7 +9,7 @@

using namespace nix;

struct CmdEdit : InstallableCommand
struct CmdEdit : InstallableValueCommand
{
std::string description() override
{
Expand All @@ -25,7 +25,7 @@ struct CmdEdit : InstallableCommand

Category category() override { return catSecondary; }

void run(ref<Store> store, ref<Installable> installable) override
void run(ref<Store> store, ref<InstallableValue> installable) override
{
auto state = getEvalState();

Expand Down
8 changes: 4 additions & 4 deletions src/nix/eval.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "command.hh"
#include "command-installable-value.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
Expand All @@ -11,13 +11,13 @@

using namespace nix;

struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
{
bool raw = false;
std::optional<std::string> apply;
std::optional<Path> writeTo;

CmdEval() : InstallableCommand()
CmdEval() : InstallableValueCommand()
{
addFlag({
.longName = "raw",
Expand Down Expand Up @@ -54,7 +54,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption

Category category() override { return catSecondary; }

void run(ref<Store> store, ref<Installable> installable) override
void run(ref<Store> store, ref<InstallableValue> installable) override
{
if (raw && json)
throw UsageError("--raw and --json are mutually exclusive");
Expand Down
6 changes: 4 additions & 2 deletions src/nix/fmt.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "command.hh"
#include "installable-value.hh"
#include "run.hh"

using namespace nix;
Expand Down Expand Up @@ -31,8 +32,9 @@ struct CmdFmt : SourceExprCommand {
auto evalState = getEvalState();
auto evalStore = getEvalStore();

auto installable = parseInstallable(store, ".");
auto app = installable->toApp(*evalState).resolve(evalStore, store);
auto installable_ = parseInstallable(store, ".");
auto & installable = InstallableValue::require(*installable_);
auto app = installable.toApp(*evalState).resolve(evalStore, store);

Strings programArgs{app.program};

Expand Down
12 changes: 7 additions & 5 deletions src/nix/repl.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "eval.hh"
#include "globals.hh"
#include "command.hh"
#include "installable-value.hh"
#include "repl.hh"

namespace nix {
Expand Down Expand Up @@ -57,19 +58,20 @@ struct CmdRepl : RawInstallablesCommand
auto getValues = [&]()->AbstractNixRepl::AnnotatedValues{
auto installables = parseInstallables(store, rawInstallables);
AbstractNixRepl::AnnotatedValues values;
for (auto & installable: installables){
auto what = installable->what();
for (auto & installable_: installables){
auto & installable = InstallableValue::require(*installable_);
auto what = installable.what();
if (file){
auto [val, pos] = installable->toValue(*state);
auto what = installable->what();
auto [val, pos] = installable.toValue(*state);
auto what = installable.what();
state->forceValue(*val, pos);
auto autoArgs = getAutoArgs(*state);
auto valPost = state->allocValue();
state->autoCallFunction(*autoArgs, *val, *valPost);
state->forceValue(*valPost, pos);
values.push_back( {valPost, what });
} else {
auto [val, pos] = installable->toValue(*state);
auto [val, pos] = installable.toValue(*state);
values.push_back( {val, what} );
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/nix/run.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "run.hh"
#include "command.hh"
#include "command-installable-value.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
Expand Down Expand Up @@ -137,7 +137,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment

static auto rCmdShell = registerCommand<CmdShell>("shell");

struct CmdRun : InstallableCommand
struct CmdRun : InstallableValueCommand
{
using InstallableCommand::run;

Expand Down Expand Up @@ -183,7 +183,7 @@ struct CmdRun : InstallableCommand
return res;
}

void run(ref<Store> store, ref<Installable> installable) override
void run(ref<Store> store, ref<InstallableValue> installable) override
{
auto state = getEvalState();

Expand Down
6 changes: 3 additions & 3 deletions src/nix/search.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "command.hh"
#include "command-installable-value.hh"
#include "globals.hh"
#include "eval.hh"
#include "eval-inline.hh"
Expand All @@ -22,7 +22,7 @@ std::string wrap(std::string prefix, std::string s)
return concatStrings(prefix, s, ANSI_NORMAL);
}

struct CmdSearch : InstallableCommand, MixJSON
struct CmdSearch : InstallableValueCommand, MixJSON
{
std::vector<std::string> res;
std::vector<std::string> excludeRes;
Expand Down Expand Up @@ -61,7 +61,7 @@ struct CmdSearch : InstallableCommand, MixJSON
};
}

void run(ref<Store> store, ref<Installable> installable) override
void run(ref<Store> store, ref<InstallableValue> installable) override
{
settings.readOnlyMode = true;
evalSettings.enableImportFromDerivation.setDefault(false);
Expand Down