// Returns null if project is valid
        private string ValidateProject()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder(300);

            if (!Directory.Exists(versionsPath))
            {
                sb.AppendLine(Localization.Get(StringId.E_DirectoryXMissing, versionsPath));
            }

            if (!File.Exists(projectInfoPath))
            {
                sb.AppendLine(Localization.Get(StringId.E_FileXMissing, projectInfoPath));
            }
            else
            {
                ProjectInfo projectInfo = null;
                try
                {
                    projectInfo = PatchUtils.GetProjectInfoFromPath(projectInfoPath);
                }
                catch (Exception e)
                {
                    sb.AppendLine(e.ToString());
                }

                if (projectInfo == null)
                {
                    sb.AppendLine(Localization.Get(StringId.E_ProjectInfoCouldNotBeDeserializedFromX, projectInfoPath));
                }
                else if (projectInfo.Version != ProjectInfo.LATEST_VERSION)
                {
                    sb.AppendLine(Localization.Get(StringId.E_ProjectInfoOutdated));
                }
            }

            if (sb.Length == 0)
            {
                return(null);
            }

            return(string.Concat(Localization.Get(StringId.E_ProjectInvalid), Environment.NewLine, Environment.NewLine, sb.ToString()));
        }
        private PatchResult GeneratePatchInternal()
        {
            if (!Directory.Exists(versionsPath))
            {
                Log(Localization.Get(StringId.E_XDoesNotExist, versionsPath));
                return(PatchResult.Failed);
            }

            if (!File.Exists(projectInfoPath))
            {
                Log(Localization.Get(StringId.E_XDoesNotExist, projectInfoPath));
                return(PatchResult.Failed);
            }

            string[] versions = Directory.GetDirectories(versionsPath);
            if (versions.Length == 0)
            {
                Log(Localization.Get(StringId.E_DirectoryXIsEmpty, versionsPath));
                return(PatchResult.Failed);
            }

            string validationResult = ValidateProject();

            if (!string.IsNullOrEmpty(validationResult))
            {
                Log(validationResult);
                return(PatchResult.Failed);
            }

            Stopwatch timer = Stopwatch.StartNew();

            // Here's how it works:
            // Move previous incremental patch files to Temp\IncrementalFormer
            // Generate repair patch and installer patch files on Temp\Output
            // Foreach incremental patch to generate:
            //   Generate incremental patch files on Temp\Incremental
            //   Move the incremental patch files from there to Temp\IncrementalFormer
            // Replace the contents of outputPath with Temp\Output:
            //   Delete outputPath directory
            //   Move Temp\Output to outputPath
            //   Move Temp\IncrementalFormer to outputPath
            // Delete Temp
            string tempRoot                   = projectRoot + "Temp" + Path.DirectorySeparatorChar;
            string tempOutput                 = tempRoot + "Output" + Path.DirectorySeparatorChar;
            string tempIncrementalOutput      = tempRoot + "Incremental" + Path.DirectorySeparatorChar;
            string tempPrevIncrementalPatches = tempRoot + "IncrementalFormer" + Path.DirectorySeparatorChar;

            PatchUtils.DeleteDirectory(tempOutput);
            PatchUtils.DeleteDirectory(tempIncrementalOutput);

            // Preserve the previous incremental patches
            string versionInfoPath        = outputPath + PatchParameters.VERSION_INFO_FILENAME;
            string incrementalPatchesPath = outputPath + PatchParameters.INCREMENTAL_PATCH_DIRECTORY;

            if (Directory.Exists(incrementalPatchesPath))
            {
                PatchUtils.MoveDirectory(incrementalPatchesPath, tempPrevIncrementalPatches);
            }

            List <IncrementalPatch> incrementalPatches = new List <IncrementalPatch>();

            if (File.Exists(versionInfoPath))
            {
                VersionInfo oldVersionInfo = PatchUtils.GetVersionInfoFromPath(versionInfoPath);
                if (oldVersionInfo != null)
                {
                    incrementalPatches.AddRange(oldVersionInfo.IncrementalPatches);
                }
            }

            Array.Sort(versions, new VersionComparer());

            string      latestVersion = versions[versions.Length - 1];
            ProjectInfo projectInfo   = PatchUtils.GetProjectInfoFromPath(projectInfoPath);

            if (projectInfo.IsSelfPatchingApp && Directory.Exists(selfPatcherPath) && Directory.GetFileSystemEntries(selfPatcherPath).Length > 0)
            {
                PatchUtils.CopyDirectory(selfPatcherPath, Path.Combine(latestVersion, PatchParameters.SELF_PATCHER_DIRECTORY));
            }

            patchCreator = new PatchCreator(latestVersion, tempOutput, projectInfo.Name, Path.GetFileName(latestVersion)).SetListener(this).
                           SetCompressionFormat(projectInfo.CompressionFormatRepairPatch, projectInfo.CompressionFormatInstallerPatch, projectInfo.CompressionFormatIncrementalPatch).
                           CreateRepairPatch(projectInfo.CreateRepairPatch).CreateInstallerPatch(projectInfo.CreateInstallerPatch).CreateIncrementalPatch(false).
                           AddIgnoredPaths(projectInfo.IgnoredPaths).SilentMode(silentMode).SetBaseDownloadURL(projectInfo.BaseDownloadURL).SetMaintenanceCheckURL(projectInfo.MaintenanceCheckURL);

            // Generate repair patch and installer patch files
            if (cancel || !ExecuteCurrentPatch())
            {
                return(PatchResult.Failed);
            }

            if (projectInfo.CreateIncrementalPatch && versions.Length > 1)
            {
                string incrementalPatchesGenerated = tempIncrementalOutput + PatchParameters.INCREMENTAL_PATCH_DIRECTORY;
                string versionInfoGenerated        = tempIncrementalOutput + PatchParameters.VERSION_INFO_FILENAME;

                patchCreator = new PatchCreator(latestVersion, tempIncrementalOutput, projectInfo.Name, Path.GetFileName(latestVersion)).SetListener(this).
                               SetCompressionFormat(projectInfo.CompressionFormatRepairPatch, projectInfo.CompressionFormatInstallerPatch, projectInfo.CompressionFormatIncrementalPatch).
                               AddIgnoredPaths(projectInfo.IgnoredPaths).SilentMode(silentMode).CreateRepairPatch(false).CreateInstallerPatch(false);

                for (int i = versions.Length - 2; i >= 0; i--)
                {
                    Log(Localization.Get(StringId.CreatingIncrementalPatchX, Path.GetFileName(versions[i]) + "->" + Path.GetFileName(latestVersion)));

                    // Generate incremental patch files
                    patchCreator.CreateIncrementalPatch(true, versions[i], projectInfo.BinaryDiffQuality);
                    if (cancel || !ExecuteCurrentPatch())
                    {
                        return(PatchResult.Failed);
                    }

                    List <IncrementalPatch> newIncrementalPatches = PatchUtils.GetVersionInfoFromPath(versionInfoGenerated).IncrementalPatches;
                    for (int j = incrementalPatches.Count - 1; j >= 0; j--)
                    {
                        // Don't allow duplicate IncrementalPatch entries
                        for (int k = newIncrementalPatches.Count - 1; k >= 0; k--)
                        {
                            if (incrementalPatches[j].FromVersion == newIncrementalPatches[k].FromVersion && incrementalPatches[j].ToVersion == newIncrementalPatches[k].ToVersion)
                            {
                                incrementalPatches.RemoveAt(j);
                                break;
                            }
                        }
                    }

                    incrementalPatches.AddRange(newIncrementalPatches);

                    // Move incremental patch files to Temp
                    PatchUtils.MoveDirectory(incrementalPatchesGenerated, tempPrevIncrementalPatches);
                    PatchUtils.DeleteDirectory(tempIncrementalOutput);

                    if (!projectInfo.CreateAllIncrementalPatches)
                    {
                        break;
                    }
                }
            }

            PatchUtils.DeleteDirectory(outputPath);
            PatchUtils.MoveDirectory(tempOutput, outputPath);

            if (Directory.Exists(tempPrevIncrementalPatches))
            {
                PatchUtils.MoveDirectory(tempPrevIncrementalPatches, incrementalPatchesPath);
            }

            VersionInfo versionInfo = PatchUtils.GetVersionInfoFromPath(versionInfoPath);

            incrementalPatches.Sort(PatchUtils.IncrementalPatchComparison);
            versionInfo.IncrementalPatches = incrementalPatches;
            PatchUtils.SerializeVersionInfoToXML(versionInfo, versionInfoPath);

            PatchUtils.DeleteDirectory(tempRoot);

            Log(Localization.Get(StringId.AllPatchesCreatedInXSeconds, timer.ElapsedSeconds()));
            return(PatchResult.Success);
        }
Example #3
0
 public ProjectInfo LoadProjectInfo()
 {
     return(PatchUtils.GetProjectInfoFromPath(projectInfoPath));
 }