示例#1
0
        public void ContentFilesAreIncludedInCreatedPackage()
        {
            var inputPackage  = IntegrationTestHelper.GetPath("fixtures", "ProjectWithContent.1.0.0.0-beta.nupkg");
            var outputPackage = Path.GetTempFileName() + ".nupkg";
            var sourceDir     = IntegrationTestHelper.GetPath("fixtures", "packages");

            var fixture = new ReleasePackage(inputPackage);

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            try {
                fixture.CreateReleasePackage(outputPackage, sourceDir);

                this.Log().Info("Resulting package is at {0}", outputPackage);
                var pkg = new ZipPackage(outputPackage);

                int refs = pkg.FrameworkAssemblies.Count();
                this.Log().Info("Found {0} refs", refs);
                refs.ShouldEqual(0);

                this.Log().Info("Files in release package:");

                var contentFiles = pkg.GetContentFiles();
                Assert.Equal(2, contentFiles.Count());

                var contentFilePaths = contentFiles.Select(f => f.EffectivePath);

                Assert.Contains("some-words.txt", contentFilePaths);
                Assert.Contains("dir\\item-in-subdirectory.txt", contentFilePaths);

                Assert.Equal(1, pkg.GetLibFiles().Count());
            } finally {
                File.Delete(outputPackage);
            }
        }
示例#2
0
        public void WhenBasePackageReleaseIsNullThrowsException()
        {
            var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");
            var newPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");

            var sourceDir = IntegrationTestHelper.GetPath("..", "packages");

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            var baseFixture = new ReleasePackage(basePackage);
            var fixture     = new ReleasePackage(newPackage);

            var tempFile = Path.GetTempPath() + Guid.NewGuid() + ".nupkg";

            try
            {
                Assert.Throws <ArgumentException>(() =>
                {
                    var deltaBuilder = new DeltaPackageBuilder();
                    deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFile);
                });
            }
            finally {
                File.Delete(tempFile);
            }
        }
