Exemplo n.º 1
0
        /// <inheritdoc cref="IUpdateCreator.CreateFullPackage"/>
        public bool CreateFullPackage(
            ApplicationMetadata applicationMetadata,
            string applicationLocation,
            SemanticVersion version,
            string fullUpdateLocation,
            OSPlatform?intendedOs    = null,
            Action <double>?progress = null)
        {
            if (!Directory.Exists(applicationLocation))
            {
                _logger.Error("{0} doesn't exist, can't create update", applicationLocation);
                return(false);
            }
            _logger.Debug("Creating full update file");

            var zipArchive     = CreateZipArchive(fullUpdateLocation);
            var files          = Directory.EnumerateFiles(applicationLocation, "*", SearchOption.AllDirectories).ToArray();
            var tempFolder     = new TemporaryFolder(applicationMetadata.TempFolder);
            var progressReport = new ProgressReport(files.Length, progress);

            void Cleanup()
            {
                zipArchive.Dispose();
                tempFolder.Dispose();
                progressReport.DoneCleanup();
            }

            foreach (var file in files)
            {
                //We will process the file as a "new" file as we always want to copy it over
                using var fileStream = File.OpenRead(file);
                if (AddNewFile(zipArchive, fileStream, file.RemovePath(applicationLocation)))
                {
                    progressReport.ProcessedFile();
                    continue;
                }

                //if we can't add it then hard fail, can't do anything to save this
                _logger.Error("Wasn't able to process file, bailing");
                Cleanup();
                return(false);
            }

            //Add the loader into the package
            if (ShouldMakeLoader &&
                !AddLoaderFile(tempFolder, applicationMetadata, zipArchive, version, applicationLocation))
            {
                _logger.Error("Wasn't able to create loader for this application");
                Cleanup();
                return(false);
            }
            progressReport.ProcessedFile();
            Cleanup();
            return(true);
        }
