forked from lix-project/lix
refactor some nix-env and nix profile code into libcmd
Change-Id: Iefc8bbd34b4bc6012175cb3d6e6a8207973bc792
This commit is contained in:
parent
78ce710722
commit
1d00657e9b
100
src/libcmd/cmd-profiles.cc
Normal file
100
src/libcmd/cmd-profiles.cc
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "cmd-profiles.hh"
|
||||
#include "built-path.hh"
|
||||
#include "names.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
namespace nix
|
||||
{
|
||||
DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||
{
|
||||
DrvInfos elems;
|
||||
if (pathExists(userEnv + "/manifest.json"))
|
||||
throw Error("profile '%s' is incompatible with 'nix-env'; please use 'nix profile' instead", userEnv);
|
||||
auto manifestFile = userEnv + "/manifest.nix";
|
||||
if (pathExists(manifestFile)) {
|
||||
Value v;
|
||||
state.evalFile(state.rootPath(CanonPath(manifestFile)), v);
|
||||
Bindings & bindings(*state.allocBindings(0));
|
||||
getDerivations(state, v, "", bindings, elems, false);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
std::string showVersions(const std::set<std::string> & versions)
|
||||
{
|
||||
if (versions.empty()) return "∅";
|
||||
std::set<std::string> versions2;
|
||||
for (auto & version : versions)
|
||||
versions2.insert(version.empty() ? "ε" : version);
|
||||
return concatStringsSep(", ", versions2);
|
||||
}
|
||||
|
||||
bool ProfileElementSource::operator<(const ProfileElementSource & other) const
|
||||
{
|
||||
return std::tuple(originalRef.to_string(), attrPath, outputs)
|
||||
< std::tuple(other.originalRef.to_string(), other.attrPath, other.outputs);
|
||||
}
|
||||
|
||||
std::string ProfileElementSource::to_string() const
|
||||
{
|
||||
return fmt("%s#%s%s", originalRef, attrPath, outputs.to_string());
|
||||
}
|
||||
|
||||
std::string ProfileElement::identifier() const
|
||||
{
|
||||
if (source) {
|
||||
return source->to_string();
|
||||
}
|
||||
StringSet names;
|
||||
for (auto & path : storePaths) {
|
||||
names.insert(DrvName(path.name()).name);
|
||||
}
|
||||
return concatStringsSep(", ", names);
|
||||
}
|
||||
|
||||
std::set<std::string> ProfileElement::toInstallables(Store & store)
|
||||
{
|
||||
if (source) {
|
||||
return {source->to_string()};
|
||||
}
|
||||
StringSet rawPaths;
|
||||
for (auto & path : storePaths) {
|
||||
rawPaths.insert(store.printStorePath(path));
|
||||
}
|
||||
return rawPaths;
|
||||
}
|
||||
|
||||
std::string ProfileElement::versions() const
|
||||
{
|
||||
StringSet versions;
|
||||
for (auto & path : storePaths) {
|
||||
versions.insert(DrvName(path.name()).version);
|
||||
}
|
||||
return showVersions(versions);
|
||||
}
|
||||
|
||||
bool ProfileElement::operator<(const ProfileElement & other) const
|
||||
{
|
||||
return std::tuple(identifier(), storePaths) < std::tuple(other.identifier(), other.storePaths);
|
||||
}
|
||||
|
||||
void ProfileElement::updateStorePaths(
|
||||
ref<Store> evalStore, ref<Store> store, const BuiltPaths & builtPaths
|
||||
)
|
||||
{
|
||||
storePaths.clear();
|
||||
for (auto & buildable : builtPaths) {
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const BuiltPath::Opaque & bo) { storePaths.insert(bo.path); },
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs) {
|
||||
storePaths.insert(output.second);
|
||||
}
|
||||
},
|
||||
},
|
||||
buildable.raw()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
56
src/libcmd/cmd-profiles.hh
Normal file
56
src/libcmd/cmd-profiles.hh
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "built-path.hh"
|
||||
#include "eval.hh"
|
||||
#include "flake/flakeref.hh"
|
||||
#include "get-drvs.hh"
|
||||
#include "types.hh"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace nix
|
||||
{
|
||||
|
||||
struct ProfileElementSource
|
||||
{
|
||||
FlakeRef originalRef;
|
||||
// FIXME: record original attrpath.
|
||||
FlakeRef lockedRef;
|
||||
std::string attrPath;
|
||||
ExtendedOutputsSpec outputs;
|
||||
|
||||
bool operator<(const ProfileElementSource & other) const;
|
||||
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
constexpr int DEFAULT_PRIORITY = 5;
|
||||
|
||||
struct ProfileElement
|
||||
{
|
||||
StorePathSet storePaths;
|
||||
std::optional<ProfileElementSource> source;
|
||||
bool active = true;
|
||||
int priority = DEFAULT_PRIORITY;
|
||||
|
||||
std::string identifier() const;
|
||||
|
||||
/**
|
||||
* Return a string representing an installable corresponding to the current
|
||||
* element, either a flakeref or a plain store path
|
||||
*/
|
||||
std::set<std::string> toInstallables(Store & store);
|
||||
|
||||
std::string versions() const;
|
||||
|
||||
bool operator<(const ProfileElement & other) const;
|
||||
|
||||
void updateStorePaths(ref<Store> evalStore, ref<Store> store, const BuiltPaths & builtPaths);
|
||||
};
|
||||
|
||||
DrvInfos queryInstalled(EvalState & state, const Path & userEnv);
|
||||
std::string showVersions(const std::set<std::string> & versions);
|
||||
|
||||
}
|
|
@ -342,8 +342,6 @@ void completeFlakeRefWithFragment(
|
|||
const Strings & defaultFlakeAttrPaths,
|
||||
std::string_view prefix);
|
||||
|
||||
std::string showVersions(const std::set<std::string> & versions);
|
||||
|
||||
void printClosureDiff(
|
||||
ref<Store> store,
|
||||
const StorePath & beforePath,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
libcmd_sources = files(
|
||||
'built-path.cc',
|
||||
'command-installable-value.cc',
|
||||
'cmd-profiles.cc',
|
||||
'command.cc',
|
||||
'common-eval-args.cc',
|
||||
'editor-for.cc',
|
||||
|
@ -18,6 +19,7 @@ libcmd_sources = files(
|
|||
libcmd_headers = files(
|
||||
'built-path.hh',
|
||||
'command-installable-value.hh',
|
||||
'cmd-profiles.hh',
|
||||
'command.hh',
|
||||
'common-eval-args.hh',
|
||||
'editor-for.hh',
|
||||
|
|
|
@ -16,22 +16,6 @@
|
|||
namespace nix {
|
||||
|
||||
|
||||
DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||
{
|
||||
DrvInfos elems;
|
||||
if (pathExists(userEnv + "/manifest.json"))
|
||||
throw Error("profile '%s' is incompatible with 'nix-env'; please use 'nix profile' instead", userEnv);
|
||||
auto manifestFile = userEnv + "/manifest.nix";
|
||||
if (pathExists(manifestFile)) {
|
||||
Value v;
|
||||
state.evalFile(state.rootPath(CanonPath(manifestFile)), v);
|
||||
Bindings & bindings(*state.allocBindings(0));
|
||||
getDerivations(state, v, "", bindings, elems, false);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||
const Path & profile, bool keepDerivations,
|
||||
const std::string & lockToken)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "command.hh"
|
||||
#include "cmd-profiles.hh"
|
||||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
#include "common-args.hh"
|
||||
|
@ -43,15 +44,6 @@ GroupedPaths getClosureInfo(ref<Store> store, const StorePath & toplevel)
|
|||
return groupedPaths;
|
||||
}
|
||||
|
||||
std::string showVersions(const std::set<std::string> & versions)
|
||||
{
|
||||
if (versions.empty()) return "∅";
|
||||
std::set<std::string> versions2;
|
||||
for (auto & version : versions)
|
||||
versions2.insert(version.empty() ? "ε" : version);
|
||||
return concatStringsSep(", ", versions2);
|
||||
}
|
||||
|
||||
void printClosureDiff(
|
||||
ref<Store> store,
|
||||
const StorePath & beforePath,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "command.hh"
|
||||
#include "cmd-profiles.hh"
|
||||
#include "installable-flake.hh"
|
||||
#include "common-args.hh"
|
||||
#include "shared.hh"
|
||||
|
@ -17,92 +18,6 @@
|
|||
|
||||
using namespace nix;
|
||||
|
||||
struct ProfileElementSource
|
||||
{
|
||||
FlakeRef originalRef;
|
||||
// FIXME: record original attrpath.
|
||||
FlakeRef lockedRef;
|
||||
std::string attrPath;
|
||||
ExtendedOutputsSpec outputs;
|
||||
|
||||
bool operator < (const ProfileElementSource & other) const
|
||||
{
|
||||
return
|
||||
std::tuple(originalRef.to_string(), attrPath, outputs) <
|
||||
std::tuple(other.originalRef.to_string(), other.attrPath, other.outputs);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return fmt("%s#%s%s", originalRef, attrPath, outputs.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
const int defaultPriority = 5;
|
||||
|
||||
struct ProfileElement
|
||||
{
|
||||
StorePathSet storePaths;
|
||||
std::optional<ProfileElementSource> source;
|
||||
bool active = true;
|
||||
int priority = defaultPriority;
|
||||
|
||||
std::string identifier() const
|
||||
{
|
||||
if (source)
|
||||
return source->to_string();
|
||||
StringSet names;
|
||||
for (auto & path : storePaths)
|
||||
names.insert(DrvName(path.name()).name);
|
||||
return concatStringsSep(", ", names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing an installable corresponding to the current
|
||||
* element, either a flakeref or a plain store path
|
||||
*/
|
||||
std::set<std::string> toInstallables(Store & store)
|
||||
{
|
||||
if (source)
|
||||
return {source->to_string()};
|
||||
StringSet rawPaths;
|
||||
for (auto & path : storePaths)
|
||||
rawPaths.insert(store.printStorePath(path));
|
||||
return rawPaths;
|
||||
}
|
||||
|
||||
std::string versions() const
|
||||
{
|
||||
StringSet versions;
|
||||
for (auto & path : storePaths)
|
||||
versions.insert(DrvName(path.name()).version);
|
||||
return showVersions(versions);
|
||||
}
|
||||
|
||||
bool operator < (const ProfileElement & other) const
|
||||
{
|
||||
return std::tuple(identifier(), storePaths) < std::tuple(other.identifier(), other.storePaths);
|
||||
}
|
||||
|
||||
void updateStorePaths(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
const BuiltPaths & builtPaths)
|
||||
{
|
||||
storePaths.clear();
|
||||
for (auto & buildable : builtPaths) {
|
||||
std::visit(overloaded {
|
||||
[&](const BuiltPath::Opaque & bo) {
|
||||
storePaths.insert(bo.path);
|
||||
},
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs)
|
||||
storePaths.insert(output.second);
|
||||
},
|
||||
}, buildable.raw());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ProfileManifest
|
||||
{
|
||||
|
@ -361,8 +276,8 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
|||
: ({
|
||||
auto * info2 = dynamic_cast<ExtraPathInfoValue *>(&*info);
|
||||
info2
|
||||
? info2->value.priority.value_or(defaultPriority)
|
||||
: defaultPriority;
|
||||
? info2->value.priority.value_or(DEFAULT_PRIORITY)
|
||||
: DEFAULT_PRIORITY;
|
||||
});
|
||||
|
||||
element.updateStorePaths(getEvalStore(), store, res);
|
||||
|
|
Loading…
Reference in a new issue