From 692b562342ac7ead43ef06497f6a8b4b6e724ae5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 23 Jun 2003 14:40:49 +0000 Subject: [PATCH] * `nix --delete' command. --- src/nix.cc | 14 +++++++++++++- src/test.cc | 4 +++- src/util.cc | 29 +++++++++++++++++++++++++++++ src/util.hh | 5 +++++ src/values.cc | 12 ++++++++++++ src/values.hh | 4 ++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/nix.cc b/src/nix.cc index bd35658109..9b21f0379c 100644 --- a/src/nix.cc +++ b/src/nix.cc @@ -112,8 +112,20 @@ static void opEvaluate(Strings opFlags, Strings opArgs) static void opDelete(Strings opFlags, Strings opArgs) { getArgType(opFlags); + if (!opFlags.empty()) throw UsageError("unknown flag"); - cerr << "delete!\n"; + for (Strings::iterator it = opArgs.begin(); + it != opArgs.end(); it++) + { + Hash hash; + if (argType == atpHash) + hash = parseHash(*it); + else if (argType == atpName) + throw Error("not implemented"); + else + throw Error("invalid argument type"); + deleteValue(hash); + } } diff --git a/src/test.cc b/src/test.cc index c8e3292e3a..268b35d899 100644 --- a/src/test.cc +++ b/src/test.cc @@ -68,7 +68,7 @@ void runTests() #endif /* Restoring. */ -#if 1 +#if 0 MySource source; restorePath("outdir", source); cout << (string) hashPath("outdir") << endl; @@ -116,6 +116,8 @@ void runTests() Expr e3 = ATmake("Deref(Hash())", ((string) h3).c_str()); evalTest(e3); + + deleteValue(h3); } diff --git a/src/util.cc b/src/util.cc index 8c397aace8..4dada48ba6 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1,5 +1,10 @@ #include +#include +#include +#include +#include + #include "util.hh" @@ -49,6 +54,30 @@ string baseNameOf(string path) } +void deletePath(string path) +{ + struct stat st; + if (lstat(path.c_str(), &st)) + throw SysError("getting attributes of path " + path); + + if (S_ISDIR(st.st_mode)) { + DIR * dir = opendir(path.c_str()); + + struct dirent * dirent; + while (errno = 0, dirent = readdir(dir)) { + string name = dirent->d_name; + if (name == "." || name == "..") continue; + deletePath(path + "/" + name); + } + + closedir(dir); /* !!! close on exception */ + } + + if (remove(path.c_str()) == -1) + throw SysError("cannot unlink " + path); +} + + void debug(string s) { cerr << "debug: " << s << endl; diff --git a/src/util.hh b/src/util.hh index 45719e701f..7d5f00a2e8 100644 --- a/src/util.hh +++ b/src/util.hh @@ -54,6 +54,11 @@ string dirOf(string path); string baseNameOf(string path); +/* Delete a path; i.e., in the case of a directory, it is deleted + recursively. Don't use this at home, kids. */ +void deletePath(string path); + + void debug(string s); diff --git a/src/values.cc b/src/values.cc index 22f84c83e6..c8a3b58cb9 100644 --- a/src/values.cc +++ b/src/values.cc @@ -135,6 +135,18 @@ string fetchURL(string url) #endif +void deleteValue(Hash hash) +{ + string name; + if (queryDB(nixDB, dbRefs, hash, name)) { + string fn = absValuePath(name); + deletePath(fn); + delDB(nixDB, dbRefs, hash); + } +} + + +/* !!! bad name, "query" implies no side effect => getValuePath() */ string queryValuePath(Hash hash) { bool checkedNet = false; diff --git a/src/values.hh b/src/values.hh index 5dd7b89c40..d66ae770f9 100644 --- a/src/values.hh +++ b/src/values.hh @@ -13,6 +13,10 @@ using namespace std; Hash addValue(string pathName); +/* Delete a value from the nixValues directory. */ +void deleteValue(Hash hash); + + /* Obtain the path of a value with the given hash. If a file with that hash is known to exist in the local file system (as indicated by the dbRefs database), we use that. Otherwise, we attempt to