public void Test002_CreateClient() { p4.Client = "UnicodeTest"; p4ClientRootDirectory = Path.Combine(Path.GetTempPath(), "p4temprootU"); if (Directory.Exists(p4ClientRootDirectory)) { // what to do??? } else { Directory.CreateDirectory(p4ClientRootDirectory); } P4Form client = p4.Fetch_Form("client"); //test the indexer client["Root"] = p4ClientRootDirectory; //test the Fields collection client.Fields["Description"] = "Created from unit test"; P4UnParsedRecordSet result = p4.Save_Form(client); Assert.AreEqual(result.Messages.Length, 1, "While saving client spec, unexpected number of messages"); Assert.AreEqual(result[0], "Client UnicodeTest saved.", "Unable to save client spec"); }
public void Test003_AddFiles() { p4.Disconnect(); p4.Charset = "utf16le-bom"; p4.Connect(); string testPath = Path.Combine(p4ClientRootDirectory, "TestUnicode"); //Create some test files Directory.CreateDirectory(testPath); P4PendingChangelist cl = p4.CreatePendingChangelist("TestUnicode"); string[] args = new string[13]; args[0] = "-c"; args[1] = cl.Number.ToString(); args[2] = "-tunicode"; for (int i = 0; i < 10; i++) { string fn = string.Format("File{0}", i); string contents = string.Format("this is file: {0}\nEn español.\nΚαλημέρα κόσμε\nこんにちは 世界", i); StreamWriter sw = new StreamWriter(Path.Combine(testPath, fn), false, System.Text.Encoding.Unicode); sw.Write(contents); sw.Close(); args[i + 3] = Path.Combine(testPath, fn); } P4UnParsedRecordSet r = p4.RunUnParsed("add", args); Assert.AreEqual(r.Messages.Length, 10, "Invalid response from p4 add"); for (int i = 0; i < 10; i++) { Assert.AreEqual(string.Format("//depot/TestUnicode/File{0}#1 - opened for add", i), r.Messages[i], "Invalid response from p4 add"); } r = cl.Submit(); Assert.AreEqual("Submitting change 8.", r.Messages[0], "Unexpected output from p4 submit"); }
/// <summary> /// Add a fileName to Perforce then submit it. /// Used for testing /// </summary> /// <param name="vsFileName">The file name to add then submit.</param> /// <param name="message">The first line of the P4 command result if no error, else the error message.</param> /// <returns>false if error (see message)</returns> public bool AddAndSubmitFile(string vsFileName, out string message) { // Need to do this for unit testing, or we get NullReferenceException in P4API Connect(); Disconnect(); P4PendingChangelist cl = null; try { cl = _p4.CreatePendingChangelist("A testing changelist"); } catch (NullReferenceException ex) { Trace.WriteLine(String.Format("P4Service.AddAndSubmitFile: {0}", ex.Message)); } P4RecordSet recordSet; string p4FileName = GetP4FileName(vsFileName); bool result = SendCommand("add", out message, out recordSet, "-c", cl.Number.ToString(), p4FileName); if (!result) { return(false); } P4UnParsedRecordSet unparsedRecordset = null; try { unparsedRecordset = cl.Submit(); } catch (P4API.Exceptions.RunUnParsedException ex) { message = HandleRunUnParsedExceptionError(ex); return(false); } return(true); }
internal RunUnParsedException(P4UnParsedRecordSet rs) { _rs = rs; }
//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(); } }
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. } } }
internal RunUnParsedException(P4UnParsedRecordSet rs) { _rs = rs; }