public bool revertFileInChangelist(string filepath, P4PendingChangelist list) { string[] args = new string[] { "-c", list.Number.ToString(), filepath }; P4RecordSet setRes = RunCmd("revert", args); // "-c", cl.Number.ToString(), "//depot/path/foo.cs", "//depot/path/bar.cs"); return(true); }
public void parseFromRecordset(P4RecordSet rs) { if (rs.HasErrors()) { } if (rs.HasWarnings()) { for (int i = 0; i < rs.Warnings.Length; i++) { string warning = rs.Warnings[i]; if (warning.Contains("no such file(s)")) { mIsFileInPerforce = false; } } } if (rs.Records.Length != 0) { P4Record stat = rs.Records[0]; //set the bools mIsFileInPerforce = stat["headAction"] != "delete"; mIsFileLatestRevision = stat["headRev"] == stat["haveRev"]; mIsFileCheckedOutByMe = stat["action"] == "actionOwner"; mIsFileCheckedOutByOther = stat["otherOpen0"] != null; } }
private ArrayList getUnpublishedFiles(String path) { this.Cursor = Cursors.WaitCursor; if (scan == false) { int trimIndex = path.IndexOf("art"); path = path.Substring(trimIndex, path.Length - trimIndex); path = "//depot/phoenix/xbox/published/" + path.Replace("\\", "/"); } p4 = new P4Connection(); p4.Connect(); p4I = new P4Interface(); ArrayList unpublished = new ArrayList(); String[] args = { "-n", "-d", "-i", "-t", "-v", "-b", "phx_published", path }; P4RecordSet record = p4I.Run("integrate", args); foreach (P4Record entry in record) { unpublished.Add(entry.Fields["fromFile"]); } this.Cursor = Cursors.Default; return(unpublished); p4.Disconnect(); }
public P4RecordSet SyncFiles(String[] path) { p4.Connect(); P4RecordSet syncFiles = RunCmd("sync", path); p4.Disconnect(); return(syncFiles); }
//--------------------------------- public P4FileStatus getFileStatus(string filepath) { string[] args = new string[] { "-m1", filepath }; P4RecordSet setRes = RunCmd("fstat", args); P4FileStatus fs = new P4FileStatus(); fs.parseFromRecordset(setRes); return(fs); }
public bool isOpenForEdit(string _file) { if (m_connection == null) { return(false); } P4RecordSet p4rs = m_connection.Run("opened", _file); return(p4rs.Records.Length != 0); }
//========================================================================================= // file operation // private bool fileExists(string _file) { if (m_connection == null) { return(false); } P4RecordSet p4rs = m_connection.Run("files", _file); return(p4rs.Records.Length != 0); }
public override void P4Execute() { try { P4RecordSet rs = _p4.Run(_command, _args); _errors.AddRange(rs.Errors); _warnings.AddRange(rs.Warnings); _messages.AddRange(rs.Messages); foreach (string m in _errors) { Log.LogError(m); } int i = 0; foreach (P4Record r in rs) { string itemspec = string.Format("P4Output-{0}-{1:D8}", _command, i); TaskItem item = new TaskItem(itemspec); LogMessage(MessageImportance.High, "{0}", itemspec); foreach (string key in r.Fields.Keys) { LogMessage(MessageImportance.Normal, " {0,-10} : {1}", key, r[key]); item.SetMetadata(key, r[key]); } // array fields will be populated as: // key : arr-<keyname> // value: ';' delimited list foreach (string key in r.ArrayFields.Keys) { string newKey = string.Format("arr-{0}", key); string newVal = string.Empty; foreach (string val in r.ArrayFields[key]) { if (newVal != string.Empty) { newVal += ";"; } newVal += val; } LogMessage(MessageImportance.Normal, " {0,-10} : {1}", newKey, newVal); item.SetMetadata(newKey, newVal); } _parsedOutput.Add(item); i++; } } catch (Exception e) { Log.LogError(e.Message); } }
public ArrayList GetUsers() { ArrayList userList = new ArrayList(); P4RecordSet users = Run("users"); foreach (P4Record user in users) { userList.Add(user.Fields["User"]); } return(userList); }
//----------------------------------------------------------------------------------------- public bool ClientIsValid() { P4RecordSet p4rs = m_connection.Run("clients"); foreach (P4Record p4r in p4rs) { if (p4r["client"] == m_connection.Client && p4r["Host"] == m_connection.Host && p4r["Owner"] == m_connection.User) { return(true); } } return(false); }
public P4RecordSet Run(String command, String[] args) { try { P4RecordSet results = p4.Run(command, args); return(results); } catch (System.Exception e) { MessageBox.Show(e.Message, "Perforce Error!"); return(null); } }
//--------------------------------- public P4RecordSet GetSyncFiles(String[] path) { String[] args = new String[path.Length + 1]; args[0] = "-n"; for (int i = 1; i < args.Length; i++) { args[i] = path[i - 1]; } p4.Connect(); P4RecordSet syncFiles = RunCmd("sync", args); p4.Disconnect(); return(syncFiles); }
public bool addOrCheckout(string _file) { clearError(); if (m_connection == null) { m_error = "Error: perforce not connected"; return(false); } if (isOpenForEdit(_file)) { return(true); } string message = String.Empty; P4RecordSet p4rs = null; try { if (fileExists(_file)) { p4rs = m_connection.Run("edit", _file); } else { p4rs = m_connection.Run("add", _file); } } catch (Exception ex) { m_error = ex.Message; return(false); } if (p4rs.Messages.Length > 0) { m_warnings = ""; foreach (string msg in p4rs.Messages) { m_warnings += msg + "\n"; } } return(true); }
private static string executeP4Cmd(string cmd, string [] args) { string results = ""; try { P4Connection p4 = new P4Connection(); p4.Connect(); P4RecordSet recSet = p4.Run(cmd, args); foreach (object obj in recSet.Messages) { results += String.Format("{0}\r\n", (string)obj); } foreach (P4Record rec in recSet) { FieldDictionary fd = rec.Fields; if (cmd.Equals("opened")) { results += fd["clientFile"]; } else { foreach (string key in fd.Keys) { results += String.Format("{0}\t\t{1}\r\n", key, fd[key]); } } results += "\r\n"; } p4.Disconnect(); } catch (Exception ex) { return(ex.Message); } return(results); }
/// <summary> /// Send the equivalent to a P4 command. /// Note that P4UnParsedRecordSet returns Empty from fstat. /// </summary> /// <param name="command">the p4 command, like "edit"</param> /// <param name="message">The first line of the P4 command result if no error, else the error message.</param> /// <param name="recordSet">The recordSet from P4</param> /// <param name="args">The args to add to the P4 command.</param> /// <returns>false if error (see message)</returns> private bool SendCommand(string command, out string message, out P4RecordSet recordSet, params string[] args) { string argsStr = Concatenate(args); try { //Log.Information(String.Format("P4Service.SendCommand() Starting: {0} {1}", command, argsStr)); recordSet = _p4.Run(command, args); } catch (Exception ex) { Log.Error(String.Format("P4Service.SendCommand() Exception: {0}", ex.Message)); message = ex.Message; recordSet = null; return(false); } if (recordSet.HasErrors()) { Log.Error(String.Format("P4Service.SendCommand() 1: {0}", recordSet.ErrorMessage)); message = recordSet.ErrorMessage; return(false); } if (recordSet.HasWarnings()) { message = Concatenate(recordSet.Warnings); Log.Warning(String.Format("P4Service.SendCommand() 2: {0}", message)); return(true); } message = Concatenate(recordSet.Messages); if (!String.IsNullOrEmpty(message)) { Log.Information(String.Format("P4Service.SendCommand() 3: {0}", message)); } //Log.Information(String.Format("P4Service.SendCommand() Finished: {0} {1}", command, argsStr)); return(true); }
private ArrayList getUnpublishedFiles() { this.Cursor = Cursors.WaitCursor; Scanning scan = new Scanning(); scan.StartPosition = FormStartPosition.CenterParent; scan.Show(); scan.Refresh(); p4 = new P4Connection(); p4.Connect(); p4I = new P4Interface(); ArrayList unpublished = new ArrayList(); String[] args = { "-n", "-d", "-i", "-t", "-v", "-b", "phx_published", "//depot/phoenix/xbox/published/..." }; // logging String tmp = ""; foreach (String t in args) { tmp += t; tmp += " "; } LogLine(String.Concat("Running: Integrate ", tmp)); P4RecordSet record = p4I.Run("integrate", args); LogLine(String.Concat("Total Records: ", record.Records.Length)); foreach (P4Record entry in record) { if (checkBoxFilter.Checked) { String file = entry.Fields["depotFile"]; String delim = "/"; int trimIndex = -1; if (file.Split(delim.ToCharArray())[6] == "art") { trimIndex = file.IndexOf("art"); } else if (file.Split(delim.ToCharArray())[6] == "scenario") { trimIndex = file.IndexOf("scenario"); } file = file.Substring(trimIndex, file.Length - trimIndex); file = "//depot/phoenix/xbox/published/" + file.Replace("\\", "/"); String[] args2 = { file.Replace("//depot/phoenix/xbox/published", localPath).Replace("\\", "/") }; P4RecordSet changes = p4I.Run("changes", args2); if (changes.Records.Length > 0 && changes[0].Fields["user"] == comboBoxUsers.SelectedItem.ToString()) { LogLine(String.Concat("Record: ", entry.Fields["depotFile"])); unpublished.Add(entry.Fields["fromFile"]); } } else { unpublished.Add(entry.Fields["fromFile"]); } } scan.Close(); this.Cursor = Cursors.Default; return(unpublished); p4.Disconnect(); }
internal RunException(P4RecordSet rs) { _rs = rs; }
/// <summary> /// Add to states the state for each file, all at one time (Fast) /// If there's an exception, falls back to doing one at a time. /// </summary> /// <param name="filesUnderPerforceRoot">the VS fileNames for files already verified to be under the Perforce root</param> /// <param name="p4FileNames">parallel list of the P4 fileNames for files in filesUnderPerforceRoot</param> /// <param name="states">The dictionary we are loading. Key is vsFileName</param> private void AddStatesForAllFilesUnderPerforceRoot(List <string> filesUnderPerforceRoot, List <string> p4FileNames, IDictionary <string, FileState> states) { if (filesUnderPerforceRoot.Count == 0) { return; } P4RecordSet recordSet = null; string message; bool result = SendCommand("fstat", out message, out recordSet, p4FileNames.ToArray()); if (!result) { //Some kind of error. Try to do each file individually so the error doesn't reflect on EVERY file AddStateForEachFile(filesUnderPerforceRoot, states); return; } if (recordSet.Records.Length <= 0) { foreach (var vsFileName in filesUnderPerforceRoot) { states[vsFileName] = FileState.NotInPerforce; } return; } // Now decode each record. Missing records must be NotInPerforce // The key to filesWithState is p4FileName var filesWithState = new Dictionary <string, FileState>(filesUnderPerforceRoot.Count); foreach (P4Record record in recordSet) { string p4FileName; FileState state = GetFileStateFromRecordSet(record, out p4FileName); filesWithState[p4FileName.ToLower()] = state; } #if DEBUG var keysTmp = new List <string>(filesWithState.Count); var statesTmp = new List <FileState>(filesWithState.Count); foreach (var kvp in filesWithState) { keysTmp.Add(kvp.Key); statesTmp.Add(kvp.Value); } #endif // Now set each state we return. for (int i = 0; i < filesUnderPerforceRoot.Count; i++) { string vsFileName = filesUnderPerforceRoot[i]; var p4FileName = GetP4FileName(vsFileName); FileState state; bool hasState = filesWithState.TryGetValue(p4FileName.ToLower(), out state); if (hasState) { states[vsFileName] = state; } else { states[vsFileName] = FileState.NotInPerforce; } } }
private void BuildLabel(string JobName, P4Connection p4, EventLog log) { string LabelName = string.Format(_labelNameFormat, JobName); // delete the label... it may not exist, but finding that out is worse performance // than just deleting and assuming it doesn't exist. // The '-f' flag may cause problems if the p4 account running this command isn't a // super user. You should be able to remove the flag... so long as no one // manually monkey's with the labels. P4UnParsedRecordSet labelDel = p4.RunUnParsed("label", "-f", "-d", LabelName); List <int> JobChanges = new List <int>(); // Run a fixes to get all the changelists we need to add P4RecordSet fixes = p4.Run("fixes", "-j", JobName); // Spin the recordset to build a unique list of changelists foreach (P4Record fix in fixes) { JobChanges.Add(int.Parse(fix["Change"])); } // Sort them to be certain they are ascending JobChanges.Sort(); // only build the label if there are indeed fixes if (JobChanges.Count > 0) { //re-create the label P4Form labelForm = p4.Fetch_Form("label", "-t", _labelTemplate, LabelName); // make sure the form is unlocked labelForm["Options"] = "unlocked"; // make sure we're the owner labelForm["Owner"] = _p4user; p4.Save_Form(labelForm); int ChangesAdded = 0; //now need to labelsync to all latest changes foreach (int change in JobChanges) { // using tag here so a valid client spec is not needed. // for older servers, you could substitue for labelsync, // but you'd need to pass in and set a valid client spec P4UnParsedRecordSet ls = p4.RunUnParsed("tag", "-l", LabelName, string.Format("@={0}", change)); // this is why we set exception level to NoExceptionOnErrors if (ls.HasErrors()) { if (ls.ErrorMessage.StartsWith("Can't use a pending changelist number for this command.")) { // Nothing to worry about. p4 fixes returns fix records for pending changelists, // but we don't know that going into this. It's likely more performant to just // assume it is a submitted changelist and ignore this error. } else { // Something's gone ary. Should throw an Exception. // But I'm lazy so we just log the error. log.WriteEntry(ls.ErrorMessage); } } else { ChangesAdded++; } } // If ChangesAdded is still 0, then we should delete the label since // there are no files anyway if (ChangesAdded == 0) { p4.RunUnParsed("label", "-f", "-d", LabelName); } else { // now lock the label labelForm["Options"] = "locked"; p4.Save_Form(labelForm); // Note this trick. You can re-save a form as many times as you need, // no need to fetch before each save. In fact you can use the form to save // new objects... like: // labelForm["Label"] = "newLabelName"; // p4.Save_Form(labelForm); // and you created a new label named newLabelName. // Cool, huh? Well, I don't deserve the credit... it's the way the // native C++ API works. } } }
//Guts of the logic. This is where the app will dynamicaly build the job labels public void RunLabeler(EventLog log) { P4Connection p4 = null; try { p4 = new P4Connection(); p4.Port = _p4port; p4.User = _p4user; if (!_useLogin) { p4.Password = _p4password; } p4.Connect(); if (_useLogin) { p4.Login(_p4password); } // Don't throw an exception on a Perforce error. We handle these manually. p4.ExceptionLevel = P4ExceptionLevels.NoExceptionOnErrors; //Use unparsed b/c older server versions do not support //parsed output for the counter command. And, it's easy //to parse by hand. P4UnParsedRecordSet counter = p4.RunUnParsed("counter", _p4counter); int counterValue = int.Parse(counter[0]); int LastSequenceNumber = 0; List <string> JobList = new List <string>(); //Run p4 logger to find all the changes and jobs since the last run P4RecordSet loggers = p4.Run("logger", "-c", counterValue.ToString()); //spin the results, and get a unique list of jobs foreach (P4Record r in loggers) { if (r.Fields["key"] == "job") { string JobName = r.Fields["attr"]; if (!JobList.Contains(JobName)) { JobList.Add(JobName); } } LastSequenceNumber = int.Parse(r.Fields["sequence"]); } // We're done with loggers, so lets remove the reference and // give the GC a chance to clean memory. If it's been a long time // since the last run, it could be thousands of jobs to catch up. loggers = null; // Now spin all the jobs and build the label foreach (string JobName in JobList) { BuildLabel(JobName, p4, log); } //Now we update the counter to the last sequence number from logger. p4.RunUnParsed("counter", _p4counter, LastSequenceNumber.ToString()); } catch (Exception e) { // rethrow... b/c I'm lazy :-) throw e; } finally { // All done here... time to disconnect. p4.Disconnect(); } }
public void ProcessRequest(HttpContext context) { // Don't allow this response to be cached by the browser. context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetNoStore(); context.Response.Cache.SetExpires(DateTime.MinValue); // Create a new p4 connection, and set the appropriate properties P4Connection p4 = new P4Connection(); AppSettingsReader appSettings = new AppSettingsReader(); p4.Port = (string)appSettings.GetValue("P4PORT", typeof(string)); p4.User = (string)appSettings.GetValue("P4USER", typeof(string)); p4.Client = (string)appSettings.GetValue("P4CLIENT", typeof(string)); p4.Password = (string)appSettings.GetValue("P4PASSWD", typeof(string)); try { p4.Connect(); //Figure out the clientPath for the file string clientPath = string.Format("//{0}/{1}", p4.Client, context.Request.AppRelativeCurrentExecutionFilePath.Substring(2)); if (!clientPath.EndsWith("/")) { // We have a path to a file // find the MIME type and set it string ext = Path.GetExtension(clientPath); string mimeType = getMimeType(ext); context.Response.ContentType = mimeType; //stream the results ... will throw an exception if the path isn't found try { p4.PrintStream(context.Response.OutputStream, clientPath); context.Response.OutputStream.Flush(); } catch (P4API.Exceptions.FileNotFound) { context.Response.StatusCode = 404; } } else { // we have a directory... let's look for a default "index" file and redirect // My Rule for a default page is: // :: "index.htm" or "index.html" in the current directory (case insensitive) // // I don't rely on the Perforce server to be case insensitive, so I will run an fstat for // all files in the directory and see if there are any "index.htm*" files P4RecordSet rs = p4.Run("fstat", "-Op", clientPath + "*"); foreach (P4Record r in rs) { if (r["depotFile"].ToLower().EndsWith("index.html") || r["depotFile"].ToLower().EndsWith("index.htm")) { // the -Op switch means client file will be //<clientname>/<clientpath> clientPath = r["clientFile"]; break; } } if (clientPath.EndsWith("/")) { // clientPath not updated, means we can't find a default page // For now, just 404... in the future we could allow directory browsing // (which we be a lot bigger than a sample application ;-) context.Response.StatusCode = 404; } else { // redirect to the index page string redirect = "~" + clientPath.Substring(p4.Client.Length + 2); context.Response.Redirect(redirect, false); } } } catch (Exception e) { // unhandled exception... send a 500 to the browser System.Diagnostics.Trace.WriteLine(e.StackTrace); context.Response.StatusCode = 500; } finally { p4.Disconnect(); context.Response.End(); } }