Exemplo n.º 2
0
        public bool CreateDeltaPackage(
            ApplicationMetadata applicationMetadata,
            string newVersionLocation,
            SemanticVersion newVersion,
            string baseVersionLocation,
            SemanticVersion oldVersion,
            string outputFolder,
            string deltaUpdateLocation,
            OSPlatform?intendedOs    = null,
            Action <double>?progress = null)
        {
            if (!Directory.Exists(newVersionLocation) ||
                !Directory.Exists(baseVersionLocation))
            {
                _logger.Error("One of the folders don't exist, can't create delta update....");
                return(false);
            }

            _logger.Debug("Creating delta file");
            var zipArchive = CreateZipArchive(deltaUpdateLocation);
            var tempFolder = new TemporaryFolder(applicationMetadata.TempFolder);

            void Cleanup()
            {
                lock (zipArchive)
                {
                    zipArchive.Dispose();
                }
                tempFolder.Dispose();
                progress?.Invoke(1);
            }

            //Get all the files that are in the new version (Removing the Path so we only have the relative path of the file)
            var newVersionFiles = Directory.EnumerateFiles(newVersionLocation, "*", SearchOption.AllDirectories)
                                  .RemovePath(newVersionLocation).ToArray();

            //and get the files from the old version
            var baseVersionFiles = Directory.EnumerateFiles(baseVersionLocation, "*", SearchOption.AllDirectories)
                                   .RemovePath(baseVersionLocation).ToArray();

            //Find any files that are in both version and process them based on if they had any changes
            var sameFiles = newVersionFiles.Where(x => baseVersionFiles.Contains(x)).ToArray();
            var newFiles  = newVersionFiles.Where(x => !sameFiles.Contains(x)).ToArray();

            var progressReport = new ProgressReport(newFiles.Length + sameFiles.Length, progress);
            var deltaFiles     = new List <string>(sameFiles.Length);

            //First process any files that didn't change, don't even count them in the progress as it will be quick af
            _logger.Information("Processing files that are in both versions");
            foreach (var maybeDeltaFile in sameFiles)
            {
                _logger.Debug("Processing possible delta file {0}", maybeDeltaFile);
                var newFileLocation = Path.Combine(newVersionLocation, maybeDeltaFile);

                /*See if we got a delta file, if so then store it for
                 * processing after files that haven't changed*/
                if (IsDeltaFile(Path.Combine(baseVersionLocation, maybeDeltaFile),
                                newFileLocation))
                {
                    deltaFiles.Add(maybeDeltaFile);
                    continue;
                }

                //Add a pointer to the file that hasn't changed
                _logger.Debug("{0} hasn't changed, processing as unchanged file", maybeDeltaFile);

                using var fileStream = File.OpenRead(newFileLocation);
                if (AddSameFile(zipArchive, maybeDeltaFile, SHA256Util.CreateSHA256Hash(fileStream)))
                {
                    progressReport.ProcessedFile();
                    continue;
                }
                _logger.Warning("We wasn't able to add {0} as a file that was unchanged, adding as a \"new\" file",
                                maybeDeltaFile);

                //We wasn't able to add the file as a pointer, try to add it as a new file
                if (!AddNewFile(zipArchive, fileStream, maybeDeltaFile))
                {
                    //Hard bail if we can't even do that
                    _logger.Error("Wasn't able to process {0} as a new file as well, bailing", maybeDeltaFile);
                    Cleanup();
                    return(false);
                }
                progressReport.ProcessedFile();
            }

            //TODO: add "moved files"
            //Now process files that was added into the new version
            _logger.Information("Processing files that only exist in the new version");
            foreach (var newFile in newFiles)
            {
                _logger.Debug("Processing new file {0}", newFile);

                //Process new file
                using var fileStream = File.OpenRead(Path.Combine(newVersionLocation, newFile));
                if (AddNewFile(zipArchive, fileStream, newFile))
                {
                    progressReport.ProcessedFile();
                    continue;
                }

                //if we can't add it then hard fail, can't do anything to save this
                _logger.Error("Wasn't able to process new file, bailing");
                Cleanup();
                return(false);
            }

            //Now process files that changed
            var result = Parallel.ForEach(deltaFiles, (deltaFile, state) =>
            {
                var deltaFileLocation = Path.Combine(newVersionLocation, deltaFile);
                _logger.Debug("Processing changed file {0}", deltaFile);

                //Try to add the file as a delta file
                if (AddDeltaFile(tempFolder,
                                 zipArchive,
                                 Path.Combine(baseVersionLocation, deltaFile),
                                 deltaFileLocation,
                                 intendedOs,
                                 (pro) => progressReport.PartialProcessedFile(pro)))
                {
                    progressReport.ProcessedFile();
                    return;
                }

                //If we can't make the file as a delta file try to create it as a "new" file
                _logger.Warning("Wasn't able to make delta file, adding file as \"new\" file");
                using var fileStream = File.OpenRead(Path.Combine(newVersionLocation, deltaFileLocation));
                if (AddNewFile(zipArchive, fileStream, deltaFile))
                {
                    progressReport.ProcessedFile();
                    return;
                }

                //Hard bail if we can't even do that
                _logger.Error("Wasn't able to process file as a new file, bailing");
                Cleanup();
                state.Break();
            });

            //This will return false if something failed
            if (!result.IsCompleted)
            {
                return(false);
            }

            if (ShouldMakeLoader &&
                !AddLoaderFile(
                    tempFolder,
                    applicationMetadata,
                    zipArchive,
                    newVersion,
                    newVersionLocation,
                    intendedOs,
                    oldVersion,
                    outputFolder))
            {
                _logger.Error("Wasn't able to create loader for this application");
                Cleanup();
                return(false);
            }
            progressReport.ProcessedFile();

            //We have created the delta file if we get here, do cleanup and then report as success!
            _logger.Information("We are done with creating the delta file, cleaning up");
            Cleanup();
            return(true);
        }