///<summary>Returns an ODGridCell formatted to show the status of the backport.</summary> private GridCell GetStatusCell(string backportVersion, ODFileChanges changedFile) { GridCell cell = new GridCell(); ODBackportResult backportResult = _listBackportResults.Find(x => x.FilePathHead == changedFile.FilePathHead); if (backportResult != null) { ResultType result = backportResult.GetResult(backportVersion); int numFailed = backportResult.GetFailedChanges(backportVersion).Count; cell.Text = result.ToString(); switch (result) { case ResultType.Ok: cell.ColorText = Color.DarkGreen; break; case ResultType.Partial: cell.ColorText = Color.YellowGreen; cell.Text += " (" + (changedFile.ListLineChanges.Count - numFailed).ToString() + "/" + changedFile.ListLineChanges.Count + ")"; break; case ResultType.Failed: cell.ColorText = Color.DarkRed; break; case ResultType.None: default: cell.ColorText = Color.Black; cell.Text = ""; break; } } return(cell); }
///<summary>This modifies the files with the passed in changes. The core of the logic for backporting is here.</summary> ///<param name="changeFile">The file that is being modified.</param> ///<param name="backportVersion">The version the file is being backported to.</param> ///<param name="backportResult">The objects where the results are stored.</param> public static ResultType ModifyFile(ODFileChanges changeFile, string backportVersion, ODBackportResult backportResult) { ResultType result = ResultType.None; string filePath = changeFile.DictVersionFilePath[backportVersion]; //Get the correct encoding of the head file. Filstream.CurrentEncoding is not accurate. Because our code uses special symbols on occasion, we //need to ensure when backporting files, files do not lose characters as they could be crucial. Get the head path as the encoding may have //changed. Encoding fileEncodingHead = GetEncoding(changeFile.FilePathHead); //The encoding of the file to be backported before any changes. Encoding fileEncodingOld = GetEncoding(filePath); //Read in file with the encoding. string originalFile = File.ReadAllText(filePath, fileEncodingOld).Replace("\r\n", "\n").Replace("\n", "\r\n"); //Create a copy of the original lines so that we have something to safely manipulate. string changedFile = originalFile; List <ODLineChange> listFailedLineChanges = new List <ODLineChange>(); foreach (ODLineChange lineChange in changeFile.ListLineChanges) { //If there's at least one match if (changedFile.Contains(lineChange.SVNChangesBefore)) { //Replace the string to see how many lines it got rid of. This is preferred over Regex.Match.Count as that has been unreliable //for special characters. string fileNoMatches = changedFile.Replace(lineChange.SVNChangesBefore, ""); int numberOfMatches = (changedFile.Length - fileNoMatches.Length) / lineChange.SVNChangesBefore.Length; if (numberOfMatches == 1) { //One match. Replace the before text with the after text. changedFile = changedFile.Replace(lineChange.SVNChangesBefore, lineChange.SVNChangesAfter); } else { //More than one match. Just fail it. They will have to manually copy over the change. listFailedLineChanges.Add(lineChange); result = ResultType.Partial; } } else //no match { listFailedLineChanges.Add(lineChange); result = ResultType.Partial; } } if (changedFile == originalFile) { result = ResultType.Failed; return(result); } //Overwrites file File.WriteAllText(filePath, changedFile, fileEncodingHead); if (result == ResultType.None) //if nothing bad happened, set it to Ok { result = ResultType.Ok; } //Update list of failed changes. backportResult.UpdateListFailedChanges(backportVersion, listFailedLineChanges); return(result); }
///<summary>This addes the given file to the given version.</summary> ///<param name="changeFile">The file that is being added.</param> ///<param name="backportVersion">The version the file is being backported to.</param> public static ResultType AddFile(ODFileChanges changeFile, string backportVersion) { try { File.Copy(changeFile.FilePathHead, changeFile.DictVersionFilePath[backportVersion]); RunWindowsCommand($@"svn add ""{changeFile.DictVersionFilePath[backportVersion]}"""); return(ResultType.Ok); } catch { return(ResultType.Failed); } }
///<summary>This removes the given file from the given version.</summary> ///<param name="changeFile">The file that is being deleted.</param> ///<param name="backportVersion">The version the file is being backported to.</param> public static ResultType DeleteFile(ODFileChanges changeFile, string backportVersion) { string result = RunWindowsCommand($@"svn delete ""{changeFile.DictVersionFilePath[backportVersion]}"""); if (result.Contains("D ")) { return(ResultType.Ok); } else { return(ResultType.Failed); } }
///<summary>Gets a list of modified files with all changes recorded from SVN.</summary> public static List <ODFileChanges> GetListOfFiles(string pathOnRefresh, List <string> listVersions, string ignoreListName, BackportProject currentProject) { List <ODFileChanges> listFilesChanged = new List <ODFileChanges>(); string headString = ""; if (currentProject.PatternHead == HeadPattern.head) { headString = "head"; } else if (currentProject.PatternHead == HeadPattern.Name_head) { headString = Enum.GetName(currentProject.Name.GetType(), currentProject.Name) + "_head"; } string rawOutputFilesModified = RunWindowsCommand("svn diff --summarize \"" + pathOnRefresh + "\\" + headString + "\""); string rawOutputFilesIgnored = RunWindowsCommand("svn status --cl \"" + ignoreListName + "\" \"" + pathOnRefresh + "\\" + headString + "\""); //Change list List <string> listModifiedFiles = ExtractFileNames(rawOutputFilesModified); List <string> listIgnoreFiles = ExtractFileNames(rawOutputFilesIgnored); //gets the list of files to not include in the output. listModifiedFiles = listModifiedFiles.Except(listIgnoreFiles).ToList(); foreach (string modFile in listModifiedFiles) { ODFileChanges file = new ODFileChanges(); switch (modFile[0]) { case 'M': file.ModificationType = FileModificationType.Modified; break; case 'D': file.ModificationType = FileModificationType.Deleted; break; case 'A': file.ModificationType = FileModificationType.Added; break; default: file.ModificationType = FileModificationType.Unknown; break; } file.FilePathHead = modFile.Substring(1).Trim(); //Remove the modification type from the beginning to get the file path. file.GetFilePaths(listVersions, currentProject, headString); listFilesChanged.Add(file); } //Fill listFilesModified with information List <string> listLineChanges = new List <string>(); foreach (ODFileChanges file in listFilesChanged) { listLineChanges.Add(RunWindowsCommand("svn diff " + "\"" + file.FilePathHead + "\"")); } //Extract individual changes listLineChanges = ExtractModifiedLines(listLineChanges); if (listLineChanges.Count == 0) { return(new List <ODFileChanges>()); } //Extracts the exact lines that were changed and stores them in a list of LineChanges for (int i = 0; i < listLineChanges.Count; i++) { listFilesChanged[i].FillChanges(listLineChanges[i]); } return(listFilesChanged); }