Skip to content
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
46 changes: 37 additions & 9 deletions src/libcmd/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "nix/cmd/command.hh"
#include "nix/cmd/legacy.hh"
#include "nix/cmd/markdown.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-fs-store.hh"
#include "nix/store/derivations.hh"
Expand Down Expand Up @@ -63,6 +64,25 @@ void NixMultiCommand::run()
command->second->run();
}

StoreConfigCommand::StoreConfigCommand() {}

ref<StoreConfig> StoreConfigCommand::getStoreConfig()
{
if (!_storeConfig)
_storeConfig = createStoreConfig();
return ref<StoreConfig>(_storeConfig);
}

ref<StoreConfig> StoreConfigCommand::createStoreConfig()
{
return resolveStoreConfig(StoreReference::parse(settings.storeUri.get()));
}

void StoreConfigCommand::run()
{
run(getStoreConfig());
}

StoreCommand::StoreCommand() {}

ref<Store> StoreCommand::getStore()
Expand All @@ -74,12 +94,20 @@ ref<Store> StoreCommand::getStore()

ref<Store> StoreCommand::createStore()
{
return openStore();
auto store = getStoreConfig()->openStore();
store->init();
return store;
}

void StoreCommand::run()
void StoreCommand::run(ref<StoreConfig> storeConfig)
{
run(getStore());
// We can either efficiently implement getStore/createStore with memoization,
// or use the StoreConfig passed in run.
// It's more efficient to memoize, especially since there are some direct users
// of getStore. The StoreConfig in both cases should be the same, though.
auto store = getStore();
assert(&*storeConfig == &store->config);
run(std::move(store));
}

CopyCommand::CopyCommand()
Expand All @@ -99,9 +127,9 @@ CopyCommand::CopyCommand()
});
}

ref<Store> CopyCommand::createStore()
ref<StoreConfig> CopyCommand::createStoreConfig()
{
return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri);
return srcUri.empty() ? StoreCommand::createStoreConfig() : resolveStoreConfig(StoreReference::parse(srcUri));
}

ref<Store> CopyCommand::getDstStore()
Expand Down Expand Up @@ -257,18 +285,18 @@ MixProfile::MixProfile()
});
}

void MixProfile::updateProfile(const StorePath & storePath)
void MixProfile::updateProfile(Store & store_, const StorePath & storePath)
{
if (!profile)
return;
auto store = getDstStore().dynamic_pointer_cast<LocalFSStore>();
auto * store = dynamic_cast<LocalFSStore *>(&store_);
if (!store)
throw Error("'--profile' is not supported for this Nix store");
auto profile2 = absPath(*profile);
switchLink(profile2, createGeneration(*store, profile2, storePath));
}

void MixProfile::updateProfile(const BuiltPaths & buildables)
void MixProfile::updateProfile(Store & store, const BuiltPaths & buildables)
{
if (!profile)
return;
Expand All @@ -292,7 +320,7 @@ void MixProfile::updateProfile(const BuiltPaths & buildables)
throw UsageError(
"'--profile' requires that the arguments produce a single store path, but there are %d", result.size());

updateProfile(result[0]);
updateProfile(store, result[0]);
}

MixDefaultProfile::MixDefaultProfile()
Expand Down
45 changes: 30 additions & 15 deletions src/libcmd/include/nix/cmd/command.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,42 @@ struct NixMultiCommand : MultiCommand, virtual Command
#pragma GCC diagnostic ignored "-Woverloaded-virtual"

/**
* A command that requires a \ref Store "Nix store".
* A command that requires a \ref StoreConfig store configuration.
*/
struct StoreCommand : virtual Command
struct StoreConfigCommand : virtual Command
{
StoreCommand();
StoreConfigCommand();
void run() override;

/**
* Return the default Nix store.
* Return the default Nix store configuration.
*/
ref<Store> getStore();
ref<StoreConfig> getStoreConfig();

virtual ref<StoreConfig> createStoreConfig();
/**
* Return the destination Nix store.
* Main entry point, with a `StoreConfig` provided
*/
virtual ref<Store> getDstStore()
{
return getStore();
}
virtual void run(ref<StoreConfig>) = 0;

private:
std::shared_ptr<StoreConfig> _storeConfig;
};

/**
* A command that requires a \ref Store "Nix store".
*/
struct StoreCommand : virtual StoreConfigCommand
{
StoreCommand();
void run(ref<StoreConfig>) override;

/**
* Return the default Nix store.
*/
ref<Store> getStore();

virtual ref<Store> createStore();
ref<Store> createStore();
/**
* Main entry point, with a `Store` provided
*/
Expand All @@ -81,9 +96,9 @@ struct CopyCommand : virtual StoreCommand

CopyCommand();

ref<Store> createStore() override;
ref<StoreConfig> createStoreConfig() override;

ref<Store> getDstStore() override;
ref<Store> getDstStore();
};

/**
Expand Down Expand Up @@ -315,11 +330,11 @@ struct MixProfile : virtual StoreCommand
MixProfile();

/* If 'profile' is set, make it point at 'storePath'. */
void updateProfile(const StorePath & storePath);
void updateProfile(Store & store, const StorePath & storePath);

/* If 'profile' is set, make it point at the store path produced
by 'buildables'. */
void updateProfile(const BuiltPaths & buildables);
void updateProfile(Store & store, const BuiltPaths & buildables);
};

struct MixDefaultProfile : MixProfile
Expand Down
2 changes: 1 addition & 1 deletion src/nix/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ struct CmdBuild : InstallablesCommand, MixOutLinkByDefault, MixDryRun, MixJSON,
BuiltPaths buildables2;
for (auto & b : buildables)
buildables2.push_back(b.path);
updateProfile(buildables2);
updateProfile(*store, buildables2);
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/nix/copy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand, MixProfile, Mix

copyPaths(*srcStore, *dstStore, stuffToCopy, NoRepair, checkSigs, substitute);

updateProfile(rootPaths);
updateProfile(*dstStore, rootPaths);

if (outLink) {
if (auto store2 = dstStore.dynamic_pointer_cast<LocalFSStore>())
Expand Down
2 changes: 1 addition & 1 deletion src/nix/develop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ struct Common : InstallableCommand, MixProfile
{
auto shellOutPath = getShellOutPath(store, installable);

updateProfile(shellOutPath);
updateProfile(*store, shellOutPath);

debug("reading environment file '%s'", store->printStorePath(shellOutPath));

Expand Down
6 changes: 3 additions & 3 deletions src/nix/profile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ struct CmdProfileAdd : InstallablesCommand, MixDefaultProfile
}

try {
updateProfile(manifest.build(store));
updateProfile(*store, manifest.build(store));
} catch (BuildEnvFileConflictError & conflictError) {
// FIXME use C++20 std::ranges once macOS has it
// See
Expand Down Expand Up @@ -668,7 +668,7 @@ struct CmdProfileRemove : virtual EvalCommand, MixDefaultProfile, MixProfileElem
auto removedCount = oldManifest.elements.size() - newManifest.elements.size();
printInfo("removed %d packages, kept %d packages", removedCount, newManifest.elements.size());

updateProfile(newManifest.build(store));
updateProfile(*store, newManifest.build(store));
}
};

Expand Down Expand Up @@ -775,7 +775,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
element.updateStorePaths(getEvalStore(), store, builtPaths.find(&*installable)->second.first);
}

updateProfile(manifest.build(store));
updateProfile(*store, manifest.build(store));
}
};

Expand Down
Loading