public NetSdkManagedInstaller(IReporter reporter, SdkFeatureBand sdkFeatureBand, IWorkloadResolver workloadResolver, string userProfileDir, INuGetPackageDownloader nugetPackageDownloader = null, string dotnetDir = null, string tempDirPath = null, VerbosityOptions verbosity = VerbosityOptions.normal, PackageSourceLocation packageSourceLocation = null, RestoreActionConfig restoreActionConfig = null) { _userProfileDir = userProfileDir; _dotnetDir = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); _tempPackagesDir = new DirectoryPath(tempDirPath ?? Path.GetTempPath()); ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger(); _restoreActionConfig = restoreActionConfig; _nugetPackageDownloader = nugetPackageDownloader ?? new NuGetPackageDownloader(_tempPackagesDir, filePermissionSetter: null, new FirstPartyNuGetPackageSigningVerifier(_tempPackagesDir), logger, restoreActionConfig: _restoreActionConfig); bool userLocal = WorkloadFileBasedInstall.IsUserLocal(_dotnetDir, sdkFeatureBand.ToString()); _workloadMetadataDir = Path.Combine(userLocal ? _userProfileDir : _dotnetDir, "metadata", "workloads"); _reporter = reporter; _sdkFeatureBand = sdkFeatureBand; _workloadResolver = workloadResolver; _installationRecordRepository = new NetSdkManagedInstallationRecordRepository(_workloadMetadataDir); _packageSourceLocation = packageSourceLocation; }
public void GivenWorkloadUpdateAcrossFeatureBandsItUpdatesPacks(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var manifestPath = Path.Combine(_testAssetsManager.GetAndValidateTestProjectDirectory("SampleManifest"), "BasicSample.json"); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { manifestPath }), dotnetRoot, userLocal, userProfileDir); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var manifestUpdater = new MockWorkloadManifestUpdater(); var sdkFeatureVersion = "6.0.100"; var installingWorkload = "simple-workload"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } var workloadPacks = new List <PackInfo>() { CreatePackInfo("mock-pack-1", "1.0.0", WorkloadPackKind.Framework, Path.Combine(installRoot, "packs", "mock-pack-1", "1.0.0"), "mock-pack-1"), CreatePackInfo("mock-pack-2", "2.0.0", WorkloadPackKind.Framework, Path.Combine(installRoot, "packs", "mock-pack-2", "2.0.0"), "mock-pack-2") }; // Lay out workload installs for a previous feature band var oldFeatureBand = "5.0.100"; var packRecordDir = Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1"); foreach (var pack in workloadPacks) { Directory.CreateDirectory(Path.Combine(packRecordDir, pack.Id, pack.Version)); File.Create(Path.Combine(packRecordDir, pack.Id, pack.Version, oldFeatureBand)); } Directory.CreateDirectory(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads")); Directory.CreateDirectory(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads")); File.Create(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads", installingWorkload)); File.Create(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)); // Update workload (without installing any workloads to this feature band) var updateParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "update", "--from-previous-sdk" }); var updateCommand = new WorkloadUpdateCommand(updateParseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater, userProfileDir: userProfileDir, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); updateCommand.Execute(); foreach (var pack in workloadPacks) { Directory.Exists(pack.Path).Should().BeTrue(because: $"Pack should be installed {testDirectory}"); File.Exists(Path.Combine(packRecordDir, pack.Id, pack.Version, oldFeatureBand)) .Should().BeTrue(because: "Pack install record should still be present for old feature band"); } File.Exists(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads", installingWorkload)) .Should().BeTrue(because: "Workload install record should still be present for old feature band"); File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)) .Should().BeTrue(because: "Workload install record should be present for current feature band"); }
private void UninstallWorkload(string uninstallingWorkload, string testDirectory, string sdkFeatureVersion) { var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); bool userLocal = WorkloadFileBasedInstall.IsUserLocal(dotnetRoot, sdkFeatureVersion); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var uninstallParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "uninstall", uninstallingWorkload }); var uninstallCommand = new WorkloadUninstallCommand(uninstallParseResult, reporter: _reporter, workloadResolver, nugetDownloader, dotnetDir: dotnetRoot, version: sdkFeatureVersion, userProfileDir: userProfileDir); uninstallCommand.Execute(); }
public void GivenWorkloadUninstallItCanUninstallOnlySpecifiedFeatureBand(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var prevSdkFeatureVersion = "5.0.100"; var sdkFeatureVersion = "6.0.100"; var uninstallingWorkload = "mock-1"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, prevSdkFeatureVersion); } InstallWorkload(uninstallingWorkload, testDirectory, prevSdkFeatureVersion); InstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion); // Assert installs were successful var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); installPacks.Count().Should().Be(2); File.Exists(Path.Combine(installRoot, "metadata", "workloads", prevSdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload)) .Should().BeTrue(); File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload)) .Should().BeTrue(); var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(3); var featureBandMarkerFiles = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")) .SelectMany(packIdDirs => Directory.GetDirectories(packIdDirs)) .SelectMany(packVersionDirs => Directory.GetFiles(packVersionDirs)); featureBandMarkerFiles.Count().Should().Be(6); // 3 packs x 2 feature bands UninstallWorkload(uninstallingWorkload, testDirectory, sdkFeatureVersion); // Assert uninstall was successful, other workload is still installed installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); installPacks.Count().Should().Be(2); File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload)) .Should().BeFalse(); File.Exists(Path.Combine(installRoot, "metadata", "workloads", prevSdkFeatureVersion, "InstalledWorkloads", uninstallingWorkload)) .Should().BeTrue(); packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(3); }
public void GivenExtraPacksInstalledRepairGarbageCollects(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var manifestUpdater = new MockWorkloadManifestUpdater(); var sdkFeatureVersion = "6.0.100"; var installingWorkload = "xamarin-android"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } // Install a workload var installParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "install", installingWorkload }); var installCommand = new WorkloadInstallCommand(installParseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater, userProfileDir: userProfileDir, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); installCommand.Execute(); // Add extra pack dirs and records var extraPackRecordPath = Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1", "Test.Pack.A", "1.0.0", sdkFeatureVersion); Directory.CreateDirectory(Path.GetDirectoryName(extraPackRecordPath)); File.WriteAllText(extraPackRecordPath, string.Empty); var extraPackPath = Path.Combine(installRoot, "packs", "Test.Pack.A", "1.0.0"); Directory.CreateDirectory(extraPackPath); var repairCommand = new WorkloadRepairCommand(_parseResult, reporter: _reporter, workloadResolver: workloadResolver, userProfileDir: userProfileDir, nugetPackageDownloader: nugetDownloader, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); repairCommand.Execute(); // Check that pack dirs and records have been removed File.Exists(extraPackRecordPath).Should().BeFalse(); Directory.Exists(Path.GetDirectoryName(Path.GetDirectoryName(extraPackRecordPath))).Should().BeFalse(); Directory.Exists(extraPackPath).Should().BeFalse(); // Expected packs are still present Directory.GetDirectories(Path.Combine(installRoot, "packs")).Length.Should().Be(7); Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")).Length.Should().Be(8); }
public void GivenMissingPacksRepairFixesInstall(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var manifestUpdater = new MockWorkloadManifestUpdater(); var sdkFeatureVersion = "6.0.100"; var installingWorkload = "xamarin-android"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } // Install a workload var installParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "install", installingWorkload }); var installCommand = new WorkloadInstallCommand(installParseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater, userProfileDir: userProfileDir, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); installCommand.Execute(); // Delete pack dirs/ records var deletedPackRecordPath = Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1", "Xamarin.Android.Sdk", "8.4.7", sdkFeatureVersion); File.Delete(deletedPackRecordPath); var deletedPackPath = Path.Combine(installRoot, "packs", "Xamarin.Android.Sdk"); Directory.Delete(deletedPackPath, true); var repairCommand = new WorkloadRepairCommand(_parseResult, reporter: _reporter, workloadResolver: workloadResolver, userProfileDir: userProfileDir, nugetPackageDownloader: nugetDownloader, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); repairCommand.Execute(); // Check that pack dirs and records have been replaced File.Exists(deletedPackRecordPath).Should().BeTrue(); Directory.Exists(deletedPackPath).Should().BeTrue(); // All expected packs are still present Directory.GetDirectories(Path.Combine(installRoot, "packs")).Length.Should().Be(7); Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")).Length.Should().Be(8); }
public static IInstaller GetWorkloadInstaller( IReporter reporter, SdkFeatureBand sdkFeatureBand, IWorkloadResolver workloadResolver, VerbosityOptions verbosity, string userProfileDir, bool verifySignatures, INuGetPackageDownloader nugetPackageDownloader = null, string dotnetDir = null, string tempDirPath = null, PackageSourceLocation packageSourceLocation = null, RestoreActionConfig restoreActionConfig = null, bool elevationRequired = true) { dotnetDir = string.IsNullOrWhiteSpace(dotnetDir) ? Path.GetDirectoryName(Environment.ProcessPath) : dotnetDir; var installType = GetWorkloadInstallType(sdkFeatureBand, dotnetDir); if (installType == InstallType.Msi) { if (!OperatingSystem.IsWindows()) { throw new InvalidOperationException(LocalizableStrings.OSDoesNotSupportMsi); } return(NetSdkMsiInstallerClient.Create(verifySignatures, sdkFeatureBand, workloadResolver, nugetPackageDownloader, verbosity, packageSourceLocation, reporter, tempDirPath)); } if (elevationRequired && !WorkloadFileBasedInstall.IsUserLocal(dotnetDir, sdkFeatureBand.ToString()) && !CanWriteToDotnetRoot(dotnetDir)) { throw new GracefulException(LocalizableStrings.InadequatePermissions, isUserError: false); } userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath; return(new FileBasedInstaller(reporter, sdkFeatureBand, workloadResolver, userProfileDir, nugetPackageDownloader, dotnetDir: dotnetDir, tempDirPath: tempDirPath, verbosity: verbosity, packageSourceLocation: packageSourceLocation, restoreActionConfig: restoreActionConfig)); }
internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func <string, string?> getEnvironmentVariable, string?userProfileDir) { if (string.IsNullOrWhiteSpace(sdkVersion)) { throw new ArgumentException($"'{nameof(sdkVersion)}' cannot be null or whitespace", nameof(sdkVersion)); } if (string.IsNullOrWhiteSpace(sdkRootPath)) { throw new ArgumentException($"'{nameof(sdkRootPath)}' cannot be null or whitespace", nameof(sdkRootPath)); } _sdkRootPath = sdkRootPath; _sdkVersionBand = new SdkFeatureBand(sdkVersion); var knownManifestIdsFilePath = Path.Combine(_sdkRootPath, "sdk", sdkVersion, "IncludedWorkloadManifests.txt"); if (File.Exists(knownManifestIdsFilePath)) { _knownManifestIds = File.ReadAllLines(knownManifestIdsFilePath).Where(l => !string.IsNullOrEmpty(l)).ToHashSet(); } string?userManifestsDir = userProfileDir is null ? null : Path.Combine(userProfileDir, "sdk-manifests", _sdkVersionBand.ToString()); string dotnetManifestDir = Path.Combine(_sdkRootPath, "sdk-manifests", _sdkVersionBand.ToString()); if (userManifestsDir != null && WorkloadFileBasedInstall.IsUserLocal(_sdkRootPath, _sdkVersionBand.ToString()) && Directory.Exists(userManifestsDir)) { _manifestDirectories = new[] { userManifestsDir, dotnetManifestDir }; } else { _manifestDirectories = new[] { dotnetManifestDir }; } var manifestDirectoryEnvironmentVariable = getEnvironmentVariable(EnvironmentVariableNames.WORKLOAD_MANIFEST_ROOTS); if (manifestDirectoryEnvironmentVariable != null) { // Append the SDK version band to each manifest root specified via the environment variable. This allows the same // environment variable settings to be shared by multiple SDKs. _manifestDirectories = manifestDirectoryEnvironmentVariable.Split(Path.PathSeparator) .Select(p => Path.Combine(p, _sdkVersionBand.ToString())) .Concat(_manifestDirectories).ToArray(); } }
private string GetPackPath(string packName, string packVersion) { IEnumerable <string> GetPackFolders() { var packRootEnvironmentVariable = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WORKLOAD_PACK_ROOTS); if (!string.IsNullOrEmpty(packRootEnvironmentVariable)) { foreach (var packRoot in packRootEnvironmentVariable.Split(Path.PathSeparator)) { yield return(Path.Combine(packRoot, "packs")); } } if (!string.IsNullOrEmpty(NetCoreRoot) && !string.IsNullOrEmpty(NETCoreSdkVersion)) { if (WorkloadFileBasedInstall.IsUserLocal(NetCoreRoot, NETCoreSdkVersion) && CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath() is { } userProfileDir) { yield return(Path.Combine(userProfileDir, "packs")); } } if (!string.IsNullOrEmpty(TargetingPackRoot)) { yield return(TargetingPackRoot); } } foreach (var packFolder in GetPackFolders()) { string packPath = Path.Combine(packFolder, packName, packVersion); if (Directory.Exists(packPath)) { return(packPath); } } return(null); }
public void GivenNoWorkloadsAreInstalledRepairIsNoOp(bool userLocal) { _reporter.Clear(); var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir); var sdkFeatureVersion = "6.0.100"; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } var repairCommand = new WorkloadRepairCommand(_parseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, version: sdkFeatureVersion, dotnetDir: dotnetRoot, userProfileDir: userProfileDir); repairCommand.Execute(); _reporter.Lines.Should().Contain(LocalizableStrings.NoWorkloadsToRepair); }
public void GivenWorkloadUninstallItCanUninstallWorkload(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var sdkFeatureVersion = "6.0.100"; var installingWorkload = "mock-1"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } InstallWorkload(installingWorkload, testDirectory, sdkFeatureVersion); // Assert install was successful var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); installPacks.Count().Should().Be(2); File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)) .Should().BeTrue(); var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(3); UninstallWorkload(installingWorkload, testDirectory, sdkFeatureVersion); // Assert uninstall was successful installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); installPacks.Count().Should().Be(0); File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)) .Should().BeFalse(); packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(0); }
public void GivenWorkloadUpdateItRemovesOldPacksAfterInstall(bool userLocal) { var testDirectory = _testAssetsManager.CreateTestDirectory(identifier: userLocal ? "userlocal" : "default").Path; var dotnetRoot = Path.Combine(testDirectory, "dotnet"); var userProfileDir = Path.Combine(testDirectory, "user-profile"); var workloadResolver = WorkloadResolver.CreateForTests(new MockManifestProvider(new[] { _manifestPath }), dotnetRoot, userLocal, userProfileDir); var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot); var manifestUpdater = new MockWorkloadManifestUpdater(); var sdkFeatureVersion = "6.0.100"; var installingWorkload = "xamarin-android"; string installRoot = userLocal ? userProfileDir : dotnetRoot; if (userLocal) { WorkloadFileBasedInstall.SetUserLocal(dotnetRoot, sdkFeatureVersion); } // Install a workload var installParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "install", installingWorkload }); var installCommand = new WorkloadInstallCommand(installParseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater, userProfileDir: userProfileDir, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); installCommand.Execute(); // 7 packs in packs dir, 1 template pack var installPacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); installPacks.Count().Should().Be(7); foreach (var packDir in installPacks) { Directory.GetDirectories(packDir).Count().Should().Be(1); // 1 version of each pack installed } File.Exists(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1", "Xamarin.Android.Sdk", "8.4.7", "6.0.100")) // Original pack version is installed .Should().BeTrue(); File.Exists(Path.Combine(installRoot, "template-packs", "xamarin.android.templates.1.0.3.nupkg")) .Should().BeTrue(); // Install records are correct File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)) .Should().BeTrue(); var packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(8); foreach (var packRecordDir in packRecordDirs) { var packVersionRecordDirs = Directory.GetDirectories(packRecordDir); packVersionRecordDirs.Count().Should().Be(1); // 1 version of each pack installed Directory.GetFiles(packVersionRecordDirs.First()).Count().Should().Be(1); // 1 feature band file for this pack id and version } // Mock updating the manifest workloadResolver = WorkloadResolver.CreateForTests( new MockManifestProvider(new[] { Path.Combine(_testAssetsManager.GetAndValidateTestProjectDirectory("SampleUpdatedManifest"), "Sample.json") }), dotnetRoot, userLocal, userProfileDir); // Update workload var updateParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "update" }); var updateCommand = new WorkloadUpdateCommand(updateParseResult, reporter: _reporter, workloadResolver: workloadResolver, nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater, userProfileDir: userProfileDir, version: sdkFeatureVersion, dotnetDir: dotnetRoot, tempDirPath: testDirectory); updateCommand.Execute(); // 6 packs in packs dir, 1 template pack var updatePacks = Directory.GetDirectories(Path.Combine(installRoot, "packs")); updatePacks.Count().Should().Be(6); foreach (var packDir in updatePacks) { Directory.GetDirectories(packDir).Count().Should().Be(1); // 1 version of each pack installed } File.Exists(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1", "Xamarin.Android.Sdk", "8.5.7", "6.0.100")) // New pack version is installed .Should().BeTrue(); File.Exists(Path.Combine(installRoot, "template-packs", "xamarin.android.templates.2.1.3.nupkg")) .Should().BeTrue(); // Install records are correct File.Exists(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)) .Should().BeTrue(); packRecordDirs = Directory.GetDirectories(Path.Combine(installRoot, "metadata", "workloads", "InstalledPacks", "v1")); packRecordDirs.Count().Should().Be(7); foreach (var packRecordDir in packRecordDirs) { var packVersionRecordDirs = Directory.GetDirectories(packRecordDir); packVersionRecordDirs.Count().Should().Be(1); // 1 version of each pack installed Directory.GetFiles(packVersionRecordDirs.First()).Count().Should().Be(1); // 1 feature band file for this pack id and version } }
public void InstallWorkloadManifest(ManifestId manifestId, ManifestVersion manifestVersion, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null, bool isRollback = false) { string packagePath = null; string tempExtractionDir = null; string tempBackupDir = null; string rootInstallDir = WorkloadFileBasedInstall.IsUserLocal(_dotnetDir, sdkFeatureBand.ToString()) ? _userProfileDir : _dotnetDir; var manifestPath = Path.Combine(rootInstallDir, "sdk-manifests", sdkFeatureBand.ToString(), manifestId.ToString()); _reporter.WriteLine(string.Format(LocalizableStrings.InstallingWorkloadManifest, manifestId, manifestVersion)); try { TransactionalAction.Run( action: () => { if (offlineCache == null || !offlineCache.HasValue) { packagePath = _nugetPackageDownloader.DownloadPackageAsync(WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId), new NuGetVersion(manifestVersion.ToString()), _packageSourceLocation).GetAwaiter().GetResult(); } else { packagePath = Path.Combine(offlineCache.Value.Value, $"{WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId)}.{manifestVersion}.nupkg"); if (!File.Exists(packagePath)) { throw new Exception(string.Format(LocalizableStrings.CacheMissingPackage, WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId), manifestVersion, offlineCache)); } } tempExtractionDir = Path.Combine(_tempPackagesDir.Value, $"{manifestId}-{manifestVersion}-extracted"); Directory.CreateDirectory(tempExtractionDir); var manifestFiles = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)).GetAwaiter().GetResult(); if (Directory.Exists(manifestPath) && Directory.GetFileSystemEntries(manifestPath).Any()) { // Backup existing manifest data for roll back purposes tempBackupDir = Path.Combine(_tempPackagesDir.Value, $"{manifestId}-{manifestVersion}-backup"); if (Directory.Exists(tempBackupDir)) { Directory.Delete(tempBackupDir, true); } FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(manifestPath, tempBackupDir)); } Directory.CreateDirectory(Path.GetDirectoryName(manifestPath)); FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(Path.Combine(tempExtractionDir, "data"), manifestPath)); }, rollback: () => { if (!string.IsNullOrEmpty(tempBackupDir) && Directory.Exists(tempBackupDir)) { FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(tempBackupDir, manifestPath)); } }); // Delete leftover dirs and files if (!string.IsNullOrEmpty(packagePath) && File.Exists(packagePath) && (offlineCache == null || !offlineCache.HasValue)) { File.Delete(packagePath); } var versionDir = Path.GetDirectoryName(packagePath); if (Directory.Exists(versionDir) && !Directory.GetFileSystemEntries(versionDir).Any()) { Directory.Delete(versionDir); var idDir = Path.GetDirectoryName(versionDir); if (Directory.Exists(idDir) && !Directory.GetFileSystemEntries(idDir).Any()) { Directory.Delete(idDir); } } if (!string.IsNullOrEmpty(tempExtractionDir) && Directory.Exists(tempExtractionDir)) { Directory.Delete(tempExtractionDir, true); } if (!string.IsNullOrEmpty(tempBackupDir) && Directory.Exists(tempBackupDir)) { Directory.Delete(tempBackupDir, true); } } catch (Exception e) { throw new Exception(string.Format(LocalizableStrings.FailedToInstallWorkloadManifest, manifestId, manifestVersion, e.Message)); } }