From 1c0b052243da4c6ccd7d49e75eaf2d3123e90354 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Thu, 28 Jun 2007 11:05:11 +0000 Subject: [PATCH] before merging executeAndPrintShellCommand to runProgram --- scripts/nix-statecommit.sh.in | 2 +- src/libstore/local-store.cc | 14 +---- src/libstore/store-state.cc | 15 ++--- src/libutil/util.cc | 102 ++++++++++++++++++++++++++++------ src/libutil/util.hh | 4 +- src/nix-state/nix-state.cc | 24 ++++---- 6 files changed, 111 insertions(+), 50 deletions(-) diff --git a/scripts/nix-statecommit.sh.in b/scripts/nix-statecommit.sh.in index 7f8b73662..7fe55d628 100755 --- a/scripts/nix-statecommit.sh.in +++ b/scripts/nix-statecommit.sh.in @@ -145,7 +145,7 @@ do let "i_checkout+=1" done - if ! test -d "${path}.svn/"; then #if the dir exists but is not yet an svn dir: checkout repos, if it doenst exits (is removed or something) than we dont do anything + if ! test -d "${path}.svn/"; then #if the dir exists but is not yet an svn dir: checkout repos, if it doenst exits (is removed or something) than we dont do anything if [ "$deletesvn" != "1" ]; then $debug $checkoutcommand; fi diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 0077e838f..df1e3781b 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -507,17 +507,15 @@ void LocalStore::queryStateReferrers(const Path & storePath, PathSet & stateRefe void setDeriver(const Transaction & txn, const Path & storePath, const Path & deriver) { - printMsg(lvlError, format("xxxxxxxxxxxxxxxxxxxxxxx")); - assertStorePath(storePath); - printMsg(lvlError, format("Ttttttttttttttttttttttttt")); if (deriver == "") return; - printMsg(lvlError, format("uuuuuuuuuuuuuuuuuuuuuuuuuuuuu")); assertStorePath(deriver); - printMsg(lvlError, format("yyyyyyyyyyyyyyyyyyyyyyyyy")); + printMsg(lvlError, format("yyyyyyyyyyyyyyyyyyyyyyyyy")); //hanged !!!!!!!! if (!isRealisablePath(txn, storePath)) throw Error(format("path `%1%' is not valid") % storePath); + + printMsg(lvlError, format("Ttttttttttttttttttttttttt %1%") % deriver); if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component printMsg(lvlError, format("bbbbbbbbbbbbbbb")); @@ -538,19 +536,13 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path if (!isRealisablePath(txn, storePath)) throw Error(format("path `%1%' is not valid") % storePath); - printMsg(lvlError, format("dddddddddddddd")); - Derivation drv = derivationFromPath(deriver); string identifier = drv.stateOutputs.find("state")->second.stateIdentifier; string user = drv.stateOutputs.find("state")->second.username; - printMsg(lvlError, format("eeeeeeeeeeeeeeeeee")); - PathSet currentDerivers = queryDerivers(txn, storePath, identifier, user); PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true); - printMsg(lvlError, format("ffffffffffffffffffff")); - Strings data; for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i) //Convert Paths to Strings data.push_back(*i); diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 91783e61e..778367693 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -19,13 +19,10 @@ namespace nix { void updatedStateDerivation(Path storePath) { //We dont remove the old .svn folders - //New repostorys are created by createStateDirs + //nothing to do since New repostorys are created by createStateDirs printMsg(lvlTalkative, format("Resetting state drv settings like repositorys")); - - //Create a repository for this state location - - // + } void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs, const StringPairs & env) @@ -42,7 +39,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De //Make sure the 'root' path which holds the repositorys exists, so svn doenst complain. string repos_root_path = getStateReposRootPath("stateOutput:staterepospath", stateDir, drvName, stateIdentifier); - executeAndPrintShellCommand("mkdir -p " + repos_root_path, "mkdir"); + executeAndPrintShellCommand("mkdir -p " + repos_root_path, "mkdir", true); //TODO check if we can create state and staterepos dirs @@ -55,7 +52,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De //Check if and how this dir needs to be versioned if(d.type == "none"){ - executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir"); + executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir", true); continue; } @@ -66,7 +63,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De if(IsDirectory(repos)) printMsg(lvlTalkative, format("Repos %1% already exists, so we use that repository") % repos); else - executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit then ?? + executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin", true); //TODO create as nixbld.nixbld chmod 700... can you still commit then ?? if(d.type == "interval"){ intervalPaths.insert(statePath); @@ -77,7 +74,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De string fullstatedir_svn = fullstatedir + "/.svn/"; if( ! IsDirectory(fullstatedir_svn) ){ string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir; - executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user + executeAndPrintShellCommand(checkoutcommand, "svn", true); //TODO checkout as user } else printMsg(lvlTalkative, format("Statedir %1% already exists, so dont check out its repository again") % fullstatedir_svn); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index d0d7aeed6..0dfef7763 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -934,6 +934,47 @@ Strings tokenizeString(const string & s, const string & separators) return result; } +//Splits on a space +//Uses quotes: "...." to group multiple spaced arguments into one +//Removes the grouping quotes at the call +//TODO bug a call with args: a b "c" d will fail +//TODO bug a call with args: a bc"d " e will fail +Strings tokenizeStringWithQuotes(const string & s) +{ + string separator = " "; + Strings result; + string::size_type pos = s.find_first_not_of(separator, 0); + + string quote = "\""; + string inquotes = ""; + + while (pos != string::npos) { + string::size_type end = s.find_first_of(separator, pos + 1); + if (end == string::npos) end = s.size(); + string token(s, pos, end - pos); + + pos = s.find_first_not_of(separator, end); + + //if first or last item is a quote, we switch inquotes + if(token.substr(0,1) == quote || token.substr(token.size()-1,token.size()) == quote){ + if(inquotes == ""){ //begin + inquotes = token; + continue; + } + else{ //end + token = inquotes + token; + token = token.substr(1,token.size()-2); //remove the grouping quotes + inquotes = ""; + } + } + + if(inquotes != "") //middle + inquotes += separator + token; + else + result.push_back(token); //normal + } + return result; +} string statusToString(int status) { @@ -1028,10 +1069,30 @@ string trim(const string & s) { */ -void executeAndPrintShellCommand(const string & command, const string & commandName) +void executeAndPrintShellCommand(const string & command, const string & commandName, const bool & captureOutput) { + /////////////////////// + + if(captureOutput){ + Strings progam_args = tokenizeStringWithQuotes(command); + string program_command = progam_args.front(); + progam_args.pop_front(); + + string program_output = runProgram(program_command, true, progam_args); + + //Remove the trailing \n + size_t found = program_output.find_last_of("\n"); + printMsg(lvlError, format("%1%") % program_output.substr(0,found)); + return; + } + + ///////////////////// + string tempoutput = "/tmp/svnoutput.txt"; - string newcommand = command + " &> " + tempoutput; //the &> sends also stderr to stdout + string newcommand = command; + + if(captureOutput) + newcommand += " &> " + tempoutput; //the &> sends also stderr to stdout int kidstatus, deadpid; pid_t kidpid = fork(); @@ -1045,38 +1106,43 @@ void executeAndPrintShellCommand(const string & command, const string & commandN string line; std::ifstream myfile (tempoutput.c_str()); - if (myfile.is_open()){ - while (! myfile.eof() ) - { - getline (myfile,line); - if(trim(line) != "") - printMsg(lvlError, format("[%2%]: %1%") % line % commandName); - } - myfile.close(); + + if(captureOutput){ + if (myfile.is_open()){ + while (! myfile.eof() ) + { + getline (myfile,line); + if(trim(line) != "") + printMsg(lvlError, format("[%2%]: %1%") % line % commandName); + } + myfile.close(); + } + else{ + throw SysError("executeAndPrintShellCommand(..) error"); + quickExit(1); + } } - else{ - throw SysError("svn state error"); - quickExit(1); - } if (rv == -1) { - throw SysError("svn state error"); + throw SysError("executeAndPrintShellCommand(..) error"); quickExit(99); } quickExit(0); } catch (std::exception & e) { - std::cerr << format("state child error: %1%\n") % e.what(); + std::cerr << format("executeAndPrintShellCommand(..) child error: %1%\n") % e.what(); quickExit(1); } } + deadpid = waitpid(kidpid, &kidstatus, 0); if (deadpid == -1) { std::cerr << format("state child waitpid error\n"); quickExit(1); } - remove(tempoutput.c_str()); //Remove the tempoutput file + if(captureOutput) + remove(tempoutput.c_str()); //Remove the tempoutput file } string time_t2string(const time_t & t) @@ -1121,7 +1187,7 @@ string getCallingUserName() Strings empty; string username = runProgram("whoami", true, empty); //the username of the user that is trying to build the component //TODO Can be faked, so this is clearly unsafe ... :( - //Remove the \n + //Remove the trailing \n int pos = username.find("\n",0); username.erase(pos,1); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index da9e82dea..bf70230e9 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -267,6 +267,8 @@ Strings unpackStrings(const string & s); /* String tokenizer. */ Strings tokenizeString(const string & s, const string & separators = " \t\n\r"); +/* String tokenizer for commandline agruments. */ +Strings tokenizeStringWithQuotes(const string & s); /* Convert the exit status of a child as returned by wait() into an error string. */ @@ -291,7 +293,7 @@ string trimr(const string & s); string trim(const string & s); //excecute a shell command -void executeAndPrintShellCommand(const string & command, const string & commandName); +void executeAndPrintShellCommand(const string & command, const string & commandName, const bool & captureOutput); //Convert time_t to a string string time_t2string(const time_t & t); diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 9a12956fa..d87f15011 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -67,9 +67,7 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c if(opArgs.size() > 1){ opArgs.pop_front(); allargs = opArgs.front(); - - Strings progam_args; - //TODO !!!!!!!!!!!!!!!!!!!!!! + Strings progam_args = tokenizeString(allargs, " "); } printMsg(lvlError, format("'%1%' - '%2%' - '%3%' - '%4%' - '%5%'") % componentPath % stateIdentifier % binary % username % allargs); @@ -212,7 +210,11 @@ static void opRunComponent(Strings opFlags, Strings opArgs) //Transaction txn; //createStoreTransaction(txn); //txn.commit(); - + + //******************* Run **************************** + + executeAndPrintShellCommand(componentPath + binary, "", false); //more efficient way needed ??? + //******************* With everything in place, we call the commit script on all statePaths ********************** for (PathSet::iterator d = drvs.begin(); d != drvs.end(); ++d) @@ -320,7 +322,10 @@ static void opRunComponent(Strings opFlags, Strings opArgs) " \"" + subversionedpathsCommitBooleansarray + "\" " + " \"" + nonversionedstatepathsarray + "\" " + " \"" + commandsarray + "\" ", - "commit-script"); + "commit-script", true); + + //TODO + //Scan again?? } } @@ -368,7 +373,7 @@ void run(Strings args) return; */ - + /* test */ for (Strings::iterator i = args.begin(); i != args.end(); ) { @@ -376,7 +381,7 @@ void run(Strings args) Operation oldOp = op; - if (arg == "--commit" || arg == "-c") + if (arg == "--run" || arg == "-r") op = opRunComponent; else if (arg == "--showstatepath") op = opShowStatePath; @@ -386,8 +391,9 @@ void run(Strings args) op = opShowDerivations; /* - --commit + --commit + --run-without-commit --backup @@ -418,8 +424,6 @@ void run(Strings args) if(username == "") username = getCallingUserName(); - printMsg(lvlError, format("%1% - %2%") % stateIdentifier % username); - if (!op) throw UsageError("no operation specified"); /* !!! hack */