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); } }
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); } }
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); } }
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); } }
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); } }
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); } }
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); } } }
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); }
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); }
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")); }
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); }
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); }); }
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); } }
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); } }
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); } }
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); }
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); }
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); } } }
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); } } }
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); })); }
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); } }
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(); } } }
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); } }
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(); } } }
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); } }