async Task <ICoreRunLib> BuildCoreRunLibAsync() { await _snapEmbeddedResources.ExtractCoreRunLibAsync(_snapFilesystem, _snapCryptoProvider, _coreRunLibDirectory, _baseFixture.OsPlatform); var coreRunLib = new CoreRunLib(_snapFilesystem, _baseFixture.OsPlatform, _coreRunLibDirectory); return(coreRunLib); }
static int Install([NotNull] ISnapInstallerEnvironment environment, [NotNull] ISnapInstallerEmbeddedResources snapInstallerEmbeddedResources, [NotNull] ISnapInstaller snapInstaller, [NotNull] ISnapFilesystem snapFilesystem, [NotNull] ISnapPack snapPack, [NotNull] ISnapOs snapOs, [NotNull] CoreRunLib coreRunLib, [NotNull] ISnapAppReader snapAppReader, [NotNull] ISnapAppWriter snapAppWriter, [NotNull] INugetService nugetService, [NotNull] ISnapPackageManager snapPackageManager, [NotNull] ISnapExtractor snapExtractor, [NotNull] ILog diskLogger, bool headless) { if (environment == null) { throw new ArgumentNullException(nameof(environment)); } if (snapInstallerEmbeddedResources == null) { throw new ArgumentNullException(nameof(snapInstallerEmbeddedResources)); } if (snapInstaller == null) { throw new ArgumentNullException(nameof(snapInstaller)); } if (snapFilesystem == null) { throw new ArgumentNullException(nameof(snapFilesystem)); } if (snapPack == null) { throw new ArgumentNullException(nameof(snapPack)); } if (snapOs == null) { throw new ArgumentNullException(nameof(snapOs)); } if (coreRunLib == null) { throw new ArgumentNullException(nameof(coreRunLib)); } if (snapAppReader == null) { throw new ArgumentNullException(nameof(snapAppReader)); } if (snapAppWriter == null) { throw new ArgumentNullException(nameof(snapAppWriter)); } if (nugetService == null) { throw new ArgumentNullException(nameof(nugetService)); } if (snapPackageManager == null) { throw new ArgumentNullException(nameof(snapPackageManager)); } if (snapExtractor == null) { throw new ArgumentNullException(nameof(snapExtractor)); } if (diskLogger == null) { throw new ArgumentNullException(nameof(diskLogger)); } // NB! All filesystem operations has to be readonly until check that verifies // current user is not elevated to root has run. var cancellationToken = environment.CancellationToken; var installerProgressSource = new SnapProgressSource(); var onFirstAnimationRenderedEvent = new ManualResetEventSlim(false); var exitCode = 1; // ReSharper disable once ImplicitlyCapturedClosure async Task InstallInBackgroundAsync(IMainWindowViewModel mainWindowViewModel) { if (mainWindowViewModel == null) { throw new ArgumentNullException(nameof(mainWindowViewModel)); } if (mainWindowViewModel.Headless) { diskLogger.Info("Headless install."); onFirstAnimationRenderedEvent.Dispose(); } else { diskLogger.Info("Waiting for main window to become visible."); onFirstAnimationRenderedEvent.Wait(cancellationToken); onFirstAnimationRenderedEvent.Dispose(); diskLogger.Info("Main window should now be visible."); } var mainWindowLogger = new LogForwarder(LogLevel.Info, diskLogger, (level, func, exception, parameters) => { var message = func?.Invoke(); if (message == null) { return; } SetStatusText(mainWindowViewModel, message); }); if (coreRunLib.IsElevated()) { var rootUserText = snapOs.OsPlatform == OSPlatform.Windows ? "Administrator" : "root"; mainWindowLogger.Error($"Error! Installer cannot run in an elevated user context: {rootUserText}"); goto done; } diskLogger.Debug($"{nameof(environment.Io.WorkingDirectory)}: {environment.Io.WorkingDirectory}"); diskLogger.Debug($"{nameof(environment.Io.ThisExeWorkingDirectory)}: {environment.Io.ThisExeWorkingDirectory}"); var snapAppDllAbsolutePath = snapFilesystem.PathCombine(environment.Io.ThisExeWorkingDirectory, SnapConstants.SnapAppDllFilename); diskLogger.Debug($"{nameof(snapAppDllAbsolutePath)}: {snapAppDllAbsolutePath}."); if (!snapFilesystem.FileExists(snapAppDllAbsolutePath)) { mainWindowLogger.Info($"Unable to find: {snapFilesystem.PathGetFileName(snapAppDllAbsolutePath)}"); goto done; } SnapApp snapApp; SnapChannel snapChannel; try { snapApp = environment.Io.ThisExeWorkingDirectory.GetSnapAppFromDirectory(snapFilesystem, snapAppReader); snapChannel = snapApp.GetCurrentChannelOrThrow(); } catch (Exception ex) { mainWindowLogger.ErrorException($"Error reading {SnapConstants.SnapAppDllFilename}", ex); goto done; } var nupkgAbsolutePath = snapFilesystem.PathCombine(environment.Io.ThisExeWorkingDirectory, "Setup.nupkg"); var nupkgReleasesAbsolutePath = snapFilesystem.PathCombine(environment.Io.ThisExeWorkingDirectory, snapApp.BuildNugetReleasesFilename()); var offlineInstaller = false; using (var webInstallerDir = new DisposableDirectory(snapOs.SpecialFolders.NugetCacheDirectory, snapFilesystem)) { ISnapAppChannelReleases snapAppChannelReleases; SnapRelease snapReleaseToInstall; // Offline installer if (snapFilesystem.FileExists(nupkgAbsolutePath)) { mainWindowLogger.Info("Offline installer is loading releases nupkg"); try { var releasesFileStream = snapFilesystem.FileRead(nupkgReleasesAbsolutePath); using var packageArchiveReader = new PackageArchiveReader(releasesFileStream); var snapAppsReleases = await snapExtractor.GetSnapAppsReleasesAsync(packageArchiveReader, snapAppReader, cancellationToken); snapAppChannelReleases = snapAppsReleases.GetReleases(snapApp, snapChannel); var isGenesis = !snapAppChannelReleases.HasDeltaReleases(); snapReleaseToInstall = snapAppChannelReleases.GetMostRecentRelease().AsFullRelease(isGenesis); } catch (Exception e) { mainWindowLogger.ErrorException($"Error reading {nupkgAbsolutePath}", e); goto done; } offlineInstaller = true; } // Web installer else if (snapFilesystem.FileExists(snapAppDllAbsolutePath)) { mainWindowLogger.Info("Web installer is downloading releases nupkg"); try { var(snapAppsReleases, packageSource, releasesMemoryStream) = await snapPackageManager.GetSnapsReleasesAsync(snapApp, mainWindowLogger, cancellationToken); releasesMemoryStream?.Dispose(); if (snapAppsReleases == null) { mainWindowLogger.Error("Failed to download releases nupkg. Try rerunning the installer."); goto done; } var snapAppsReleasesBytes = snapAppWriter.ToSnapAppsReleases(snapAppsReleases); await snapFilesystem.FileWriteAsync(snapAppsReleasesBytes, nupkgReleasesAbsolutePath, cancellationToken); snapAppChannelReleases = snapAppsReleases.GetReleases(snapApp, snapApp.GetCurrentChannelOrThrow()); if (!snapAppChannelReleases.Any()) { mainWindowLogger.Error($"Unable to find any releases in channel: {snapAppChannelReleases.Channel.Name}."); goto done; } var isGenesis = snapAppChannelReleases.Count() == 1; snapReleaseToInstall = snapAppChannelReleases.GetMostRecentRelease().AsFullRelease(isGenesis); snapApp.Version = snapReleaseToInstall.Version; mainWindowLogger.Info($"Current version: {snapApp.Version}. Channel: {snapAppChannelReleases.Channel.Name}."); // ReSharper disable once MethodSupportsCancellation await Task.Delay(TimeSpan.FromSeconds(3)); mainWindowLogger.Info("Downloading required assets"); void UpdateProgress(string type, int totalPercentage, long releasesChecksummed = 0, long releasesToChecksum = 0, long releasesDownloaded = 0, long releasesToDownload = 0, long filesRestored = 0, long filesToRestore = 0, long totalBytesDownloaded = 0, long totalBytesToDownload = 0) { void SetProgressText(long current, long total, string defaultText, string pluralText) { var outputText = total > 1 ? pluralText : defaultText; switch (type) { case "Download": if (total > 1) { SetStatusText(mainWindowViewModel, $"{outputText} ({totalPercentage}%): {current} of {total}. " + $"Downloaded so far: {totalBytesDownloaded.BytesAsHumanReadable()}. " + $"Total: {totalBytesToDownload.BytesAsHumanReadable()}"); goto incrementProgress; } SetStatusText(mainWindowViewModel, $"{outputText} ({totalPercentage}%): " + $"Downloaded so far: {totalBytesDownloaded.BytesAsHumanReadable()}. " + $"Total: {totalBytesToDownload.BytesAsHumanReadable()}"); goto incrementProgress; default: if (total > 1) { SetStatusText(mainWindowViewModel, $"{outputText} ({totalPercentage}%): {current} of {total}."); goto incrementProgress; } SetStatusText(mainWindowViewModel, $"{outputText}: {totalPercentage}%"); goto incrementProgress; } incrementProgress: installerProgressSource.Raise(totalPercentage); } switch (type) { case "Checksum": SetProgressText(releasesChecksummed, releasesToChecksum, "Validating payload", "Validating payloads"); break; case "Download": SetProgressText(releasesDownloaded, releasesToDownload, "Downloading payload", "Downloading payloads"); break; case "Restore": SetProgressText(filesRestored, filesToRestore, "Restoring file", "Restoring files"); break; default: diskLogger.Warn($"Unknown progress type: {type}"); break; } } var snapPackageManagerProgressSource = new SnapPackageManagerProgressSource { ChecksumProgress = x => UpdateProgress("Checksum", x.progressPercentage, x.releasesChecksummed, x.releasesToChecksum), DownloadProgress = x => UpdateProgress("Download", x.progressPercentage, releasesDownloaded: x.releasesDownloaded, releasesToDownload: x.releasesToDownload, totalBytesDownloaded: x.totalBytesDownloaded, totalBytesToDownload: x.totalBytesToDownload), RestoreProgress = x => UpdateProgress("Restore", x.progressPercentage, filesRestored: x.filesRestored, filesToRestore: x.filesToRestore) }; var restoreSummary = await snapPackageManager.RestoreAsync(webInstallerDir.WorkingDirectory, snapAppChannelReleases, packageSource, SnapPackageManagerRestoreType.Default, snapPackageManagerProgressSource, diskLogger, cancellationToken); if (!restoreSummary.Success) { mainWindowLogger.Info("Unknown error while restoring assets."); goto done; } mainWindowLogger.Info("Preparing to install payload"); var setupNupkgAbsolutePath = snapOs.Filesystem.PathCombine(webInstallerDir.WorkingDirectory, snapReleaseToInstall.Filename); if (!snapFilesystem.FileExists(setupNupkgAbsolutePath)) { mainWindowLogger.Error($"Payload does not exist on disk: {setupNupkgAbsolutePath}."); goto done; } nupkgAbsolutePath = snapFilesystem.PathCombine(environment.Io.ThisExeWorkingDirectory, "Setup.nupkg"); mainWindowLogger.Info("Copying payload to installer directory"); snapOs.Filesystem.FileDeleteIfExists(nupkgAbsolutePath); await snapOs.Filesystem.FileCopyAsync(setupNupkgAbsolutePath, nupkgAbsolutePath, cancellationToken); mainWindowLogger.Info("Successfully copied payload"); installerProgressSource.Reset(); } catch (Exception e) { mainWindowLogger.ErrorException("Unknown error while restoring assets", e); goto done; } } else { mainWindowLogger.Error("Unknown error. Could not find offline or web installer payload."); goto done; } diskLogger.Trace($"Offline installer: {offlineInstaller}"); diskLogger.Trace($"{nameof(nupkgAbsolutePath)}: {nupkgAbsolutePath}"); diskLogger.Trace($"{nameof(nupkgReleasesAbsolutePath)}: {nupkgReleasesAbsolutePath}"); if (!snapFilesystem.FileExists(nupkgAbsolutePath)) { mainWindowLogger.Error($"Unable to find installer payload: {snapFilesystem.PathGetFileName(nupkgAbsolutePath)}"); goto done; } mainWindowLogger.Info("Attempting to read payload release details"); if (!snapFilesystem.FileExists(nupkgReleasesAbsolutePath)) { mainWindowLogger.Error($"Unable to find releases nupkg: {snapFilesystem.PathGetFileName(nupkgReleasesAbsolutePath)}"); goto done; } var baseDirectory = snapFilesystem.PathCombine(snapOs.SpecialFolders.LocalApplicationData, snapApp.Id); mainWindowLogger.Info($"Installing {snapApp.Id}. Channel name: {snapChannel.Name}"); try { var snapAppInstalled = await snapInstaller.InstallAsync(nupkgAbsolutePath, baseDirectory, snapReleaseToInstall, snapChannel, installerProgressSource, mainWindowLogger, cancellationToken, offlineInstaller); if (snapAppInstalled == null) { goto done; } if (!offlineInstaller && snapAppChannelReleases.HasDeltaReleases()) { var snapReleasesToCopy = new List <SnapRelease> { snapAppChannelReleases.GetGenesisRelease() }; snapReleasesToCopy.AddRange(snapAppChannelReleases.GetDeltaReleases()); if (snapReleasesToCopy.Any()) { var totalSnapReleasesToCopyCount = snapReleasesToCopy.Count; mainWindowLogger.Info($"Copying 1 of {totalSnapReleasesToCopyCount} payloads to application directory."); var packagesDirectory = snapFilesystem.PathCombine(baseDirectory, "packages"); var snapReleasesCopied = 1; foreach (var snapRelease in snapReleasesToCopy) { var nupkgPackageWebInstallerDirectoryAbsolutePath = snapFilesystem.PathCombine( webInstallerDir.WorkingDirectory, snapRelease.Filename); var nupkgPackagePackagesDirectoryAbsolutePath = snapFilesystem.PathCombine( packagesDirectory, snapRelease.Filename); await snapFilesystem.FileCopyAsync( nupkgPackageWebInstallerDirectoryAbsolutePath, nupkgPackagePackagesDirectoryAbsolutePath, cancellationToken); mainWindowLogger.Info($"Copied {snapReleasesCopied} of {totalSnapReleasesToCopyCount} payloads to application directory."); ++snapReleasesCopied; } mainWindowLogger.Info("Successfully copied all payloads."); } snapFilesystem.FileDeleteIfExists(nupkgAbsolutePath); } mainWindowLogger.Info($"Successfully installed {snapApp.Id}."); exitCode = 0; } catch (Exception e) { mainWindowLogger.ErrorException("Unknown error during install", e); } } done: // Give user enough time to read final log message. Thread.Sleep(exitCode == 0 ? 3000 : 10000); environment.Shutdown(); } if (headless) { try { InstallInBackgroundAsync(new ConsoleMainViewModel()).Wait(cancellationToken); } catch (OperationCanceledException) { // ignore } return(exitCode); } var avaloniaApp = BuildAvaloniaApp <App>() .AfterSetup(builder => { MainWindow.Environment = environment; MainWindow.ViewModel = new AvaloniaMainWindowViewModel(snapInstallerEmbeddedResources, installerProgressSource, () => onFirstAnimationRenderedEvent.Set(), cancellationToken); Task.Factory.StartNew(() => InstallInBackgroundAsync(MainWindow.ViewModel), TaskCreationOptions.LongRunning); }); avaloniaApp.StartWithClassicDesktopLifetime(null); return(exitCode); }
static async Task <(int exitCode, SnapInstallerType installerType)> MainImplAsync([NotNull] ISnapInstallerEnvironment snapInstallerEnvironment, [NotNull] ILog snapInstallerLogger, bool headless) { if (snapInstallerEnvironment == null) { throw new ArgumentNullException(nameof(snapInstallerEnvironment)); } if (snapInstallerLogger == null) { throw new ArgumentNullException(nameof(snapInstallerLogger)); } var snapOs = snapInstallerEnvironment.Container.GetInstance <ISnapOs>(); var snapEmbeddedResources = snapInstallerEnvironment.Container.GetInstance <ISnapEmbeddedResources>(); var snapCryptoProvider = snapInstallerEnvironment.Container.GetInstance <ISnapCryptoProvider>(); var thisExeWorkingDirectory = snapInstallerEnvironment.Io.ThisExeWorkingDirectory; var workingDirectory = snapInstallerEnvironment.Io.WorkingDirectory; TplHelper.RunSync(() => snapEmbeddedResources.ExtractCoreRunLibAsync(snapOs.Filesystem, snapCryptoProvider, thisExeWorkingDirectory, snapOs.OsPlatform)); var coreRunLib = new CoreRunLib(snapOs.Filesystem, snapOs.OsPlatform, thisExeWorkingDirectory); var snapInstaller = snapInstallerEnvironment.Container.GetInstance <ISnapInstaller>(); var snapInstallerEmbeddedResources = snapInstallerEnvironment.Container.GetInstance <ISnapInstallerEmbeddedResources>(); var snapPack = snapInstallerEnvironment.Container.GetInstance <ISnapPack>(); var snapAppReader = snapInstallerEnvironment.Container.GetInstance <ISnapAppReader>(); var snapAppWriter = snapInstallerEnvironment.Container.GetInstance <ISnapAppWriter>(); var snapFilesystem = snapInstallerEnvironment.Container.GetInstance <ISnapFilesystem>(); snapFilesystem.DirectoryCreateIfNotExists(snapOs.SpecialFolders.InstallerCacheDirectory); var snapPackageManager = snapInstallerEnvironment.Container.GetInstance <ISnapPackageManager>(); var snapExtractor = snapInstallerEnvironment.Container.GetInstance <ISnapExtractor>(); var nugetServiceCommandInstall = new NugetService(snapOs.Filesystem, new NugetLogger(snapInstallerLogger)); Task <(int exitCode, SnapInstallerType installerType)> RunInstallerAsync() { return(InstallAsync(snapInstallerEnvironment, snapInstallerEmbeddedResources, snapInstaller, snapFilesystem, snapPack, snapOs, coreRunLib, snapAppReader, snapAppWriter, nugetServiceCommandInstall, snapPackageManager, snapExtractor, snapInstallerLogger, headless)); } try { var mutexName = snapCryptoProvider.Sha256(Encoding.UTF8.GetBytes(workingDirectory)); _mutexSingleInstanceWorkingDirectory = new Mutex(true, $"Global\\{mutexName}", out var createdNew); if (!createdNew) { snapInstallerLogger.Error("Setup is already running, exiting..."); return(1, SnapInstallerType.None); } _mutexIsTaken = true; } catch (Exception e) { snapInstallerLogger.ErrorException("Error creating installer mutex, exiting...", e); return(1, SnapInstallerType.None); } return(await RunInstallerAsync()); }
static int MainImplAsync([NotNull] string[] args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } using var cts = new CancellationTokenSource(); ISnapOs snapOs; try { snapOs = SnapOs.AnyOs; } catch (PlatformNotSupportedException) { SnapLogger.Error($"Platform is not supported: {RuntimeInformation.OSDescription}"); return(1); } catch (Exception e) { SnapLogger.ErrorException("Exception thrown while initializing snap os", e); return(1); } snapOs.InstallExitSignalHandler(async() => { cts.Cancel(); await OnExitAsync(); }); var workingDirectory = Environment.CurrentDirectory; if (!workingDirectory.EndsWith(snapOs.Filesystem.DirectorySeparator)) { workingDirectory += snapOs.Filesystem.DirectorySeparator; } var toolWorkingDirectory = snapOs.Filesystem.PathGetDirectoryName(typeof(Program).Assembly.Location); var snapCryptoProvider = new SnapCryptoProvider(); var snapEmbeddedResources = new SnapEmbeddedResources(); snapEmbeddedResources.ExtractCoreRunLibAsync(snapOs.Filesystem, snapCryptoProvider, toolWorkingDirectory, snapOs.OsPlatform).GetAwaiter().GetResult(); var snapXEmbeddedResources = new SnapxEmbeddedResources(); var coreRunLib = new CoreRunLib(snapOs.Filesystem, snapOs.OsPlatform, toolWorkingDirectory); var snapAppReader = new SnapAppReader(); var snapAppWriter = new SnapAppWriter(); var snapPack = new SnapPack(snapOs.Filesystem, snapAppReader, snapAppWriter, snapCryptoProvider, snapEmbeddedResources); var snapExtractor = new SnapExtractor(snapOs.Filesystem, snapPack, snapEmbeddedResources); var snapSpecsReader = new SnapAppReader(); var snapNetworkTimeProvider = new SnapNetworkTimeProvider("time.cloudflare.com", 123); var snapHttpClient = new SnapHttpClient(new HttpClient()); var nugetServiceCommandPack = new NugetService(snapOs.Filesystem, new NugetLogger(SnapPackLogger)); var nugetServiceCommandPromote = new NugetService(snapOs.Filesystem, new NugetLogger(SnapPromoteLogger)); var nugetServiceCommandDemote = new NugetService(snapOs.Filesystem, new NugetLogger(SnapDemoteLogger)); var nugetServiceCommandRestore = new NugetService(snapOs.Filesystem, new NugetLogger(SnapRestoreLogger)); var nugetServiceNoopLogger = new NugetService(snapOs.Filesystem, new NugetLogger(new LogProvider.NoOpLogger())); var snapPackageRestorer = new SnapPackageManager(snapOs.Filesystem, snapOs.SpecialFolders, nugetServiceCommandPack, snapHttpClient, snapCryptoProvider, snapExtractor, snapAppReader, snapPack); var distributedMutexClient = new DistributedMutexClient(new JsonServiceClient("https://snapx.dev")); Console.CancelKeyPress += async(sender, eventArgs) => { eventArgs.Cancel = !cts.IsCancellationRequested; cts.Cancel(); await OnExitAsync(); }; return(MainAsync(args, coreRunLib, snapOs, snapExtractor, snapOs.Filesystem, snapSpecsReader, snapCryptoProvider, snapPack, snapAppWriter, snapXEmbeddedResources, snapPackageRestorer, snapNetworkTimeProvider, nugetServiceCommandPack, nugetServiceCommandPromote, nugetServiceCommandDemote, nugetServiceCommandRestore, nugetServiceNoopLogger, distributedMutexClient, toolWorkingDirectory, workingDirectory, cts.Token)); }
static int MainAsync([NotNull] string[] args, [NotNull] CoreRunLib coreRunLib, [NotNull] ISnapOs snapOs, [NotNull] ISnapExtractor snapExtractor, [NotNull] ISnapFilesystem snapFilesystem, [NotNull] ISnapAppReader snapAppReader, [NotNull] ISnapCryptoProvider snapCryptoProvider, [NotNull] ISnapPack snapPack, [NotNull] ISnapAppWriter snapAppWriter, [NotNull] SnapxEmbeddedResources snapXEmbeddedResources, [NotNull] SnapPackageManager snapPackageManager, [NotNull] ISnapNetworkTimeProvider snapNetworkTimeProvider, [NotNull] INugetService nugetServiceCommandPack, [NotNull] INugetService nugetServiceCommandPromote, [NotNull] INugetService nugetServiceCommandDemote, INugetService nugetServiceCommandRestore, [NotNull] INugetService nugetServiceNoopLogger, [NotNull] IDistributedMutexClient distributedMutexClient, [NotNull] string toolWorkingDirectory, [NotNull] string workingDirectory, CancellationToken cancellationToken) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (coreRunLib == null) { throw new ArgumentNullException(nameof(coreRunLib)); } if (snapOs == null) { throw new ArgumentNullException(nameof(snapOs)); } if (snapExtractor == null) { throw new ArgumentNullException(nameof(snapExtractor)); } if (snapFilesystem == null) { throw new ArgumentNullException(nameof(snapFilesystem)); } if (snapAppReader == null) { throw new ArgumentNullException(nameof(snapAppReader)); } if (snapCryptoProvider == null) { throw new ArgumentNullException(nameof(snapCryptoProvider)); } if (snapPack == null) { throw new ArgumentNullException(nameof(snapPack)); } if (snapAppWriter == null) { throw new ArgumentNullException(nameof(snapAppWriter)); } if (snapXEmbeddedResources == null) { throw new ArgumentNullException(nameof(snapXEmbeddedResources)); } if (snapPackageManager == null) { throw new ArgumentNullException(nameof(snapPackageManager)); } if (snapNetworkTimeProvider == null) { throw new ArgumentNullException(nameof(snapNetworkTimeProvider)); } if (nugetServiceCommandPromote == null) { throw new ArgumentNullException(nameof(nugetServiceCommandPromote)); } if (nugetServiceNoopLogger == null) { throw new ArgumentNullException(nameof(nugetServiceNoopLogger)); } if (distributedMutexClient == null) { throw new ArgumentNullException(nameof(distributedMutexClient)); } if (toolWorkingDirectory == null) { throw new ArgumentNullException(nameof(toolWorkingDirectory)); } if (workingDirectory == null) { throw new ArgumentNullException(nameof(workingDirectory)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } return(Parser .Default .ParseArguments <DemoteOptions, PromoteOptions, PackOptions, Sha256Options, RcEditOptions, ListOptions, RestoreOptions, LockOptions>(args) .MapResult( (DemoteOptions opts) => { var nuGetPackageSources = BuildNuGetPackageSources(snapFilesystem, SnapDemoteLogger); if (nuGetPackageSources == null) { return 1; } return CommandDemoteAsync(opts, snapFilesystem, snapAppReader, snapAppWriter, nuGetPackageSources, nugetServiceCommandDemote, distributedMutexClient, snapPackageManager, snapPack, snapNetworkTimeProvider, snapExtractor, snapOs, snapXEmbeddedResources, coreRunLib, SnapDemoteLogger, workingDirectory, cancellationToken).GetAwaiter().GetResult(); }, (PromoteOptions opts) => { var nuGetPackageSources = BuildNuGetPackageSources(snapFilesystem, SnapPromoteLogger); if (nuGetPackageSources == null) { return 1; } return CommandPromoteAsync(opts, snapFilesystem, snapAppReader, snapAppWriter, nuGetPackageSources, nugetServiceCommandPromote, distributedMutexClient, snapPackageManager, snapPack, snapOs.SpecialFolders, snapNetworkTimeProvider, snapExtractor, snapOs, snapXEmbeddedResources, coreRunLib, SnapPromoteLogger, workingDirectory, cancellationToken).GetAwaiter().GetResult(); }, (PackOptions opts) => { var nuGetPackageSources = BuildNuGetPackageSources(snapFilesystem, SnapPackLogger); if (nuGetPackageSources == null) { return 1; } return CommandPackAsync(opts, snapFilesystem, snapAppReader, snapAppWriter, nuGetPackageSources, snapPack, nugetServiceCommandPack, snapOs, snapXEmbeddedResources, snapExtractor, snapPackageManager, coreRunLib, snapNetworkTimeProvider, SnapPackLogger, distributedMutexClient, workingDirectory, cancellationToken).GetAwaiter().GetResult(); }, (Sha256Options opts) => CommandSha256(opts, snapFilesystem, snapCryptoProvider, SnapLogger), (RcEditOptions opts) => CommandRcEdit(opts, coreRunLib, snapFilesystem, SnapLogger), (ListOptions opts) => { var nuGetPackageSources = BuildNuGetPackageSources(snapFilesystem, SnapListLogger); if (nuGetPackageSources == null) { return 1; } return CommandListAsync(opts, snapFilesystem, snapAppReader, nuGetPackageSources, nugetServiceNoopLogger, snapExtractor, SnapListLogger, workingDirectory, cancellationToken).GetAwaiter().GetResult(); }, (RestoreOptions opts) => { var nuGetPackageSources = BuildNuGetPackageSources(snapFilesystem, SnapRestoreLogger); if (nuGetPackageSources == null) { return 1; } return CommandRestoreAsync(opts, snapFilesystem, snapAppReader, snapAppWriter, nuGetPackageSources, snapPackageManager, snapOs, snapXEmbeddedResources, coreRunLib, snapPack, SnapRestoreLogger, workingDirectory, cancellationToken).GetAwaiter().GetResult(); }, (LockOptions opts) => CommandLock(opts, distributedMutexClient, snapFilesystem, snapAppReader, SnapLockLogger, workingDirectory, cancellationToken).GetAwaiter().GetResult(), errs => { snapOs.EnsureConsole(); return 0; })); }