/// <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 Perforce.P4.P4CommandResult recordSet, params string[] args) { string argsStr = Concatenate(args); try { //Log.Information(String.Format("P4Service.SendCommand() Starting: {0} {1}", command, argsStr)); var cmd = new Perforce.P4.P4Command(_p4Repository.Connection, command, true); var opts = new Perforce.P4.StringList(args); recordSet = cmd.Run(opts); } catch (Exception ex) { Log.Error(String.Format("P4Service.SendCommand() Exception: {0}", ex.Message)); message = ex.Message; recordSet = null; return(false); } if (recordSet.ErrorList != null && recordSet.ErrorList.Count > 0) { List <string> errors = new List <string>(); foreach (var error in recordSet.ErrorList) { if (error.SeverityLevel >= Perforce.P4.ErrorSeverity.E_FAILED) { errors.Add(error.ErrorMessage); Log.Error(String.Format("P4Service.SendCommand(): {0} {1}", error.ErrorCode, error.ErrorMessage)); } else if (error.SeverityLevel == Perforce.P4.ErrorSeverity.E_WARN) { Log.Warning(String.Format("P4Service.SendCommand(): {0} {1}", error.ErrorCode, error.ErrorMessage)); } else if (error.SeverityLevel == Perforce.P4.ErrorSeverity.E_INFO) { Log.Information(String.Format("P4Service.SendCommand(): {0} {1}", error.ErrorCode, error.ErrorMessage)); } } if (errors.Count > 1) { message = string.Join("\n", errors); return(false); } } message = Concatenate(recordSet.InfoOutput); if (!String.IsNullOrEmpty(message)) { Log.Information(String.Format("P4Service.SendCommand() 3: {0}", message)); } return(true); }
/// <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; } Perforce.P4.P4CommandResult 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.TaggedOutput.Count <= 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 (var record in recordSet.TaggedOutput) { 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; } } }