public async Task ApplyReleaseWhichRemovesAFile() { string tempDir; using (Utility.WithTempDirectory(out tempDir)) { string appDir = Path.Combine(tempDir, "theApp"); string packagesDir = Path.Combine(appDir, "packages"); Directory.CreateDirectory(packagesDir); new[] { "Squirrel.Core.1.1.0.0-full.nupkg", "Squirrel.Core.1.2.0.0-full.nupkg", }.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x))); var fixture = new UpdateManager.ApplyReleasesImpl(appDir); var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg")); var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.2.0.0-full.nupkg")); var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40); updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue(); var progress = new List <int>(); await fixture.ApplyReleases(updateInfo, false, progress.Add); this.Log().Info("Progress: [{0}]", String.Join(",", progress)); progress .Aggregate(0, (acc, x) => { x.ShouldBeGreaterThan(acc); return(x); }) .ShouldEqual(100); var rootDirectory = Path.Combine(tempDir, "theApp", "app-1.2.0.0"); new[] { new { Name = "NLog.dll", Version = new Version("2.0.0.0") }, new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") }, }.ForEach(x => { var path = Path.Combine(rootDirectory, x.Name); this.Log().Info("Looking for {0}", path); File.Exists(path).ShouldBeTrue(); }); var removedFile = Path.Combine("sub", "Ionic.Zip.dll"); var deployedPath = Path.Combine(rootDirectory, removedFile); File.Exists(deployedPath).ShouldBeFalse(); } }
public void ApplyReleasesWithOneReleaseFile() { string tempDir; using (Utility.WithTempDirectory(out tempDir)) { string packagesDir = Path.Combine(tempDir, "theApp", "packages"); Directory.CreateDirectory(packagesDir); new[] { "Squirrel.Core.1.0.0.0-full.nupkg", "Squirrel.Core.1.1.0.0-full.nupkg", }.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x))); var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader()); var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.0.0.0-full.nupkg")); var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg")); var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40); updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue(); using (fixture) { var progress = new ReplaySubject <int>(); fixture.ApplyReleases(updateInfo, progress).First(); this.Log().Info("Progress: [{0}]", String.Join(",", progress)); progress.Buffer(2, 1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue(); progress.Last().ShouldEqual(100); } var filesToFind = new[] { new { Name = "NLog.dll", Version = new Version("2.0.0.0") }, new { Name = "NSync.Core.dll", Version = new Version("1.1.0.0") }, new { Name = Path.Combine("sub", "Ionic.Zip.dll"), Version = new Version("1.9.1.8") }, }; filesToFind.ForEach(x => { var path = Path.Combine(tempDir, "theApp", "app-1.1.0.0", x.Name); this.Log().Info("Looking for {0}", path); File.Exists(path).ShouldBeTrue(); var vi = FileVersionInfo.GetVersionInfo(path); var verInfo = new Version(vi.FileVersion ?? "1.0.0.0"); x.Version.ShouldEqual(verInfo); }); } }
private UpdateInfo DetermineUpdateInfo(IEnumerable <ReleaseEntry> localReleases, IEnumerable <ReleaseEntry> remoteReleases, bool ignoreDeltaUpdates) { var packageDirectory = Utility.PackageDirectoryForAppDir(rootAppDirectory); localReleases = localReleases ?? Enumerable.Empty <ReleaseEntry>(); if (remoteReleases == null) { Log.WarnFormat("Release information couldn't be determined due to remote corrupt RELEASES file"); throw new Exception("Corrupt remote RELEASES file"); } var latestFullRelease = Utility.FindCurrentVersion(remoteReleases); var currentRelease = Utility.FindCurrentVersion(localReleases); if (latestFullRelease == currentRelease) { Log.InfoFormat("No updates, remote and local are the same"); var info = UpdateInfo.Create(currentRelease, new[] { latestFullRelease }, packageDirectory); return(info); } if (ignoreDeltaUpdates) { remoteReleases = remoteReleases.Where(x => !x.IsDelta); } if (!localReleases.Any()) { Log.WarnFormat("First run or local directory is corrupt, starting from scratch"); return(UpdateInfo.Create(null, new[] { latestFullRelease }, packageDirectory)); } if (localReleases.Max(x => x.Version) > remoteReleases.Max(x => x.Version)) { Log.WarnFormat("hwhat, local version is greater than remote version"); return(UpdateInfo.Create(Utility.FindCurrentVersion(localReleases), new[] { latestFullRelease }, packageDirectory)); } return(UpdateInfo.Create(currentRelease, remoteReleases, packageDirectory)); }
public void WhenNoNewReleasesAreAvailableTheListIsEmpty() { string tempDir; using (Utility.WithTempDirectory(out tempDir)) { var appDir = Directory.CreateDirectory(Path.Combine(tempDir, "theApp")); var packages = Path.Combine(appDir.FullName, "packages"); Directory.CreateDirectory(packages); var package = "Squirrel.Core.1.0.0.0-full.nupkg"; File.Copy(IntegrationTestHelper.GetPath("fixtures", package), Path.Combine(packages, package)); var aGivenPackage = Path.Combine(packages, package); var baseEntry = ReleaseEntry.GenerateFromFile(aGivenPackage); var updateInfo = UpdateInfo.Create(baseEntry, new[] { baseEntry }, "dontcare"); Assert.Empty(updateInfo.ReleasesToApply); } }
public void ExecutablesPinnedToTaskbarShouldPointToNewVersion() { string tempDir; using (Utility.WithTempDirectory(out tempDir)) { string packagesDir = Path.Combine(tempDir, "theApp", "packages"); Directory.CreateDirectory(packagesDir); new[] { "SampleUpdatingApp.1.0.0.0.nupkg", "SampleUpdatingApp.1.1.0.0.nupkg", }.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x))); var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader()); var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.0.0.0.nupkg")); var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.1.0.0.nupkg")); var updateInfo = UpdateInfo.Create(null, new[] { baseEntry }, packagesDir, FrameworkVersion.Net40); using (fixture) { fixture.ApplyReleases(updateInfo).ToList().First(); } var oldExecutable = Path.Combine(tempDir, "theApp", "app-1.0.0.0", "SampleUpdatingApp.exe"); File.Exists(oldExecutable).ShouldBeTrue(); TaskbarHelper.PinToTaskbar(oldExecutable); updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40); using (fixture) { fixture.ApplyReleases(updateInfo).ToList().First(); } var newExecutable = Path.Combine(tempDir, "theApp", "app-1.1.0.0", "SampleUpdatingApp.exe"); File.Exists(newExecutable).ShouldBeTrue(); TaskbarHelper.IsPinnedToTaskbar(newExecutable).ShouldBeTrue(); Utility.Retry(() => TaskbarHelper.UnpinFromTaskbar(newExecutable)); } }
static int Main(string[] args) { var command = ""; var target = ""; var appName = default(string); var showHelp = false; var opts = new OptionSet() { { "c|command=", "One of 'check' or 'update' to return the latest update information, or to perform the update", v => command = v }, { "t|update-target=", "The URL or directory to download updates from", v => target = v }, { "n|app-name=", "(Optional) The name of the application, only necessary if updater.exe isn't in the install directory", v => appName = v }, { "h|help", "Show this message and exit", v => showHelp = v != null }, }; opts.Parse(args); if (!new[] { "check", "update", "install", }.Any(x => command.ToLowerInvariant() == x)) { Console.Error.WriteLine("Command must be either 'check' or 'update'"); showHelp = true; } if (!Directory.Exists(target) && !File.Exists(target) && !isAUrl(target)) { Console.Error.WriteLine("Target must be either a directory or a URL to check for updates"); showHelp = true; } if (showHelp) { Console.WriteLine("\nSquirrel.Updater.exe - Check for updates or update an application"); Console.WriteLine(@"Usage: Squirrel.Updater.exe [options]"); Console.WriteLine("Options:"); foreach (var v in opts) { if (v.GetNames().Length != 2) { Console.WriteLine(" --{0} - {1}", v.GetNames()[0], v.Description); } else { Console.WriteLine(" -{0}/--{1} - {2}", v.GetNames()[0], v.GetNames()[1], v.Description); } } return(0); } appName = appName ?? determineAppName(); using (var mgr = new UpdateManager(target, appName, FrameworkVersion.Net40)) { if (command.ToLowerInvariant() == "check") { var updateInfo = default(UpdateInfo); try { updateInfo = mgr.CheckForUpdate().First(); if (updateInfo.ReleasesToApply.Count > 0) { mgr.DownloadReleases(updateInfo.ReleasesToApply).First(); } } catch (Exception ex) { writeJsonForException(ex, "Failed to check for updates"); return(-1); } var releaseNotes = new Dictionary <ReleaseEntry, string>(); try { releaseNotes = (updateInfo.ReleasesToApply.Count > 0) ? updateInfo.FetchReleaseNotes() : releaseNotes; } catch (Exception ex) { // TODO: Find a way to log this } Console.WriteLine(JsonConvert.SerializeObject(new { UpdateInfo = updateInfo, ReleaseNotes = releaseNotes, })); return(0); } if (command.ToLowerInvariant() == "update") { var result = default(ReleaseEntry); try { result = mgr.UpdateAppAsync().Result; } catch (Exception ex) { writeJsonForException(ex, "Failed to update application"); return(-1); } Console.WriteLine(JsonConvert.SerializeObject(result)); return(0); } if (command.ToLowerInvariant() == "install") { var targetRelease = ReleaseEntry.GenerateFromFile(target); mgr.ApplyReleases(UpdateInfo.Create(null, new[] { targetRelease }, Path.GetDirectoryName(target), FrameworkVersion.Net40)).First(); return(0); } } throw new Exception("How even did we get here?"); }