internal void PerformDiffOfFile(DiffFile diffFile, ref bool fileNeedsToBeCounted)
        {
            // Don't process files that had errors during generation
            for (int errFileCounter = 0; errFileCounter < GenerationErrors.Count; errFileCounter++)
            {
                if (Slyce.Common.Utility.StringsAreEqual(diffFile.RelativePath, GenerationErrors[errFileCounter].FileName, false))
                {
                    //continue;
                    return;
                }
            }
            if (UniqueFilesForCount[diffFile.RelativePath] != null &&
                (bool)UniqueFilesForCount[diffFile.RelativePath] == false)
            {
                fileNeedsToBeCounted = true;
                UniqueFilesForCount[diffFile.RelativePath] = true;
            }
            else
            {
                fileNeedsToBeCounted = false;
            }
            if (diffFile.Path.IndexOf(".aaz") > 0 ||
                diffFile.HasParseError)
            {
                //continue;
                return;
            }
            if (FileBeingProcessed != null)
            {
                FileBeingProcessed(diffFile.Path);
            }
            // Perform a 3-way diff on the file
            string parentFile = Path.Combine(PreviousGenerationFolder, diffFile.RelativePath);
            string userFile = Path.Combine(Controller.Instance.ProjectSettings.ProjectPath, diffFile.RelativePath);
            string templateFile = Path.Combine(Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator), diffFile.RelativePath);
            string mergedFile = Path.Combine(StagingFolder, diffFile.RelativePath + ".merged");

            if(CheckFilesForModifications(diffFile.RelativePath) == false)
            {
                RaiseDiffFinishedEvent(diffFile.Name, TypeOfDiff.ExactCopy);
                return;
            }

            diffFile.FilePathTemplate = templateFile;
            diffFile.FilePathUser = userFile;
            diffFile.FilePathPrevGen = parentFile;

            if (File.Exists(mergedFile))
            {
                bool mergeComplete = true;

                // Binary files are never in an unknown state, they are all or nothing.
                // Text files need to be checked.
                if (diffFile.IsText)
                {
                    using (TextReader tr = new StreamReader(mergedFile))
                    {
                        string line;
                        //int lineCounter = 0;

                        while ((line = tr.ReadLine()) != null &&
                            mergeComplete)
                        {
                            int pipeIndex = line.IndexOf("|");
                            int backColor = int.Parse(line.Substring(0, pipeIndex));

                            if (backColor != -1 &&
                                backColor != 0)
                            {
                                mergeComplete = false;
                            }
                            //lineCounter++;
                        }
                    }
                }
                if (mergeComplete)
                {
                    diffFile.DiffType = TypeOfDiff.Warning;
                }
                else
                {
                    diffFile.DiffType = TypeOfDiff.Conflict;
                }
            }
            else
            {
                if (diffFile.IsText)
                {
                    if (File.Exists(parentFile) &&
                              File.Exists(userFile) &&
                              File.Exists(templateFile))
                    {
                        // Perform 3-way diff
                        string fileBodyParent = IOUtility.GetTextFileBody(parentFile);
                        string fileBodyUser = IOUtility.GetTextFileBody(userFile);
                        string fileBodyGenerated = IOUtility.GetTextFileBody(templateFile);

                        string mergedText;
                        slyceMerge = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText);
                        diffFile.DiffType = slyceMerge.DiffType;
                        string newFile = "";

                        if (slyceMerge.DiffType != TypeOfDiff.Conflict)
                        {
                            switch (slyceMerge.DiffType)
                            {
                                case TypeOfDiff.ExactCopy:
                                    newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                    Slyce.Common.Utility.FileCopy(userFile, newFile);
                                    break;
                                case TypeOfDiff.TemplateChangeOnly:
                                    newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                    Slyce.Common.Utility.FileCopy(templateFile, newFile);
                                    break;
                                case TypeOfDiff.UserAndTemplateChange:
                                    newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";

                                    if (!Directory.Exists(Path.GetDirectoryName(newFile)))
                                    {
                                        Directory.CreateDirectory(Path.GetDirectoryName(newFile));
                                    }
                                    Slyce.Common.Utility.WriteToFile(newFile, mergedText);
                                    break;
                                case TypeOfDiff.UserChangeOnly:
                                    newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                    Slyce.Common.Utility.FileCopy(userFile, newFile);
                                    break;
                                case TypeOfDiff.Warning:
                                    throw new Exception("Oops");
                            }
                        }
                    }
                    else if (File.Exists(parentFile) &&
                              File.Exists(userFile) &&
                              !File.Exists(templateFile))
                    {
                        // No template file, just use the user file
                        diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else if (File.Exists(parentFile) &&
                                  !File.Exists(userFile) &&
                                  File.Exists(templateFile))
                    {
                        // No user file, just use the template file
                        diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                                  File.Exists(userFile) &&
                                  File.Exists(templateFile))
                    {
                        // No parent file, make sure the user merges the template and user files
                        SlyceMerge.LineSpan[] userLines;
                        SlyceMerge.LineSpan[] templateLines;
                        string combinedText;
                        diffFile.DiffType = SlyceMerge.PerformTwoWayDiff(false, IOUtility.GetTextFileBody(userFile), IOUtility.GetTextFileBody(templateFile), out userLines, out templateLines, out combinedText);

                        if (diffFile.DiffType == TypeOfDiff.ExactCopy)
                        {
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(templateFile, newPath);
                        }
                        else
                        {
                            throw new NotImplementedException("This scenario has not been handled yet. Please contact [email protected] with: PerformDiffOfFolder(PrevGen file doesn't exist, and TypeOfDiff = " + diffFile.DiffType + ")");
                        }
                        //diffFile.DiffType = SlyceMerge.TypeOfDiff.Conflict; // TODO: Work out what should be done in this instance
                        //throw new Exception("TODO: determine course of action, what should be copied to staging folder.");
                        //string newPath = templateFile.Replace(ProjectFolder, StagingFolder) + ".copy";
                        //Utility.FileCopy(templateFile, newPath);
                    }
                    else if (File.Exists(parentFile) &&
                        !File.Exists(userFile) &&
                        !File.Exists(templateFile))
                    {
                        // TODO: It looks like the file was deleted by the user, AND it was removed from the template, so therefore the
                        // user doesn't want this file anymore. Get user to confirm?
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(parentFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                                 !File.Exists(userFile) &&
                                 File.Exists(templateFile))
                    {
                        string newPath = templateFile.Replace(Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator), StagingFolder) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                                  File.Exists(userFile) &&
                                  !File.Exists(templateFile))
                    {
                        // TODO: Do we really need to go to the effort of copying etc, because it only exists in the user folder,
                        // so if we take no action it will still exist there - that should be fine ;-)
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else
                    {
                        // TODO: Shouldn't really be a warning...
                        diffFile.DiffType = TypeOfDiff.Warning;
                        throw new Exception(string.Format("TODO: determine course of action, what should be copied to staging folder, because no file exists: \n{0}\n{1}\n{2}", parentFile, userFile, templateFile));
                    }
                }
                else // Binary file
                {
                    string crcParent = File.Exists(parentFile) ? Slyce.Common.Utility.GetCheckSumOfFile(parentFile) : "";
                    string crcTemplate = File.Exists(templateFile) ? Slyce.Common.Utility.GetCheckSumOfFile(templateFile) : "";
                    string crcUser = File.Exists(userFile) ? Slyce.Common.Utility.GetCheckSumOfFile(userFile) : "";

                    diffFile.MD5Parent = crcParent;
                    diffFile.MD5Template = crcTemplate;
                    diffFile.MD5User = crcUser;

                    // TODO: perform CheckSum of binary file
                    if (!string.IsNullOrEmpty(crcParent) &&
                        !string.IsNullOrEmpty(crcTemplate) &&
                        !string.IsNullOrEmpty(crcUser))
                    {
                        if (crcParent == crcUser &&
                                crcUser == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.ExactCopy;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent == crcUser &&
                                    crcParent != crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent != crcUser &&
                                    crcParent == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent != crcUser &&
                             crcUser == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.UserAndTemplateChange;
                        }
                    }
                    else if (string.IsNullOrEmpty(crcParent) &&
                        !string.IsNullOrEmpty(crcTemplate) &&
                        !string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.Conflict;
                    }
                    else if (!string.IsNullOrEmpty(crcParent) &&
                                !string.IsNullOrEmpty(crcTemplate) &&
                                string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!string.IsNullOrEmpty(crcParent) &&
                            string.IsNullOrEmpty(crcTemplate) &&
                            !string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else if (string.IsNullOrEmpty(crcParent) &&
                            !string.IsNullOrEmpty(crcTemplate) &&
                            string.IsNullOrEmpty(crcUser))
                    {
                        // This is a new file that has been generated
                        diffFile.DiffType = TypeOfDiff.ExactCopy;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else
                    {
                        throw new NotImplementedException("Not coded yet. Seems like only one version of binary file exists. Probably just need to copy as-is.");
                    }
                }
            }
            if (diffFile.DiffType != TypeOfDiff.ExactCopy)
            {
                // Only perform the costly SuperDiff if it is not an exact copy
                //ArchAngel.IntelliMerge.DiffItems.DiffFile diffFile = diffFile;
                PerformSuperDiff(ref diffFile);
            }
            if (fileNeedsToBeCounted)
            {
                switch (diffFile.DiffType)
                {
                    case TypeOfDiff.Conflict:
                        m_numConflicts++;
                        break;
                    case TypeOfDiff.ExactCopy:
                        m_numExactCopy++;
                        break;
                    case TypeOfDiff.TemplateChangeOnly:
                    case TypeOfDiff.UserAndTemplateChange:
                    case TypeOfDiff.UserChangeOnly:
                    case TypeOfDiff.Warning:
                        m_numResolvable++;
                        break;
                    default:
                        throw new NotImplementedException("Not coded yet");
                }
                RaiseDiffFinishedEvent(diffFile.Name, diffFile.DiffType);
            }

            Slyce.Common.Utility.DeleteFileBrute(templateFile + ".prevgen.md5");
            Slyce.Common.Utility.DeleteFileBrute(templateFile + ".user.md5");

            if (diffFile.DiffType == TypeOfDiff.ExactCopy)
            {
                // Store the MD5 hashes of the files we just diff'd, so we don't do them again.
                if(File.Exists(parentFile))
                    Slyce.Common.Utility.CreateMD5HashFileForTextFile(parentFile, templateFile + ".prevgen.md5");
                if(File.Exists(userFile))
                    Slyce.Common.Utility.CreateMD5HashFileForTextFile(userFile, templateFile + ".user.md5");
            }
        }
Exemple #2
0
 internal void SetDiffType(TypeOfDiff diffType)
 {
     DiffType = SlyceMerge.CombineDiffTypes(DiffType, diffType);
 }