From f3dabd62063ad3fc5171b9d063a804f72c715b49 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Thu, 12 Jul 2007 14:46:15 +0000 Subject: [PATCH] before making computeFSClosure recursively transactional ..... (adding Transaction txn) --- src/libstore/Makefile.am | 2 +- src/libstore/build.cc | 17 +++- src/libstore/db.cc | 13 ++- src/libstore/local-store.cc | 66 +++--------- src/libstore/local-store.hh | 5 + src/libstore/remote-store.cc | 11 ++ src/libstore/remote-store.hh | 4 + src/libstore/store-api.hh | 4 + src/libstore/store-state.cc | 157 +++++++++++++++++++++++++++++ src/libstore/store-state.hh | 11 ++ src/nix-state/nix-state.cc | 188 ++++------------------------------- 11 files changed, 246 insertions(+), 232 deletions(-) diff --git a/src/libstore/Makefile.am b/src/libstore/Makefile.am index 2d3c70c77..9e31d7a92 100644 --- a/src/libstore/Makefile.am +++ b/src/libstore/Makefile.am @@ -17,7 +17,7 @@ BUILT_SOURCES = derivations-ast.cc derivations-ast.hh EXTRA_DIST = derivations-ast.def derivations-ast.cc AM_CXXFLAGS = -Wall \ - -I$(srcdir)/.. ${bdb_include} ${aterm_include} -I$(srcdir)/../libutil + -I$(srcdir)/.. ${bdb_include} ${aterm_include} -I$(srcdir)/../libutil -I$(srcdir)/../nix-state derivations-ast.cc derivations-ast.hh: ../aterm-helper.pl derivations-ast.def $(perl) $(srcdir)/../aterm-helper.pl derivations-ast.hh derivations-ast.cc < $(srcdir)/derivations-ast.def diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 5d09ef123..9e1a6c2ee 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -7,7 +7,6 @@ #include "util.hh" #include "store-state.hh" - #include #include #include @@ -1787,15 +1786,22 @@ void DerivationGoal::computeClosure() //Register the state path valid if(isStateDrvTxn(txn, drv)) { - //TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!! - - Path statePath = drv.stateOutputs.find("state")->second.statepath; + //TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!! (why?) + Path statePath = drv.stateOutputs.find("state")->second.statepath; + registerValidPath(txn, statePath, Hash(), //emtpy hash state_references, state_stateReferences, - drvPath, 0); + drvPath, 0); //TODO !!!!!!!!!!!! + + //Commit state + commitStatePathTxn(txn, statePath); + + //Set first revision (if we committed something) + if(readRevisionNumber(statePath) == 1) + updateRevisionsRecursivelyTxn(txn, statePath); } txn.commit(); @@ -2104,6 +2110,7 @@ void SubstitutionGoal::tryToRun() logPipe.create(); /* Remove the (stale) output path if it exists. */ + /* TODO also remove state Path ? */ if (pathExists(storePath)) deletePathWrapped(storePath); diff --git a/src/libstore/db.cc b/src/libstore/db.cc index f935f0846..8b548a0ba 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -449,9 +449,9 @@ void Database::enumTable(const Transaction & txn, TableId table, Path Database::makeStatePathRevision(const Path & statePath, const int revision) { string prefix = "-REV-"; - return statePath + prefix + int2String(revision); } + void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision) { string prefix = "-REV-"; @@ -606,8 +606,7 @@ void Database::setStateRevisions(const Transaction & txn, TableId table, //Debugging //for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i) // printMsg(lvlError, format("Insert: %1% into %2%") % int2String(revisions.at(*i)) % *i); - - + //Convert the int's into Strings Strings data; for (RevisionNumbers::const_iterator i = sorted_revisions.begin(); i != sorted_revisions.end(); ++i) { @@ -639,13 +638,17 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table, const Strings data; bool notempty = queryStrings(txn, table, key, data); //now that we have the key, we can query the revisions - + + //Check + if(statePath_deps.size() != data.size()) + throw Error(format("The number of statepath references doenst equal the number of revisions for '%1%'") % statePath); + //sort all state references recursively vector sortedStatePaths; for (PathSet::iterator i = statePath_deps.begin(); i != statePath_deps.end(); ++i) sortedStatePaths.push_back(*i); sort(sortedStatePaths.begin(), sortedStatePaths.end()); - + //Convert the Strings into int's and match them to the sorted statePaths for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i){ string getRevisionS = data.front(); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 048761851..e35540fc5 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -13,6 +13,8 @@ #include "derivations.hh" #include "misc.hh" +#include "store-state.hh" + #include #include @@ -668,8 +670,6 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path } -//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! remove this entire function, replace by - /* * Returns true or false wheter a store-component has a state component (e.g. has a state dir) or not. * Do NOT confuse this function with isValidStatePath @@ -1643,57 +1643,6 @@ void LocalStore::storePathRequisites(const Path & storeOrstatePath, const bool i return nix::storePathRequisites(storeOrstatePath, includeOutputs, paths, withComponents, withState, revision); } -/* - * TODO - * - * Not used yet ......................... (should we use it .... ???) - * - */ -/* -void getDependenciesAtBuildTime(const Transaction & txn, const Path & drvPath) -{ - Derivation drv = derivationFromPath(drvPath); - PathSet allPaths; - PathSet inputPaths; - - //TODO THIS IS A DIRECT COPY FROM BUILD.CC WE SHOULD MERGE !!!!!!!!!!!!1!!!!!!!!!!!!! - - // The outputs are referenceable paths. - for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i) - { - debug(format("building path `%1%'") % i->second.path); - allPaths.insert(i->second.path); - } - - // First, the input derivations. - for (DerivationInputs::iterator i = drv.inputDrvs.begin(); - i != drv.inputDrvs.end(); ++i) - { - // Add the relevant output closures of the input derivation - // `*i' as input paths. Only add the closures of output paths - // that are specified as inputs. - assert(store->isValidPath(i->first)); - Derivation inDrv = derivationFromPath(i->first); - for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j) - if (inDrv.outputs.find(*j) != inDrv.outputs.end()) - computeFSClosure(inDrv.outputs[*j].path, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE - else - throw Error(format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") % drvPath % *j % i->first); - } - - // Second, the input sources. - for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i) - computeFSClosure(*i, inputPaths, true, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE - - //debug(format("added input paths %1%") % showPaths(inputPaths)); //TODO - allPaths.insert(inputPaths.begin(), inputPaths.end()); - - for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i) - printMsg(lvlError, format("ALLPATHS2: %1%") % *i); -} -*/ - - void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, PathSet & allStatePaths) { Paths allComponentPaths2; @@ -1725,6 +1674,8 @@ bool queryStateRevisionsTxn(const Transaction & txn, const Path & statePath, Rev { PathSet statePaths; storePathRequisites(statePath, false, statePaths, false, true, revision); //Get all current state dependencies + statePaths.insert(statePath); //also insert the root statePath + return nixDB.queryStateRevisions(txn, dbStateRevisions, statePaths, statePath, revisions, revision); } @@ -1743,8 +1694,15 @@ bool LocalStore::queryAvailableStateRevisions(const Path & statePath, RevisionNu return nix::queryAvailableStateRevisionsTxn(noTxn, statePath, revisions); } +void LocalStore::commitStatePath(const Path & statePath) +{ + nix::commitStatePathTxn(noTxn, statePath); +} - +void LocalStore::updateRevisionsRecursively(const Path & statePath) +{ + nix::updateRevisionsRecursivelyTxn(noTxn, statePath); +} /* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */ static void upgradeStore07() diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 09af5c70e..eecf8af59 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -106,6 +106,9 @@ public: bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions); + void commitStatePath(const Path & statePath); + + void updateRevisionsRecursively(const Path & statePath); }; @@ -225,6 +228,8 @@ bool isValidStatePathTxn(const Transaction & txn, const Path & path); void queryReferencesTxn(const Transaction & txn, const Path & path, PathSet & references, const int revision); void queryStateReferencesTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferences, const int revision); Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath); +void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision); +void setStateRevisionsTxn(const Transaction & txn, const Path & statePath, const RevisionNumbersSet & revisions); } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 88fbfbbeb..976f09d1c 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -486,5 +486,16 @@ bool RemoteStore::queryAvailableStateRevisions(const Path & statePath, RevisionN return false; } +//TODO +void RemoteStore::commitStatePath(const Path & statePath) +{ + +} + +//TODO +void RemoteStore::updateRevisionsRecursively(const Path & statePath) +{ + +} } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index beea481b1..519d10b02 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -93,6 +93,10 @@ public: bool queryStateRevisions(const Path & statePath, RevisionNumbersSet & revisions, const int revision); bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions); + + void commitStatePath(const Path & statePath); + + void updateRevisionsRecursively(const Path & statePath); private: AutoCloseFD fdSocket; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 0c9dbe50d..b9e15ea27 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -227,6 +227,10 @@ public: /* TODO */ virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0; + + virtual void commitStatePath(const Path & statePath) = 0; + + virtual void updateRevisionsRecursively(const Path & statePath) = 0; }; diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index e15779d04..d3d7ca27c 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -12,6 +12,8 @@ #include "derivations.hh" #include "store-api.hh" #include "local-store.hh" +#include "misc.hh" +#include "archive.hh" namespace nix { @@ -89,5 +91,160 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De store->setStatePathsInterval(intervalPaths, empty, true); } +void commitStatePathTxn(const Transaction & txn, const Path & statePath) +{ + if(!isValidStatePathTxn(txn, statePath)) + throw Error(format("path `%1%' is not a valid state path") % statePath); + + + //queryDeriversStatePath?? + Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, statePath)); + + //Extract the neccecary info from each Drv + DerivationStateOutputs stateOutputs = drv.stateOutputs; + //Path statePath = stateOutputs.find("state")->second.statepath; + DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs; + + //Specifiy the SVN binarys + string svnbin = nixSVNPath + "/svn"; + string svnadminbin = nixSVNPath + "/svnadmin"; + + //Print + printMsg(lvlError, format("Committing statePath: %1%") % statePath); + + //Vector includeing all commit scripts: + vector subversionedpaths; + vector subversionedpathsCommitBoolean; + vector nonversionedpaths; //of type none, no versioning needed + + //Get all the inverals from the database at once + PathSet intervalPaths; + for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){ + DerivationStateOutputDir d = i->second; + + string thisdir = d.path; + string fullstatedir = statePath + "/" + thisdir; + + if(d.type == "interval"){ + intervalPaths.insert(fullstatedir); + } + } + vector intervals = store->getStatePathsInterval(intervalPaths); //TODO !!!!!!!!!!!!! txn ?? + + int intervalAt=0; + for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){ + DerivationStateOutputDir d = i->second; + string thisdir = d.path; + + string fullstatedir = statePath + "/" + thisdir; + if(thisdir == "/") //exception for the root dir + fullstatedir = statePath + "/"; + + if(d.type == "none"){ + nonversionedpaths.push_back(fullstatedir); + continue; + } + + subversionedpaths.push_back(fullstatedir); + + if(d.type == "interval"){ + //Get the interval-counter from the database + int interval_counter = intervals[intervalAt]; + int interval = d.getInterval(); + subversionedpathsCommitBoolean.push_back(interval_counter % interval == 0); + + //update the interval + intervals[intervalAt] = interval_counter + 1; + intervalAt++; + } + else if(d.type == "full") + subversionedpathsCommitBoolean.push_back(true); + else if(d.type == "manual") //TODO !!!!! + subversionedpathsCommitBoolean.push_back(false); + else + throw Error(format("interval '%1%' is not handled in nix-state") % d.type); + } + + //Get the a repository for this state location + string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc + string checkoutcommand = svnbin + " --ignore-externals checkout file://" + repos + " " + statePath; + + //Call the commit script with the appropiate paramenters + string subversionedstatepathsarray; + for (vector::iterator i = subversionedpaths.begin(); i != subversionedpaths.end(); ++i) + subversionedstatepathsarray += *(i) + " "; + + string subversionedpathsCommitBooleansarray; + for (vector::iterator i = subversionedpathsCommitBoolean.begin(); i != subversionedpathsCommitBoolean.end(); ++i) + subversionedpathsCommitBooleansarray += bool2string(*i) + " "; + + string nonversionedstatepathsarray; + for (vector::iterator i = nonversionedpaths.begin(); i != nonversionedpaths.end(); ++i) + nonversionedstatepathsarray += *(i) + " "; + + //make the call to the commit script + Strings p_args; + p_args.push_back(svnbin); + p_args.push_back(subversionedstatepathsarray); + p_args.push_back(subversionedpathsCommitBooleansarray); + p_args.push_back(nonversionedstatepathsarray); + p_args.push_back(checkoutcommand); + p_args.push_back(statePath); + runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-statecommit.sh", true, p_args, "svn"); + + //Update the intervals again + //setStatePathsIntervalTxn(txn, intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! uncomment and txn ?? +} + +void updateRevisionsRecursivelyTxn(const Transaction & txn, const Path & statePath) +{ + //Save all revisions for the call to + RevisionNumbersSet rivisionMapping; + + PathSet statePaths; + storePathRequisites(statePath, false, statePaths, false, true, -1); //Get all current state dependencies + + //Add own statePath (may already be in there, but its a set, so no doubles) + statePaths.insert(statePath); + + //Sort + vector sortedStatePaths; + for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i) + sortedStatePaths.push_back(*i); + sort(sortedStatePaths.begin(), sortedStatePaths.end()); + + //call scanForAllReferences again on all newly found statePaths + for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i) + rivisionMapping[*i] = readRevisionNumber(*i); + + //Store the revision numbers in the database for this statePath with revision number + setStateRevisionsTxn(txn, statePath, rivisionMapping); +} + +int readRevisionNumber(Path statePath) +{ + string svnbin = nixSVNPath + "/svn"; + RevisionNumbers revisions; + + string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc + + //TODO Check if the .svn exists, it might be deleted, then we dont have to remember the state revision (set -1) + + Strings p_args; + p_args.push_back(svnbin); + p_args.push_back("file://" + repos); + string output = runProgram(nixLibexecDir + "/nix/nix-readrevisions.sh", true, p_args); //run + + int pos = output.find("\n",0); //remove trailing \n + output.erase(pos,1); + + int revision; + bool succeed = string2Int(output, revision); + if(!succeed) + throw Error(format("Cannot read revision number of path '%1%'") % repos); + + return revision; +} + } diff --git a/src/libstore/store-state.hh b/src/libstore/store-state.hh index 90fae5720..4fce4c128 100644 --- a/src/libstore/store-state.hh +++ b/src/libstore/store-state.hh @@ -2,12 +2,23 @@ #define __STORESTATE_H #include "derivations.hh" +#include "types.hh" +#include "db.hh" namespace nix { /* Create a state directory. */ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs); +/* TODO */ +void commitStatePathTxn(const Transaction & txn, const Path & statePath); + +/* TODO */ +void updateRevisionsRecursivelyTxn(const Transaction & txn, const Path & statePath); + +/* TODO */ +int readRevisionNumber(Path statePath); + } #endif /* !__STORESTATE_H */ diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index e2bd68b03..c0ddbd4cf 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -11,6 +11,7 @@ #include "local-store.hh" #include "derivations.hh" #include "references.hh" +#include "store-state.hh" using namespace nix; using std::cin; @@ -24,6 +25,7 @@ string stateIdentifier; string username; int revision_arg; bool scanforReferences = false; +bool only_commit = false; /************************* Build time Functions ******************************/ @@ -225,33 +227,6 @@ static void queryAvailableStateRevisions(Strings opFlags, Strings opArgs) printMsg(lvlError, format("Available Revisions: %1%") % revisions_txt); } -int readRevisionNumber(Path statePath) -{ - string svnbin = nixSVNPath + "/svn"; - RevisionNumbers revisions; - - string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc - - //TODO Check if the .svn exists, it might be deleted, then we dont have to remember the state revision (set -1) - - Strings p_args; - p_args.push_back(svnbin); - p_args.push_back("file://" + repos); - string output = runProgram(nixLibexecDir + "/nix/nix-readrevisions.sh", true, p_args); //run - - int pos = output.find("\n",0); //remove trailing \n - output.erase(pos,1); - - int revision; - bool succeed = string2Int(output, revision); - if(!succeed) - throw Error(format("Cannot read revision number of path '%1%'") % repos); - - return revision; -} - - - static void revertToRevision(Strings opFlags, Strings opArgs) { Path componentPath; @@ -415,30 +390,6 @@ void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path } } -void updateRevisionsRecursively(Path statePath) -{ - //Save all revisions for the call to - RevisionNumbersSet rivisionMapping; - - PathSet statePaths; - store->storePathRequisites(statePath, false, statePaths, false, true, -1); //Get all current state dependencies - - //Add own statePath (may already be in there, but its a set, so no doubles) - statePaths.insert(statePath); - - //Sort - vector sortedStatePaths; - for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i) - sortedStatePaths.push_back(*i); - sort(sortedStatePaths.begin(), sortedStatePaths.end()); - - //call scanForAllReferences again on all newly found statePaths - for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i) - rivisionMapping[*i] = readRevisionNumber(*i); - - //Store the revision numbers in the database for this statePath with revision number - store->setStateRevisions(statePath, rivisionMapping); -} static void opRunComponent(Strings opFlags, Strings opArgs) @@ -452,136 +403,34 @@ static void opRunComponent(Strings opFlags, Strings opArgs) string root_program_args; Derivation root_drv = getDerivation_andCheckArgs(opFlags, opArgs, root_componentPath, root_statePath, root_binary, root_derivationPath, root_isStateComponent, root_program_args); - //Specifiy the SVN binarys - string svnbin = nixSVNPath + "/svn"; - string svnadminbin = nixSVNPath + "/svnadmin"; - - //Check for locks ... ? or put locks on the neseccary state components //WARNING: we need to watch out for deadlocks! //add locks ... ? //svn lock ... ? - //get all current dependecies (if neccecary | recusively) of all state components that need to be updated - PathSet root_drvs = getAllStateDerivationsRecursively(root_componentPath, -1); - //TODO WHAT ABOUT YOURSELF?????????? + //get all current dependecies (if neccecary | recusively) of all state components that need to be updated + PathSet statePaths; + store->storePathRequisites(root_componentPath, false, statePaths, false, true, -1); + statePaths.insert(root_statePath); //TODO maybe also scan the parameters for state or component hashes? //program_args - //???? + //TODO Transaction txn; //createStoreTransaction(txn); - //txn.commit(); + //******************* Run **************************** - executeShellCommand(root_componentPath + root_binary + " " + root_program_args); //more efficient way needed ??? + if(!only_commit) + executeShellCommand(root_componentPath + root_binary + " " + root_program_args); //more efficient way needed ??? //******************* With everything in place, we call the commit script on all statePaths (in)directly referenced ********************** - PathSet statePaths; - RevisionNumbersSet rivisionMapping; - - for (PathSet::iterator d = root_drvs.begin(); d != root_drvs.end(); ++d) //TODO first commit own state path? - { - //Extract the neccecary info from each Drv - Path drvPath = *d; - Derivation drv = derivationFromPath(drvPath); - DerivationStateOutputs stateOutputs = drv.stateOutputs; - Path statePath = stateOutputs.find("state")->second.statepath; - DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs; - - //Print - printMsg(lvlError, format("Committing statePath: %1%") % statePath); - - //Vector includeing all commit scripts: - vector subversionedpaths; - vector subversionedpathsCommitBoolean; - vector nonversionedpaths; //of type none, no versioning needed - - //Get all the inverals from the database at once - PathSet intervalPaths; - for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){ - DerivationStateOutputDir d = i->second; - - string thisdir = d.path; - string fullstatedir = statePath + "/" + thisdir; - - if(d.type == "interval"){ - intervalPaths.insert(fullstatedir); - } - } - vector intervals = store->getStatePathsInterval(intervalPaths); //TODO !!!!!!!!!!!!! txn ?? - - int intervalAt=0; - for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){ - DerivationStateOutputDir d = i->second; - string thisdir = d.path; - - string fullstatedir = statePath + "/" + thisdir; - if(thisdir == "/") //exception for the root dir - fullstatedir = statePath + "/"; - - if(d.type == "none"){ - nonversionedpaths.push_back(fullstatedir); - continue; - } - - subversionedpaths.push_back(fullstatedir); - - if(d.type == "interval"){ - //Get the interval-counter from the database - int interval_counter = intervals[intervalAt]; - int interval = d.getInterval(); - subversionedpathsCommitBoolean.push_back(interval_counter % interval == 0); - - //update the interval - intervals[intervalAt] = interval_counter + 1; - intervalAt++; - } - else if(d.type == "full") - subversionedpathsCommitBoolean.push_back(true); - else if(d.type == "manual") //TODO !!!!! - subversionedpathsCommitBoolean.push_back(false); - else - throw Error(format("interval '%1%' is not handled in nix-state") % d.type); - } - - //Get the a repository for this state location - string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc - string checkoutcommand = svnbin + " --ignore-externals checkout file://" + repos + " " + statePath; - - //Call the commit script with the appropiate paramenters - string subversionedstatepathsarray; - for (vector::iterator i = subversionedpaths.begin(); i != subversionedpaths.end(); ++i) - { - subversionedstatepathsarray += *(i) + " "; - } - string subversionedpathsCommitBooleansarray; - for (vector::iterator i = subversionedpathsCommitBoolean.begin(); i != subversionedpathsCommitBoolean.end(); ++i) - { - subversionedpathsCommitBooleansarray += bool2string(*i) + " "; - } - string nonversionedstatepathsarray; - for (vector::iterator i = nonversionedpaths.begin(); i != nonversionedpaths.end(); ++i) - { - nonversionedstatepathsarray += *(i) + " "; - } - - //make the call to the commit script - Strings p_args; - p_args.push_back(svnbin); - p_args.push_back(subversionedstatepathsarray); - p_args.push_back(subversionedpathsCommitBooleansarray); - p_args.push_back(nonversionedstatepathsarray); - p_args.push_back(checkoutcommand); - p_args.push_back(statePath); - runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-statecommit.sh", true, p_args, "svn"); - - //Update the intervals again - //store->setStatePathsInterval(intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! uncomment and txn ?? - } + //Commit all statePaths + for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i) //TODO first commit own state path? + commitStatePathTxn(txn, *i); //Start transaction TODO @@ -590,10 +439,11 @@ static void opRunComponent(Strings opFlags, Strings opArgs) scanAndUpdateAllReferencesRecusivelyTxn(txn, root_statePath); //Get new revision number - updateRevisionsRecursively(root_statePath); + updateRevisionsRecursivelyTxn(txn, root_statePath); - //Commit transaction TODO - + //Commit transaction + //txn.commit(); + //Debugging RevisionNumbersSet getRivisions; bool b = store->queryStateRevisions(root_statePath, getRivisions, -1); @@ -720,6 +570,10 @@ void run(Strings args) if (arg == "--run" || arg == "-r") op = opRunComponent; + else if (arg == "--commit-only"){ + op = opRunComponent; + only_commit = true; + } else if (arg == "--showstatepath") op = opShowStatePath; else if (arg == "--showstatereposrootpath")