diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fix.cc | 8 | ||||
-rw-r--r-- | src/fstate.cc | 22 | ||||
-rw-r--r-- | src/globals.cc | 4 | ||||
-rw-r--r-- | src/globals.hh | 2 | ||||
-rw-r--r-- | src/nix.cc | 24 | ||||
-rw-r--r-- | src/shared.cc | 1 | ||||
-rw-r--r-- | src/store.cc | 51 | ||||
-rw-r--r-- | src/store.hh | 8 |
8 files changed, 69 insertions, 51 deletions
diff --git a/src/fix.cc b/src/fix.cc index 9e5b8b5d416a..5c4297bfb760 100644 --- a/src/fix.cc +++ b/src/fix.cc @@ -15,6 +15,8 @@ static Strings searchDirs; static string searchPath(string relPath) { + if (string(relPath, 0, 1) == "/") return relPath; + for (Strings::iterator i = searchDirs.begin(); i != searchDirs.end(); i++) { @@ -218,7 +220,10 @@ static Expr evalExpr(Expr e) static Expr evalFile(string relPath) { - Expr e = ATreadFromNamedFile(searchPath(relPath).c_str()); + string path = searchPath(relPath); + Expr e = ATreadFromNamedFile(path.c_str()); + if (!e) + throw Error(format("unable to read a term from `%1%'") % path); return evalExpr(e); } @@ -228,6 +233,7 @@ void run(Strings args) Strings files; searchDirs.push_back("."); + searchDirs.push_back(nixDataDir + "/fix"); for (Strings::iterator it = args.begin(); it != args.end(); ) diff --git a/src/fstate.cc b/src/fstate.cc index e289ca7b1958..fdd43d1b1384 100644 --- a/src/fstate.cc +++ b/src/fstate.cc @@ -149,7 +149,7 @@ Hash hashTerm(ATerm t) ATerm termFromHash(const Hash & hash, string * p) { - string path = queryPathByHash(hash); + string path = expandHash(hash); if (p) *p = path; ATerm t = ATreadFromNamedFile(path.c_str()); if (!t) throw Error(format("cannot read aterm %1%") % path); @@ -253,26 +253,6 @@ static FState realise(FState fs, StringSet & paths) /* Expand the hash into the target path. */ expandHash(hash, path); -#if 0 - /* Perhaps the path already exists and has the right hash? */ - if (pathExists(path)) { - - if (hash != hashPath(path)) - throw Error(format("path %1% exists, but does not have hash %2%") - % path % (string) hash); - - debug(format("path %1% already has hash %2%") - % path % (string) hash); - - } else { - - /* Do we know a path with that hash? If so, copy it. */ - string path2 = queryPathByHash(hash); - copyPath(path2, path); - - } -#endif - return nf; } diff --git a/src/globals.cc b/src/globals.cc index 40a5a981b871..9893d7ad22b4 100644 --- a/src/globals.cc +++ b/src/globals.cc @@ -4,8 +4,11 @@ string dbHash2Paths = "hash2paths"; string dbSuccessors = "successors"; +string dbSubstitutes = "substitutes"; + string nixStore = "/UNINIT"; +string nixDataDir = "/UNINIT"; string nixLogDir = "/UNINIT"; string nixDB = "/UNINIT"; @@ -14,4 +17,5 @@ void initDB() { createDB(nixDB, dbHash2Paths); createDB(nixDB, dbSuccessors); + createDB(nixDB, dbSubstitutes); } diff --git a/src/globals.hh b/src/globals.hh index 8d8c63bd7565..0668ac40e57e 100644 --- a/src/globals.hh +++ b/src/globals.hh @@ -52,6 +52,8 @@ extern string dbSubstitutes; derived files. */ extern string nixStore; +extern string nixDataDir; /* !!! fix */ + /* nixLogDir is the directory where we log various operations. */ extern string nixLogDir; diff --git a/src/nix.cc b/src/nix.cc index d6f2db4fefd1..4721563fdff5 100644 --- a/src/nix.cc +++ b/src/nix.cc @@ -37,7 +37,7 @@ static ArgType argType = atpUnknown; Source selection for --install, --dump: - --file / -f: by file name + --file / -f: by file name !!! -> path --hash / -h: by hash Query flags: @@ -87,6 +87,12 @@ static Hash argToHash(const string & arg) } +static FState hash2fstate(Hash hash) +{ + return ATmake("Include(<str>)", ((string) hash).c_str()); +} + + /* Realise (or install) paths from the given Nix fstate expressions. */ static void opInstall(Strings opFlags, Strings opArgs) @@ -98,7 +104,7 @@ static void opInstall(Strings opFlags, Strings opArgs) it != opArgs.end(); it++) { StringSet paths; - realiseFState(termFromHash(argToHash(*it)), paths); + realiseFState(hash2fstate(argToHash(*it)), paths); } } @@ -157,14 +163,16 @@ static void opQuery(Strings opFlags, Strings opArgs) switch (query) { - case qPath: + case qPath: { + StringSet refs; cout << format("%s\n") % - (string) fstatePath(termFromHash(hash)); + (string) fstatePath(realiseFState(termFromHash(hash), refs)); break; + } case qRefs: { StringSet refs; - FState fs = ATmake("Include(<str>)", ((string) hash).c_str()); + FState fs = hash2fstate(hash); fstateRefs(realiseFState(fs, refs), refs); for (StringSet::iterator j = refs.begin(); j != refs.end(); j++) @@ -203,10 +211,8 @@ static void opDump(Strings opFlags, Strings opArgs) string arg = *opArgs.begin(); string path; - if (argType == atpHash) - path = queryPathByHash(parseHash(arg)); - else if (argType == atpPath) - path = arg; + if (argType == atpHash) path = expandHash(parseHash(arg)); + else if (argType == atpPath) path = arg; dumpPath(path, sink); } diff --git a/src/shared.cc b/src/shared.cc index bd165ce9781b..bfd7498de16d 100644 --- a/src/shared.cc +++ b/src/shared.cc @@ -16,6 +16,7 @@ static void initAndRun(int argc, char * * argv) { /* Setup Nix paths. */ nixStore = NIX_STORE_DIR; + nixDataDir = NIX_DATA_DIR; nixLogDir = NIX_LOG_DIR; nixDB = (string) NIX_STATE_DIR + "/nixstate.db"; diff --git a/src/store.cc b/src/store.cc index 38e059a294b5..5a3a4e0678fe 100644 --- a/src/store.cc +++ b/src/store.cc @@ -131,25 +131,53 @@ bool isInPrefix(const string & path, const string & _prefix) } -static string queryPathByHashPrefix(Hash hash, const string & prefix) +string expandHash(const Hash & hash, const string & target, + const string & prefix) { Strings paths; + if (!target.empty() && !isInPrefix(target, prefix)) + abort(); + if (!queryListDB(nixDB, dbHash2Paths, hash, paths)) throw Error(format("no paths known with hash `%1%'") % (string) hash); - /* Arbitrarily pick the first one that exists and still hash the - right hash. */ + /* !!! we shouldn't check for staleness by default --- too slow */ + + /* Pick one equal to `target'. */ + if (!target.empty()) { + + for (Strings::iterator i = paths.begin(); + i != paths.end(); i++) + { + string path = *i; + try { + if (path == target && hashPath(path) == hash) + return path; + } catch (Error & e) { + debug(format("stale path: %1%") % e.msg()); + /* try next one */ + } + } + + } + /* Arbitrarily pick the first one that exists and isn't stale. */ for (Strings::iterator it = paths.begin(); it != paths.end(); it++) { string path = *it; try { - if (isInPrefix(path, prefix) && hashPath(path) == hash) - return path; + if (isInPrefix(path, prefix) && hashPath(path) == hash) { + if (target.empty()) + return path; + else { + copyPath(path, target); + return target; + } + } } catch (Error & e) { - debug(format("checking hash: %1%") % e.msg()); + debug(format("stale path: %1%") % e.msg()); /* try next one */ } } @@ -157,16 +185,7 @@ static string queryPathByHashPrefix(Hash hash, const string & prefix) throw Error(format("all paths with hash `%1%' are stale") % (string) hash); } - -string expandHash(const Hash & hash, const string & outPath = "") -{ -string queryPathByHash(Hash hash) -{ - return queryPathByHashPrefix(hash, "/"); -} - - void addToStore(string srcPath, string & dstPath, Hash & hash) { srcPath = absPath(srcPath); @@ -174,7 +193,7 @@ void addToStore(string srcPath, string & dstPath, Hash & hash) hash = hashPath(srcPath); try { - dstPath = queryPathByHashPrefix(hash, nixStore); + dstPath = expandHash(hash, "", nixStore); return; } catch (...) { } diff --git a/src/store.hh b/src/store.hh index f747b7ee3aa8..8b02cba99681 100644 --- a/src/store.hh +++ b/src/store.hh @@ -13,15 +13,15 @@ void copyPath(string src, string dst); /* Register a path keyed on its hash. */ Hash registerPath(const string & path, Hash hash = Hash()); -/* Return a path whose contents have the given hash. If outPath is - not empty, ensure that such a path is realised in outPath (if +/* 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 empty, only return a path that is an descendent of prefix. If no path with the given hash is known to exist in the file - system, ... + system, */ -string expandHash(const Hash & hash, const string & outPath = "", +string expandHash(const Hash & hash, const string & target = "", const string & prefix = "/"); /* Copy a file to the nixStore directory and register it in dbRefs. |