private async Task CopyFilesAsync(string sourcePath, string destinationPath, string[] files) { // Exit early if there are no files if (files.Length == 0) { return; } Task[] tasks = new Task[files.Length]; // Queue up all the file copies for (int i = 0; i < files.Length; i++) { var file = files[i]; var relativeFilePath = DirectoryCompare.GetRelativePath(file, sourcePath); var fullDestinationPath = Path.Combine(destinationPath, relativeFilePath); var fileDirectory = Path.GetDirectoryName(fullDestinationPath); // Create the directory if it doesn't already exist Directory.CreateDirectory(fileDirectory); tasks[i] = Task.Run(() => File.Copy(file, fullDestinationPath, true)); } // Wait for all the files to copy await Task.WhenAll(tasks); }
private void WriteFilesToArchive(ZipArchive archive, string[] files, string rootPath) { if (files == null || files.Length == 0) { return; } for (int i = 0; i < files.Length; i++) { var file = files[i]; // Relative Path for this file var relativePath = DirectoryCompare.GetRelativePath(file, rootPath); // Make the file in form "<BundleName>/ReleaseFiles/<RelativePath>" for the archive var archiveFilePath = Path.Combine(this.BundleName, "ReleaseFiles", relativePath); archive.CreateEntryFromFile(file, archiveFilePath, this.CompressionLevel); } }
private void WriteInfoFile(string outputPath, string[] differences, string description) { using (var streamWriter = new StreamWriter(outputPath, true)) { if (description.HasValue()) { streamWriter.WriteLine("/********************************* Description *********************************/"); streamWriter.WriteLine(); streamWriter.WriteLine(description + Environment.NewLine); } streamWriter.WriteLine("/******************************** Changed Files ********************************/"); streamWriter.WriteLine(); foreach (var file in differences) { streamWriter.WriteLine(DirectoryCompare.GetRelativePath(file, this.TargetPath)); } } }
public async Task CreateBundleAsync(bool createFullBackup, string customOutputPath = null) { this.UpdateProgress("Starting Bundle"); Task clearDirectoryTask = ClearDirectoryAsync(this.OutputPath); Task backupTask = null; bool shouldtaskBackup = createFullBackup && this.FullBackupPath.HasValue(); // Start the cloning task if we want to take a backup and we have a backup path. if (shouldtaskBackup) { backupTask = CloneDirectoryAsync(this.SourcePath, this.FullBackupPath); } this.UpdateProgress("Finding Differences"); var directoryComparer = new DirectoryCompare(this.SourcePath, this.TargetPath); var differences = await directoryComparer.GetDifferencesAsync(true); this.UpdateProgress("Waiting For Databases To Register"); Database sourceDatabase = this.SourceDatabaseTask?.Result; Database targetDatabase = this.TargetDatabaseTask?.Result; this.UpdateProgress("Comparing Databases"); string databaseUpdateScript = null; using (var databaseComparer = new DatabaseCompare(sourceDatabase, targetDatabase)) { databaseUpdateScript = await databaseComparer.GenerateUpdateScriptAsync(); // If there is any kind of SQL change, output the files if (databaseUpdateScript.HasValue()) { File.WriteAllText(Path.Combine(this.OutputPath, SqlFileName), databaseUpdateScript); this.UpdateProgress("Writing Database Schema To File"); targetDatabase.SaveToDisk(Path.Combine(this.OutputPath, SnapshotFileName)); } } if ((differences == null || differences.Length == 0) && databaseUpdateScript.IsEmpty()) { throw new InvalidOperationException("No differences were found. Aborting bundle."); } this.UpdateProgress("Clearing Directory"); await clearDirectoryTask; Directory.CreateDirectory(this.OutputPath); this.UpdateProgress("Creating Manual Update Zip"); var manualUpdateBundler = new ManualUpdateBundler(this.BundleName, this.Build); await manualUpdateBundler.CreateBundleAsync(this.OutputPath, this.TargetPath, differences, databaseUpdateScript); this.UpdateProgress("Writing BundleInfo.txt"); this.WriteInfoFile(Path.Combine(this.OutputPath, "BundleInfo.txt"), differences, this.BundleDescription); if (shouldtaskBackup) { this.UpdateProgress("Waiting For Full Backup To Finish Copying"); await backupTask; this.UpdateProgress("Applying Differences To Backup"); await this.CopyFilesAsync(this.SourcePath, this.FullBackupPath, new string[1]); } // If we have a custom output path, copy everything there if (customOutputPath.HasValue()) { // Add the bundle name to the output path customOutputPath = Path.Combine(customOutputPath, this.BundleName); this.UpdateProgress("Copying To Custom Output Path"); await ClearDirectoryAsync(customOutputPath); await CloneDirectoryAsync(this.OutputPath, customOutputPath); } }