示例#3
0
        public void ReleasePackageIntegrationTest()
        {
            var inputPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");
            var outputPackage = Path.GetTempFileName() + ".nupkg";
            var sourceDir     = IntegrationTestHelper.GetPath("..", "packages");

            var fixture = new ReleasePackage(inputPackage);

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            try {
                fixture.CreateReleasePackage(outputPackage, sourceDir);

                this.Log().Info("Resulting package is at {0}", outputPackage);
                var pkg = new ZipPackage(outputPackage);

                int refs = pkg.FrameworkAssemblies.Count();
                this.Log().Info("Found {0} refs", refs);
                refs.ShouldEqual(0);

                this.Log().Info("Files in release package:");

                List <IPackageFile> files = pkg.GetFiles().ToList();
                files.ForEach(x => this.Log().Info(x.Path));

                List <string> nonDesktopPaths = new[] { "sl", "winrt", "netcore", "win8", "windows8", "MonoAndroid", "MonoTouch", "MonoMac", "wp", }
                .Select(x => @"lib\" + x)
                .ToList();

                files.Any(x => nonDesktopPaths.Any(y => x.Path.ToLowerInvariant().Contains(y.ToLowerInvariant()))).ShouldBeFalse();
                files.Any(x => x.Path.ToLowerInvariant().Contains(@".xml")).ShouldBeFalse();
            } finally {
                File.Delete(outputPackage);
            }
        }
示例#4
0
        public void WhenAProjectContainsNet40BinariesItDoesntShipTheNet45Dependencies()
        {
            var outputPackage = Path.GetTempFileName() + ".nupkg";

            var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ThisShouldBeANet4Project.1.0.nupkg");

            var rightPackage     = "Caliburn.Micro.1.5.2.nupkg";
            var rightPackagePath = IntegrationTestHelper.GetPath("fixtures", rightPackage);

            try
            {
                var sourceDir = IntegrationTestHelper.GetPath("..", "packages");
                (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

                File.Copy(rightPackagePath, Path.Combine(sourceDir, rightPackage), true);

                var package        = new ReleasePackage(inputPackage);
                var outputFileName = package.CreateReleasePackage(outputPackage, sourceDir);

                var zipPackage = new ZipPackage(outputFileName);

                var dependency = zipPackage.GetLibFiles()
                                 .Where(f => f.Path.EndsWith("Caliburn.Micro.dll"))
                                 .FirstOrDefault(f => f.TargetFramework
                                                 == new FrameworkName(".NETFramework,Version=v4.5"));

                Assert.Null(dependency);
            }
            finally
            {
                File.Delete(outputPackage);
            }
        }
示例#5
0
        public void WhenBasePackageIsNewerThanNewPackageThrowException()
        {
            var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");
            var newPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0.nupkg");

            var sourceDir = IntegrationTestHelper.GetPath("..", "packages");

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            var baseFixture = new ReleasePackage(basePackage);
            var fixture     = new ReleasePackage(newPackage);

            var tempFiles = Enumerable.Range(0, 3)
                            .Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
                            .ToArray();

            try
            {
                baseFixture.CreateReleasePackage(tempFiles[0], sourceDir);
                fixture.CreateReleasePackage(tempFiles[1], sourceDir);

                (new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
                (new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();

                Assert.Throws <InvalidOperationException>(() =>
                {
                    var deltaBuilder = new DeltaPackageBuilder();
                    deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
                });
            }
            finally
            {
                tempFiles.ForEach(File.Delete);
            }
        }
示例#6
0
        public void ReleasePackageIntegrationTest()
        {
            var inputPackage  = IntegrationTestHelper.GetPath("fixtures", "Shimmer.Core.1.0.0.0.nupkg");
            var outputPackage = Path.GetTempFileName() + ".nupkg";
            var sourceDir     = IntegrationTestHelper.GetPath("..", "packages");

            var fixture = new ReleasePackage(inputPackage);

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            try {
                fixture.CreateReleasePackage(outputPackage, sourceDir);

                this.Log().Info("Resulting package is at {0}", outputPackage);
                var pkg = new ZipPackage(outputPackage);

                int refs = pkg.FrameworkAssemblies.Count();
                this.Log().Info("Found {0} refs", refs);
                refs.ShouldEqual(0);

                this.Log().Info("Files in release package:");
                pkg.GetFiles().ForEach(x => this.Log().Info(x.Path));

                pkg.GetFiles().Any(x => x.Path.ToLowerInvariant().Contains(@"lib\sl")).ShouldBeFalse();
                pkg.GetFiles().Any(x => x.Path.ToLowerInvariant().Contains(@".xml")).ShouldBeFalse();
            } finally {
                File.Delete(outputPackage);
            }
        }
        public void WhenNewPackageDoesNotExistThrowException()
        {
            var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
            var newPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");

            var sourceDir = IntegrationTestHelper.GetPath("fixtures", "packages");

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            var baseFixture = new ReleasePackage(basePackage);
            var fixture     = new ReleasePackage(newPackage);

            var tempFiles = Enumerable.Range(0, 3)
                            .Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
                            .ToArray();

            try {
                baseFixture.CreateReleasePackage(tempFiles[0], sourceDir);
                fixture.CreateReleasePackage(tempFiles[1], sourceDir);

                (new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
                (new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();

                // NOW WATCH AS THE FILE DISAPPEARS
                File.Delete(fixture.ReleasePackageFile);

                Assert.Throws <FileNotFoundException>(() => {
                    var deltaBuilder = new DeltaPackageBuilder();
                    deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);
                });
            } finally {
                tempFiles.ForEach(File.Delete);
            }
        }
示例#8
0
        public void SpecFileMarkdownRenderingTest()
        {
            var dontcare  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nupkg");
            var inputSpec = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0.nuspec");
            var fixture   = new ReleasePackage(dontcare);

            var targetFile = Path.GetTempFileName();

            File.Copy(inputSpec, targetFile, true);

            try {
                var processor = new Func <string, string>(input =>
                                                          (new Markdown()).Transform(input));

                // NB: For No Reason At All, renderReleaseNotesMarkdown is
                // invulnerable to ExposedObject. Whyyyyyyyyy
                var renderMinfo = fixture.GetType().GetMethod("renderReleaseNotesMarkdown",
                                                              BindingFlags.NonPublic | BindingFlags.Instance);
                renderMinfo.Invoke(fixture, new object[] { targetFile, processor });

                var        doc             = XDocument.Load(targetFile);
                XNamespace ns              = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd";
                var        relNotesElement = doc.Descendants(ns + "releaseNotes").First();
                var        htmlText        = relNotesElement.Value;

                this.Log().Info("HTML Text:\n{0}", htmlText);

                htmlText.Contains("## Release Notes").ShouldBeFalse();
            } finally {
                File.Delete(targetFile);
            }
        }
        public void ApplyDeltaPackageSmokeTest()
        {
            var basePackage         = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.0.0.0-full.nupkg"));
            var deltaPackage        = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0-delta.nupkg"));
            var expectedPackageFile = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.1.1.0.0-full.nupkg");
            var outFile             = Path.GetTempFileName() + ".nupkg";

            try {
                var deltaBuilder = new DeltaPackageBuilder();
                deltaBuilder.ApplyDeltaPackage(basePackage, deltaPackage, outFile);

                var result   = new ZipPackage(outFile);
                var expected = new ZipPackage(expectedPackageFile);

                result.Id.ShouldEqual(expected.Id);
                result.Version.ShouldEqual(expected.Version);

                this.Log().Info("Expected file list:");
                var expectedList = expected.GetFiles().Select(x => x.Path).OrderBy(x => x).ToList();
                expectedList.ForEach(x => this.Log().Info(x));

                this.Log().Info("Actual file list:");
                var actualList = result.GetFiles().Select(x => x.Path).OrderBy(x => x).ToList();
                actualList.ForEach(x => this.Log().Info(x));

                Enumerable.Zip(expectedList, actualList, (e, a) => e == a)
                .All(x => x != false)
                .ShouldBeTrue();
            } finally {
                if (File.Exists(outFile))
                {
                    File.Delete(outFile);
                }
            }
        }
示例#10
0
        static int Main(string[] args)
        {
            var optParams = ParseCommands.ParseOptions(args);

            if (optParams == null)
            {
                return(-1);
            }

            var targetDir  = optParams["target"];
            var package    = new ReleasePackage(optParams["input"]);
            var targetFile = Path.Combine(targetDir, package.SuggestedReleaseFileName);

            string fullRelease;

            try {
                fullRelease = package.CreateReleasePackage(targetFile,
                                                           optParams["pkgdir"] != "" ? optParams["pkgdir"] : null,
                                                           input => (new Markdown()).Transform(input));
            }
            catch (Exception ex) {
                Console.Error.WriteLine();
                Console.Error.WriteLine("Unexpected exception occurred creating package:");
                Console.Error.WriteLine(ex);
                Console.Error.WriteLine();
                Console.Error.WriteLine();
                return(-4);
            }

            Console.WriteLine("{0};", fullRelease);

            var releaseFile = Path.Combine(targetDir, "RELEASES");

            if (File.Exists(releaseFile))
            {
                var releasesText   = File.ReadAllText(releaseFile, Encoding.UTF8);
                var releaseEntries = ReleaseEntry.ParseReleaseFile(releasesText);

                var previousFullRelease = ReleaseEntry.GetPreviousRelease(releaseEntries, package, targetDir);

                if (previousFullRelease != null &&
                    File.Exists(previousFullRelease.ReleasePackageFile))
                {
                    var deltaFile = Path.Combine(targetDir, package.SuggestedReleaseFileName.Replace("full", "delta"));
                    Console.WriteLine("{0}; {1}", previousFullRelease.InputPackageFile, deltaFile);

                    if (File.Exists(deltaFile))
                    {
                        File.Delete(deltaFile);
                    }

                    var deltaBuilder = new DeltaPackageBuilder();
                    deltaBuilder.CreateDeltaPackage(previousFullRelease, package, deltaFile);
                }
            }

            ReleaseEntry.BuildReleasesFile(targetDir);

            return(0);
        }
示例#11
0
        private static void ReleasifyElectron(string package, string targetDir = null, string baseUrl = null)
        {
            // check that package is valid
            new ZipPackage(package).GetType();

            if (baseUrl != null)
            {
                if (!Utility.IsHttpUrl(baseUrl))
                {
                    throw new Exception($"Invalid --baseUrl '{baseUrl}'. A base URL must start with http or https and be a valid URI.");
                }

                if (!baseUrl.EndsWith("/"))
                {
                    baseUrl += "/";
                }
            }

            targetDir = targetDir ?? Path.Combine(".", "Releases");

            var di = new DirectoryInfo(targetDir);

            var releaseFilePath  = Path.Combine(di.FullName, "RELEASES");
            var previousReleases = new List <ReleaseEntry>();

            if (File.Exists(releaseFilePath))
            {
                previousReleases.AddRange(ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8)));
            }

            var processed = new List <string>();
            var rp        = new ReleasePackage(package, true);

            processed.Add(package);

            var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir);

            if (prev != null)
            {
                var deltaBuilder = new DeltaPackageBuilder();

                var dp = deltaBuilder.CreateDeltaPackage(prev, rp,
                                                         Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta")));
                processed.Insert(0, dp.InputPackageFile);
            }

            var newReleaseEntries = processed
                                    .Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl))
                                    .ToList();
            var distinctPreviousReleases = previousReleases
                                           .Where(x => !newReleaseEntries.Select(e => e.Version).Contains(x.Version));
            var releaseEntries = distinctPreviousReleases.Concat(newReleaseEntries).ToList();

            ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath);

            var newestFullRelease = releaseEntries.MaxBy(x => x.Version).First(x => !x.IsDelta);

            Console.Out.WriteLine(ReleaseEntry.GenerateFromFile(Path.Combine(di.FullName, newestFullRelease.Filename)).EntryAsString);
        }
