forked from lix-project/lix
Compare commits
7 commits
c2fd44e9d7
...
3dbfdfcced
Author | SHA1 | Date | |
---|---|---|---|
alois31 | 3dbfdfcced | ||
alois31 | d34c683819 | ||
alois31 | 4202552cce | ||
alois31 | fa92f41a18 | ||
Quantum Jump | 6e0ca02425 | ||
Qyriad | accfd8aa9d | ||
alois31 | f5ff70d7f3 |
|
@ -96,6 +96,10 @@ puck:
|
|||
forgejo: puck
|
||||
github: puckipedia
|
||||
|
||||
quantumjump:
|
||||
display_name: Quantum Jump
|
||||
github: QuantumBJump
|
||||
|
||||
r-vdp:
|
||||
github: r-vdp
|
||||
|
||||
|
|
29
doc/manual/rl-next/fix-gc-dry-run.md
Normal file
29
doc/manual/rl-next/fix-gc-dry-run.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
synopsis: Fix nix-collect-garbage --dry-run
|
||||
issues: [fj#432]
|
||||
cls: [1566]
|
||||
category: Fixes
|
||||
credits: [quantumjump]
|
||||
---
|
||||
|
||||
`nix-collect-garbage --dry-run` did not previously give any output - it simply
|
||||
exited without even checking to see what paths would be deleted.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
$
|
||||
```
|
||||
|
||||
We updated the behaviour of the flag such that instead it prints out how many
|
||||
paths it *would* delete, but doesn't actually delete them.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
finding garbage collector roots...
|
||||
determining live/dead paths...
|
||||
...
|
||||
<nix store paths>
|
||||
...
|
||||
2670 store paths deleted, 0.00MiB freed
|
||||
$
|
||||
```
|
|
@ -45,7 +45,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat
|
|||
}
|
||||
|
||||
|
||||
std::string DrvInfo::queryName() const
|
||||
std::string DrvInfo::queryName()
|
||||
{
|
||||
if (name == "" && attrs) {
|
||||
auto i = attrs->find(state->sName);
|
||||
|
@ -56,7 +56,7 @@ std::string DrvInfo::queryName() const
|
|||
}
|
||||
|
||||
|
||||
std::string DrvInfo::querySystem() const
|
||||
std::string DrvInfo::querySystem()
|
||||
{
|
||||
if (system == "" && attrs) {
|
||||
auto i = attrs->find(state->sSystem);
|
||||
|
@ -66,7 +66,7 @@ std::string DrvInfo::querySystem() const
|
|||
}
|
||||
|
||||
|
||||
std::optional<StorePath> DrvInfo::queryDrvPath() const
|
||||
std::optional<StorePath> DrvInfo::queryDrvPath()
|
||||
{
|
||||
if (!drvPath && attrs) {
|
||||
Bindings::iterator i = attrs->find(state->sDrvPath);
|
||||
|
@ -80,7 +80,7 @@ std::optional<StorePath> DrvInfo::queryDrvPath() const
|
|||
}
|
||||
|
||||
|
||||
StorePath DrvInfo::requireDrvPath() const
|
||||
StorePath DrvInfo::requireDrvPath()
|
||||
{
|
||||
if (auto drvPath = queryDrvPath())
|
||||
return *drvPath;
|
||||
|
@ -88,7 +88,7 @@ StorePath DrvInfo::requireDrvPath() const
|
|||
}
|
||||
|
||||
|
||||
StorePath DrvInfo::queryOutPath() const
|
||||
StorePath DrvInfo::queryOutPath()
|
||||
{
|
||||
if (!outPath && attrs) {
|
||||
Bindings::iterator i = attrs->find(state->sOutPath);
|
||||
|
@ -164,7 +164,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
|
|||
}
|
||||
|
||||
|
||||
std::string DrvInfo::queryOutputName() const
|
||||
std::string DrvInfo::queryOutputName()
|
||||
{
|
||||
if (outputName == "" && attrs) {
|
||||
Bindings::iterator i = attrs->find(state->sOutputName);
|
||||
|
|
|
@ -19,11 +19,11 @@ public:
|
|||
private:
|
||||
EvalState * state;
|
||||
|
||||
mutable std::string name;
|
||||
mutable std::string system;
|
||||
mutable std::optional<std::optional<StorePath>> drvPath;
|
||||
mutable std::optional<StorePath> outPath;
|
||||
mutable std::string outputName;
|
||||
std::string name;
|
||||
std::string system;
|
||||
std::optional<std::optional<StorePath>> drvPath;
|
||||
std::optional<StorePath> outPath;
|
||||
std::string outputName;
|
||||
Outputs outputs;
|
||||
|
||||
/**
|
||||
|
@ -47,12 +47,12 @@ public:
|
|||
DrvInfo(EvalState & state, std::string attrPath, Bindings * attrs);
|
||||
DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPathWithOutputs);
|
||||
|
||||
std::string queryName() const;
|
||||
std::string querySystem() const;
|
||||
std::optional<StorePath> queryDrvPath() const;
|
||||
StorePath requireDrvPath() const;
|
||||
StorePath queryOutPath() const;
|
||||
std::string queryOutputName() const;
|
||||
std::string queryName();
|
||||
std::string querySystem();
|
||||
std::optional<StorePath> queryDrvPath();
|
||||
StorePath requireDrvPath();
|
||||
StorePath queryOutPath();
|
||||
std::string queryOutputName();
|
||||
/**
|
||||
* Return the unordered map of output names to (optional) output paths.
|
||||
* The "outputs to install" are determined by `meta.outputsToInstall`.
|
||||
|
|
|
@ -356,7 +356,7 @@ std::chrono::milliseconds ProgressBar::draw(State & state, const std::optional<s
|
|||
line += "]";
|
||||
}
|
||||
if (printMultiline && !line.empty()) {
|
||||
writeToStderr(filterANSIEscapes(line, false, width) + "\n");
|
||||
writeToStderr(filterANSIEscapes(line, false, width) + ANSI_NORMAL "\n");
|
||||
state.lastLines++;
|
||||
}
|
||||
|
||||
|
@ -398,7 +398,7 @@ std::chrono::milliseconds ProgressBar::draw(State & state, const std::optional<s
|
|||
|
||||
if (printMultiline) {
|
||||
if (state.lastLines < (height -1)) {
|
||||
writeToStderr(filterANSIEscapes(activity_line, false, width) + "\n");
|
||||
writeToStderr(filterANSIEscapes(activity_line, false, width) + ANSI_NORMAL "\n");
|
||||
state.lastLines++;
|
||||
} else moreActivities++;
|
||||
}
|
||||
|
|
|
@ -89,12 +89,21 @@ static int main_nix_collect_garbage(int argc, char * * argv)
|
|||
|
||||
// Run the actual garbage collector.
|
||||
if (!dryRun) {
|
||||
options.action = GCOptions::gcDeleteDead;
|
||||
} else {
|
||||
options.action = GCOptions::gcReturnDead;
|
||||
}
|
||||
auto store = openStore();
|
||||
auto & gcStore = require<GcStore>(*store);
|
||||
options.action = GCOptions::gcDeleteDead;
|
||||
GCResults results;
|
||||
PrintFreed freed(true, results);
|
||||
gcStore.collectGarbage(options, results);
|
||||
|
||||
if (dryRun) {
|
||||
// Only print results for dry run; when !dryRun, paths will be printed as they're deleted.
|
||||
for (auto & i : results.paths) {
|
||||
printInfo("%s", i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -236,10 +236,10 @@ static void checkSelectorUse(DrvNames & selectors)
|
|||
|
||||
namespace {
|
||||
|
||||
std::set<std::string> searchByPrefix(const DrvInfos & allElems, std::string_view prefix) {
|
||||
std::set<std::string> searchByPrefix(DrvInfos & allElems, std::string_view prefix) {
|
||||
constexpr std::size_t maxResults = 3;
|
||||
std::set<std::string> result;
|
||||
for (const auto & drvInfo : allElems) {
|
||||
for (auto & drvInfo : allElems) {
|
||||
const auto drvName = DrvName { drvInfo.queryName() };
|
||||
if (drvName.name.starts_with(prefix)) {
|
||||
result.emplace(drvName.name);
|
||||
|
@ -319,7 +319,7 @@ std::vector<Match> pickNewestOnly(EvalState & state, std::vector<Match> matches)
|
|||
|
||||
} // end namespace
|
||||
|
||||
static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
|
||||
static DrvInfos filterBySelector(EvalState & state, DrvInfos & allElems,
|
||||
const Strings & args, bool newestOnly)
|
||||
{
|
||||
DrvNames selectors = drvNamesFromArgs(args);
|
||||
|
@ -331,7 +331,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
|
|||
|
||||
for (auto & selector : selectors) {
|
||||
std::vector<Match> matches;
|
||||
for (const auto & [index, drvInfo] : enumerate(allElems)) {
|
||||
for (auto && [index, drvInfo] : enumerate(allElems)) {
|
||||
const auto drvName = DrvName { drvInfo.queryName() };
|
||||
if (selector.matches(drvName)) {
|
||||
++selector.hits;
|
||||
|
@ -457,9 +457,12 @@ static void queryInstSources(EvalState & state,
|
|||
user environment. These are then filtered as in the
|
||||
`srcNixExprDrvs' case. */
|
||||
case srcProfile: {
|
||||
elems = filterBySelector(state,
|
||||
queryInstalled(state, instSource.profile),
|
||||
args, newestOnly);
|
||||
auto installed = queryInstalled(state, instSource.profile);
|
||||
elems = filterBySelector(
|
||||
state,
|
||||
installed,
|
||||
args, newestOnly
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -838,7 +841,7 @@ static bool cmpChars(char a, char b)
|
|||
}
|
||||
|
||||
|
||||
static bool cmpElemByName(const DrvInfo & a, const DrvInfo & b)
|
||||
static bool cmpElemByName(DrvInfo & a, DrvInfo & b)
|
||||
{
|
||||
auto a_name = a.queryName();
|
||||
auto b_name = b.queryName();
|
||||
|
@ -891,7 +894,7 @@ void printTable(Table & table)
|
|||
typedef enum { cvLess, cvEqual, cvGreater, cvUnavail } VersionDiff;
|
||||
|
||||
static VersionDiff compareVersionAgainstSet(
|
||||
const DrvInfo & elem, const DrvInfos & elems, std::string & version)
|
||||
DrvInfo & elem, DrvInfos & elems, std::string & version)
|
||||
{
|
||||
DrvName name(elem.queryName());
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ functional_tests_scripts = [
|
|||
'flakes/flake-in-submodule.sh',
|
||||
'gc.sh',
|
||||
'nix-collect-garbage-d.sh',
|
||||
'nix-collect-garbage-dry-run.sh',
|
||||
'remote-store.sh',
|
||||
'legacy-ssh-store.sh',
|
||||
'lang.sh',
|
||||
|
|
40
tests/functional/nix-collect-garbage-dry-run.sh
Normal file
40
tests/functional/nix-collect-garbage-dry-run.sh
Normal file
|
@ -0,0 +1,40 @@
|
|||
source common.sh
|
||||
|
||||
clearStore
|
||||
|
||||
## Test `nix-collect-garbage --dry-run`
|
||||
|
||||
|
||||
testCollectGarbageDryRun () {
|
||||
clearProfiles
|
||||
# Install then uninstall a package
|
||||
# This should leave packages ready to be garbage collected.
|
||||
nix-env -f ./user-envs.nix -i foo-1.0
|
||||
nix-env -f ./user-envs.nix -e foo-1.0
|
||||
|
||||
|
||||
nix-env --delete-generations old
|
||||
[[ $(nix-store --gc --print-dead | wc -l) -eq 7 ]]
|
||||
|
||||
nix-collect-garbage --dry-run
|
||||
[[ $(nix-store --gc --print-dead | wc -l) -eq 7 ]]
|
||||
|
||||
}
|
||||
|
||||
testCollectGarbageDryRun
|
||||
|
||||
# Run the same test, but forcing the profiles an arbitrary location.
|
||||
rm ~/.nix-profile
|
||||
ln -s $TEST_ROOT/blah ~/.nix-profile
|
||||
testCollectGarbageDryRun
|
||||
|
||||
# Run the same test, but forcing the profiles at their legacy location under
|
||||
# /nix/var/nix.
|
||||
#
|
||||
# Note that we *don't* use the default profile; `nix-collect-garbage` will
|
||||
# need to check the legacy conditional unconditionally not just follow
|
||||
# `~/.nix-profile` to pass this test.
|
||||
#
|
||||
# Regression test for #8294
|
||||
rm ~/.nix-profile
|
||||
testCollectGarbageDryRun --profile "$NIX_STATE_DIR/profiles/per-user/me"
|
Loading…
Reference in a new issue