* `nix-store -qb' to query derivation environment bindings. Useful
for finding build-time dependencies (possibly after a build).  E.g.,
    $ nix-store -qb aterm $(nix-store -qd $(which strc))
    /nix/store/jw7c7s65n1gwhxpn35j9rgcci6ilzxym-aterm-2.3.1
* Arguments to nix-store can be files within store objects, e.g.,
  /nix/store/jw7c...-aterm-2.3.1/bin/baffle.
* Idem for garbage collector roots.
			
			
This commit is contained in:
		
							parent
							
								
									450c358e20
								
							
						
					
					
						commit
						fbc434ee4c
					
				
					 4 changed files with 60 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -60,7 +60,7 @@ void createSymlink(const Path & link, const Path & target, bool careful)
 | 
			
		|||
 | 
			
		||||
    /* Remove the old symlink. */
 | 
			
		||||
    if (pathExists(link)) {
 | 
			
		||||
        if (careful && (!isLink(link) || !isStorePath(readLink(link))))
 | 
			
		||||
        if (careful && (!isLink(link) || !isInStore(readLink(link))))
 | 
			
		||||
            throw Error(format("cannot create symlink `%1%'; already exists") % link);
 | 
			
		||||
        unlink(link.c_str());
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -250,10 +250,10 @@ static void findRoots(const Path & path, bool recurseSymlinks,
 | 
			
		|||
        string target = readLink(path);
 | 
			
		||||
        Path target2 = absPath(target, dirOf(path));
 | 
			
		||||
 | 
			
		||||
        if (isStorePath(target2)) {
 | 
			
		||||
        if (isInStore(target2)) {
 | 
			
		||||
            debug(format("found root `%1%' in `%2%'")
 | 
			
		||||
                % target2 % path);
 | 
			
		||||
            roots.insert(target2);
 | 
			
		||||
            roots.insert(toStorePath(target2));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        else if (recurseSymlinks) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -176,12 +176,18 @@ void copyPath(const Path & src, const Path & dst)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool isStorePath(const Path & path)
 | 
			
		||||
bool isInStore(const Path & path)
 | 
			
		||||
{
 | 
			
		||||
    return path[0] == '/'
 | 
			
		||||
        && path.compare(0, nixStore.size(), nixStore) == 0
 | 
			
		||||
        && path.size() >= nixStore.size() + 2
 | 
			
		||||
        && path[nixStore.size()] == '/'
 | 
			
		||||
        && path[nixStore.size()] == '/';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool isStorePath(const Path & path)
 | 
			
		||||
{
 | 
			
		||||
    return isInStore(path)
 | 
			
		||||
        && path.find('/', nixStore.size() + 1) == Path::npos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -193,6 +199,18 @@ void assertStorePath(const Path & path)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Path toStorePath(const Path & path)
 | 
			
		||||
{
 | 
			
		||||
    if (!isInStore(path))
 | 
			
		||||
        throw Error(format("path `%1%' is not in the Nix store") % path);
 | 
			
		||||
    unsigned int slash = path.find('/', nixStore.size() + 1);
 | 
			
		||||
    if (slash == Path::npos)
 | 
			
		||||
        return path;
 | 
			
		||||
    else
 | 
			
		||||
        return Path(path, 0, slash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void canonicalisePathMetaData(const Path & path)
 | 
			
		||||
{
 | 
			
		||||
    checkInterrupt();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,8 +63,13 @@ void registerValidPath(const Transaction & txn,
 | 
			
		|||
/* Throw an exception if `path' is not directly in the Nix store. */
 | 
			
		||||
void assertStorePath(const Path & path);
 | 
			
		||||
 | 
			
		||||
bool isInStore(const Path & path);
 | 
			
		||||
bool isStorePath(const Path & path);
 | 
			
		||||
 | 
			
		||||
/* Chop off the parts after the top-level store name, e.g.,
 | 
			
		||||
   /nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
 | 
			
		||||
Path toStorePath(const Path & path);
 | 
			
		||||
 | 
			
		||||
/* "Fix", or canonicalise, the meta-data of the files in a store path
 | 
			
		||||
   after it has been built.  In particular:
 | 
			
		||||
   - the last modification date on each file is set to 0 (i.e.,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,15 +32,15 @@ static Path findOutput(const Derivation & drv, string id)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static Path followSymlinks(Path & path)
 | 
			
		||||
static Path fixPath(Path path)
 | 
			
		||||
{
 | 
			
		||||
    path = absPath(path);
 | 
			
		||||
    while (!isStorePath(path)) {
 | 
			
		||||
        if (!isLink(path)) return path;
 | 
			
		||||
    while (!isInStore(path)) {
 | 
			
		||||
        if (!isLink(path)) break;
 | 
			
		||||
        string target = readLink(path);
 | 
			
		||||
        path = absPath(target, dirOf(path));
 | 
			
		||||
    }
 | 
			
		||||
    return path;
 | 
			
		||||
    return toStorePath(path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
 | 
			
		|||
 | 
			
		||||
    for (Strings::iterator i = opArgs.begin();
 | 
			
		||||
         i != opArgs.end(); i++)
 | 
			
		||||
        *i = followSymlinks(*i);
 | 
			
		||||
        *i = fixPath(*i);
 | 
			
		||||
            
 | 
			
		||||
    if (opArgs.size() > 1) {
 | 
			
		||||
        PathSet drvPaths;
 | 
			
		||||
| 
						 | 
				
			
			@ -162,19 +162,27 @@ static void printPathSet(const PathSet & paths)
 | 
			
		|||
static void opQuery(Strings opFlags, Strings opArgs)
 | 
			
		||||
{
 | 
			
		||||
    enum { qOutputs, qRequisites, qReferences, qReferers,
 | 
			
		||||
           qReferersClosure, qDeriver, qGraph } query = qOutputs;
 | 
			
		||||
           qReferersClosure, qDeriver, qBinding, qGraph } query = qOutputs;
 | 
			
		||||
    bool useOutput = false;
 | 
			
		||||
    bool includeOutputs = false;
 | 
			
		||||
    bool forceRealise = false;
 | 
			
		||||
    string bindingName;
 | 
			
		||||
 | 
			
		||||
    for (Strings::iterator i = opFlags.begin();
 | 
			
		||||
         i != opFlags.end(); i++)
 | 
			
		||||
         i != opFlags.end(); ++i)
 | 
			
		||||
        if (*i == "--outputs") query = qOutputs;
 | 
			
		||||
        else if (*i == "--requisites" || *i == "-R") query = qRequisites;
 | 
			
		||||
        else if (*i == "--references") query = qReferences;
 | 
			
		||||
        else if (*i == "--referers") query = qReferers;
 | 
			
		||||
        else if (*i == "--referers-closure") query = qReferersClosure;
 | 
			
		||||
        else if (*i == "--deriver" || *i == "-d") query = qDeriver;
 | 
			
		||||
        else if (*i == "--binding" || *i == "-b") {
 | 
			
		||||
            if (opArgs.size() == 0)
 | 
			
		||||
                throw UsageError("expected binding name");
 | 
			
		||||
            bindingName = opArgs.front();
 | 
			
		||||
            opArgs.pop_front();
 | 
			
		||||
            query = qBinding;
 | 
			
		||||
        }
 | 
			
		||||
        else if (*i == "--graph") query = qGraph;
 | 
			
		||||
        else if (*i == "--use-output" || *i == "-u") useOutput = true;
 | 
			
		||||
        else if (*i == "--force-realise" || *i == "-f") forceRealise = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +195,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
 | 
			
		|||
            for (Strings::iterator i = opArgs.begin();
 | 
			
		||||
                 i != opArgs.end(); i++)
 | 
			
		||||
            {
 | 
			
		||||
                *i = followSymlinks(*i);
 | 
			
		||||
                *i = fixPath(*i);
 | 
			
		||||
                if (forceRealise) realisePath(*i);
 | 
			
		||||
                Derivation drv = derivationFromPath(*i);
 | 
			
		||||
                cout << format("%1%\n") % findOutput(drv, "out");
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +211,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
 | 
			
		|||
            for (Strings::iterator i = opArgs.begin();
 | 
			
		||||
                 i != opArgs.end(); i++)
 | 
			
		||||
            {
 | 
			
		||||
                *i = followSymlinks(*i);
 | 
			
		||||
                *i = fixPath(*i);
 | 
			
		||||
                Path path = maybeUseOutput(*i, useOutput, forceRealise);
 | 
			
		||||
                if (query == qRequisites)
 | 
			
		||||
                    storePathRequisites(path, includeOutputs, paths);
 | 
			
		||||
| 
						 | 
				
			
			@ -219,13 +227,26 @@ static void opQuery(Strings opFlags, Strings opArgs)
 | 
			
		|||
            for (Strings::iterator i = opArgs.begin();
 | 
			
		||||
                 i != opArgs.end(); i++)
 | 
			
		||||
            {
 | 
			
		||||
                *i = followSymlinks(*i);
 | 
			
		||||
                *i = fixPath(*i);
 | 
			
		||||
                Path deriver = queryDeriver(noTxn, *i);
 | 
			
		||||
                cout << format("%1%\n") %
 | 
			
		||||
                    (deriver == "" ? "unknown-deriver" : deriver);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
        case qBinding:
 | 
			
		||||
            for (Strings::iterator i = opArgs.begin();
 | 
			
		||||
                 i != opArgs.end(); i++)
 | 
			
		||||
            {
 | 
			
		||||
                *i = fixPath(*i);
 | 
			
		||||
                Derivation drv = derivationFromPath(*i);
 | 
			
		||||
                StringPairs::iterator j = drv.env.find(bindingName);
 | 
			
		||||
                if (j == drv.env.end())
 | 
			
		||||
                    throw Error(format("derivation `%1%' has no environment binding named `%2%'")
 | 
			
		||||
                        % *i % bindingName);
 | 
			
		||||
                cout << format("%1%\n") % j->second;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
#if 0            
 | 
			
		||||
        case qGraph: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue