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

Stratify ExtraPathInfo along Installable hierarchy #7763

Merged
merged 1 commit into from
Mar 27, 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
2 changes: 1 addition & 1 deletion src/libcmd/command.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "installables.hh"
#include "installable-value.hh"
#include "args.hh"
#include "common-eval-args.hh"
#include "path.hh"
Expand Down
4 changes: 4 additions & 0 deletions src/libcmd/installable-attr-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
.drvPath = drvPath,
.outputs = outputs,
},
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value {
/* FIXME: reconsider backwards compatibility above
so we can fill in this info. */
}),
});

return res;
Expand Down
5 changes: 4 additions & 1 deletion src/libcmd/installable-derived-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ std::string InstallableDerivedPath::what() const

DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths()
{
return {{.path = derivedPath, .info = {} }};
return {{
.path = derivedPath,
.info = make_ref<ExtraPathInfo>(),
}};
}

std::optional<StorePath> InstallableDerivedPath::getStorePath()
Expand Down
26 changes: 16 additions & 10 deletions src/libcmd/installable-flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
}
},
.info = make_ref<ExtraPathInfo>(),
}};
}

Expand All @@ -113,7 +114,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
return {{
.path = DerivedPath::Opaque {
.path = std::move(*storePath),
}
},
.info = make_ref<ExtraPathInfo>(),
}};
} else
throw Error("flake output attribute '%s' evaluates to the string '%s' which is not a store path", attrPath, s);
Expand Down Expand Up @@ -160,13 +162,16 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
},
}, extendedOutputsSpec.raw()),
},
.info = {
.priority = priority,
.originalRef = flakeRef,
.resolvedRef = getLockedFlake()->flake.lockedRef,
.attrPath = attrPath,
.extendedOutputsSpec = extendedOutputsSpec,
}
.info = make_ref<ExtraPathInfoFlake>(
ExtraPathInfoValue::Value {
.priority = priority,
.attrPath = attrPath,
.extendedOutputsSpec = extendedOutputsSpec,
},
ExtraPathInfoFlake::Flake {
.originalRef = flakeRef,
.resolvedRef = getLockedFlake()->flake.lockedRef,
}),
}};
}

Expand Down Expand Up @@ -212,6 +217,7 @@ std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
{
if (!_lockedFlake) {
flake::LockFlags lockFlagsApplyConfig = lockFlags;
// FIXME why this side effect?
lockFlagsApplyConfig.applyNixConfig = true;
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlagsApplyConfig));
}
Expand All @@ -229,7 +235,7 @@ FlakeRef InstallableFlake::nixpkgsFlakeRef() const
}
}

return Installable::nixpkgsFlakeRef();
return InstallableValue::nixpkgsFlakeRef();
}

}
30 changes: 28 additions & 2 deletions src/libcmd/installable-flake.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

namespace nix {

/**
* Extra info about a \ref DerivedPath "derived path" that ultimately
* come from a Flake.
*
* Invariant: every ExtraPathInfo gotten from an InstallableFlake should
* be possible to downcast to an ExtraPathInfoFlake.
*/
struct ExtraPathInfoFlake : ExtraPathInfoValue
{
/**
* Extra struct to get around C++ designated initializer limitations
*/
struct Flake {
FlakeRef originalRef;
FlakeRef resolvedRef;
};

Flake flake;

ExtraPathInfoFlake(Value && v, Flake && f)
: ExtraPathInfoValue(std::move(v)), flake(f)
{ }
};

struct InstallableFlake : InstallableValue
{
FlakeRef flakeRef;
Expand Down Expand Up @@ -33,8 +57,10 @@ struct InstallableFlake : InstallableValue

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

/* Get a cursor to every attrpath in getActualAttrPaths()
that exists. However if none exists, throw an exception. */
/**
* Get a cursor to every attrpath in getActualAttrPaths() that
* exists. However if none exists, throw an exception.
*/
std::vector<ref<eval_cache::AttrCursor>>
getCursors(EvalState & state) override;

Expand Down
71 changes: 67 additions & 4 deletions src/libcmd/installable-value.hh
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#pragma once

#include "installables.hh"
#include "flake/flake.hh"

namespace nix {

struct DrvInfo;
struct SourceExprCommand;

namespace eval_cache { class EvalCache; class AttrCursor; }

struct App
{
std::vector<DerivedPath> context;
Expand All @@ -17,26 +23,83 @@ struct UnresolvedApp
App resolve(ref<Store> evalStore, ref<Store> store);
};

/**
* Extra info about a \ref DerivedPath "derived path" that ultimately
* come from a Nix language value.
*
* Invariant: every ExtraPathInfo gotten from an InstallableValue should
* be possible to downcast to an ExtraPathInfoValue.
*/
struct ExtraPathInfoValue : ExtraPathInfo
{
/**
* Extra struct to get around C++ designated initializer limitations
*/
struct Value {
/**
* An optional priority for use with "build envs". See Package
*/
std::optional<NixInt> priority;

/**
* The attribute path associated with this value. The idea is
* that an installable referring to a value typically refers to
* a larger value, from which we project a smaller value out
* with this.
*/
std::string attrPath;

/**
* \todo merge with DerivedPath's 'outputs' field?
*/
ExtendedOutputsSpec extendedOutputsSpec;
};

Value value;

ExtraPathInfoValue(Value && v)
: value(v)
{ }

virtual ~ExtraPathInfoValue() = default;
};

/**
* An Installable which corresponds a Nix langauge value, in addition to
* a collection of \ref DerivedPath "derived paths".
*/
struct InstallableValue : Installable
{
ref<EvalState> state;

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

virtual ~InstallableValue() { }

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

virtual FlakeRef nixpkgsFlakeRef() const
{
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
}

static InstallableValue & require(Installable & installable);
static ref<InstallableValue> require(ref<Installable> installable);
};
Expand Down
2 changes: 1 addition & 1 deletion src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build

struct Aux
{
ExtraPathInfo info;
ref<ExtraPathInfo> info;
ref<Installable> installable;
};

Expand Down
Loading