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

nix-collect-garbage: translate to C++ #522

Merged
merged 1 commit into from
Apr 22, 2015
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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ makefiles = \
src/nix-instantiate/local.mk \
src/nix-env/local.mk \
src/nix-daemon/local.mk \
src/nix-collect-garbage/local.mk \
src/download-via-ssh/local.mk \
src/nix-log2xml/local.mk \
src/bsdiff-4.3/local.mk \
Expand Down
1 change: 0 additions & 1 deletion scripts/local.mk
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
nix_bin_scripts := \
$(d)/nix-build \
$(d)/nix-channel \
$(d)/nix-collect-garbage \
$(d)/nix-copy-closure \
$(d)/nix-generate-patches \
$(d)/nix-install-package \
Expand Down
65 changes: 0 additions & 65 deletions scripts/nix-collect-garbage.in

This file was deleted.

7 changes: 7 additions & 0 deletions src/nix-collect-garbage/local.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
programs += nix-collect-garbage

nix-collect-garbage_DIR := $(d)

nix-collect-garbage_SOURCES := $(d)/nix-collect-garbage.cc

nix-collect-garbage_LIBS = libmain libstore libutil libformat
87 changes: 87 additions & 0 deletions src/nix-collect-garbage/nix-collect-garbage.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "hash.hh"
#include "shared.hh"
#include "globals.hh"

#include <iostream>

using namespace nix;

std::string gen = "";
bool dryRun = false;

void runProgramSimple(Path program, const Strings & args)
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't runProgram() work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

runProgram grabs the output, here I just let the child inherit the stdout.

{
checkInterrupt();

/* Fork. */
Pid pid = startProcess([&]() {
Strings args_(args);
args_.push_front(program);
auto cargs = stringsToCharPtrs(args_);

execv(program.c_str(), (char * *) &cargs[0]);

throw SysError(format("executing ‘%1%’") % program);
});

pid.wait(true);
}


/* If `-d' was specified, remove all old generations of all profiles.
* Of course, this makes rollbacks to before this point in time
* impossible. */

void removeOldGenerations(std::string dir)
{
for (auto & i : readDirectory(dir)) {
checkInterrupt();

auto path = dir + "/" + i.name;
auto type = getFileType(path);

if (type == DT_LNK) {
auto link = readLink(path);
if (link.find("link") != string::npos) {
printMsg(lvlInfo, format("removing old generations of profile %1%") % path);

runProgramSimple(settings.nixBinDir + "/nix-env", Strings{"-p", path, "--delete-generations", gen, dryRun ? "--dry-run" : ""});
Copy link
Member

Choose a reason for hiding this comment

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

Rather than calling nix-env, it would be cleaner to factor out opDeleteGenerations() from nix-env.cc into a library function and call it directly. IMHO that's one of the main benefits of rewriting in C++ (being able to call APIs directly rather than going through command line invocations).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not yet confident with doing this, can we accept this in the while as a 1:1 translation?

}
} else if (type == DT_DIR) {
removeOldGenerations(path);
}
}
}

int main(int argc, char * * argv)
{
bool removeOld = false;
Strings extraArgs;

return handleExceptions(argv[0], [&]() {
initNix();

parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help")
showManPage("nix-collect-garbage");
else if (*arg == "--version")
printVersion("nix-collect-garbage");
else if (*arg == "--delete-old" || *arg == "-d") removeOld = true;
else if (*arg == "--delete-older-than") {
removeOld = true;
gen = getArg(*arg, arg, end);
}
else if (*arg == "--dry-run") dryRun = true;
else
extraArgs.push_back(*arg);
return true;
});

auto profilesDir = settings.nixStateDir + "/profiles";
if (removeOld) removeOldGenerations(profilesDir);

// Run the actual garbage collector.
if (!dryRun) runProgramSimple(settings.nixBinDir + "/nix-store", Strings{"--gc"});
Copy link
Member

Choose a reason for hiding this comment

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

Here you can just call store->collectGarbage().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above.

});
}