aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-07-21 14:46:01 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-07-21 14:46:01 +0000
commit49231fbe419d37717b0d951377fbfc9bf445dd55 (patch)
tree1802eacb403ad72f6b10805816a06c025116db1f
parent401452e57ae897d3e5829ed12bfcccac82548e91 (diff)
* Changes to the command line syntax of Nix.
* A function to find all Nix expressions whose output ids are completely contained in some set. Useful for uploading relevant Nix expressions to a shared cache.
-rw-r--r--src/nix.cc128
-rw-r--r--src/normalise.cc49
-rw-r--r--src/normalise.hh6
-rw-r--r--src/store.cc9
-rw-r--r--src/store.hh3
5 files changed, 117 insertions, 78 deletions
diff --git a/src/nix.cc b/src/nix.cc
index ad4e6a468..de60c28c5 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -9,9 +9,7 @@
typedef void (* Operation) (Strings opFlags, Strings opArgs);
-typedef enum { atpHash, atpPath, atpUnknown } ArgType;
-
-static ArgType argType = atpUnknown;
+static bool pathArgs = false;
/* Nix syntax:
@@ -39,12 +37,11 @@ static ArgType argType = atpUnknown;
Source selection for --install, --dump:
- --file / -f: by file name !!! -> path
- --hash / -h: by hash (identifier)
+ --path / -p: by file name !!! -> path
Query flags:
- --path / -p: query the path of an fstate
+ --list / -l: query the output paths (roots) of an fstate
--refs / -r: query paths referenced by an fstate
Options:
@@ -53,39 +50,16 @@ static ArgType argType = atpUnknown;
*/
-/* Parse the `-f' / `-h' / flags, i.e., the type of arguments. These
- flags are deleted from the referenced vector. */
-static void getArgType(Strings & flags)
-{
- for (Strings::iterator it = flags.begin();
- it != flags.end(); )
- {
- string arg = *it;
- ArgType tp;
- if (arg == "--hash" || arg == "-h") tp = atpHash;
- else if (arg == "--file" || arg == "-f") tp = atpPath;
- else { it++; continue; }
- if (argType != atpUnknown)
- throw UsageError("only one argument type specified may be specified");
- argType = tp;
- it = flags.erase(it);
- }
- if (argType == atpUnknown)
- throw UsageError("argument type not specified");
-}
-
-
static FSId argToId(const string & arg)
{
- if (argType == atpHash)
+ if (!pathArgs)
return parseHash(arg);
- else if (argType == atpPath) {
- string path;
+ else {
FSId id;
- addToStore(arg, path, id);
+ if (!queryPathId(arg, id))
+ throw Error(format("don't know id of `%1%'") % arg);
return id;
}
- else abort();
}
@@ -93,7 +67,6 @@ static FSId argToId(const string & arg)
expressions. */
static void opInstall(Strings opFlags, Strings opArgs)
{
- getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator it = opArgs.begin();
@@ -117,7 +90,6 @@ static void opDelete(Strings opFlags, Strings opArgs)
paths. */
static void opAdd(Strings opFlags, Strings opArgs)
{
- getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag");
for (Strings::iterator it = opArgs.begin();
@@ -134,47 +106,61 @@ static void opAdd(Strings opFlags, Strings opArgs)
/* Perform various sorts of queries. */
static void opQuery(Strings opFlags, Strings opArgs)
{
- enum { qPath, qRefs, qUnknown } query = qPath;
-
- for (Strings::iterator it = opFlags.begin();
- it != opFlags.end(); )
- {
- string arg = *it;
- if (arg == "--path" || arg == "-p") query = qPath;
- else if (arg == "--refs" || arg == "-r") query = qRefs;
- else { it++; continue; }
- it = opFlags.erase(it);
- }
-
- getArgType(opFlags);
- if (!opFlags.empty()) throw UsageError("unknown flag");
-
- for (Strings::iterator it = opArgs.begin();
- it != opArgs.end(); it++)
- {
- FSId id = argToId(*it);
-
- switch (query) {
-
- case qPath: {
- Strings paths = fstatePaths(id, true);
- for (Strings::iterator j = paths.begin();
- j != paths.end(); j++)
- cout << format("%s\n") % *j;
+ enum { qPaths, qRefs, qGenerators, qUnknown } query = qPaths;
+
+ for (Strings::iterator i = opFlags.begin();
+ i != opFlags.end(); i++)
+ if (*i == "--list" || *i == "-l") query = qPaths;
+ else if (*i == "--refs" || *i == "-r") query = qRefs;
+ else if (*i == "--generators" || *i == "-g") query = qGenerators;
+ else throw UsageError(format("unknown flag `%1%'") % *i);
+
+ switch (query) {
+
+ case qPaths: {
+ StringSet paths;
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); i++)
+ {
+ Strings paths2 = fstatePaths(argToId(*i), true);
+ paths.insert(paths2.begin(), paths2.end());
+ }
+ for (StringSet::iterator i = paths.begin();
+ i != paths.end(); i++)
+ cout << format("%s\n") % *i;
break;
}
case qRefs: {
- StringSet refs = fstateRefs(id);
- for (StringSet::iterator j = refs.begin();
- j != refs.end(); j++)
- cout << format("%s\n") % *j;
+ StringSet paths;
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); i++)
+ {
+ Strings paths2 = fstateRefs(argToId(*i));
+ paths.insert(paths2.begin(), paths2.end());
+ }
+ for (StringSet::iterator i = paths.begin();
+ i != paths.end(); i++)
+ cout << format("%s\n") % *i;
+ break;
+ }
+
+ case qGenerators: {
+ FSIds outIds;
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); i++)
+ outIds.push_back(argToId(*i));
+
+ FSIds genIds = findGenerators(outIds);
+
+ for (FSIds::iterator i = genIds.begin();
+ i != genIds.end(); i++)
+ cout << format("%s\n") % (string) *i;
break;
}
default:
abort();
- }
}
}
@@ -224,16 +210,12 @@ struct StdoutSink : DumpSink
output. */
static void opDump(Strings opFlags, Strings opArgs)
{
- getArgType(opFlags);
if (!opFlags.empty()) throw UsageError("unknown flag");
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
StdoutSink sink;
string arg = *opArgs.begin();
- string path;
-
- if (argType == atpHash) path = expandId(parseHash(arg));
- else if (argType == atpPath) path = arg;
+ string path = pathArgs ? arg : expandId(parseHash(arg));
dumpPath(path, sink);
}
@@ -313,6 +295,8 @@ void run(Strings args)
op = opInit;
else if (arg == "--verify")
op = opVerify;
+ else if (arg == "--path" || arg == "-p")
+ pathArgs = true;
else if (arg[0] == '-')
opFlags.push_back(arg);
else
diff --git a/src/normalise.cc b/src/normalise.cc
index bdeddf08d..fcb9c4d0d 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -248,18 +248,57 @@ Strings fstatePaths(const FSId & id, bool normalise)
}
-StringSet fstateRefs(const FSId & id)
+Strings fstateRefs(const FSId & id)
{
- StringSet paths;
+ Strings paths;
Slice slice = normaliseFState(id);
for (SliceElems::const_iterator i = slice.elems.begin();
i != slice.elems.end(); i++)
- paths.insert(i->path);
+ paths.push_back(i->path);
return paths;
}
-void findGenerators(const FSIds & ids)
+FSIds findGenerators(const FSIds & _ids)
{
-
+ FSIdSet ids(_ids.begin(), _ids.end());
+ FSIds generators;
+
+ /* !!! hack; for performance, we just look at the rhs of successor
+ mappings, since we know that those are Nix expressions. */
+
+ Strings sucs;
+ enumDB(nixDB, dbSuccessors, sucs);
+
+ for (Strings::iterator i = sucs.begin();
+ i != sucs.end(); i++)
+ {
+ string s;
+ queryDB(nixDB, dbSuccessors, *i, s);
+ FSId id = parseHash(s);
+
+ FState fs;
+ try {
+ /* !!! should substitutes be used? */
+ fs = parseFState(termFromId(id));
+ } catch (...) { /* !!! only catch parse errors */
+ continue;
+ }
+
+ if (fs.type != FState::fsSlice) continue;
+
+ bool okay = true;
+ for (SliceElems::const_iterator i = fs.slice.elems.begin();
+ i != fs.slice.elems.end(); i++)
+ if (ids.find(i->id) == ids.end()) {
+ okay = false;
+ break;
+ }
+
+ if (!okay) continue;
+
+ generators.push_back(id);
+ }
+
+ return generators;
}
diff --git a/src/normalise.hh b/src/normalise.hh
index 85dbca5ef..49f9e68ee 100644
--- a/src/normalise.hh
+++ b/src/normalise.hh
@@ -16,7 +16,11 @@ void realiseSlice(const Slice & slice);
Strings fstatePaths(const FSId & id, bool normalise);
/* Get the list of paths referenced by the given fstate-expression. */
-StringSet fstateRefs(const FSId & id);
+Strings fstateRefs(const FSId & id);
+
+/* Return the list of the ids of all known fstate-expressions whose
+ output ids are completely contained in `ids'. */
+FSIds findGenerators(const FSIds & ids);
/* Register a successor. */
void registerSuccessor(const FSId & id1, const FSId & id2);
diff --git a/src/store.cc b/src/store.cc
index 6f1a2fc39..6157b4bc2 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -148,6 +148,15 @@ void unregisterPath(const string & _path)
}
+bool queryPathId(const string & path, FSId & id)
+{
+ string s;
+ if (!queryDB(nixDB, dbPath2Id, path, s)) return false;
+ id = parseHash(s);
+ return true;
+}
+
+
bool isInPrefix(const string & path, const string & _prefix)
{
string prefix = canonPath(_prefix + "/");
diff --git a/src/store.hh b/src/store.hh
index 78d5529e7..faac76009 100644
--- a/src/store.hh
+++ b/src/store.hh
@@ -20,6 +20,9 @@ void registerSubstitute(const FSId & srcId, const FSId & subId);
/* Register a path keyed on its id. */
void registerPath(const string & path, const FSId & id);
+/* Query the id of a path. */
+bool queryPathId(const string & path, FSId & id);
+
/* Return a path whose contents have the given hash. If target is
not empty, ensure that such a path is realised in target (if
necessary by copying from another location). If prefix is not