* `nix-store --register-validity': allow a path to refer to a path

listed later in the list of new valid paths.
This commit is contained in:
Eelco Dolstra 2005-03-23 13:07:28 +00:00
parent a04c62e0c4
commit 3f236f01ae
3 changed files with 62 additions and 24 deletions

View file

@ -508,24 +508,48 @@ Hash queryPathHash(const Path & path)
void registerValidPath(const Transaction & txn, void registerValidPath(const Transaction & txn,
const Path & _path, const Hash & hash, const PathSet & references, const Path & path, const Hash & hash, const PathSet & references,
const Path & deriver) const Path & deriver)
{ {
Path path(canonPath(_path)); ValidPathInfo info;
assertStorePath(path); info.path = path;
info.hash = hash;
info.references = references;
info.deriver = deriver;
ValidPathInfos infos;
infos.push_back(info);
registerValidPaths(txn, infos);
}
debug(format("registering path `%1%'") % path);
setHash(txn, path, hash);
setReferences(txn, path, references); void registerValidPaths(const Transaction & txn,
const ValidPathInfos & infos)
{
PathSet newPaths;
for (ValidPathInfos::const_iterator i = infos.begin();
i != infos.end(); ++i)
newPaths.insert(i->path);
for (ValidPathInfos::const_iterator i = infos.begin();
i != infos.end(); ++i)
{
assertStorePath(i->path);
debug(format("registering path `%1%'") % i->path);
setHash(txn, i->path, i->hash);
setReferences(txn, i->path, i->references);
/* Check that all referenced paths are also valid. */ /* Check that all referenced paths are also valid (or about to
for (PathSet::iterator i = references.begin(); i != references.end(); ++i) become valid). */
if (!isValidPathTxn(txn, *i)) for (PathSet::iterator j = i->references.begin();
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid") j != i->references.end(); ++j)
% path % *i); if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end())
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
% i->path % *j);
setDeriver(txn, path, deriver); setDeriver(txn, i->path, i->deriver);
}
} }

View file

@ -66,6 +66,19 @@ void registerValidPath(const Transaction & txn,
const Path & path, const Hash & hash, const PathSet & references, const Path & path, const Hash & hash, const PathSet & references,
const Path & deriver); const Path & deriver);
struct ValidPathInfo
{
Path path;
Path deriver;
Hash hash;
PathSet references;
};
typedef list<ValidPathInfo> ValidPathInfos;
void registerValidPaths(const Transaction & txn,
const ValidPathInfos & infos);
/* Throw an exception if `path' is not directly in the Nix store. */ /* Throw an exception if `path' is not directly in the Nix store. */
void assertStorePath(const Path & path); void assertStorePath(const Path & path);

View file

@ -405,31 +405,32 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
if (!opFlags.empty()) throw UsageError("unknown flag"); if (!opFlags.empty()) throw UsageError("unknown flag");
if (!opArgs.empty()) throw UsageError("no arguments expected"); if (!opArgs.empty()) throw UsageError("no arguments expected");
Transaction txn; ValidPathInfos infos;
createStoreTransaction(txn);
while (1) { while (1) {
Path path; ValidPathInfo info;
Path deriver; getline(cin, info.path);
PathSet references;
getline(cin, path);
if (cin.eof()) break; if (cin.eof()) break;
getline(cin, deriver); getline(cin, info.deriver);
string s; int n; string s; int n;
getline(cin, s); getline(cin, s);
if (!string2Int(s, n)) throw Error("number expected"); if (!string2Int(s, n)) throw Error("number expected");
while (n--) { while (n--) {
getline(cin, s); getline(cin, s);
references.insert(s); info.references.insert(s);
} }
if (!cin || cin.eof()) throw Error("missing input"); if (!cin || cin.eof()) throw Error("missing input");
if (!isValidPathTxn(txn, path)) { if (!isValidPath(info.path)) {
/* !!! races */ /* !!! races */
canonicalisePathMetaData(path); canonicalisePathMetaData(info.path);
registerValidPath(txn, path, hashPath(htSHA256, path), references, deriver); info.hash = hashPath(htSHA256, info.path);
infos.push_back(info);
} }
} }
Transaction txn;
createStoreTransaction(txn);
registerValidPaths(txn, infos);
txn.commit(); txn.commit();
} }