示例#12
0
        public void WhenCurrentReleaseMatchesLastReleaseReturnNull()
        {
            var package = new ReleasePackage("Espera-1.7.6-beta.nupkg");

            var releaseEntries = new[] {
                ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg"))
            };

            Assert.Null(ReleaseEntry.GetPreviousRelease(
                            releaseEntries, package, @"C:\temp\somefolder"));
        }
示例#13
0
        public void FindDependentPackagesForDummyPackage()
        {
            var inputPackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
            var fixture      = new ReleasePackage(inputPackage);
            var sourceDir    = IntegrationTestHelper.GetPath("fixtures", "packages");

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            IEnumerable <IPackage> results = fixture.findAllDependentPackages(default(IPackage), (IPackageRepository) new LocalPackageRepository(sourceDir), default(HashSet <string>), default(FrameworkName));

            results.Count().ShouldBeGreaterThan(0);
        }
示例#14
0
        public void WhenInputPackageTargetsMultipleFrameworksCrashHard()
        {
            var packagesDir  = IntegrationTestHelper.GetPath("..", "packages");
            var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ProjectTargetingMultiplePlatforms.1.0.0.0.nupkg");

            var outputPackage = Path.GetTempFileName() + ".nupkg";

            var package = new ReleasePackage(inputPackage);

            Assert.Throws <InvalidOperationException>(() => {
                package.CreateReleasePackage(outputPackage, packagesDir);
            });
        }
示例#15
0
        public void CanLoadPackageWhichHasNoDependencies()
        {
            var inputPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Core.NoDependencies.1.0.0.0.nupkg");
            var outputPackage = Path.GetTempFileName() + ".nupkg";
            var fixture       = new ReleasePackage(inputPackage);
            var sourceDir     = IntegrationTestHelper.GetPath("..", "packages");

            try {
                fixture.CreateReleasePackage(outputPackage, sourceDir);
            }
            finally {
                File.Delete(outputPackage);
            }
        }
示例#16
0
        public void DependentPackageFoundAndIncludedInReleasePackage()
        {
            var packagesDir  = IntegrationTestHelper.GetPath("..", "packages");
            var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ProjectDependsOnJsonDotNet.1.0.nupkg");

            var outputPackage = Path.GetTempFileName() + ".nupkg";

            try {
                var package = new ReleasePackage(inputPackage);
                package.CreateReleasePackage(outputPackage, packagesDir);
                Assert.True(File.Exists(outputPackage));
            } finally {
                File.Delete(outputPackage);
            }
        }
