public override async Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { var dependency = new PackageDependency(packageIdentity.Id, new VersionRange(packageIdentity.Version)); var json = await GetJsonAsync(); json.dependencies.Add(packageIdentity.Id, packageIdentity.Version.ToString()); await SaveJsonAsync(json); var packageReader = downloadResourceResult.PackageReader ?? new PackageArchiveReader(downloadResourceResult.PackageStream, leaveStreamOpen: true); IAsyncPackageContentReader packageContentReader = packageReader; IAsyncPackageCoreReader packageCoreReader = packageReader; var libItemGroups = await packageContentReader.GetLibItemsAsync(token); var referenceItemGroups = await packageContentReader.GetReferenceItemsAsync(token); var frameworkReferenceGroups = await packageContentReader.GetFrameworkItemsAsync(token); var contentFileGroups = await packageContentReader.GetContentItemsAsync(token); var buildFileGroups = await packageContentReader.GetBuildItemsAsync(token); var toolItemGroups = await packageContentReader.GetToolItemsAsync(token); var depsGroups = await packageContentReader.GetPackageDependenciesAsync(token); IEnumerable <FrameworkSpecificGroup> refItemGroups = null; if (packageReader is PackageArchiveReader reader) { refItemGroups = await reader.GetItemsAsync(PackagingConstants.Folders.Ref, token); } else if (packageReader is PackageFolderReader reader2) { refItemGroups = await reader2.GetItemsAsync(PackagingConstants.Folders.Ref, token); } var sha256 = ""; if (!_skipSha256) { sha256 = GetSha(downloadResourceResult.PackageStream); } var entry = new WorkspaceEntry(packageIdentity, sha256, depsGroups, libItemGroups, toolItemGroups, refItemGroups, _mainFile, _variable); //if (!SdkList.Dlls.Contains(entry.PackageIdentity.Id.ToLower())) //{ await AddEntry(entry); //} return(await base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token)); }
public async Task <SnapAppsReleases> GetSnapAppsReleasesAsync([NotNull] IAsyncPackageCoreReader asyncPackageCoreReader, ISnapAppReader snapAppReader, CancellationToken cancellationToken = default) { if (asyncPackageCoreReader == null) { throw new ArgumentNullException(nameof(asyncPackageCoreReader)); } if (snapAppReader == null) { throw new ArgumentNullException(nameof(snapAppReader)); } var snapReleasesFilename = _snapFilesystem.PathCombine(SnapConstants.NuspecRootTargetPath, SnapConstants.ReleasesFilename); using var snapReleasesCompressedStream = await asyncPackageCoreReader .GetStreamAsync(snapReleasesFilename, cancellationToken) .ReadToEndAsync(cancellationToken); using var snapReleasesUncompressedStream = new MemoryStream(); using var reader = ReaderFactory.Open(snapReleasesCompressedStream); reader.MoveToNextEntry(); reader.WriteEntryTo(snapReleasesUncompressedStream); snapReleasesUncompressedStream.Seek(0, SeekOrigin.Begin); return(await snapAppReader.BuildSnapAppsReleasesFromStreamAsync(snapReleasesUncompressedStream)); }
public override async Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { var dependency = new PackageDependency(packageIdentity.Id, new VersionRange(packageIdentity.Version)); var json = await GetJsonAsync(); JsonConfigUtility.AddDependency(json, dependency); await SaveJsonAsync(json); var packageReader = downloadResourceResult.PackageReader ?? new PackageArchiveReader(downloadResourceResult.PackageStream, leaveStreamOpen: true); IAsyncPackageContentReader packageContentReader = packageReader; IAsyncPackageCoreReader packageCoreReader = packageReader; var libItemGroups = await packageContentReader.GetLibItemsAsync(token); var referenceItemGroups = await packageContentReader.GetReferenceItemsAsync(token); var frameworkReferenceGroups = await packageContentReader.GetFrameworkItemsAsync(token); var contentFileGroups = await packageContentReader.GetContentItemsAsync(token); var buildFileGroups = await packageContentReader.GetBuildItemsAsync(token); var toolItemGroups = await packageContentReader.GetToolItemsAsync(token); var depsGroups = await packageContentReader.GetPackageDependenciesAsync(token); IEnumerable <FrameworkSpecificGroup> refItemGroups = null; if (packageReader is PackageArchiveReader reader) { refItemGroups = await reader.GetItemsAsync(PackagingConstants.Folders.Ref, token); } else if (packageReader is PackageFolderReader reader2) { refItemGroups = await reader2.GetItemsAsync(PackagingConstants.Folders.Ref, token); } var deps = (PackageDependencyInfo)NuGetProjectActions.First(x => x.PackageIdentity.Equals(packageIdentity)).PackageIdentity; var entry = new WorkspaceEntry(packageIdentity, GetSha(downloadResourceResult.PackageStream), depsGroups, libItemGroups, toolItemGroups, refItemGroups, _mainFile); if (!SdkList.Dlls.Contains(entry.PackageIdentity.Id.ToLower())) { var workspace = await GetWorkspaceAsync(); var updater = new WorkspaceWriter(); var updated = updater.AddEntry(workspace, entry); await SaveWorkspaceAsync(updated); } return(await base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token)); }
public static async Task <IEnumerable <string> > GetPackageFilesAsync( this IAsyncPackageCoreReader packageReader, PackageSaveMode packageSaveMode, CancellationToken cancellationToken) { return((await packageReader .GetFilesAsync(cancellationToken)) .Where(file => PackageHelper.IsPackageFile(file, packageSaveMode))); }
internal static async Task <ManifestMetadata> GetManifestMetadataAsync([NotNull] this IAsyncPackageCoreReader asyncPackageCoreReader, CancellationToken cancellationToken) { if (asyncPackageCoreReader == null) { throw new ArgumentNullException(nameof(asyncPackageCoreReader)); } await using var nuspecStream = await asyncPackageCoreReader.GetNuspecAsync(cancellationToken).ReadToEndAsync(cancellationToken: cancellationToken); return(Manifest.ReadFrom(nuspecStream, false)?.Metadata); }
internal static async Task <NuspecReader> GetNuspecReaderAsync([NotNull] this IAsyncPackageCoreReader asyncPackageCoreReader, CancellationToken cancellationToken) { if (asyncPackageCoreReader == null) { throw new ArgumentNullException(nameof(asyncPackageCoreReader)); } using var nuspecStream = await asyncPackageCoreReader.GetNuspecAsync(cancellationToken).ReadToEndAsync(cancellationToken); return(new NuspecReader(nuspecStream)); }
public async Task <List <string> > ExtractAsync(string destinationDirectoryAbsolutePath, [NotNull] SnapRelease snapRelease, IAsyncPackageCoreReader asyncPackageCoreReader, CancellationToken cancellationToken = default) { if (destinationDirectoryAbsolutePath == null) { throw new ArgumentNullException(nameof(destinationDirectoryAbsolutePath)); } if (snapRelease == null) { throw new ArgumentNullException(nameof(snapRelease)); } if (asyncPackageCoreReader == null) { throw new ArgumentNullException(nameof(asyncPackageCoreReader)); } var snapApp = await _snapPack.GetSnapAppAsync(asyncPackageCoreReader, cancellationToken); var coreRunExeFilename = _snapEmbeddedResources.GetCoreRunExeFilenameForSnapApp(snapApp); var extractedFiles = new List <string>(); _snapFilesystem.DirectoryCreateIfNotExists(destinationDirectoryAbsolutePath); var files = !snapRelease.IsFull ? snapRelease .New .Concat(snapRelease.Modified) .OrderBy(x => x.NuspecTargetPath, new OrdinalIgnoreCaseComparer()) .ToList() : snapRelease.Files; foreach (var checksum in files) { var isSnapRootTargetItem = checksum.NuspecTargetPath.StartsWith(SnapConstants.NuspecAssetsTargetPath); string dstFilename; if (isSnapRootTargetItem) { dstFilename = _snapFilesystem.PathCombine(destinationDirectoryAbsolutePath, checksum.Filename); if (checksum.Filename == coreRunExeFilename) { dstFilename = _snapFilesystem.PathCombine( _snapFilesystem.DirectoryGetParent(destinationDirectoryAbsolutePath), checksum.Filename); } } else { var targetPath = checksum.NuspecTargetPath[(SnapConstants.NuspecRootTargetPath.Length + 1)..];
/// <summary> /// A package is deemed to be a satellite package if it has a language property set, the id of the package is /// of the format [.*].[Language] /// and it has at least one dependency with an id that maps to the runtime package . /// </summary> private static async Task <SatellitePackageInfo> GetSatellitePackageInfoAsync( IAsyncPackageCoreReader packageReader, CancellationToken cancellationToken) { // A satellite package has the following properties: // 1) A package suffix that matches the package's language, with a dot preceding it // 2) A dependency on the package with the same Id minus the language suffix // 3) The dependency can be found by Id in the repository (as its path is needed for installation) // Example: foo.ja-jp, with a dependency on foo var nuspec = await packageReader.GetNuspecAsync(cancellationToken); var nuspecReader = new NuspecReader(nuspec); var packageId = nuspecReader.GetId(); var packageLanguage = nuspecReader.GetLanguage(); string localRuntimePackageId = null; PackageIdentity runtimePackageIdentity = null; if (!string.IsNullOrEmpty(packageLanguage) && packageId.EndsWith('.' + packageLanguage, StringComparison.OrdinalIgnoreCase)) { // The satellite pack's Id is of the format <Core-Package-Id>.<Language>. Extract the core package id using this. // Additionally satellite packages have a strict dependency on the core package localRuntimePackageId = packageId.Substring(0, packageId.Length - packageLanguage.Length - 1); foreach (var group in nuspecReader.GetDependencyGroups()) { foreach (var dependencyPackage in group.Packages) { if (dependencyPackage.Id.Equals(localRuntimePackageId, StringComparison.OrdinalIgnoreCase) && dependencyPackage.VersionRange != null && dependencyPackage.VersionRange.MaxVersion == dependencyPackage.VersionRange.MinVersion && dependencyPackage.VersionRange.IsMaxInclusive && dependencyPackage.VersionRange.IsMinInclusive) { var runtimePackageVersion = new NuGetVersion(dependencyPackage.VersionRange.MinVersion.ToNormalizedString()); runtimePackageIdentity = new PackageIdentity(dependencyPackage.Id, runtimePackageVersion); } } } } return(new SatellitePackageInfo(runtimePackageIdentity != null, packageLanguage, runtimePackageIdentity)); }
public override async Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (downloadResourceResult == null) { throw new ArgumentNullException(nameof(downloadResourceResult)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } if (downloadResourceResult.Status != DownloadResourceResultStatus.AvailableWithoutStream && !downloadResourceResult.PackageStream.CanSeek) { throw new ArgumentException(Strings.PackageStreamShouldBeSeekable); } // Step-1: Check if the package already exists after setting the nuGetProjectContext ProjectSystem.NuGetProjectContext = nuGetProjectContext; var packageReference = (await GetInstalledPackagesAsync(token)) .FirstOrDefault(p => p.PackageIdentity.Equals(packageIdentity)); if (packageReference != null) { nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageAlreadyExistsInProject, packageIdentity, ProjectSystem.ProjectName); return(false); } // Step-2: Create PackageArchiveReader using the PackageStream and obtain the various item groups if (downloadResourceResult.Status != DownloadResourceResultStatus.AvailableWithoutStream) { downloadResourceResult.PackageStream.Seek(0, SeekOrigin.Begin); } // These casts enforce use of -Async(...) methods. var packageReader = downloadResourceResult.PackageReader ?? new PackageArchiveReader(downloadResourceResult.PackageStream, leaveStreamOpen: true); IAsyncPackageContentReader packageContentReader = packageReader; IAsyncPackageCoreReader packageCoreReader = packageReader; var libItemGroups = await packageContentReader.GetLibItemsAsync(token); var referenceItemGroups = await packageContentReader.GetReferenceItemsAsync(token); var frameworkReferenceGroups = await packageContentReader.GetFrameworkItemsAsync(token); var contentFileGroups = await packageContentReader.GetContentItemsAsync(token); var buildFileGroups = await packageContentReader.GetBuildItemsAsync(token); var toolItemGroups = await packageContentReader.GetToolItemsAsync(token); // Step-3: Get the most compatible items groups for all items groups var hasCompatibleProjectLevelContent = false; var compatibleLibItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, libItemGroups); var compatibleReferenceItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, referenceItemGroups); var compatibleFrameworkReferencesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, frameworkReferenceGroups); var compatibleContentFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, contentFileGroups); var compatibleBuildFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, buildFileGroups); var compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, toolItemGroups); compatibleLibItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleLibItemsGroup); compatibleReferenceItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleReferenceItemsGroup); compatibleFrameworkReferencesGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleFrameworkReferencesGroup); compatibleContentFilesGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleContentFilesGroup); compatibleBuildFilesGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleBuildFilesGroup); compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleToolItemsGroup); hasCompatibleProjectLevelContent = MSBuildNuGetProjectSystemUtility.IsValid(compatibleLibItemsGroup) || MSBuildNuGetProjectSystemUtility.IsValid(compatibleFrameworkReferencesGroup) || MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup) || MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup); // Check if package has any content for project var hasProjectLevelContent = libItemGroups.Any() || frameworkReferenceGroups.Any() || contentFileGroups.Any() || buildFileGroups.Any(); var onlyHasCompatibleTools = false; var onlyHasDependencies = false; if (!hasProjectLevelContent) { // Since it does not have project-level content, check if it has dependencies or compatible tools // Note that we are not checking if it has compatible project level content, but, just that it has project level content // If the package has project-level content, but nothing compatible, we still need to throw // If a package does not have any project-level content, it can be a // Legacy solution level packages which only has compatible tools group onlyHasCompatibleTools = MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup) && compatibleToolItemsGroup.Items.Any(); if (!onlyHasCompatibleTools) { // If it does not have compatible tool items either, check if it at least has dependencies onlyHasDependencies = (await packageContentReader.GetPackageDependenciesAsync(token)).Any(); } } else { var shortFramework = ProjectSystem.TargetFramework.GetShortFolderName(); nuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity, GetMetadata <string>(NuGetProjectMetadataKeys.Name), shortFramework); } // Step-4: Check if there are any compatible items in the package or that this is not a package with only tools group. If not, throw if (!hasCompatibleProjectLevelContent && !onlyHasCompatibleTools && !onlyHasDependencies) { throw new InvalidOperationException( string.Format(CultureInfo.CurrentCulture, Strings.UnableToFindCompatibleItems, packageIdentity.Id + " " + packageIdentity.Version.ToNormalizedString(), ProjectSystem.TargetFramework)); } if (hasCompatibleProjectLevelContent) { var shortFramework = ProjectSystem.TargetFramework.GetShortFolderName(); nuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity, GetMetadata <string>(NuGetProjectMetadataKeys.Name), shortFramework); } else if (onlyHasCompatibleTools) { nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageWithOnlyToolsGroup, packageIdentity, GetMetadata <string>(NuGetProjectMetadataKeys.Name)); } else if (onlyHasDependencies) { nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageWithOnlyDependencies, packageIdentity, GetMetadata <string>(NuGetProjectMetadataKeys.Name)); } // Step-5: Raise PackageInstalling event // At this point, GetInstalledPath is pointless since the package is, likely, not already installed. It will be empty // Using PackagePathResolver.GetInstallPath would be wrong, since, package version from the nuspec is always used var packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, installPath: string.Empty); if (PackageInstalling != null) { PackageInstalling(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyInstalling(packageEventArgs); // Step-6: Install package to FolderNuGetProject await FolderNuGetProject.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token); // Step-7: Raise PackageInstalled event // Call GetInstalledPath to get the package installed path var packageInstallPath = FolderNuGetProject.GetInstalledPath(packageIdentity); packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, packageInstallPath); if (PackageInstalled != null) { PackageInstalled(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyInstalled(packageEventArgs); // Step-8: MSBuildNuGetProjectSystem operations // Step-8.1: Add references to project if (!IsSkipAssemblyReferences(nuGetProjectContext) && MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup)) { foreach (var referenceItem in compatibleReferenceItemsGroup.Items) { if (IsAssemblyReference(referenceItem)) { var referenceItemFullPath = Path.Combine(packageInstallPath, referenceItem); var referenceName = Path.GetFileName(referenceItem); if (await ProjectSystem.ReferenceExistsAsync(referenceName)) { await ProjectSystem.RemoveReferenceAsync(referenceName); } await ProjectSystem.AddReferenceAsync(referenceItemFullPath); } } } // Step-8.2: Add Frameworkreferences to project if (!IsSkipAssemblyReferences(nuGetProjectContext) && MSBuildNuGetProjectSystemUtility.IsValid(compatibleFrameworkReferencesGroup)) { foreach (var frameworkReference in compatibleFrameworkReferencesGroup.Items) { if (!await ProjectSystem.ReferenceExistsAsync(frameworkReference)) { await ProjectSystem.AddFrameworkReferenceAsync(frameworkReference, packageIdentity.Id); } } } // Step-8.3: Add Content Files if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup)) { await MSBuildNuGetProjectSystemUtility.AddFilesAsync( ProjectSystem, packageCoreReader, compatibleContentFilesGroup, FileTransformers, token); } // Step-8.4: Add Build imports if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup)) { foreach (var buildImportFile in compatibleBuildFilesGroup.Items) { var fullImportFilePath = Path.Combine(packageInstallPath, buildImportFile); ProjectSystem.AddImport(fullImportFilePath, fullImportFilePath.EndsWith(".props", StringComparison.OrdinalIgnoreCase) ? ImportLocation.Top : ImportLocation.Bottom); } } // Step-9: Install package to PackagesConfigNuGetProject await PackagesConfigNuGetProject.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token); // Step-10: Add packages.config to MSBuildNuGetProject ProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath)); // Step 11: Raise PackageReferenceAdded event PackageReferenceAdded?.Invoke(this, packageEventArgs); PackageEventsProvider.Instance.NotifyReferenceAdded(packageEventArgs); // Step-12: Execute powershell script - install.ps1 var anyFrameworkToolsGroup = toolItemGroups.FirstOrDefault(g => g.TargetFramework.Equals(NuGetFramework.AnyFramework)); if (anyFrameworkToolsGroup != null) { var initPS1RelativePath = anyFrameworkToolsGroup.Items.Where(p => p.StartsWith(PowerShellScripts.InitPS1RelativePath, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (!string.IsNullOrEmpty(initPS1RelativePath)) { initPS1RelativePath = PathUtility.ReplaceAltDirSeparatorWithDirSeparator( initPS1RelativePath); await ProjectServices.ScriptService.ExecutePackageScriptAsync( packageIdentity, packageInstallPath, initPS1RelativePath, nuGetProjectContext, throwOnFailure : true, token : token); } } if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup)) { var installPS1RelativePath = compatibleToolItemsGroup.Items.FirstOrDefault( p => p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Install, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(installPS1RelativePath)) { await ProjectServices.ScriptService.ExecutePackageScriptAsync( packageIdentity, packageInstallPath, installPS1RelativePath, nuGetProjectContext, throwOnFailure : true, token : token); } } return(true); }
internal static async Task AddFilesAsync( IMSBuildProjectSystem projectSystem, IAsyncPackageCoreReader packageReader, FrameworkSpecificGroup frameworkSpecificGroup, IDictionary <FileTransformExtensions, IPackageFileTransformer> fileTransformers, CancellationToken cancellationToken) { var packageTargetFramework = frameworkSpecificGroup.TargetFramework; var packageItemListAsArchiveEntryNames = frameworkSpecificGroup.Items.ToList(); packageItemListAsArchiveEntryNames.Sort(new PackageItemComparer()); try { var paths = packageItemListAsArchiveEntryNames.Select( file => ResolvePath(fileTransformers, fte => fte.InstallExtension, GetEffectivePathForContentFile(packageTargetFramework, file))); paths = paths.Where(p => !string.IsNullOrEmpty(p)); projectSystem.RegisterProcessedFiles(paths); } catch (Exception) { // Ignore all exceptions for now } foreach (var file in packageItemListAsArchiveEntryNames) { if (IsEmptyFolder(file)) { continue; } var effectivePathForContentFile = GetEffectivePathForContentFile(packageTargetFramework, file); // Resolve the target path IPackageFileTransformer installTransformer; var path = ResolveTargetPath(projectSystem, fileTransformers, fte => fte.InstallExtension, effectivePathForContentFile, out installTransformer); if (projectSystem.IsSupportedFile(path)) { if (installTransformer != null) { await installTransformer.TransformFileAsync( () => packageReader.GetStreamAsync(file, cancellationToken), path, projectSystem, cancellationToken); } else { // Ignore uninstall transform file during installation string truncatedPath; var uninstallTransformer = FindFileTransformer(fileTransformers, fte => fte.UninstallExtension, effectivePathForContentFile, out truncatedPath); if (uninstallTransformer != null) { continue; } await TryAddFileAsync( projectSystem, path, () => packageReader.GetStreamAsync(file, cancellationToken), cancellationToken); } } } }
public override async Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { var dependency = new PackageDependency(packageIdentity.Id, new VersionRange(packageIdentity.Version)); var json = await GetJsonAsync(); json.dependencies.Add(packageIdentity.Id, packageIdentity.Version.ToString()); await SaveJsonAsync(json); var packageReader = downloadResourceResult.PackageReader ?? new PackageArchiveReader(downloadResourceResult.PackageStream, leaveStreamOpen: true); IAsyncPackageContentReader packageContentReader = packageReader; IAsyncPackageCoreReader packageCoreReader = packageReader; var libItemGroups = await packageContentReader.GetLibItemsAsync(token); var referenceItemGroups = await packageContentReader.GetReferenceItemsAsync(token); var frameworkReferenceGroups = await packageContentReader.GetFrameworkItemsAsync(token); var contentFileGroups = await packageContentReader.GetContentItemsAsync(token); var buildFileGroups = await packageContentReader.GetBuildItemsAsync(token); var toolItemGroups = await packageContentReader.GetToolItemsAsync(token); var depsGroups = await packageContentReader.GetPackageDependenciesAsync(token); // Very ugly hack to extract build folder and runtimes folder content // Unfortunately, the original implementation only returns .prop and .targets files. var readerBase = (PackageReaderBase)packageContentReader; var dynMethod = readerBase.GetType().BaseType.GetMethod("GetFileGroups", BindingFlags.NonPublic | BindingFlags.Instance); var allBuildFileGroups = (IEnumerable <FrameworkSpecificGroup>)dynMethod.Invoke(readerBase, new object?[] { "build" }); var allRuntimes = (IEnumerable <FrameworkSpecificGroup>)dynMethod.Invoke(readerBase, new object?[] { "runtimes" }); IEnumerable <FrameworkSpecificGroup> refItemGroups = null; if (packageReader is PackageArchiveReader reader) { refItemGroups = await reader.GetItemsAsync(PackagingConstants.Folders.Ref, token); } else if (packageReader is PackageFolderReader reader2) { refItemGroups = await reader2.GetItemsAsync(PackagingConstants.Folders.Ref, token); } var sha256 = ""; if (!_skipSha256) { sha256 = GetSha(downloadResourceResult.PackageStream); } var entry = new WorkspaceEntry(json.dependencies, packageIdentity, sha256, depsGroups, libItemGroups, toolItemGroups, refItemGroups, allBuildFileGroups, allRuntimes, _mainFile, _variable, _nugetSourceCustom); _entries.Add(packageIdentity, entry); await AddEntry(entry); return(await base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token)); }