virtual bool Run(P4Task& task, const CommandArgs& args) { // Old version used "changes -l -s submitted ...#>have" but that does not include submitted // changelist only containing files not already synced to current workspace ie. newly added // files from another client. // Instead do as the p4v tool does: // Run a fstat on entire workspace and get headChange for all files. This will give the // most recent changelist available. // On the same fstate get the headRev and haveRev revision for each file. If they are not equal // then record the changelist id. ClearStatus(); m_Changelists.clear(); Conn().Log().Info() << args[0] << "::Run()" << Endl; // const std::string cmd = string("fstat -T \"depotFile headChange haveRev headRev headAction action\" //depot/..."); string rootPathWildcard = TrimEnd(TrimEnd(task.GetProjectPath(), '/'), '\\') + "/..."; const std::string cmd = string("fstat -T \"depotFile headChange haveRev headRev headAction action\" \"") + rootPathWildcard + "\""; Conn().BeginList(); if (!task.CommandRun(cmd, this)) { // The OutputStat and other callbacks will now output to stdout. // We just wrap up the communication here. m_Changelists.clear(); Conn().EndList(); Conn() << GetStatus(); Conn().EndResponse(); return true; } // Fetch the descriptions for the incoming changelists. // @TODO: could save some roundtrips by make only one changes call for each sequence of // changelist ids. stringstream ss; for (set<int>::const_iterator i = m_Changelists.begin(); i != m_Changelists.end(); ++i) { ss.str(""); ss << "changes -l -s submitted \"@" << *i << ",@" << *i << "\""; Conn().Log().Info() << " " << ss.str() << Endl; if (!task.CommandRun(ss.str(), this)) { break; } } m_Changelists.clear(); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Conn().EndList(); Conn() << GetStatus(); Conn().EndResponse(); return true; }
bool P4FileSetBaseCommand::Run(P4Task& task, const CommandArgs& args) { ClearStatus(); Conn().Log().Info() << args[0] << "::Run()" << Endl; string cmd = SetupCommand(args); VersionedAssetList assetList; Conn() >> assetList; string paths = ResolvePaths(assetList, GetResolvePathFlags()); Conn().Log().Debug() << "Paths resolved are: " << paths << Endl; if (paths.empty()) { Conn().WarnLine("No paths in fileset perforce command", MARemote); Conn().EndResponse(); return true; } cmd += " " + paths; task.CommandRun(cmd, this); Conn() << GetStatus(); // Stat the files to get the most recent state. // This could probably be optimized by reading the output of the specific // commands and figure out the new state. RunAndSendStatus(task, assetList); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Conn().EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); Conn().Log().Info() << args[0] << "::Run()" << Endl; const string cmd = string("changes -s pending -u ") + Quote(task.GetP4User()) + " -c " + Quote(task.GetP4Client()); Conn().BeginList(); // The default list is always there Changelist defaultItem; const char * kDefaultList = "default"; defaultItem.SetDescription(kDefaultList); defaultItem.SetRevision(kDefaultListRevision); Conn() << defaultItem; task.CommandRun(cmd, this); Conn().EndList(); Conn() << GetStatus(); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Conn().EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { if (!task.IsConnected()) // Cannot login without being connected { Conn().Log().Info() << "Cannot login when not connected" << Endl; return false; } ClearStatus(); m_LoggedIn = false; m_Password = task.GetP4Password(); m_CheckingForLoggedIn = args.size() > 1; const string cmd = string("login") + (m_CheckingForLoggedIn ? string(" " ) + args[1] : string()); if (!task.CommandRun(cmd, this) && !m_CheckingForLoggedIn) { string errorMessage = GetStatusMessage(); Conn().Log().Notice() << "ERROR: " << errorMessage << Endl; } if (m_CheckingForLoggedIn) Conn().Log().Debug() << "Is logged in: " << (m_LoggedIn ? "yes" : "no") << Endl; else Conn().Log().Info() << "Login " << (m_LoggedIn ? "succeeded" : "failed") << Endl; m_CheckingForLoggedIn = false; return m_LoggedIn; }
void P4StatusCommand::RunAndSend(P4Task& task, const VersionedAssetList& assetList, bool recursive) { string paths = ResolvePaths(assetList, kPathWild | kPathSkipFolders | (recursive ? kPathRecursive : kNone) ); Pipe().Log().Debug() << "Paths to stat are: " << paths << unityplugin::Endl; Pipe().BeginList(); if (paths.empty()) { Pipe().EndList(); // Pipe().ErrorLine("No paths to stat", MASystem); return; } string cmd = "fstat -T \"depotFile,clientFile,action,ourLock,unresolved,headAction,otherOpen,otherLock,headRev,haveRev\" "; cmd += " " + paths; // We're sending along an asset list with an unknown size. task.CommandRun(cmd, this); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Pipe().EndList(); }
virtual bool Run(P4Task& task, const CommandArgs& args) { incomingAssetList.clear(); ClearStatus(); Pipe().Log().Info() << args[0] << "::Run()" << unityplugin::Endl; string cmd = "sync"; VersionedAssetList assetList; Pipe() >> assetList; string paths = ResolvePaths(assetList, kPathWild | kPathRecursive); Pipe().Log().Debug() << "Paths resolved are: " << paths << unityplugin::Endl; if (paths.empty()) { Pipe().WarnLine("No paths in getlatest perforce command", MARemote); Pipe().EndResponse(); return true; } cmd += " " + paths; task.CommandRun(cmd, this); Pipe() << GetStatus(); // Stat the files to get the most recent state. // This could probably be optimized by reading the output of the command better RunAndSendStatus(task, incomingAssetList); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Pipe().EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); m_ProjectPath = task.GetP4Root(); ChangelistRevision cl; upipe >> cl; upipe.BeginList(); vector<string> toks; if (Tokenize(toks, m_ProjectPath, "/") == 0) { upipe.ErrorLine(string("Project path invalid - ") + m_ProjectPath); upipe.EndList(); upipe.ErrorLine("Invalid project path", MARemote); upipe.EndResponse(); return true; } upipe.Log() << "Project path is " << m_ProjectPath << endl; string rev = cl == kDefaultListRevision ? string("default") : cl; const std::string cmd = string("describe -s ") + rev; task.CommandRun(cmd, this); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. upipe.EndList(); upipe << GetStatus(); upipe.EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { if (!task.IsConnected()) // Cannot logout without being connected { Pipe().Log().Info() << "Cannot logout when not connected" << unityplugin::Endl; return false; } ClearStatus(); if (!task.CommandRun("logout", this)) { string errorMessage = GetStatusMessage(); Pipe().Log().Notice() << errorMessage << unityplugin::Endl; } return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); m_ProjectPath = task.GetP4Root(); m_Result.clear(); ChangelistRevision cl; Pipe() >> cl; vector<string> toks; if (Tokenize(toks, m_ProjectPath, "/") == 0) { Pipe().BeginList(); Pipe().WarnLine(string("Project path invalid - ") + m_ProjectPath); Pipe().EndList(); Pipe().EndResponse(); return true; } Pipe().Log().Debug() << "Project path is " << m_ProjectPath << unityplugin::Endl; string rev = cl == kDefaultListRevision ? string("default") : cl; const std::string cmd = string("describe -s ") + rev; task.CommandRun(cmd, this); if (!MapToLocal(task, m_Result)) { // Abort since there was an error mapping files to depot path Pipe().BeginList(); Pipe().WarnLine("Files couldn't be mapped in perforce view"); Pipe().EndList(); Pipe().EndResponse(); return true; } Pipe() << m_Result; m_Result.clear(); Pipe() << GetStatus(); Pipe().EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); Conn().Log().Info() << "ChangeDescriptionCommand::Run()" << Endl; ChangelistRevision cl; Conn() >> cl; const string cmd = string("change -o ") + (cl == kDefaultListRevision ? string("") : cl); task.CommandRun(cmd, this); Conn() << GetStatus(); // The OutputState and other callbacks will now output to stdout. // We just wrap up the communication here. Conn().EndResponse(); return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); Conn().Log().Info() << args[0] << "::Run()" << Endl; bool noLocalFileMove = args.size() > 1 && args[1] == "noLocalFileMove"; VersionedAssetList assetList; Conn() >> assetList; if ( assetList.empty() ) { Conn().EndResponse(); return true; } // Process two assets at a time ie. src,dest if ( assetList.size() % 2 ) { Conn().WarnLine("uneven number of assets during move", MASystem); Conn().EndResponse(); return true; } VersionedAssetList::const_iterator b = assetList.begin(); VersionedAssetList::const_iterator e = b; // Split into two steps. 1st make everything editable and 2nd do the move. // this makes changes more atomic. while (b != assetList.end()) { e += 2; const VersionedAsset& src = *b; string paths = ResolvePaths(b, e, kPathWild | kPathRecursive); Conn().Log().Debug() << "Ensure editable source " << paths << Endl; string err; bool editable = (src.GetState() & (kCheckedOutLocal | kAddedLocal | kLockedLocal)) != 0; if (!editable) { string srcPath = ResolvePaths(b, b+1, kPathWild | kPathRecursive); Conn().Log().Info() << "edit " << srcPath << Endl; if (!task.CommandRun("edit " + srcPath, this)) { break; } } b = e; } b = assetList.begin(); e = b; VersionedAssetList targetAssetList; string noLocalFileMoveFlag = noLocalFileMove ? " -k " : ""; while (!HasErrors() && b != assetList.end()) { e += 2; const VersionedAsset& src = *b; const VersionedAsset& dest = *(b+1); targetAssetList.push_back(dest); string paths = ResolvePaths(b, e, kPathWild | kPathRecursive); Conn().Log().Info() << "move " << noLocalFileMoveFlag << paths << Endl; if (!task.CommandRun("move " + noLocalFileMoveFlag + paths, this)) { break; } // Make the actual file system move if perforce didn't do it ie. in // the case of an empty folder rename or a non versioned asset/folder move/rename if (!PathExists(dest.GetPath())) { // Move the file if (!MoveAFile(src.GetPath(), dest.GetPath())) { string errorMessage = "Error moving file "; errorMessage += src.GetPath(); errorMessage += " to "; errorMessage += dest.GetPath(); Conn().WarnLine(errorMessage); } } // Delete move folder src since perforce leaves around empty folders. // This only works because unity will not send embedded moves. if (src.IsFolder() && IsDirectory(src.GetPath())) { DeleteRecursive(src.GetPath()); } b = e; } // We just wrap up the communication here. Conn() << GetStatus(); RunAndSendStatus(task, targetAssetList); Conn().EndResponse(); return true; }