示例#17
0
        public void UsesTheRightVersionOfADependencyWhenMultipleAreInPackages()
        {
            var    outputPackage = Path.GetTempFileName() + ".nupkg";
            string outputFile    = null;

            var inputPackage = IntegrationTestHelper.GetPath("fixtures", "CaliburnMicroDemo.1.0.0.nupkg");

            var wrongPackage     = "Caliburn.Micro.1.4.1.nupkg";
            var wrongPackagePath = IntegrationTestHelper.GetPath("fixtures", wrongPackage);
            var rightPackage     = "Caliburn.Micro.1.5.2.nupkg";
            var rightPackagePath = IntegrationTestHelper.GetPath("fixtures", rightPackage);

            try {
                var sourceDir = IntegrationTestHelper.GetPath("..", "packages");
                (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

                File.Copy(wrongPackagePath, Path.Combine(sourceDir, wrongPackage), true);
                File.Copy(rightPackagePath, Path.Combine(sourceDir, rightPackage), true);

                var package        = new ReleasePackage(inputPackage);
                var outputFileName = package.CreateReleasePackage(outputPackage, sourceDir);

                var zipPackage = new ZipPackage(outputFileName);

                var fileName   = "Caliburn.Micro.dll";
                var dependency = zipPackage.GetLibFiles()
                                 .Where(f => f.Path.EndsWith(fileName))
                                 .Single(f => f.TargetFramework
                                         == new FrameworkName(".NETFramework,Version=v4.0"));

                outputFile = new FileInfo(Path.Combine(sourceDir, fileName)).FullName;

                using (var of = File.Create(outputFile))
                {
                    dependency.GetStream().CopyTo(of);
                }

                var assemblyName = AssemblyName.GetAssemblyName(outputFile);
                Assert.Equal(1, assemblyName.Version.Major);
                Assert.Equal(5, assemblyName.Version.Minor);
            }
            finally {
                File.Delete(outputPackage);
                File.Delete(outputFile);
            }
        }
示例#18
0
        public void WhenMultipleReleaseMatchesReturnEarlierResult()
        {
            var expected = new Version("1.7.5");
            var package  = new ReleasePackage("Espera-1.7.6-beta.nupkg");

            var releaseEntries = new[] {
                ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")),
                ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg"))
            };

            var actual = ReleaseEntry.GetPreviousRelease(
                releaseEntries,
                package,
                @"C:\temp\");

            Assert.Equal(expected, actual.Version);
        }
示例#19
0
        public void WhenMultipleReleasesFoundInOtherOrderReturnPreviousVersion()
        {
            var expected = new Version("1.7.6");
            var input    = new ReleasePackage("Espera-1.7.7-beta.nupkg");

            var releaseEntries = new[] {
                ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg")),
                ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg"))
            };

            var actual = ReleaseEntry.GetPreviousRelease(
                releaseEntries,
                input,
                @"C:\temp\");

            Assert.Equal(expected, actual.Version);
        }
示例#20
0
        public void DependentPackageNotFoundAndThrowsError()
        {
            string packagesDir;

            // use empty packages folder
            using (Utility.WithTempDirectory(out packagesDir)) {
                var inputPackage = IntegrationTestHelper.GetPath("fixtures", "ProjectDependsOnJsonDotNet.1.0.nupkg");

                var outputPackage = Path.GetTempFileName() + ".nupkg";

                try {
                    var package = new ReleasePackage(inputPackage);
                    Assert.Throws <Exception>(() =>
                                              package.CreateReleasePackage(outputPackage, packagesDir));
                } finally {
                    File.Delete(outputPackage);
                }
            }
        }
示例#21
0
文件: Program.cs 项目: anthrax3/NSync
        static int Main(string[] args)
        {
            var optParams = parseOptions(args);

            if (optParams == null)
            {
                return(-1);
            }

            var targetDir  = optParams["target"];
            var package    = new ReleasePackage(optParams["input"]);
            var targetFile = Path.Combine(targetDir, package.SuggestedReleaseFileName);

            var fullRelease = package.CreateReleasePackage(targetFile,
                                                           optParams["pkgdir"] != "" ? optParams["pkgdir"] : null,
                                                           input => (new Markdown()).Transform(input));

            var releaseFile = Path.Combine(targetDir, "RELEASES");

            if (File.Exists(releaseFile))
            {
                var releaseEntries = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFile, Encoding.UTF8));

                var latestFullRelease = releaseEntries
                                        .Where(x => x.IsDelta == false)
                                        .MaxBy(x => x.Version)
                                        .Select(x => new ReleasePackage(Path.Combine(targetDir, x.Filename), true))
                                        .FirstOrDefault();

                var deltaFile = Path.Combine(targetDir, package.SuggestedReleaseFileName.Replace("full", "delta"));
                Console.WriteLine("{0} {1}", latestFullRelease.InputPackageFile, deltaFile);

                var deltaBuilder = new DeltaPackageBuilder();
                deltaBuilder.CreateDeltaPackage(package, latestFullRelease, deltaFile);
            }

            ReleaseEntry.BuildReleasesFile(targetDir);

            Console.WriteLine(fullRelease);
            return(0);
        }
        public void ApplyDeltaWithBothBsdiffAndNormalDiffDoesntFail()
        {
            var basePackage  = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "slack-1.1.8-full.nupkg"));
            var deltaPackage = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "slack-1.2.0-delta.nupkg"));
            var outFile      = Path.GetTempFileName() + ".nupkg";

            try {
                var deltaBuilder = new DeltaPackageBuilder();
                deltaBuilder.ApplyDeltaPackage(basePackage, deltaPackage, outFile);

                var result = new ZipPackage(outFile);

                result.Id.ShouldEqual("slack");
                result.Version.ShouldEqual(new SemanticVersion("1.2.0"));
            } finally {
                if (File.Exists(outFile))
                {
                    File.Delete(outFile);
                }
            }
        }
示例#23
0
        IObservable <ReleaseEntry> createFullPackagesFromDeltas(IEnumerable <ReleaseEntry> releasesToApply, ReleaseEntry currentVersion)
        {
            Contract.Requires(releasesToApply != null);

            // If there are no deltas in our list, we're already done
            if (!releasesToApply.Any() || releasesToApply.All(x => !x.IsDelta))
            {
                return(Observable.Return(releasesToApply.MaxBy(x => x.Version).First()));
            }

            if (!releasesToApply.All(x => x.IsDelta))
            {
                return(Observable.Throw <ReleaseEntry>(new Exception("Cannot apply combinations of delta and full packages")));
            }

            // Smash together our base full package and the nearest delta
            var ret = Observable.Start(() => {
                var basePkg  = new ReleasePackage(Path.Combine(rootAppDirectory, "packages", currentVersion.Filename));
                var deltaPkg = new ReleasePackage(Path.Combine(rootAppDirectory, "packages", releasesToApply.First().Filename));

                var deltaBuilder = new DeltaPackageBuilder();

                return(deltaBuilder.ApplyDeltaPackage(basePkg, deltaPkg,
                                                      Regex.Replace(deltaPkg.InputPackageFile, @"-delta.nupkg$", ".nupkg", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)));
            }, RxApp.TaskpoolScheduler);

            if (releasesToApply.Count() == 1)
            {
                return(ret.Select(x => ReleaseEntry.GenerateFromFile(x.InputPackageFile)));
            }

            return(ret.SelectMany(x => {
                var fi = fileSystem.GetFileInfo(x.InputPackageFile);
                var entry = ReleaseEntry.GenerateFromFile(fi.OpenRead(), fi.Name);

                // Recursively combine the rest of them
                return createFullPackagesFromDeltas(releasesToApply.Skip(1), entry);
            }));
        }
示例#24
0
        public void CanResolveMultipleLevelsOfDependencies()
        {
            var inputPackage  = IntegrationTestHelper.GetPath("fixtures", "SampleUpdatingApp.1.0.0.0.nupkg");
            var outputPackage = Path.GetTempFileName() + ".nupkg";
            var sourceDir     = IntegrationTestHelper.GetPath("..", "packages");

            var fixture = new ReleasePackage(inputPackage);

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            try {
                fixture.CreateReleasePackage(outputPackage, sourceDir);

                this.Log().Info("Resulting package is at {0}", outputPackage);
                var pkg = new ZipPackage(outputPackage);

                int refs = pkg.FrameworkAssemblies.Count();
                this.Log().Info("Found {0} refs", refs);
                refs.ShouldEqual(0);

                this.Log().Info("Files in release package:");
                pkg.GetFiles().ForEach(x => this.Log().Info(x.Path));

                var filesToLookFor = new[] {
                    "System.Reactive.Core.dll",
                    "ReactiveUI.dll",
                    "MarkdownSharp.dll",
                    "SampleUpdatingApp.exe",
                };

                filesToLookFor.ForEach(name => {
                    this.Log().Info("Looking for {0}", name);
                    pkg.GetFiles().Any(y => y.Path.ToLowerInvariant().Contains(name.ToLowerInvariant())).ShouldBeTrue();
                });
            } finally {
                File.Delete(outputPackage);
            }
        }
示例#25
0
        public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null, string backgroundGif = null, string signingOpts = null, string baseUrl = null, string setupIcon = null, bool generateMsi = true)
        {
            if (baseUrl != null)
            {
                if (!Utility.IsHttpUrl(baseUrl))
                {
                    throw new Exception(string.Format("Invalid --baseUrl '{0}'. A base URL must start with http or https and be a valid URI.", baseUrl));
                }

                if (!baseUrl.EndsWith("/"))
                {
                    baseUrl += "/";
                }
            }

            targetDir       = targetDir ?? Path.Combine(".", "Releases");
            packagesDir     = packagesDir ?? ".";
            bootstrapperExe = bootstrapperExe ?? Path.Combine(".", "Setup.exe");

            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            if (!File.Exists(bootstrapperExe))
            {
                bootstrapperExe = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
                    "Setup.exe");
            }

            this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe);

            var di = new DirectoryInfo(targetDir);

            File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true);

            var allNuGetFiles = di.EnumerateFiles()
                                .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase));

            var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full"));
            var processed = new List <string>();

            var releaseFilePath  = Path.Combine(di.FullName, "RELEASES");
            var previousReleases = new List <ReleaseEntry>();

            if (File.Exists(releaseFilePath))
            {
                previousReleases.AddRange(ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8)));
            }

            foreach (var file in toProcess)
            {
                this.Log().Info("Creating release package: " + file.FullName);

                var rp = new ReleasePackage(file.FullName);
                rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir, contentsPostProcessHook: pkgPath => {
                    new DirectoryInfo(pkgPath).GetAllFilesRecursively()
                    .Where(x => x.Name.ToLowerInvariant().EndsWith(".exe"))
                    .Where(x => !x.Name.ToLowerInvariant().Contains("squirrel.exe"))
                    .Where(x => Utility.ExecutableUsesWin32Subsystem(x.FullName))
                    .ForEachAsync(x => createExecutableStubForExe(x.FullName))
                    .Wait();

                    if (signingOpts == null)
                    {
                        return;
                    }

                    new DirectoryInfo(pkgPath).GetAllFilesRecursively()
                    .Where(x => Utility.FileIsLikelyPEImage(x.Name))
                    .ForEachAsync(async x => {
                        if (isPEFileSigned(x.FullName))
                        {
                            this.Log().Info("{0} is already signed, skipping", x.FullName);
                            return;
                        }

                        this.Log().Info("About to sign {0}", x.FullName);
                        await signPEFile(x.FullName, signingOpts);
                    })
                    .Wait();
                });

                processed.Add(rp.ReleasePackageFile);

                var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir);
                if (prev != null)
                {
                    var deltaBuilder = new DeltaPackageBuilder(null);

                    var dp = deltaBuilder.CreateDeltaPackage(prev, rp,
                                                             Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta")));
                    processed.Insert(0, dp.InputPackageFile);
                }
            }

            foreach (var file in toProcess)
            {
                File.Delete(file.FullName);
            }

            var newReleaseEntries = processed
                                    .Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl))
                                    .ToList();
            var distinctPreviousReleases = previousReleases
                                           .Where(x => !newReleaseEntries.Select(e => e.Version).Contains(x.Version));
            var releaseEntries = distinctPreviousReleases.Concat(newReleaseEntries).ToList();

            ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath);

            var targetSetupExe    = Path.Combine(di.FullName, "Setup.exe");
            var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First();

            File.Copy(bootstrapperExe, targetSetupExe, true);
            var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName, backgroundGif, signingOpts).Result;

            var writeZipToSetup = findExecutable("WriteZipToSetup.exe");

            try {
                var result = Utility.InvokeProcessAsync(writeZipToSetup, String.Format("\"{0}\" \"{1}\"", targetSetupExe, zipPath), CancellationToken.None).Result;
                if (result.Item1 != 0)
                {
                    throw new Exception("Failed to write Zip to Setup.exe!\n\n" + result.Item2);
                }
            } catch (Exception ex) {
                this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex);
            } finally {
                File.Delete(zipPath);
            }

            Utility.Retry(() =>
                          setPEVersionInfoAndIcon(targetSetupExe, new ZipPackage(package), setupIcon).Wait());

            if (signingOpts != null)
            {
                signPEFile(targetSetupExe, signingOpts).Wait();
            }

            if (generateMsi)
            {
                createMsiPackage(targetSetupExe, new ZipPackage(package)).Wait();

                if (signingOpts != null)
                {
                    signPEFile(targetSetupExe.Replace(".exe", ".msi"), signingOpts).Wait();
                }
            }
        }
示例#26
0
        public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null, string backgroundGif = null, string signingOpts = null, string baseUrl = null, string setupIcon = null)
        {
            if (baseUrl != null)
            {
                if (!Utility.IsHttpUrl(baseUrl))
                {
                    throw new Exception(string.Format("Invalid --baseUrl '{0}'. A base URL must start with http or https and be a valid URI.", baseUrl));
                }

                if (!baseUrl.EndsWith("/"))
                {
                    baseUrl += "/";
                }
            }

            targetDir       = targetDir ?? ".\\Releases";
            packagesDir     = packagesDir ?? ".";
            bootstrapperExe = bootstrapperExe ?? ".\\Setup.exe";

            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            if (!File.Exists(bootstrapperExe))
            {
                bootstrapperExe = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
                    "Setup.exe");
            }

            this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe);

            var di = new DirectoryInfo(targetDir);

            File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true);

            var allNuGetFiles = di.EnumerateFiles()
                                .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase));

            var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full"));
            var processed = new List <string>();

            var releaseFilePath  = Path.Combine(di.FullName, "RELEASES");
            var previousReleases = Enumerable.Empty <ReleaseEntry>();

            if (File.Exists(releaseFilePath))
            {
                previousReleases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8));
            }

            foreach (var file in toProcess)
            {
                this.Log().Info("Creating release package: " + file.FullName);

                var rp = new ReleasePackage(file.FullName);
                rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir, contentsPostProcessHook: pkgPath => {
                    if (signingOpts == null)
                    {
                        return;
                    }

                    new DirectoryInfo(pkgPath).GetAllFilesRecursively()
                    .Where(x => x.Name.ToLowerInvariant().EndsWith(".exe"))
                    .ForEachAsync(x => signPEFile(x.FullName, signingOpts))
                    .Wait();
                });

                processed.Add(rp.ReleasePackageFile);

                var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir);
                if (prev != null)
                {
                    var deltaBuilder = new DeltaPackageBuilder();

                    var dp = deltaBuilder.CreateDeltaPackage(prev, rp,
                                                             Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta")));
                    processed.Insert(0, dp.InputPackageFile);
                }
            }

            foreach (var file in toProcess)
            {
                File.Delete(file.FullName);
            }

            var releaseEntries = previousReleases.Concat(processed.Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl)));

            ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath);

            var targetSetupExe    = Path.Combine(di.FullName, "Setup.exe");
            var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First();

            File.Copy(bootstrapperExe, targetSetupExe, true);
            var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName, backgroundGif, signingOpts).Result;

            try {
                var zip = File.ReadAllBytes(zipPath);

                IntPtr handle = NativeMethods.BeginUpdateResource(targetSetupExe, false);
                if (handle == IntPtr.Zero)
                {
                    throw new Win32Exception();
                }

                if (!NativeMethods.UpdateResource(handle, "DATA", new IntPtr(131), 0x0409, zip, zip.Length))
                {
                    throw new Win32Exception();
                }

                if (!NativeMethods.EndUpdateResource(handle, false))
                {
                    throw new Win32Exception();
                }
            } catch (Exception ex) {
                this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex);
            } finally {
                File.Delete(zipPath);
            }

            Utility.Retry(() =>
                          setPEVersionInfoAndIcon(targetSetupExe, new ZipPackage(package), setupIcon).Wait());

            if (signingOpts != null)
            {
                signPEFile(targetSetupExe, signingOpts).Wait();
            }
        }
        public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null)
        {
            targetDir       = targetDir ?? ".\\Releases";
            packagesDir     = packagesDir ?? ".";
            bootstrapperExe = bootstrapperExe ?? ".\\Setup.exe";

            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            if (!File.Exists(bootstrapperExe))
            {
                bootstrapperExe = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
                    "Setup.exe");
            }

            this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe);

            var di = new DirectoryInfo(targetDir);

            File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true);

            var allNuGetFiles = di.EnumerateFiles()
                                .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase));

            var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full"));

            var releaseFilePath  = Path.Combine(di.FullName, "RELEASES");
            var previousReleases = Enumerable.Empty <ReleaseEntry>();

            if (File.Exists(releaseFilePath))
            {
                previousReleases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8));
            }

            foreach (var file in toProcess)
            {
                this.Log().Info("Creating release package: " + file.FullName);

                var rp = new ReleasePackage(file.FullName);
                rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir);

                var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir);
                if (prev != null)
                {
                    var deltaBuilder = new DeltaPackageBuilder();

                    deltaBuilder.CreateDeltaPackage(prev, rp,
                                                    Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta")));
                }
            }

            foreach (var file in toProcess)
            {
                File.Delete(file.FullName);
            }

            var releaseEntries = allNuGetFiles.Select(x => ReleaseEntry.GenerateFromFile(x.FullName));

            ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath);

            var targetSetupExe    = Path.Combine(di.FullName, "Setup.exe");
            var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First();

            File.Copy(bootstrapperExe, targetSetupExe, true);
            var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName);

            try {
                var zip = File.ReadAllBytes(zipPath);

                IntPtr handle = NativeMethods.BeginUpdateResource(targetSetupExe, false);
                if (handle == IntPtr.Zero)
                {
                    throw new Win32Exception();
                }

                if (!NativeMethods.UpdateResource(handle, "DATA", new IntPtr(131), 0x0409, zip, zip.Length))
                {
                    throw new Win32Exception();
                }

                if (!NativeMethods.EndUpdateResource(handle, false))
                {
                    throw new Win32Exception();
                }
            } catch (Exception ex) {
                this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex);
            } finally {
                File.Delete(zipPath);
            }
        }
示例#28
0
        public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null, string backgroundGif = null, string signingOpts = null, string baseUrl = null, string setupIcon = null, bool generateMsi = true)
        {
            if (baseUrl != null) {
                if (!Utility.IsHttpUrl(baseUrl)) {
                    throw new Exception(string.Format("Invalid --baseUrl '{0}'. A base URL must start with http or https and be a valid URI.", baseUrl));
                }

                if (!baseUrl.EndsWith("/")) {
                    baseUrl += "/";
                }
            }

            targetDir = targetDir ?? Path.Combine(".", "Releases");
            packagesDir = packagesDir ?? ".";
            bootstrapperExe = bootstrapperExe ?? Path.Combine(".", "Setup.exe");

            if (!Directory.Exists(targetDir)) {
                Directory.CreateDirectory(targetDir);
            }

            if (!File.Exists(bootstrapperExe)) {
                bootstrapperExe = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
                    "Setup.exe");
            }

            this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe);

            var di = new DirectoryInfo(targetDir);
            File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true);

            var allNuGetFiles = di.EnumerateFiles()
                .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase));

            var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full"));
            var processed = new List<string>();

            var releaseFilePath = Path.Combine(di.FullName, "RELEASES");
            var previousReleases = new List<ReleaseEntry>();
            if (File.Exists(releaseFilePath)) {
                previousReleases.AddRange(ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8)));
            }

            foreach (var file in toProcess) {
                this.Log().Info("Creating release package: " + file.FullName);

                var rp = new ReleasePackage(file.FullName);
                rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir, contentsPostProcessHook: pkgPath => {
                    if (signingOpts == null) return;

                    new DirectoryInfo(pkgPath).GetAllFilesRecursively()
                        .Where(x => x.Name.ToLowerInvariant().EndsWith(".exe"))
                        .ForEachAsync(x => signPEFile(x.FullName, signingOpts))
                        .Wait();
                });

                processed.Add(rp.ReleasePackageFile);

                var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir);
                if (prev != null) {
                    var deltaBuilder = new DeltaPackageBuilder(null);

                    var dp = deltaBuilder.CreateDeltaPackage(prev, rp,
                        Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta")));
                    processed.Insert(0, dp.InputPackageFile);
                }
            }

            foreach (var file in toProcess) { File.Delete(file.FullName); }

            var newReleaseEntries = processed
                .Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl))
                .ToList();
            var distinctPreviousReleases = previousReleases
                .Where(x => !newReleaseEntries.Select(e => e.Version).Contains(x.Version));
            var releaseEntries = distinctPreviousReleases.Concat(newReleaseEntries).ToList();

            ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath);

            var targetSetupExe = Path.Combine(di.FullName, "Setup.exe");
            var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First();

            File.Copy(bootstrapperExe, targetSetupExe, true);
            var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName, backgroundGif, signingOpts).Result;

            var writeZipToSetup = findExecutable("WriteZipToSetup.exe");

            try {
                var result = Utility.InvokeProcessAsync(writeZipToSetup, String.Format("\"{0}\" \"{1}\"", targetSetupExe, zipPath), CancellationToken.None).Result;
                if (result.Item1 != 0) throw new Exception("Failed to write Zip to Setup.exe!\n\n" + result.Item2);
            } catch (Exception ex) {
                this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex);
            } finally {
                File.Delete(zipPath);
            }

            Utility.Retry(() =>
                setPEVersionInfoAndIcon(targetSetupExe, new ZipPackage(package), setupIcon).Wait());

            if (signingOpts != null) {
                signPEFile(targetSetupExe, signingOpts).Wait();
            }

            if (generateMsi) {
                createMsiPackage(targetSetupExe, new ZipPackage(package)).Wait();

                if (signingOpts != null) {
                    signPEFile(targetSetupExe.Replace(".exe", ".msi"), signingOpts).Wait();
                }
            }
        }
示例#29
0
        public void ApplyMultipleDeltaPackagesGeneratesCorrectHash()
        {
            var firstRelease  = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.0.0-full.nupkg"), true);
            var secondRelease = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.1.0-full.nupkg"), true);
            var thirdRelease  = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.2.0-full.nupkg"), true);

            string installDir, releasesDir;

            using (Utility.WithTempDirectory(out releasesDir))
                using (IntegrationTestHelper.WithFakeAlreadyInstalledApp("InstalledSquirrelDesktopDemo-1.0.0.zip", out installDir)) {
                    var firstDelta  = Path.Combine(releasesDir, "SquirrelDesktopDemo-1.1.0-delta.nupkg");
                    var secondDelta = Path.Combine(releasesDir, "SquirrelDesktopDemo-1.2.0-delta.nupkg");


                    new[] { firstRelease, secondRelease, thirdRelease }
                    .ForEach(file =>
                    {
                        var packageFile = file.ReleasePackageFile;
                        var fileName    = Path.GetFileName(packageFile);
                        File.Copy(packageFile, Path.Combine(releasesDir, fileName));
                    });

                    var deltaBuilder = new DeltaPackageBuilder();
                    deltaBuilder.CreateDeltaPackage(firstRelease, secondRelease, firstDelta);
                    deltaBuilder.CreateDeltaPackage(secondRelease, thirdRelease, secondDelta);

                    ReleaseEntry.BuildReleasesFile(releasesDir);

                    var updateManager = new UpdateManager(
                        releasesDir, "ShimmerDesktopDemo", FrameworkVersion.Net40, installDir);

                    using (updateManager) {
                        var updateInfo = updateManager.CheckForUpdate().First();

                        Assert.Equal(2, updateInfo.ReleasesToApply.Count());

                        updateManager.DownloadReleases(updateInfo.ReleasesToApply).Wait();
                        updateManager.ApplyReleases(updateInfo).Wait();
                    }

                    string referenceDir;
                    using (IntegrationTestHelper.WithFakeAlreadyInstalledApp("InstalledSquirrelDesktopDemo-1.2.0.zip", out referenceDir)) {
                        var referenceVersion = Path.Combine(referenceDir, "ShimmerDesktopDemo", "app-1.2.0");
                        var installVersion   = Path.Combine(installDir, "ShimmerDesktopDemo", "app-1.2.0");

                        var referenceFiles = Directory.GetFiles(referenceVersion);
                        var actualFiles    = Directory.GetFiles(installVersion);

                        Assert.Equal(referenceFiles.Count(), actualFiles.Count());

                        var invalidFiles =
                            Enumerable.Zip(referenceFiles, actualFiles,
                                           (reference, actual) => {
                            var refSha    = Utility.CalculateFileSHA1(reference);
                            var actualSha = Utility.CalculateFileSHA1(actual);

                            return(new { File = actual, Result = refSha == actualSha });
                        })
                            .Where(c => !c.Result).ToArray();

                        Assert.Empty(invalidFiles);
                    }
                }
        }
        public void CreateDeltaPackageIntegrationTest()
        {
            var basePackage = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.1.0-pre.nupkg");
            var newPackage  = IntegrationTestHelper.GetPath("fixtures", "Squirrel.Tests.0.2.0-pre.nupkg");

            var sourceDir = IntegrationTestHelper.GetPath("fixtures", "packages");

            (new DirectoryInfo(sourceDir)).Exists.ShouldBeTrue();

            var baseFixture = new ReleasePackage(basePackage);
            var fixture     = new ReleasePackage(newPackage);

            var tempFiles = Enumerable.Range(0, 3)
                            .Select(_ => Path.GetTempPath() + Guid.NewGuid().ToString() + ".nupkg")
                            .ToArray();

            try {
                baseFixture.CreateReleasePackage(tempFiles[0], sourceDir);
                fixture.CreateReleasePackage(tempFiles[1], sourceDir);

                (new FileInfo(baseFixture.ReleasePackageFile)).Exists.ShouldBeTrue();
                (new FileInfo(fixture.ReleasePackageFile)).Exists.ShouldBeTrue();

                var deltaBuilder = new DeltaPackageBuilder();
                deltaBuilder.CreateDeltaPackage(baseFixture, fixture, tempFiles[2]);

                var fullPkg  = new ZipPackage(tempFiles[1]);
                var deltaPkg = new ZipPackage(tempFiles[2]);

                //
                // Package Checks
                //

                fullPkg.Id.ShouldEqual(deltaPkg.Id);
                fullPkg.Version.CompareTo(deltaPkg.Version).ShouldEqual(0);

                // Delta packages should be smaller than the original!
                var fileInfos = tempFiles.Select(x => new FileInfo(x)).ToArray();
                this.Log().Info("Base Size: {0}, Current Size: {1}, Delta Size: {2}",
                                fileInfos[0].Length, fileInfos[1].Length, fileInfos[2].Length);

                (fileInfos[2].Length - fileInfos[1].Length).ShouldBeLessThan(0);

                //
                // File Checks
                ///

                var deltaPkgFiles = deltaPkg.GetFiles().ToList();
                deltaPkgFiles.Count.ShouldBeGreaterThan(0);

                this.Log().Info("Files in delta package:");
                deltaPkgFiles.ForEach(x => this.Log().Info(x.Path));

                var newFilesAdded = new[] {
                    "Newtonsoft.Json.dll",
                    "Refit.dll",
                    "Refit-Portable.dll",
                    "Castle.Core.dll",
                }.Select(x => x.ToLowerInvariant());

                // vNext adds a dependency on Refit
                newFilesAdded
                .All(x => deltaPkgFiles.Any(y => y.Path.ToLowerInvariant().Contains(x)))
                .ShouldBeTrue();

                // All the other files should be diffs and shasums
                deltaPkgFiles
                .Where(x => !newFilesAdded.Any(y => x.Path.ToLowerInvariant().Contains(y)))
                .All(x => x.Path.ToLowerInvariant().EndsWith("diff") || x.Path.ToLowerInvariant().EndsWith("shasum"))
                .ShouldBeTrue();

                // Every .diff file should have a shasum file
                deltaPkg.GetFiles().Any(x => x.Path.ToLowerInvariant().EndsWith(".diff")).ShouldBeTrue();
                deltaPkg.GetFiles()
                .Where(x => x.Path.ToLowerInvariant().EndsWith(".diff"))
                .ForEach(x => {
                    var lookingFor = x.Path.Replace(".diff", ".shasum");
                    this.Log().Info("Looking for corresponding shasum file: {0}", lookingFor);
                    deltaPkg.GetFiles().Any(y => y.Path == lookingFor).ShouldBeTrue();
                });
            } finally {
                tempFiles.ForEach(File.Delete);
            }
        }