public void IsLockFileStillValid_TransitiveDependencyNotCentrallyManaged_DoesNotInvalidateLockFile() { // Arrange var framework = CommonFrameworks.NetStandard20; var projectName = "project"; var cpvm1 = new CentralPackageVersion("cpvm1", VersionRange.Parse("1.0.0")); var cpvm2 = new CentralPackageVersion("cpvm2", VersionRange.Parse("1.0.0")); var dependency1 = new LibraryDependency( new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package), LibraryDependencyType.Default, LibraryIncludeFlags.All, LibraryIncludeFlags.All, new List <Common.NuGetLogCode>(), autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, LibraryDependencyReferenceType.Direct, aliases: "stuff"); var tfm = new TargetFrameworkInformation(); tfm.FrameworkName = framework; tfm.CentralPackageVersions.Add("cpvm1", cpvm1); tfm.CentralPackageVersions.Add("cpvm2", cpvm2); tfm.Dependencies.Add(dependency1); LibraryDependency.ApplyCentralVersionInformation(tfm.Dependencies, tfm.CentralPackageVersions); var project = new PackageSpec(new List <TargetFrameworkInformation>() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; DependencyGraphSpec dgSpec = new DependencyGraphSpec(); dgSpec.AddRestore(projectName); dgSpec.AddProject(project); var lockFile1 = new PackagesLockFileBuilder() .WithTarget(target => target .WithFramework(CommonFrameworks.NetStandard20) .WithDependency(dep => dep .WithId("cpvm1") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Direct)) .WithDependency(dep => dep .WithId("otherDep") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Transitive))) .Build(); var lockFile2 = new PackagesLockFileBuilder() .WithVersion(PackagesLockFileFormat.PackagesLockFileVersion) .WithTarget(target => target .WithFramework(CommonFrameworks.NetStandard20) .WithDependency(dep => dep .WithId("cpvm1") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Direct)) .WithDependency(dep => dep .WithId("otherDep") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Transitive))) .Build(); // Nothing changed // different versions of lock file versions are handled Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile1)); Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile2)); }
// TODO: Should we use framework here // // 1. Create dgspec.json via .NET Core CLI: GenerateRestoreGraphFile target // 2. Load dgspec.json into DependencyGraphSpec instance/object // For each SDK project (ProjectStyle.PackageReference) in the graph spec // 3. Get assets file (project.assets.json) for the project // 4. Construct LockFile from assets file for the project static void AnalyzeProject(string projectPath, string framework) { // Graph input var vertices = new HashSet <Node>(); var edges = new HashSet <Edge>(); var rootNuGetFramework = NuGetFramework.ParseFolder(framework); // TODO: optional filter // TODO: HACK...kan fjernes if (string.IsNullOrEmpty(projectPath)) { var rootPath = GetRepoRootPath(); //projectPath = Path.Combine(rootPath, "DotnetDependencies.sln"); projectPath = Path.Combine( Path.Combine( Path.Combine(rootPath, "src"), "Deps.CLI"), "Deps.CLI.csproj"); } // 'package graph' is a better word // Load dependency graph via nuget client tools build into msbuild (.NET Core CLI, .NET Core SDK) // TODO: opsatning af packageSources var dependencyGraphService = new DependencyGraphService(); var dependencyGraph = dependencyGraphService.GenerateDependencyGraph(projectPath); // We only support MSBuild style <PackageReference> SDK projects, where project.assets.json (lock file) is // generated in the RestoreOutputPath folder if (dependencyGraph.Projects.Any(p => p.RestoreMetadata.ProjectStyle != ProjectStyle.PackageReference)) { throw new InvalidOperationException("Only SDK projects are supported."); } PackageSpec projectRoot = dependencyGraph.Projects.Single(p => Path.GetFileName(p.FilePath) == Path.GetFileName(projectPath)); var rootNode = new ProjectReferenceNode(projectPath, projectRoot.Version.ToString(), rootNuGetFramework); vertices.Add(rootNode); var projectRootTargetFramework = projectRoot.TargetFrameworks.FirstOrDefault(tf => rootNuGetFramework.Equals(tf.FrameworkName)); if (projectRootTargetFramework == null) { throw new InvalidOperationException( $"The root project does not define the TargetFramework {rootNuGetFramework}"); } //Console.WriteLine($"project: {Path.GetFileName(project.FilePath)}"); //Console.WriteLine($"project.BaseDirectory: {Path.GetFileName(project.BaseDirectory)}"); //Console.WriteLine($"project.Name: {project.Name}"); //Console.WriteLine($"project.TargetFrameworks: {string.Join(", ", project.TargetFrameworks.Select(tfm => tfm.FrameworkName.GetShortFolderName()))}"); //Console.WriteLine($"project.Version: {project.Version}"); //Console.WriteLine($"project.RestoreMetadata.ProjectName: {project.RestoreMetadata.ProjectName}"); //Console.WriteLine($"project.RestoreMetadata.Sources: {string.Join(", ", project.RestoreMetadata.Sources)}"); //Console.WriteLine($"project.Dependencies: {string.Join(", ", project.Dependencies)}"); // TODO: Path. Unique name etc... Console.WriteLine($"Name: {projectRoot.Name}"); Console.WriteLine($"Version: {projectRoot.Version} ({rootNuGetFramework.GetShortFolderName()})"); Console.WriteLine($"Framework: {rootNuGetFramework.DotNetFrameworkName}"); Console.WriteLine($"Framework moniker: {rootNuGetFramework.GetShortFolderName()}"); Console.WriteLine(); Console.WriteLine("resolve project reference dependency graph"); Console.WriteLine(); // TODO: Path. Unique name etc... Console.WriteLine($"{projectRoot.Name}, v{projectRoot.Version} ({rootNuGetFramework.GetShortFolderName()})"); // // First resolve project reference dependency graph // foreach (ProjectRestoreMetadataFrameworkInfo targetFramework in projectRoot.RestoreMetadata.TargetFrameworks) { // only want project references defined for the TargetFramework if (!rootNuGetFramework.Equals(targetFramework.FrameworkName)) { continue; } // project references of a targetFramework foreach (var projectRestoreReference in targetFramework.ProjectReferences) { // TODO: PrivateAssets, ExcludeAssets, IncludeAssets //dependency.ProjectPath //dependency.ProjectUniqueName PackageSpec projectDependency = dependencyGraph.GetProjectSpec(projectRestoreReference.ProjectUniqueName); //Console.WriteLine($"({project.Name}, {Path.GetFileName(project.FilePath)}) is a project reference of ({projectRoot.Name}, {Path.GetFileName(projectRoot.FilePath)}"); NuGetFramework nearest = projectDependency.GetNearestFrameworkMatching(rootNuGetFramework); var projectReference = new ProjectReferenceNode(projectDependency.FilePath, projectDependency.Version.ToString(), nearest); vertices.Add(projectReference); edges.Add(new Edge(rootNode, projectReference)); ReportProjectReferences(rootNode, projectDependency, rootNuGetFramework, dependencyGraph, 1, vertices, edges); } } // TODO: What about ProjectReferences...are project references converted to package specs in dgspec file??? YES, // and available via dependencyGraph.Projects and dependencyGraph.GetProjectSpec // TODO: project Closure is part of graph all ready // closure[0] is the root // closure[1..m] contains project references IReadOnlyList <PackageSpec> projectClosure = dependencyGraph.GetClosure(projectRoot.RestoreMetadata.ProjectUniqueName); Debug.Assert(ReferenceEquals(projectRoot, projectClosure[0])); // // Second, resolve package reference dependency graph of each project // Console.WriteLine(); Console.WriteLine("resolve package reference dependency graph"); Console.WriteLine(); // for each csproj with PackageReference style (i.e. SDK csproj) foreach (PackageSpec project in dependencyGraph.Projects) { // TODO: Maybe just use the project.assets.json created by .NET Core SDK tooling // Generate lock file: A lock file has the package dependency graph for the project/solution/repo // that includes both the direct as well as transitive dependencies. var lockFileService = new LockFileService(); LockFile lockFile = lockFileService.GetLockFile(project.FilePath, project.RestoreMetadata.OutputPath); // TODO: This could change our code...we can get at the project references inside one single loop //{ // // TODO: For debugging // var projectDirectory = Path.GetDirectoryName(lockFile.PackageSpec.RestoreMetadata.ProjectPath); // // full path to the referenced msbuild files (csproj files) // var projectReferences = lockFile.Libraries // .Where(library => library.MSBuildProject != null) // .Select(library => Path.GetFullPath(Path.Combine(projectDirectory, library.MSBuildProject))) // .ToArray(); // if (projectReferences.Length > 0) // { // Console.WriteLine($"project references {string.Join(", ", projectReferences)}"); // } //} NuGetFramework nearest = project.GetNearestFrameworkMatching(rootNuGetFramework); TargetFrameworkInformation resolvedTargetFramework = project.TargetFrameworks.Single(tf => nearest.Equals(tf.FrameworkName)); // for the root should this resolve to the rootNuGetFramework Console.WriteLine($"{project.Name}, v{project.Version}, ({resolvedTargetFramework.FrameworkName.GetShortFolderName()})"); // Find the transitive closure for this tfm LockFileTarget lockFileTargetFramework = lockFile.Targets.FirstOrDefault(t => t.TargetFramework.Equals(resolvedTargetFramework.FrameworkName)); if (lockFileTargetFramework != null) { // For each direct dependency foreach (LibraryDependency directDependency in resolvedTargetFramework.Dependencies) { // Find the _resolved_ package reference LockFileTargetLibrary resolvedPackageReference = lockFileTargetFramework.Libraries.FirstOrDefault(library => library.Name == directDependency.Name); // Show transitive dependencies of this direct dependency ReportLockFilePackageDependencies(resolvedPackageReference, lockFileTargetFramework, 1); } } } }
/// <summary> /// Emulates a JSON deserialization from project.json to PackageSpec in a post-project.json world /// </summary> private async Task <PackageSpec> GetPackageSpecAsync(ISettings settings) { await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); var projectReferences = await ProjectServices .ReferencesReader .GetProjectReferencesAsync(Common.NullLogger.Instance, CancellationToken.None); var targetFramework = await _vsProjectAdapter.GetTargetFrameworkAsync(); var packageReferences = (await ProjectServices .ReferencesReader .GetPackageReferencesAsync(targetFramework, CancellationToken.None)) .ToList(); var packageTargetFallback = MSBuildStringUtility.Split(_vsProjectAdapter.PackageTargetFallback) .Select(NuGetFramework.Parse) .ToList(); var assetTargetFallback = MSBuildStringUtility.Split(_vsProjectAdapter.AssetTargetFallback) .Select(NuGetFramework.Parse) .ToList(); var projectTfi = new TargetFrameworkInformation { FrameworkName = targetFramework, Dependencies = packageReferences, }; bool isCpvmEnabled = await IsCentralPackageManagementVersionsEnabledAsync(); if (isCpvmEnabled) { // Add the central version information and merge the information to the package reference dependencies projectTfi.CentralPackageVersions.AddRange(await GetCentralPackageVersionsAsync()); LibraryDependency.ApplyCentralVersionInformation(projectTfi.Dependencies, projectTfi.CentralPackageVersions); } // Apply fallback settings AssetTargetFallbackUtility.ApplyFramework(projectTfi, packageTargetFallback, assetTargetFallback); // Build up runtime information. var runtimes = await _vsProjectAdapter.GetRuntimeIdentifiersAsync(); var supports = await _vsProjectAdapter.GetRuntimeSupportsAsync(); var runtimeGraph = new RuntimeGraph(runtimes, supports); // In legacy CSProj, we only have one target framework per project var tfis = new TargetFrameworkInformation[] { projectTfi }; var projectName = _projectName ?? _projectUniqueName; return(new PackageSpec(tfis) { Name = projectName, Version = new NuGetVersion(_vsProjectAdapter.Version), Authors = Array.Empty <string>(), Owners = Array.Empty <string>(), Tags = Array.Empty <string>(), ContentFiles = Array.Empty <string>(), FilePath = _projectFullPath, RuntimeGraph = runtimeGraph, RestoreMetadata = new ProjectRestoreMetadata { ProjectStyle = ProjectStyle.PackageReference, OutputPath = await GetMSBuildProjectExtensionsPathAsync(), ProjectPath = _projectFullPath, ProjectName = projectName, ProjectUniqueName = _projectFullPath, OriginalTargetFrameworks = tfis .Select(tfi => tfi.FrameworkName.GetShortFolderName()) .ToList(), TargetFrameworks = new List <ProjectRestoreMetadataFrameworkInfo> { new ProjectRestoreMetadataFrameworkInfo(tfis[0].FrameworkName) { ProjectReferences = projectReferences?.ToList() } }, SkipContentFileWrite = true, CacheFilePath = await GetCacheFilePathAsync(), PackagesPath = GetPackagesPath(settings), Sources = GetSources(settings), FallbackFolders = GetFallbackFolders(settings), ConfigFilePaths = GetConfigFilePaths(settings), ProjectWideWarningProperties = WarningProperties.GetWarningProperties( treatWarningsAsErrors: _vsProjectAdapter.TreatWarningsAsErrors, noWarn: _vsProjectAdapter.NoWarn, warningsAsErrors: _vsProjectAdapter.WarningsAsErrors), RestoreLockProperties = new RestoreLockProperties( await _vsProjectAdapter.GetRestorePackagesWithLockFileAsync(), await _vsProjectAdapter.GetNuGetLockFilePathAsync(), await _vsProjectAdapter.IsRestoreLockedAsync()), CentralPackageVersionsEnabled = isCpvmEnabled } }); }
private async Task <DownloadDependencyResolutionResult> ResolveDownloadDependencies(RemoteWalkContext context, ConcurrentDictionary <LibraryRange, Task <Tuple <LibraryRange, RemoteMatch> > > downloadDependenciesCache, TargetFrameworkInformation targetFrameworkInformation, CancellationToken token) { var packageDownloadTasks = targetFrameworkInformation.DownloadDependencies.Select(downloadDependency => ResolverUtility.FindPackageLibraryMatchCachedAsync( downloadDependenciesCache, downloadDependency, context.RemoteLibraryProviders, context.LocalLibraryProviders, context.CacheContext, _logger, token)); var packageDownloadMatches = await Task.WhenAll(packageDownloadTasks); return(DownloadDependencyResolutionResult.Create(targetFrameworkInformation.FrameworkName, packageDownloadMatches, context.RemoteLibraryProviders)); }
/// <summary> /// Emulates a JSON deserialization from project.json to PackageSpec in a post-project.json world /// </summary> private async Task <PackageSpec> GetPackageSpecAsync(ISettings settings) { await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); var projectReferences = await ProjectServices .ReferencesReader .GetProjectReferencesAsync(Common.NullLogger.Instance, CancellationToken.None); var targetFramework = await _vsProjectAdapter.GetTargetFrameworkAsync(); var packageReferences = (await ProjectServices .ReferencesReader .GetPackageReferencesAsync(targetFramework, CancellationToken.None)) .ToList(); var packageTargetFallback = MSBuildStringUtility.Split(_vsProjectAdapter.PackageTargetFallback) .Select(NuGetFramework.Parse) .ToList(); var assetTargetFallback = MSBuildStringUtility.Split(_vsProjectAdapter.AssetTargetFallback) .Select(NuGetFramework.Parse) .ToList(); var projectTfi = new TargetFrameworkInformation { FrameworkName = targetFramework, Dependencies = packageReferences, }; // Apply fallback settings AssetTargetFallbackUtility.ApplyFramework(projectTfi, packageTargetFallback, assetTargetFallback); // Build up runtime information. var runtimes = await _vsProjectAdapter.GetRuntimeIdentifiersAsync(); var supports = await _vsProjectAdapter.GetRuntimeSupportsAsync(); var runtimeGraph = new RuntimeGraph(runtimes, supports); // In legacy CSProj, we only have one target framework per project var tfis = new TargetFrameworkInformation[] { projectTfi }; return(new PackageSpec(tfis) { Name = _projectName ?? _projectUniqueName, Version = new NuGetVersion(_vsProjectAdapter.Version), Authors = new string[] { }, Owners = new string[] { }, Tags = new string[] { }, ContentFiles = new string[] { }, Dependencies = packageReferences, FilePath = _projectFullPath, RuntimeGraph = runtimeGraph, RestoreMetadata = new ProjectRestoreMetadata { ProjectStyle = ProjectStyle.PackageReference, OutputPath = GetBaseIntermediatePath(), ProjectPath = _projectFullPath, ProjectName = _projectName ?? _projectUniqueName, ProjectUniqueName = _projectFullPath, OriginalTargetFrameworks = tfis .Select(tfi => tfi.FrameworkName.GetShortFolderName()) .ToList(), TargetFrameworks = new List <ProjectRestoreMetadataFrameworkInfo> { new ProjectRestoreMetadataFrameworkInfo(tfis[0].FrameworkName) { ProjectReferences = projectReferences?.ToList() } }, SkipContentFileWrite = true, CacheFilePath = await GetCacheFilePathAsync(), PackagesPath = GetPackagesPath(settings), Sources = GetSources(settings), FallbackFolders = GetFallbackFolders(settings), ConfigFilePaths = GetConfigFilePaths(settings), ProjectWideWarningProperties = MSBuildRestoreUtility.GetWarningProperties( treatWarningsAsErrors: _vsProjectAdapter.TreatWarningsAsErrors, noWarn: _vsProjectAdapter.NoWarn, warningsAsErrors: _vsProjectAdapter.WarningsAsErrors) } }); }
/// <summary> /// Emulates a JSON deserialization from project.json to PackageSpec in a post-project.json world /// </summary> private async Task <PackageSpec> GetPackageSpecAsync(ISettings settings) { await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); var projectReferences = await ProjectServices .ReferencesReader .GetProjectReferencesAsync(NullLogger.Instance, CancellationToken.None); var targetFramework = await _vsProjectAdapter.GetTargetFrameworkAsync(); var packageReferences = (await ProjectServices .ReferencesReader .GetPackageReferencesAsync(targetFramework, CancellationToken.None)) .ToList(); var packageTargetFallback = MSBuildStringUtility.Split(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.PackageTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); var assetTargetFallback = MSBuildStringUtility.Split(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.AssetTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); var projectTfi = new TargetFrameworkInformation { FrameworkName = targetFramework, Dependencies = packageReferences, }; bool isCpvmEnabled = MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.ManagePackageVersionsCentrally)); if (isCpvmEnabled) { // Add the central version information and merge the information to the package reference dependencies projectTfi.CentralPackageVersions.AddRange(await GetCentralPackageVersionsAsync()); LibraryDependency.ApplyCentralVersionInformation(projectTfi.Dependencies, projectTfi.CentralPackageVersions); } // Apply fallback settings AssetTargetFallbackUtility.ApplyFramework(projectTfi, packageTargetFallback, assetTargetFallback); // Build up runtime information. var runtimes = await _vsProjectAdapter.GetRuntimeIdentifiersAsync(); var supports = await _vsProjectAdapter.GetRuntimeSupportsAsync(); var runtimeGraph = new RuntimeGraph(runtimes, supports); // In legacy CSProj, we only have one target framework per project var tfis = new TargetFrameworkInformation[] { projectTfi }; var projectName = ProjectName ?? ProjectUniqueName; string specifiedPackageId = _vsProjectAdapter.BuildProperties.GetPropertyValue(ProjectBuildProperties.PackageId); if (!string.IsNullOrWhiteSpace(specifiedPackageId)) { projectName = specifiedPackageId; } else { string specifiedAssemblyName = _vsProjectAdapter.BuildProperties.GetPropertyValue(ProjectBuildProperties.AssemblyName); if (!string.IsNullOrWhiteSpace(specifiedAssemblyName)) { projectName = specifiedAssemblyName; } } return(new PackageSpec(tfis) { Name = projectName, Version = new NuGetVersion(_vsProjectAdapter.Version), FilePath = ProjectFullPath, RuntimeGraph = runtimeGraph, RestoreMetadata = new ProjectRestoreMetadata { ProjectStyle = ProjectStyle.PackageReference, OutputPath = await GetMSBuildProjectExtensionsPathAsync(), ProjectPath = ProjectFullPath, ProjectName = projectName, ProjectUniqueName = ProjectFullPath, OriginalTargetFrameworks = tfis .Select(tfi => tfi.FrameworkName.GetShortFolderName()) .ToList(), TargetFrameworks = new List <ProjectRestoreMetadataFrameworkInfo> { new ProjectRestoreMetadataFrameworkInfo(tfis[0].FrameworkName) { ProjectReferences = projectReferences?.ToList() } }, SkipContentFileWrite = true, CacheFilePath = await GetCacheFilePathAsync(), PackagesPath = GetPackagesPath(settings), Sources = GetSources(settings), FallbackFolders = GetFallbackFolders(settings), ConfigFilePaths = GetConfigFilePaths(settings), ProjectWideWarningProperties = WarningProperties.GetWarningProperties( treatWarningsAsErrors: GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.TreatWarningsAsErrors), noWarn: GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.NoWarn), warningsAsErrors: GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.WarningsAsErrors)), RestoreLockProperties = new RestoreLockProperties( GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.RestorePackagesWithLockFile), GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.NuGetLockFilePath), MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.RestoreLockedMode))), CentralPackageVersionsEnabled = isCpvmEnabled, CentralPackageVersionOverrideDisabled = GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.CentralPackageVersionOverrideEnabled).EqualsFalse(), CentralPackageTransitivePinningEnabled = MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.CentralPackageTransitivePinningEnabled)), } }); }
private static void AssertEquality(bool expected, TargetFrameworkInformation leftSide, TargetFrameworkInformation rightSide) { if (expected) { leftSide.Should().Be(rightSide); } else { leftSide.Should().NotBe(rightSide); } }
async Task RestorePackagesAsync( IEnumerable <InteractivePackage> packages, SourceCacheContext cacheContext, CancellationToken cancellationToken) { var restoreContext = new RestoreArgs { CacheContext = cacheContext, Log = Logger, }; // NOTE: This path is typically empty. It could in theory contain nuget.config settings // files, but really we just use it to satisfy nuget API that requires paths, // even when they are never used. var rootPath = packageConfigDirectory; var globalPath = restoreContext.GetEffectiveGlobalPackagesFolder(rootPath, settings); var fallbackPaths = restoreContext.GetEffectiveFallbackPackageFolders(settings); var providerCache = new RestoreCommandProvidersCache(); var restoreProviders = providerCache.GetOrCreate( globalPath, fallbackPaths, SourceRepositories, cacheContext, Logger); // Set up a project spec similar to what you would see in a project.json. // This is sufficient for the dependency graph work done within RestoreCommand. // TODO: XF version pinning during restore? var targetFrameworkInformation = new TargetFrameworkInformation { FrameworkName = TargetFramework, Dependencies = packages.Select(ToLibraryDependency).ToList(), }; var projectSpec = new PackageSpec(new [] { targetFrameworkInformation }) { Name = project.Name, FilePath = rootPath, }; var restoreRequest = new RestoreRequest(projectSpec, restoreProviders, cacheContext, Logger); var restoreCommand = new RestoreCommand(restoreRequest); var result = await restoreCommand.ExecuteAsync(cancellationToken); if (!result.Success) { return; } project.ResetInstallationContext(); // As with installation, restore simply ensures that packages are present in the user's // global package cache. We reference them out of there just like .NET core projects do. // // All resolved packages, including the explicit inputs and their dependencies, are // available as LockFileLibrary instances. foreach (var library in result.LockFile.Libraries) { project.InstallationContext.AddInstalledPackage( GetInteractivePackageFromLibrary(library, project, packages)); } installedPackages = project.InstallationContext.InstalledPackages; UpdateInstalledPackages(); }
public override async Task <IReadOnlyList <PackageSpec> > GetPackageSpecsAsync(DependencyGraphCacheContext context) { PackageSpec packageSpec = null; if (context == null || !context.PackageSpecCache.TryGetValue(MSBuildProjectPath, out packageSpec)) { packageSpec = JsonPackageSpecReader.GetPackageSpec(ProjectName, JsonConfigPath); if (packageSpec == null) { throw new InvalidOperationException( string.Format(Strings.ProjectNotLoaded_RestoreFailed, ProjectName)); } var metadata = new ProjectRestoreMetadata(); packageSpec.RestoreMetadata = metadata; metadata.ProjectStyle = ProjectStyle.ProjectJson; metadata.OutputPath = await GetBaseIntermediatePathAsync(); metadata.ProjectPath = MSBuildProjectPath; metadata.ProjectJsonPath = packageSpec.FilePath; metadata.ProjectName = packageSpec.Name; metadata.ProjectUniqueName = MSBuildProjectPath; // Reload the target framework from csproj and update the target framework in packageSpec for restore await UpdateInternalTargetFrameworkAsync(); if (TryGetInternalFramework(out var internalTargetFramework)) { // Ensure the project json has only one target framework if (packageSpec.TargetFrameworks != null && packageSpec.TargetFrameworks.Count == 1) { var replaceTargetFramework = new TargetFrameworkInformation(); replaceTargetFramework.FrameworkName = internalTargetFramework as NuGetFramework; packageSpec.TargetFrameworks[0] = replaceTargetFramework; } } var references = (await ProjectServices .ReferencesReader .GetProjectReferencesAsync(context.Logger, CancellationToken.None)) .ToList(); if (references != null && references.Count > 0) { // Add msbuild reference groups for each TFM in the project foreach (var framework in packageSpec.TargetFrameworks.Select(e => e.FrameworkName)) { metadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(framework)); } foreach (var reference in references) { // This reference applies to all frameworks // Include/exclude flags may be applied later when merged with project.json // Add the reference for all TFM groups, there are no conditional project // references in UWP. There should also be just one TFM. foreach (var frameworkInfo in metadata.TargetFrameworks) { frameworkInfo.ProjectReferences.Add(reference); } } } // Write restore settings to the package spec. // For project.json these properties may not come from the project file. var settings = context?.Settings ?? NullSettings.Instance; packageSpec.RestoreMetadata.PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings); packageSpec.RestoreMetadata.Sources = SettingsUtility.GetEnabledSources(settings).AsList(); packageSpec.RestoreMetadata.FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).AsList(); packageSpec.RestoreMetadata.ConfigFilePaths = SettingsUtility.GetConfigFilePaths(settings).AsList(); context?.PackageSpecCache.Add(MSBuildProjectPath, packageSpec); } return(new[] { packageSpec }); }
private static async Task <PackageSpec> GetPackageSpecForPackageReferencesAsync( IDeferredProjectWorkspaceService deferredWorkspaceService, string projectPath) { var projectName = Path.GetFileNameWithoutExtension(projectPath); var projectDirectory = Path.GetDirectoryName(projectPath); var msbuildProjectDataService = await deferredWorkspaceService.GetMSBuildProjectDataService(projectPath); var packageReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, PackageReference)).ToList(); if (packageReferences.Count == 0) { return(null); } var targetFrameworks = await GetNuGetFrameworks(deferredWorkspaceService, msbuildProjectDataService, projectPath); if (targetFrameworks.Count == 0) { return(null); } var outputPath = Path.GetFullPath( Path.Combine( projectDirectory, await GetProjectPropertyOrDefault(deferredWorkspaceService, msbuildProjectDataService, BaseIntermediateOutputPath))); var crossTargeting = targetFrameworks.Count > 1; var tfis = new List <TargetFrameworkInformation>(); var projectsByFramework = new Dictionary <NuGetFramework, IEnumerable <ProjectRestoreReference> >(); var runtimes = new List <string>(); var supports = new List <string>(); foreach (var targetFramework in targetFrameworks) { var tfi = new TargetFrameworkInformation { FrameworkName = targetFramework }; // re-evaluate msbuild project data service if there are multi-targets if (targetFrameworks.Count > 1) { msbuildProjectDataService = await deferredWorkspaceService.GetMSBuildProjectDataService( projectPath, targetFramework.GetShortFolderName()); packageReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, PackageReference)).ToList(); } // Package target fallback per target framework var ptf = await deferredWorkspaceService.GetProjectPropertyAsync(msbuildProjectDataService, PackageTargetFallback); if (!string.IsNullOrEmpty(ptf)) { var fallBackList = ptf.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(NuGetFramework.Parse).ToList(); if (fallBackList.Count > 0) { tfi.FrameworkName = new FallbackFramework(tfi.FrameworkName, fallBackList); } tfi.Imports = fallBackList; } // package references per target framework tfi.Dependencies.AddRange( packageReferences.Select(ToPackageLibraryDependency)); // Project references per target framework var projectReferences = (await deferredWorkspaceService.GetProjectItemsAsync(msbuildProjectDataService, ProjectReference)) .Select(item => ToProjectRestoreReference(item, projectDirectory)); projectsByFramework.Add(tfi.FrameworkName, projectReferences); // Runtimes, Supports per target framework runtimes.AddRange(await GetRuntimeIdentifiers(deferredWorkspaceService, msbuildProjectDataService)); supports.AddRange(await GetRuntimeSupports(deferredWorkspaceService, msbuildProjectDataService)); tfis.Add(tfi); } var packageSpec = new PackageSpec(tfis) { Name = projectName, FilePath = projectPath, RestoreMetadata = new ProjectRestoreMetadata { ProjectName = projectName, ProjectUniqueName = projectPath, ProjectPath = projectPath, OutputPath = outputPath, ProjectStyle = ProjectStyle.PackageReference, TargetFrameworks = (projectsByFramework.Select( kvp => new ProjectRestoreMetadataFrameworkInfo(kvp.Key) { ProjectReferences = kvp.Value?.ToList() } )).ToList(), OriginalTargetFrameworks = tfis .Select(tf => tf.FrameworkName.GetShortFolderName()) .ToList(), CrossTargeting = crossTargeting }, RuntimeGraph = new RuntimeGraph( runtimes.Distinct(StringComparer.Ordinal).Select(rid => new RuntimeDescription(rid)), supports.Distinct(StringComparer.Ordinal).Select(s => new CompatibilityProfile(s))) }; return(packageSpec); }
private FrameworkType GetType(TargetFrameworkInformation targetFrameworkInformation) { var frameworkName = targetFrameworkInformation.FrameworkName.Framework.TrimStart('.'); return(GetType(frameworkName)); }
public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_UpdatesDependency() { // Arrange var packageId = "NuGet.Versioning"; var oldVersion = new NuGetVersion("1.0.0"); var newVersion = new NuGetVersion("2.0.0"); var frameworkA = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; var ld = new LibraryDependency { LibraryRange = new LibraryRange(packageId, new VersionRange(oldVersion), LibraryDependencyTarget.Package), VersionCentrallyManaged = true }; var frameworkB = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16, Dependencies = new List <LibraryDependency>() { ld }, }; frameworkB.CentralPackageVersions[ld.Name] = new CentralPackageVersion(ld.Name, ld.LibraryRange.VersionRange); var spec = new PackageSpec(new[] { frameworkA, frameworkB }) { RestoreMetadata = new ProjectRestoreMetadata { CentralPackageVersionsEnabled = true } }; var identity = new PackageIdentity(packageId, newVersion); //Preconditions Assert.Equal( oldVersion, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion); // Act PackageSpecOperations.AddOrUpdateDependency( spec, identity, new[] { frameworkB.FrameworkName }); // Assert Assert.Empty(spec.Dependencies); Assert.Empty(spec.TargetFrameworks[0].Dependencies); Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count); Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name); Assert.Equal(identity.Version, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.VersionRange.MinVersion); Assert.True(spec.TargetFrameworks[1].Dependencies[0].VersionCentrallyManaged); Assert.True(spec.TargetFrameworks[1].CentralPackageVersions.ContainsKey(identity.Id)); Assert.Equal(identity.Version, spec.TargetFrameworks[1].CentralPackageVersions[identity.Id].VersionRange.MinVersion); }
/// <summary> /// Creates new instance of <see cref="BoundRestoreCommandUser"/> with given parameters. /// </summary> /// <param name="nugetSettings">The settings to use.</param> /// <param name="thisFramework">The framework to bind to.</param> /// <param name="runtimeIdentifier">The runtime identifier. Will be used by <see cref="E_NuGetUtils.ExtractAssemblyPaths{TResult}(BoundRestoreCommandUser, LockFile, Func{String, IEnumerable{String}, TResult}, GetFileItemsDelegate, IEnumerable{String})"/> method.</param> /// <param name="runtimeGraph">Optional value indicating runtime graph information: either <see cref="global::NuGet.RuntimeModel.RuntimeGraph"/> directly, or <see cref="String"/> containing package ID of package holding <c>runtime.json</c> file, containing serialized runtime graph definition. If neither is specified, then <c>"Microsoft.NETCore.Platforms"</c> package ID used to locate <c>runtime.json</c> file, as per <see href="https://docs.microsoft.com/en-us/dotnet/core/rid-catalog">official documentation</see>.</param> /// <param name="nugetLogger">The logger to use in restore command.</param> /// <param name="sourceCacheContext">The optional <see cref="SourceCacheContext"/> to use.</param> /// <param name="nuspecCache">The optional <see cref="LocalPackageFileCache"/> to use.</param> /// <param name="clientPolicyContext">The optional <see cref="ClientPolicyContext"/> to use.</param> /// <param name="leaveSourceCacheOpen">Whether to leave the <paramref name="sourceCacheContext"/> open when disposing this <see cref="BoundRestoreCommandUser"/>.</param> /// <param name="lockFileCacheDir">The directory where to store serialized lock files returned by <see cref="RestoreIfNeeded"/>. If <c>null</c> or empty, then <paramref name="lockFileCacheEnvironmentVariableName"/> will be used. Set <paramref name="disableLockFileCacheDir"/> to true to disable caching lock files to file system.</param> /// <param name="lockFileCacheEnvironmentVariableName">The name of the environment variable containing the value for lock file cache directory. If <c>null</c> or empty, then environment variable reading will be skipped. If the environment variable itself is <c>null</c> or empty, then the user's home directory in conjunction with <paramref name="getDefaultLockFileCacheDir"/> will be used to deduce lock file cache directory. Set <paramref name="disableLockFileCacheDir"/> to true to disable caching lock files to file system.</param> /// <param name="getDefaultLockFileCacheDir">This callback will be used when <paramref name="lockFileCacheEnvironmentVariableName"/> is <c>null</c> or empty or when the named environment variable itself was <c>null</c> or empty. This callback will receive current user's home directory as parameter and should return the lock file cache directory. If <c>null</c>, then <see cref="GetDefaultLockFileDir"/> will be used. Set <paramref name="disableLockFileCacheDir"/> to true to disable caching lock files to file system.</param> /// <param name="disableLockFileCacheDir">This variable controls whether the results of <see cref="RestoreIfNeeded"/> will be stored to file system lock file cache directory. By default, the lock file caching is enabled. Set this parameter to <c>true</c> to completely disable caching lock files to file system.</param> /// <exception cref="ArgumentNullException">If <paramref name="nugetSettings"/> is <c>null</c>.</exception> public BoundRestoreCommandUser( ISettings nugetSettings, NuGetFramework thisFramework = null, String runtimeIdentifier = null, EitherOr <RuntimeGraph, String> runtimeGraph = default, ILogger nugetLogger = null, SourceCacheContext sourceCacheContext = null, LocalPackageFileCache nuspecCache = null, ClientPolicyContext clientPolicyContext = null, Boolean leaveSourceCacheOpen = false, String lockFileCacheDir = null, String lockFileCacheEnvironmentVariableName = DEFAULT_LOCK_FILE_CACHE_DIR_ENV_NAME, Func <String, String> getDefaultLockFileCacheDir = null, Boolean disableLockFileCacheDir = false ) { ArgumentValidator.ValidateNotNull(nameof(nugetSettings), nugetSettings); this.ThisFramework = thisFramework ?? NuGetUtility.TryAutoDetectThisProcessFramework(); if (nugetLogger == null) { nugetLogger = NullLogger.Instance; } var global = SettingsUtility.GetGlobalPackagesFolder(nugetSettings); var fallbacks = SettingsUtility.GetFallbackPackageFolders(nugetSettings); if (sourceCacheContext == null) { leaveSourceCacheOpen = false; } var ctx = sourceCacheContext ?? new SourceCacheContext(); var psp = new PackageSourceProvider(nugetSettings); var csp = new CachingSourceProvider(psp); this.RuntimeIdentifier = NuGetUtility.TryAutoDetectThisProcessRuntimeIdentifier(runtimeIdentifier); this._cacheContext = ctx; this._disposeSourceCacheContext = !leaveSourceCacheOpen; this.NuGetLogger = nugetLogger; this._restoreCommandProvider = RestoreCommandProviders.Create( global, fallbacks, new PackageSourceProvider(nugetSettings).LoadPackageSources().Where(s => s.IsEnabled).Select(s => csp.CreateRepository(s)), ctx, nuspecCache ?? new LocalPackageFileCache(), nugetLogger ); this._nugetRestoreRootDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); this._restoreTargetFW = new TargetFrameworkInformation() { FrameworkName = this.ThisFramework }; this.LocalRepositories = this._restoreCommandProvider.GlobalPackages.Singleton() .Concat(this._restoreCommandProvider.FallbackPackageFolders) .ToImmutableDictionary(r => r.RepositoryRoot, r => r); this.RuntimeGraph = new Lazy <RuntimeGraph>(() => { var rGraph = runtimeGraph.GetFirstOrDefault(); if (rGraph == null) { var packageName = runtimeGraph.GetSecondOrDefault(); if (String.IsNullOrEmpty(packageName)) { packageName = DEFAULT_RUNTIME_GRAPH_PACKAGE_ID; } var platformsPackagePath = this.LocalRepositories.Values .SelectMany(r => r.FindPackagesById(packageName)) .OrderByDescending(p => p.Version) .FirstOrDefault() ?.ExpandedPath; rGraph = String.IsNullOrEmpty(platformsPackagePath) ? null : JsonRuntimeFormat.ReadRuntimeGraph(Path.Combine(platformsPackagePath, global::NuGet.RuntimeModel.RuntimeGraph.RuntimeGraphFileName)); } return(rGraph); }, LazyThreadSafetyMode.ExecutionAndPublication); if (!disableLockFileCacheDir) { this.DiskCacheDirectory = lockFileCacheDir .OrIfNullOrEmpty(String.IsNullOrEmpty(lockFileCacheEnvironmentVariableName) ? null : Environment.GetEnvironmentVariable(lockFileCacheEnvironmentVariableName)) .OrIfNullOrEmpty((getDefaultLockFileCacheDir ?? GetDefaultLockFileDir)(Environment.GetEnvironmentVariable( #if NET46 Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32S || Environment.OSVersion.Platform == PlatformID.Win32Windows || Environment.OSVersion.Platform == PlatformID.WinCE #else System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows) #endif ? "USERPROFILE" : "HOME")) ) .OrIfNullOrEmpty(null); } this._allLockFiles = new ConcurrentDictionary <ImmutableSortedSet <String>, ImmutableDictionary <ImmutableArray <NuGetVersion>, String> >(); this._lockFileFormat = new LockFileFormat(); this._clientPolicyContext = clientPolicyContext ?? ClientPolicyContext.GetClientPolicy(nugetSettings, nugetLogger); }
/// <summary> /// Compares the project and the assets files returning the installed package. /// Assets information can be null and returns the package from the project files. /// Checks if package already exists in the project and return it, otherwise update the project installed packages. /// </summary> /// <param name="projectLibrary">Library from the project file.</param> /// <param name="targetFramework">Target framework from the project file.</param> /// <param name="assetsTargetFrameworkInformation">Target framework information from the assets file.</param> /// <param name="targets">Target assets file with the package information.</param> /// <param name="installedPackages">Installed packages information from the project.</param> internal static PackageIdentity UpdateResolvedVersion(LibraryDependency projectLibrary, NuGetFramework targetFramework, TargetFrameworkInformation assetsTargetFrameworkInformation, IEnumerable <LockFileTarget> targets, Dictionary <string, ProjectInstalledPackage> installedPackages) { NuGetVersion resolvedVersion = default; // Returns the installed version if the package: // 1. Already exists in the installedPackages // 2. The range is the same as the installed one // 3. There are no changes in the assets file if (installedPackages.TryGetValue(projectLibrary.Name, out ProjectInstalledPackage installedVersion) && installedVersion.AllowedVersions.Equals(projectLibrary.LibraryRange.VersionRange) && targets == null) { return(installedVersion.InstalledPackage); } resolvedVersion = GetInstalledVersion(projectLibrary, targetFramework, assetsTargetFrameworkInformation, targets); if (resolvedVersion == null) { resolvedVersion = projectLibrary.LibraryRange?.VersionRange?.MinVersion ?? new NuGetVersion(0, 0, 0); } // Add or update the the version of the package in the project if (installedPackages.TryGetValue(projectLibrary.Name, out ProjectInstalledPackage installedPackage)) { installedPackages[projectLibrary.Name] = new ProjectInstalledPackage(projectLibrary.LibraryRange.VersionRange, new PackageIdentity(projectLibrary.Name, resolvedVersion)); } else { ProjectInstalledPackage newInstalledPackage = new ProjectInstalledPackage(projectLibrary.LibraryRange.VersionRange, new PackageIdentity(projectLibrary.Name, resolvedVersion)); installedPackages.Add(projectLibrary.Name, newInstalledPackage); } return(new PackageIdentity(projectLibrary.Name, resolvedVersion)); }
private static void AssertHashCode(bool expected, TargetFrameworkInformation leftSide, TargetFrameworkInformation rightSide) { if (expected) { leftSide.GetHashCode().Should().Be(rightSide.GetHashCode()); } else { leftSide.GetHashCode().Should().NotBe(rightSide.GetHashCode()); } }
private static NuGetVersion GetInstalledVersion(LibraryDependency libraryProjectFile, NuGetFramework targetFramework, TargetFrameworkInformation assetsTargetFrameworkInformation, IEnumerable <LockFileTarget> targets) { LibraryDependency libraryAsset = assetsTargetFrameworkInformation?.Dependencies.FirstOrDefault(e => e.Name.Equals(libraryProjectFile.Name, StringComparison.OrdinalIgnoreCase)); if (libraryAsset == null) { return(null); } return(targets .FirstOrDefault(t => t.TargetFramework.Equals(targetFramework) && string.IsNullOrEmpty(t.RuntimeIdentifier)) ?.Libraries .FirstOrDefault(a => a.Name.Equals(libraryAsset.Name, StringComparison.OrdinalIgnoreCase))?.Version); }
public void GetTargetFrameworkInfos_WithCustomAliases_InfersCorrectTargetFramework() { // Arrange string latestNet = "latestNet"; string latestCore = "latestCore"; var atf = "net472"; var runtimeIdentifierGraphPath = Path.Combine(Path.GetTempPath(), "runtime.json"); var innerNodes = new Dictionary <string, IMSBuildProject> { [latestCore] = new MockMSBuildProject("Project-core", new Dictionary <string, string> { { "AssetTargetFallback", atf }, { "PackageTargetFallback", "" }, { "TargetFramework", latestCore }, { "TargetFrameworkIdentifier", FrameworkConstants.FrameworkIdentifiers.NetCoreApp }, { "TargetFrameworkVersion", "v5.0" }, { "TargetFrameworkMoniker", $"{FrameworkConstants.FrameworkIdentifiers.NetCoreApp},Version=5.0" }, { "TargetPlatformIdentifier", "android" }, { "TargetPlatformVersion", "21.0" }, { "TargetPlatformMoniker", "android,Version=21.0" }, { "RuntimeIdentifierGraphPath", runtimeIdentifierGraphPath } }, new Dictionary <string, IList <IMSBuildItem> > { ["PackageReference"] = new List <IMSBuildItem> { new MSBuildItem("PackageA", new Dictionary <string, string> { ["Version"] = "2.0.0" }), } }), [latestNet] = new MockMSBuildProject("Project-net", new Dictionary <string, string> { { "AssetTargetFallback", "" }, { "PackageTargetFallback", "" }, { "TargetFramework", latestNet }, { "TargetFrameworkIdentifier", FrameworkConstants.FrameworkIdentifiers.Net }, { "TargetFrameworkVersion", "v4.6.1" }, { "TargetFrameworkMoniker", $"{FrameworkConstants.FrameworkIdentifiers.Net},Version=4.6.1" }, { "TargetPlatformIdentifier", "" }, { "TargetPlatformVersion", "" }, { "TargetPlatformMoniker", "" }, { "RuntimeIdentifierGraphPath", runtimeIdentifierGraphPath } }, new Dictionary <string, IList <IMSBuildItem> > { ["PackageReference"] = new List <IMSBuildItem> { new MSBuildItem("PackageB", new Dictionary <string, string> { ["Version"] = "2.1.0" }), }, }), }; // Act List <TargetFrameworkInformation> targetFrameworkInfos = MSBuildStaticGraphRestore.GetTargetFrameworkInfos(innerNodes, isCpvmEnabled: false); // Assert targetFrameworkInfos.Should().HaveCount(2); TargetFrameworkInformation coreTFI = targetFrameworkInfos.Single(f => f.TargetAlias == latestCore); TargetFrameworkInformation netTFI = targetFrameworkInfos.Single(f => f.TargetAlias == latestNet); coreTFI.Dependencies.Should().HaveCount(1); coreTFI.Dependencies.Single().Name.Should().Be("PackageA"); coreTFI.Dependencies.Single().LibraryRange.VersionRange.OriginalString.Should().Be("2.0.0"); coreTFI.RuntimeIdentifierGraphPath.Should().Be(runtimeIdentifierGraphPath); coreTFI.FrameworkName.GetShortFolderName().Should().Be("net5.0-android21.0"); coreTFI.AssetTargetFallback.Should().BeTrue(); AssetTargetFallbackFramework assetTargetFallbackFramework = (AssetTargetFallbackFramework)coreTFI.FrameworkName; assetTargetFallbackFramework.Fallback.Should().HaveCount(1); assetTargetFallbackFramework.Fallback.Single().GetShortFolderName().Should().Be("net472"); netTFI.Dependencies.Should().HaveCount(1); netTFI.Dependencies.Single().Name.Should().Be("PackageB"); netTFI.Dependencies.Single().LibraryRange.VersionRange.OriginalString.Should().Be("2.1.0"); netTFI.RuntimeIdentifierGraphPath.Should().Be(runtimeIdentifierGraphPath); netTFI.FrameworkName.Should().Be(FrameworkConstants.CommonFrameworks.Net461); netTFI.AssetTargetFallback.Should().BeFalse(); }
/// <summary> /// Emulates a JSON deserialization from project.json to PackageSpec in a post-project.json world /// </summary> private PackageSpec GetPackageSpec() { EnsureUIThread(); var projectReferences = _project.GetLegacyCSProjProjectReferences(_desiredPackageReferenceMetadata) .Select(ToProjectRestoreReference); var packageReferences = _project.GetLegacyCSProjPackageReferences(_desiredPackageReferenceMetadata) .Select(ToPackageLibraryDependency).ToList(); var packageTargetFallback = _project.PackageTargetFallback?.Split(new[] { ';' }) .Select(NuGetFramework.Parse) .ToList(); var projectTfi = new TargetFrameworkInformation() { FrameworkName = _project.TargetNuGetFramework, Dependencies = packageReferences, Imports = packageTargetFallback ?? new List <NuGetFramework>() }; if ((projectTfi.Imports?.Count ?? 0) > 0) { projectTfi.FrameworkName = new FallbackFramework(projectTfi.FrameworkName, packageTargetFallback); } // Build up runtime information. var runtimes = _project.Runtimes; var supports = _project.Supports; var runtimeGraph = new RuntimeGraph(runtimes, supports); // In legacy CSProj, we only have one target framework per project var tfis = new TargetFrameworkInformation[] { projectTfi }; return(new PackageSpec(tfis) { Name = _projectName ?? _projectUniqueName, Version = new NuGetVersion(_project.Version), Authors = new string[] { }, Owners = new string[] { }, Tags = new string[] { }, ContentFiles = new string[] { }, Dependencies = packageReferences, FilePath = _projectFullPath, RuntimeGraph = runtimeGraph, RestoreMetadata = new ProjectRestoreMetadata { ProjectStyle = ProjectStyle.PackageReference, OutputPath = GetBaseIntermediatePath(), ProjectPath = _projectFullPath, ProjectName = _projectName ?? _projectUniqueName, ProjectUniqueName = _projectFullPath, OriginalTargetFrameworks = tfis .Select(tfi => tfi.FrameworkName.GetShortFolderName()) .ToList(), TargetFrameworks = new List <ProjectRestoreMetadataFrameworkInfo>() { new ProjectRestoreMetadataFrameworkInfo(tfis[0].FrameworkName) { ProjectReferences = projectReferences?.ToList() } } } }); }
public async Task RestoreRunner_RestoreWithExternalFile_NetCoreOutput() { // Arrange var sources = new List <PackageSource>(); var targetFrameworkInfo1 = new TargetFrameworkInformation(); targetFrameworkInfo1.FrameworkName = NuGetFramework.Parse("net45"); var frameworks1 = new[] { targetFrameworkInfo1 }; var targetFrameworkInfo2 = new TargetFrameworkInformation(); targetFrameworkInfo2.FrameworkName = NuGetFramework.Parse("net45"); var frameworks2 = new[] { targetFrameworkInfo2 }; // Create two net45 projects var spec1 = new PackageSpec(frameworks1); spec1.RestoreMetadata = new ProjectRestoreMetadata(); spec1.RestoreMetadata.ProjectUniqueName = "project1"; spec1.RestoreMetadata.ProjectName = "project1"; spec1.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var spec2 = new PackageSpec(frameworks2); spec2.RestoreMetadata = new ProjectRestoreMetadata(); spec2.RestoreMetadata.ProjectUniqueName = "project2"; spec2.RestoreMetadata.ProjectName = "project2"; spec2.RestoreMetadata.ProjectStyle = ProjectStyle.PackageReference; spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var specs = new[] { spec1, spec2 }; using (var workingDir = TestDirectory.Create()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); var project2 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project2")); packagesDir.Create(); packageSource.Create(); project1.Create(); project2.Create(); sources.Add(new PackageSource(packageSource.FullName)); var projPath1 = Path.Combine(project1.FullName, "project1.csproj"); var projPath2 = Path.Combine(project2.FullName, "project2.csproj"); File.WriteAllText(projPath1, string.Empty); File.WriteAllText(projPath2, string.Empty); spec1.RestoreMetadata.ProjectPath = projPath1; spec1.FilePath = projPath1; spec1.Name = "project1"; spec2.RestoreMetadata.ProjectPath = projPath2; spec2.FilePath = projPath1; spec2.Name = "project2"; var logger = new TestLogger(); var objPath1 = Path.Combine(project1.FullName, "obj"); var objPath2 = Path.Combine(project2.FullName, "obj"); spec1.RestoreMetadata.OutputPath = objPath1; spec2.RestoreMetadata.OutputPath = objPath2; spec1.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); spec2.RestoreMetadata.OriginalTargetFrameworks.Add("net45"); var lockPath1 = Path.Combine(objPath1, "project.assets.json"); var lockPath2 = Path.Combine(objPath2, "project.assets.json"); // Link projects spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange() { Name = "project2", TypeConstraint = LibraryDependencyTarget.ExternalProject } }); spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45"))); spec1.RestoreMetadata.TargetFrameworks .Single() .ProjectReferences .Add(new ProjectRestoreReference() { ProjectPath = projPath2, ProjectUniqueName = "project2" }); // Create dg file var dgFile = new DependencyGraphSpec(); foreach (var spec in specs) { dgFile.AddRestore(spec.RestoreMetadata.ProjectName); dgFile.AddProject(spec); } var dgPath = Path.Combine(workingDir, "input.dg"); dgFile.Save(dgPath); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Inputs = new List <string>() { dgPath }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), RequestProviders = new List <IRestoreRequestProvider>() { new DependencyGraphFileRequestProvider(providerCache) } }; // Act var summaries = await RestoreRunner.RunAsync(restoreContext); var success = summaries.All(s => s.Success); var lockFormat = new LockFileFormat(); var lockFile1 = lockFormat.Read(lockPath1); var project2Lib = lockFile1.Libraries.First(); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(File.Exists(lockPath1), lockPath1); Assert.True(File.Exists(lockPath2), lockPath2); Assert.Equal("project2", project2Lib.Name); } } }
internal static TargetFrameworkInformation ToTargetFrameworkInformation( IVsTargetFrameworkInfo targetFrameworkInfo, bool cpvmEnabled, string projectFullPath) { var tfi = new TargetFrameworkInformation { FrameworkName = GetTargetFramework(targetFrameworkInfo.Properties, projectFullPath), TargetAlias = GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.TargetFramework) }; var ptf = MSBuildStringUtility.Split(GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.PackageTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); var atf = MSBuildStringUtility.Split(GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.AssetTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); // Update TFI with fallback properties AssetTargetFallbackUtility.ApplyFramework(tfi, ptf, atf); tfi.RuntimeIdentifierGraphPath = GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.RuntimeIdentifierGraphPath); if (targetFrameworkInfo.PackageReferences != null) { tfi.Dependencies.AddRange( targetFrameworkInfo.PackageReferences .Cast <IVsReferenceItem>() .Select(pr => ToPackageLibraryDependency(pr, cpvmEnabled))); } if (targetFrameworkInfo is IVsTargetFrameworkInfo2 targetFrameworkInfo2) { if (targetFrameworkInfo2.PackageDownloads != null) { tfi.DownloadDependencies.AddRange( targetFrameworkInfo2.PackageDownloads .Cast <IVsReferenceItem>() .Select(ToPackageDownloadDependency)); } if (cpvmEnabled && targetFrameworkInfo is IVsTargetFrameworkInfo3 targetFrameworkInfo3) { if (targetFrameworkInfo3.CentralPackageVersions != null) { tfi.CentralPackageVersions.AddRange( targetFrameworkInfo3.CentralPackageVersions .Cast <IVsReferenceItem>() .Select(ToCentralPackageVersion) .Distinct(CentralPackageVersionNameComparer.Default) .ToDictionary(cpv => cpv.Name)); } // Merge the central version information to the package information LibraryDependency.ApplyCentralVersionInformation(tfi.Dependencies, tfi.CentralPackageVersions); } if (targetFrameworkInfo2.FrameworkReferences != null) { PopulateFrameworkDependencies(tfi, targetFrameworkInfo2); } } return(tfi); }
public void IsLockFileStillValid_RemovedCentralTransitivePackageVersions_InvalidateLockFile() { // Arrange var framework = CommonFrameworks.NetStandard20; var projectName = "project"; var cpvm1 = new CentralPackageVersion("cpvm1", VersionRange.Parse("1.0.0")); var cpvm2 = new CentralPackageVersion("cpvm2", VersionRange.Parse("1.0.0")); var dependency1 = new LibraryDependency( new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package), LibraryDependencyType.Default, LibraryIncludeFlags.All, LibraryIncludeFlags.All, new List <Common.NuGetLogCode>(), autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, LibraryDependencyReferenceType.Direct, aliases: "stuff"); var tfm = new TargetFrameworkInformation(); tfm.FrameworkName = framework; tfm.CentralPackageVersions.Add("cpvm1", cpvm1); tfm.CentralPackageVersions.Add("cpvm2", cpvm2); var project = new PackageSpec(new List <TargetFrameworkInformation>() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; DependencyGraphSpec dgSpec = new DependencyGraphSpec(); dgSpec.AddRestore(projectName); dgSpec.AddProject(project); var lockFile = new PackagesLockFileBuilder() .WithTarget(target => target .WithFramework(CommonFrameworks.NetStandard20) .WithDependency(dep => dep .WithId("cpvm1") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.Direct)) .WithDependency(dep => dep .WithId("cpvm2") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.CentralTransitive)) .WithDependency(dep => dep .WithId("cpvm3") .WithRequestedVersion(VersionRange.Parse("1.0.0")) .WithType(PackageDependencyType.CentralTransitive))) .Build(); // The central package version cpvm3 it was removed var actual = PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile); Assert.False(actual); }