* Maintain a database table (`derivers') that maps output paths to the
derivation that produced them. * `nix-store -qd PATH' prints out the derivation that produced a path.
This commit is contained in:
parent
a37338815d
commit
450c358e20
4 changed files with 74 additions and 13 deletions
|
@ -1140,7 +1140,8 @@ void DerivationGoal::computeClosure()
|
||||||
{
|
{
|
||||||
registerValidPath(txn, i->second.path,
|
registerValidPath(txn, i->second.path,
|
||||||
contentHashes[i->second.path],
|
contentHashes[i->second.path],
|
||||||
allReferences[i->second.path]);
|
allReferences[i->second.path],
|
||||||
|
drvPath);
|
||||||
}
|
}
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
|
@ -1501,7 +1502,7 @@ void SubstitutionGoal::finished()
|
||||||
|
|
||||||
Transaction txn;
|
Transaction txn;
|
||||||
createStoreTransaction(txn);
|
createStoreTransaction(txn);
|
||||||
registerValidPath(txn, storePath, contentHash, references);
|
registerValidPath(txn, storePath, contentHash, references, "");
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
outputLock->setDeletion(true);
|
outputLock->setDeletion(true);
|
||||||
|
|
|
@ -56,6 +56,13 @@ static TableId dbReferers = 0;
|
||||||
*/
|
*/
|
||||||
static TableId dbSubstitutes = 0;
|
static TableId dbSubstitutes = 0;
|
||||||
|
|
||||||
|
/* dbDerivers :: Path -> [Path]
|
||||||
|
|
||||||
|
This table lists the derivation used to build a path. There can
|
||||||
|
only be multiple such paths for fixed-output derivations (i.e.,
|
||||||
|
derivations specifying an expected hash). */
|
||||||
|
static TableId dbDerivers = 0;
|
||||||
|
|
||||||
|
|
||||||
bool Substitute::operator == (const Substitute & sub)
|
bool Substitute::operator == (const Substitute & sub)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +85,7 @@ void openDB()
|
||||||
dbReferences = nixDB.openTable("references");
|
dbReferences = nixDB.openTable("references");
|
||||||
dbReferers = nixDB.openTable("referers");
|
dbReferers = nixDB.openTable("referers");
|
||||||
dbSubstitutes = nixDB.openTable("substitutes");
|
dbSubstitutes = nixDB.openTable("substitutes");
|
||||||
|
dbDerivers = nixDB.openTable("derivers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,6 +326,30 @@ void queryReferers(const Path & storePath, PathSet & referers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setDeriver(const Transaction & txn, const Path & storePath,
|
||||||
|
const Path & deriver)
|
||||||
|
{
|
||||||
|
assertStorePath(storePath);
|
||||||
|
if (deriver == "") return;
|
||||||
|
assertStorePath(deriver);
|
||||||
|
if (!isRealisablePath(txn, storePath))
|
||||||
|
throw Error(format("path `%1%' is not valid") % storePath);
|
||||||
|
nixDB.setString(txn, dbDerivers, storePath, deriver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path queryDeriver(const Transaction & txn, const Path & storePath)
|
||||||
|
{
|
||||||
|
if (!isRealisablePath(noTxn, storePath))
|
||||||
|
throw Error(format("path `%1%' is not valid") % storePath);
|
||||||
|
Path deriver;
|
||||||
|
if (nixDB.queryString(txn, dbDerivers, storePath, deriver))
|
||||||
|
return deriver;
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Substitutes readSubstitutes(const Transaction & txn,
|
static Substitutes readSubstitutes(const Transaction & txn,
|
||||||
const Path & srcPath)
|
const Path & srcPath)
|
||||||
{
|
{
|
||||||
|
@ -406,7 +438,8 @@ void clearSubstitutes()
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
Path path(canonPath(_path));
|
Path path(canonPath(_path));
|
||||||
assertStorePath(path);
|
assertStorePath(path);
|
||||||
|
@ -423,6 +456,8 @@ void registerValidPath(const Transaction & txn,
|
||||||
if (!isValidPathTxn(txn, *i))
|
if (!isValidPathTxn(txn, *i))
|
||||||
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
|
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
|
||||||
% path % *i);
|
% path % *i);
|
||||||
|
|
||||||
|
setDeriver(txn, path, deriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -433,11 +468,13 @@ static void invalidatePath(const Path & path, Transaction & txn)
|
||||||
debug(format("unregistering path `%1%'") % path);
|
debug(format("unregistering path `%1%'") % path);
|
||||||
|
|
||||||
/* Clear the `references' entry for this path, as well as the
|
/* Clear the `references' entry for this path, as well as the
|
||||||
inverse `referers' entries; but only if there are no
|
inverse `referers' entries, and the `derivers' entry; but only
|
||||||
substitutes for this path. This maintains the cleanup
|
if there are no substitutes for this path. This maintains the
|
||||||
invariant. */
|
cleanup invariant. */
|
||||||
if (querySubstitutes(txn, path).size() == 0)
|
if (querySubstitutes(txn, path).size() == 0) {
|
||||||
setReferences(txn, path, PathSet());
|
setReferences(txn, path, PathSet());
|
||||||
|
nixDB.delPair(txn, dbDerivers, path);
|
||||||
|
}
|
||||||
|
|
||||||
nixDB.delPair(txn, dbValidPaths, path);
|
nixDB.delPair(txn, dbValidPaths, path);
|
||||||
}
|
}
|
||||||
|
@ -498,7 +535,7 @@ Path addToStore(const Path & _srcPath)
|
||||||
canonicalisePathMetaData(dstPath);
|
canonicalisePathMetaData(dstPath);
|
||||||
|
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
registerValidPath(txn, dstPath, h, PathSet());
|
registerValidPath(txn, dstPath, h, PathSet(), "");
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +571,7 @@ Path addTextToStore(const string & suffix, const string & s,
|
||||||
|
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
registerValidPath(txn, dstPath,
|
registerValidPath(txn, dstPath,
|
||||||
hashPath(htSHA256, dstPath), references);
|
hashPath(htSHA256, dstPath), references, "");
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ void clearSubstitutes();
|
||||||
of the file system contents of the path. The hash must be a
|
of the file system contents of the path. The hash must be a
|
||||||
SHA-256 hash. */
|
SHA-256 hash. */
|
||||||
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);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -77,7 +78,8 @@ void canonicalisePathMetaData(const Path & path);
|
||||||
/* Checks whether a path is valid. */
|
/* Checks whether a path is valid. */
|
||||||
bool isValidPath(const Path & path);
|
bool isValidPath(const Path & path);
|
||||||
|
|
||||||
/* Sets the set of outgoing FS references for a store path. */
|
/* Sets the set of outgoing FS references for a store path. Use with
|
||||||
|
care! */
|
||||||
void setReferences(const Transaction & txn, const Path & storePath,
|
void setReferences(const Transaction & txn, const Path & storePath,
|
||||||
const PathSet & references);
|
const PathSet & references);
|
||||||
|
|
||||||
|
@ -89,6 +91,14 @@ void queryReferences(const Path & storePath, PathSet & references);
|
||||||
result is not cleared. */
|
result is not cleared. */
|
||||||
void queryReferers(const Path & storePath, PathSet & referers);
|
void queryReferers(const Path & storePath, PathSet & referers);
|
||||||
|
|
||||||
|
/* Sets the deriver of a store path. Use with care! */
|
||||||
|
void setDeriver(const Transaction & txn, const Path & storePath,
|
||||||
|
const Path & deriver);
|
||||||
|
|
||||||
|
/* Query the deriver of a store path. Return the empty string if no
|
||||||
|
deriver has been set. */
|
||||||
|
Path queryDeriver(const Transaction & txn, const Path & storePath);
|
||||||
|
|
||||||
/* Constructs a unique store path name. */
|
/* Constructs a unique store path name. */
|
||||||
Path makeStorePath(const string & type,
|
Path makeStorePath(const string & type,
|
||||||
const Hash & hash, const string & suffix);
|
const Hash & hash, const string & suffix);
|
||||||
|
|
|
@ -162,7 +162,7 @@ static void printPathSet(const PathSet & paths)
|
||||||
static void opQuery(Strings opFlags, Strings opArgs)
|
static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
enum { qOutputs, qRequisites, qReferences, qReferers,
|
enum { qOutputs, qRequisites, qReferences, qReferers,
|
||||||
qReferersClosure, qGraph } query = qOutputs;
|
qReferersClosure, qDeriver, qGraph } query = qOutputs;
|
||||||
bool useOutput = false;
|
bool useOutput = false;
|
||||||
bool includeOutputs = false;
|
bool includeOutputs = false;
|
||||||
bool forceRealise = false;
|
bool forceRealise = false;
|
||||||
|
@ -174,6 +174,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
else if (*i == "--references") query = qReferences;
|
else if (*i == "--references") query = qReferences;
|
||||||
else if (*i == "--referers") query = qReferers;
|
else if (*i == "--referers") query = qReferers;
|
||||||
else if (*i == "--referers-closure") query = qReferersClosure;
|
else if (*i == "--referers-closure") query = qReferersClosure;
|
||||||
|
else if (*i == "--deriver" || *i == "-d") query = qDeriver;
|
||||||
else if (*i == "--graph") query = qGraph;
|
else if (*i == "--graph") query = qGraph;
|
||||||
else if (*i == "--use-output" || *i == "-u") useOutput = true;
|
else if (*i == "--use-output" || *i == "-u") useOutput = true;
|
||||||
else if (*i == "--force-realise" || *i == "-f") forceRealise = true;
|
else if (*i == "--force-realise" || *i == "-f") forceRealise = true;
|
||||||
|
@ -214,6 +215,18 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case qDeriver:
|
||||||
|
for (Strings::iterator i = opArgs.begin();
|
||||||
|
i != opArgs.end(); i++)
|
||||||
|
{
|
||||||
|
*i = followSymlinks(*i);
|
||||||
|
Path deriver = queryDeriver(noTxn, *i);
|
||||||
|
cout << format("%1%\n") %
|
||||||
|
(deriver == "" ? "unknown-deriver" : deriver);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
case qGraph: {
|
case qGraph: {
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
|
@ -288,7 +301,7 @@ static void opValidPath(Strings opFlags, Strings opArgs)
|
||||||
createStoreTransaction(txn);
|
createStoreTransaction(txn);
|
||||||
for (Strings::iterator i = opArgs.begin();
|
for (Strings::iterator i = opArgs.begin();
|
||||||
i != opArgs.end(); ++i)
|
i != opArgs.end(); ++i)
|
||||||
registerValidPath(txn, *i, hashPath(htSHA256, *i), PathSet());
|
registerValidPath(txn, *i, hashPath(htSHA256, *i), PathSet(), "");
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue