diff --git a/Directory.Packages.props b/Directory.Packages.props index 266ee00edfc..6027426adac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -87,6 +87,7 @@ + @@ -190,6 +191,7 @@ <_allowBuildFromSourcePackage Include="Microsoft.Extensions.FileSystemGlobbing" /> <_allowBuildFromSourcePackage Include="Microsoft.Web.Xdt" /> <_allowBuildFromSourcePackage Include="Newtonsoft.Json" /> + <_allowBuildFromSourcePackage Include="System.Collections.Immutable" /> <_allowBuildFromSourcePackage Include="System.CommandLine" /> <_allowBuildFromSourcePackage Include="System.ComponentModel.Composition" /> <_allowBuildFromSourcePackage Include="System.Formats.Asn1" /> diff --git a/build/Shared/IsExternalInit.cs b/build/Shared/IsExternalInit.cs index 8792a164950..41438e87938 100644 --- a/build/Shared/IsExternalInit.cs +++ b/build/Shared/IsExternalInit.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if !NET5_0_OR_GREATER - using System.Diagnostics; namespace System.Runtime.CompilerServices; @@ -13,5 +11,3 @@ namespace System.Runtime.CompilerServices; internal static class IsExternalInit { } - -#endif diff --git a/build/Shared/SharedExtensions.cs b/build/Shared/SharedExtensions.cs index 79b7e13a144..c74b195bff6 100644 --- a/build/Shared/SharedExtensions.cs +++ b/build/Shared/SharedExtensions.cs @@ -125,5 +125,45 @@ public static void AppendInt(this StringBuilder sb, int value) divisor /= 10; } } + + public static int SingleIndex(this IList lst, Predicate isMatch) + { + var foundIndex = -1; + + for (var index = 0; index < lst.Count; index++) + { + var item = lst[index]; + if (isMatch(item)) + { + if (foundIndex != -1) + { + throw new InvalidOperationException(); + } + + foundIndex = index; + } + } + + if (foundIndex == -1) + { + throw new InvalidOperationException(); + } + + return foundIndex; + } + + public static int FirstIndex(this IList lst, Predicate isMatch) + { + for (var index = 0; index < lst.Count; index++) + { + var item = lst[index]; + if (isMatch(item)) + { + return index; + } + } + + throw new InvalidOperationException(); + } } } diff --git a/src/NuGet.Clients/NuGet.MSSigning.Extensions/ilmerge.props b/src/NuGet.Clients/NuGet.MSSigning.Extensions/ilmerge.props index 5bf19096bb9..cf59472d630 100644 --- a/src/NuGet.Clients/NuGet.MSSigning.Extensions/ilmerge.props +++ b/src/NuGet.Clients/NuGet.MSSigning.Extensions/ilmerge.props @@ -23,6 +23,7 @@ + diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs index d80ae7920b5..bd4ee993f93 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -204,9 +205,14 @@ private static string GetReferenceMetadataValue(ProjectReference reference, stri private static LibraryDependency ToPackageLibraryDependency(PackageReference reference, bool isCpvmEnabled) { // Get warning suppressions - IList noWarn = MSBuildStringUtility.GetNuGetLogCodes(GetReferenceMetadataValue(reference, ProjectItemProperties.NoWarn)); + ImmutableArray noWarn = MSBuildStringUtility.GetNuGetLogCodes(GetReferenceMetadataValue(reference, ProjectItemProperties.NoWarn)); - var dependency = new LibraryDependency(noWarn) + (var includeType, var suppressParent) = MSBuildRestoreUtility.GetLibraryDependencyIncludeFlags( + GetReferenceMetadataValue(reference, ProjectItemProperties.IncludeAssets), + GetReferenceMetadataValue(reference, ProjectItemProperties.ExcludeAssets), + GetReferenceMetadataValue(reference, ProjectItemProperties.PrivateAssets)); + + var dependency = new LibraryDependency() { AutoReferenced = MSBuildStringUtility.IsTrue(GetReferenceMetadataValue(reference, ProjectItemProperties.IsImplicitlyDefined)), GeneratePathProperty = MSBuildStringUtility.IsTrue(GetReferenceMetadataValue(reference, ProjectItemProperties.GeneratePathProperty)), @@ -216,14 +222,11 @@ private static LibraryDependency ToPackageLibraryDependency(PackageReference ref name: reference.Name, versionRange: ToVersionRange(reference.Version, isCpvmEnabled), typeConstraint: LibraryDependencyTarget.Package), + NoWarn = noWarn, + IncludeType = includeType, + SuppressParent = suppressParent, }; - MSBuildRestoreUtility.ApplyIncludeFlags( - dependency, - GetReferenceMetadataValue(reference, ProjectItemProperties.IncludeAssets), - GetReferenceMetadataValue(reference, ProjectItemProperties.ExcludeAssets), - GetReferenceMetadataValue(reference, ProjectItemProperties.PrivateAssets)); - return dependency; } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs index 3f0cf54fce3..6b141b82587 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft; @@ -128,7 +130,7 @@ protected override async Task GetAssetsFilePathAsync(bool shouldThrow) return (new[] { packageSpec }, null); } - private Dictionary GetCentralPackageVersions() + private IReadOnlyDictionary GetCentralPackageVersions() { ThreadHelper.ThrowIfNotOnUIThread(); @@ -142,7 +144,6 @@ private Dictionary GetCentralPackageVersions() .ToDictionary(cpv => cpv.Name); } - private CentralPackageVersion ToCentralPackageVersion(string packageId, string version) { if (string.IsNullOrEmpty(packageId)) @@ -220,7 +221,7 @@ public override async Task InstallPackageAsync( BuildIntegratedInstallationContext __, CancellationToken token) { - var dependency = new LibraryDependency(noWarn: Array.Empty()) + var dependency = new LibraryDependency() { LibraryRange = new LibraryRange( name: packageId, @@ -423,7 +424,7 @@ private async Task GetPackageSpecAsync(ISettings settings) var packageReferences = (await ProjectServices .ReferencesReader .GetPackageReferencesAsync(targetFramework, CancellationToken.None)) - .ToList(); + .ToImmutableArray(); #pragma warning disable CS0618 // Type or member is obsolete // Need to validate no project systems get this property via DTE, and if so, switch to GetPropertyValue @@ -431,30 +432,36 @@ private async Task GetPackageSpecAsync(ISettings settings) .Select(NuGetFramework.Parse) .ToList(); - var assetTargetFallback = MSBuildStringUtility.Split(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.AssetTargetFallback)) + var assetTargetFallbackList = MSBuildStringUtility.Split(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.AssetTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); #pragma warning restore CS0618 // Type or member is obsolete - var projectTfi = new TargetFrameworkInformation - { - FrameworkName = targetFramework, - Dependencies = packageReferences, - }; - #pragma warning disable CS0618 // Type or member is obsolete // Need to validate no project systems get this property via DTE, and if so, switch to GetPropertyValue bool isCpvmEnabled = MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.ManagePackageVersionsCentrally)); #pragma warning restore CS0618 // Type or member is obsolete + + IReadOnlyDictionary centralPackageVersions = null; if (isCpvmEnabled) { // Add the central version information and merge the information to the package reference dependencies - projectTfi.CentralPackageVersions.AddRange(GetCentralPackageVersions()); - LibraryDependency.ApplyCentralVersionInformation(projectTfi.Dependencies, projectTfi.CentralPackageVersions); + centralPackageVersions = GetCentralPackageVersions(); + packageReferences = ApplyCentralVersionInformation(packageReferences, centralPackageVersions); } - // Apply fallback settings - AssetTargetFallbackUtility.ApplyFramework(projectTfi, packageTargetFallback, assetTargetFallback); + // Get fallback settings + (targetFramework, var imports, var assetTargetFallback, var warn) = AssetTargetFallbackUtility.GetFallbackFrameworkInformation(targetFramework, packageTargetFallback, assetTargetFallbackList); + + var projectTfi = new TargetFrameworkInformation + { + AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, + Dependencies = packageReferences, + Imports = imports, + FrameworkName = targetFramework, + Warn = warn, + }; // Build up runtime information. @@ -564,6 +571,57 @@ private async Task GetPackageSpecAsync(ISettings settings) }; } + internal static ImmutableArray ApplyCentralVersionInformation(ImmutableArray packageReferences, IReadOnlyDictionary centralPackageVersions) + { + if (packageReferences.IsDefault) + { + throw new ArgumentNullException(nameof(packageReferences)); + } + if (centralPackageVersions == null) + { + throw new ArgumentNullException(nameof(centralPackageVersions)); + } + if (centralPackageVersions.Count == 0) + { + return packageReferences; + } + + LibraryDependency[] result = new LibraryDependency[packageReferences.Length]; + for (int i = 0; i < packageReferences.Length; i++) + { + LibraryDependency d = packageReferences[i]; + if (!d.AutoReferenced && d.LibraryRange.VersionRange == null) + { + var libraryRange = d.LibraryRange; + var versionCentrallyManaged = d.VersionCentrallyManaged; + + if (d.VersionOverride != null) + { + libraryRange = new LibraryRange(d.LibraryRange) { VersionRange = d.VersionOverride }; + } + else + { + if (centralPackageVersions.TryGetValue(d.Name, out CentralPackageVersion centralPackageVersion)) + { + libraryRange = new LibraryRange(d.LibraryRange) { VersionRange = centralPackageVersion.VersionRange }; + } + + versionCentrallyManaged = true; + } + + d = new LibraryDependency(d) + { + LibraryRange = libraryRange, + VersionCentrallyManaged = versionCentrallyManaged + }; + } + + result[i] = d; + } + + return ImmutableCollectionsMarshal.AsImmutableArray(result); + } + internal static IEnumerable GetRuntimeIdentifiers(string unparsedRuntimeIdentifer, string unparsedRuntimeIdentifers) { var runtimes = Enumerable.Empty(); diff --git a/src/NuGet.Clients/NuGet.SolutionRestoreManager/VSNominationUtilities.cs b/src/NuGet.Clients/NuGet.SolutionRestoreManager/VSNominationUtilities.cs index 4485d27d810..4e70bd57ecf 100644 --- a/src/NuGet.Clients/NuGet.SolutionRestoreManager/VSNominationUtilities.cs +++ b/src/NuGet.Clients/NuGet.SolutionRestoreManager/VSNominationUtilities.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -92,11 +93,7 @@ internal static RuntimeGraph GetRuntimeGraph(IReadOnlyList? ptf = ptfString is not null @@ -108,42 +105,53 @@ internal static TargetFrameworkInformation ToTargetFrameworkInformation( ? MSBuildStringUtility.Split(atfString).Select(NuGetFramework.Parse).ToList() : null; - // Update TFI with fallback properties - AssetTargetFallbackUtility.ApplyFramework(tfi, ptf, atf); + // Get fallback properties + (frameworkName, var imports, var assetTargetFallback, var warn) = AssetTargetFallbackUtility.GetFallbackFrameworkInformation(frameworkName, ptf, atf); - tfi.RuntimeIdentifierGraphPath = GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.RuntimeIdentifierGraphPath); + ImmutableArray dependencies = []; + ImmutableArray downloadDependencies = []; + IReadOnlyDictionary? centralPackageVersions = null; + IReadOnlyCollection? frameworkReferences = null; - if (targetFrameworkInfo.Items is null) + if (targetFrameworkInfo.Items is not null) { - return tfi; - } + if (cpvmEnabled && targetFrameworkInfo.Items.TryGetValue("PackageVersion", out var packageVersions)) + { + centralPackageVersions = packageVersions + .Select(ToCentralPackageVersion) + .Distinct(CentralPackageVersionNameComparer.Default) + .ToDictionary(cpv => cpv.Name); + } - if (targetFrameworkInfo.Items.TryGetValue(ProjectItems.PackageReference, out var packageReferences)) - { - tfi.Dependencies.AddRange(packageReferences.Select(pr => ToPackageLibraryDependency(pr, cpvmEnabled))); - } + if (targetFrameworkInfo.Items.TryGetValue(ProjectItems.PackageReference, out var packageReferences)) + { + dependencies = packageReferences.Select(pr => ToPackageLibraryDependency(pr, cpvmEnabled, centralPackageVersions)).ToImmutableArray(); + } - if (targetFrameworkInfo.Items.TryGetValue("PackageDownload", out var packageDownloads)) - { - tfi.DownloadDependencies.AddRange(packageDownloads.SelectMany(ToPackageDownloadDependency)); - } + if (targetFrameworkInfo.Items.TryGetValue("PackageDownload", out var packageDownloads)) + { + downloadDependencies = packageDownloads.SelectMany(ToPackageDownloadDependency).ToImmutableArray(); + } - if (cpvmEnabled && targetFrameworkInfo.Items.TryGetValue("PackageVersion", out var centralPackageVersions)) - { - tfi.CentralPackageVersions.AddRange( - centralPackageVersions - .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 (targetFrameworkInfo.Items.TryGetValue("FrameworkReference", out var frameworkReference)) + { + frameworkReferences = PopulateFrameworkDependencies(frameworkReference); + } } - if (targetFrameworkInfo.Items.TryGetValue("FrameworkReference", out var frameworkReferences)) + var tfi = new TargetFrameworkInformation { - PopulateFrameworkDependencies(tfi, frameworkReferences); - } + AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + DownloadDependencies = downloadDependencies, + FrameworkName = frameworkName, + FrameworkReferences = frameworkReferences, + Imports = imports, + RuntimeIdentifierGraphPath = GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.RuntimeIdentifierGraphPath), + TargetAlias = GetPropertyValueOrNull(targetFrameworkInfo.Properties, ProjectBuildProperties.TargetFramework), + Warn = warn + }; return tfi; } @@ -219,11 +227,15 @@ internal static RestoreLockProperties GetRestoreLockProperties(IReadOnlyList targetFrameworks) { + var warningsAsErrors = GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.WarningsAsErrors, MSBuildStringUtility.GetNuGetLogCodes); + var noWarn = GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.NoWarn, MSBuildStringUtility.GetNuGetLogCodes); + var warningsNotAsErrors = GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.WarningsNotAsErrors, MSBuildStringUtility.GetNuGetLogCodes); + return WarningProperties.GetWarningProperties( treatWarningsAsErrors: GetSingleOrDefaultPropertyValue(targetFrameworks, ProjectBuildProperties.TreatWarningsAsErrors, e => e), - warningsAsErrors: GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.WarningsAsErrors, MSBuildStringUtility.GetNuGetLogCodes), - noWarn: GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.NoWarn, MSBuildStringUtility.GetNuGetLogCodes), - warningsNotAsErrors: GetSingleOrDefaultNuGetLogCodes(targetFrameworks, ProjectBuildProperties.WarningsNotAsErrors, MSBuildStringUtility.GetNuGetLogCodes)); + warningsAsErrors: warningsAsErrors.IsDefault ? [] : warningsAsErrors, + noWarn: noWarn.IsDefault ? [] : noWarn, + warningsNotAsErrors: warningsNotAsErrors.IsDefault ? [] : warningsNotAsErrors); } /// @@ -408,21 +420,52 @@ private static NuGetFramework GetToolFramework(IReadOnlyList 1 ? default(TValue) : properties.SingleOrDefault(); + return properties.Length > 1 ? default(TValue) : properties.SingleOrDefault(); } - private static IEnumerable GetSingleOrDefaultNuGetLogCodes( + private static ImmutableArray GetSingleOrDefaultNuGetLogCodes( IReadOnlyList values, string propertyName, - Func> valueFactory) + Func> valueFactory) { var logCodeProperties = GetNonEvaluatedPropertyOrNull(values, propertyName, valueFactory); - return logCodeProperties is not null ? MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodeProperties) : Enumerable.Empty(); + return GetDistinctNuGetLogCodesOrDefault(logCodeProperties); + } + + /// + /// Return empty list of NuGetLogCode if all lists of NuGetLogCode are not the same. + /// + public static ImmutableArray GetDistinctNuGetLogCodesOrDefault(ImmutableArray> nugetLogCodeLists) + { + if (nugetLogCodeLists.Length == 0) + { + return []; + } + + ImmutableArray result = []; + var first = true; + + foreach (ImmutableArray logCodeList in nugetLogCodeLists) + { + // If this is first item, assign it to result + if (first) + { + result = logCodeList; + first = false; + } + // Compare the rest items to the first one. + else if (result == null || logCodeList == null || result.Length != logCodeList.Length || !result.All(logCodeList.Contains)) + { + return []; + } + } + + return result; } // Trying to fetch a list of property value from all tfm property bags. - private static IEnumerable GetNonEvaluatedPropertyOrNull( + private static ImmutableArray GetNonEvaluatedPropertyOrNull( IReadOnlyList values, string propertyName, Func valueFactory) @@ -433,7 +476,8 @@ private static IEnumerable GetSingleOrDefaultNuGetLogCodes( var val = tfm.Properties is not null ? GetPropertyValueOrNull(tfm.Properties, propertyName) : null; return val != null ? valueFactory(val) : default(TValue); }) - .Distinct(); + .Distinct() + .ToImmutableArray(); } // Trying to fetch a property value from tfm property bags. @@ -443,13 +487,13 @@ private static IEnumerable GetSingleOrDefaultNuGetLogCodes( string propertyName, Func valueFactory) { - var distinctValues = GetNonEvaluatedPropertyOrNull(values, propertyName, valueFactory).ToList(); + ImmutableArray distinctValues = GetNonEvaluatedPropertyOrNull(values, propertyName, valueFactory); - if (distinctValues.Count == 0) + if (distinctValues.Length == 0) { return default(TValue); } - else if (distinctValues.Count == 1) + else if (distinctValues.Length == 1) { return distinctValues[0]; } @@ -482,9 +526,11 @@ private static IEnumerable GetAggregatePropertyValues( #region IVSReferenceItemAPIs - private static LibraryDependency ToPackageLibraryDependency(IVsReferenceItem2 item, bool cpvmEnabled) + private static LibraryDependency ToPackageLibraryDependency(IVsReferenceItem2 item, bool cpvmEnabled, IReadOnlyDictionary? centralPackageVersions) { + bool autoReferenced = GetPropertyBoolOrFalse(item, "IsImplicitlyDefined"); VersionRange? versionRange = ParseVersionRange(item, "Version"); + bool versionDefined = versionRange != null; if (versionRange == null && !cpvmEnabled) { versionRange = VersionRange.All; @@ -492,11 +538,25 @@ private static LibraryDependency ToPackageLibraryDependency(IVsReferenceItem2 it VersionRange? versionOverrideRange = ParseVersionRange(item, "VersionOverride"); + CentralPackageVersion? centralPackageVersion = null; + bool isCentrallyManaged = !versionDefined && !autoReferenced && cpvmEnabled && versionOverrideRange == null && centralPackageVersions != null && centralPackageVersions.TryGetValue(item.Name, out centralPackageVersion); + + if (centralPackageVersion != null) + { + versionRange = centralPackageVersion.VersionRange; + } + versionRange = versionOverrideRange ?? versionRange; + // Get warning suppressions string? noWarnString = GetPropertyValueOrNull(item, ProjectBuildProperties.NoWarn); - IList noWarn = noWarnString is not null ? MSBuildStringUtility.GetNuGetLogCodes(noWarnString) : Array.Empty(); + ImmutableArray noWarn = noWarnString is not null ? MSBuildStringUtility.GetNuGetLogCodes(noWarnString) : []; - var dependency = new LibraryDependency(noWarn) + (var includeType, var suppressParent) = MSBuildRestoreUtility.GetLibraryDependencyIncludeFlags( + includeAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.IncludeAssets), + excludeAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.ExcludeAssets), + privateAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.PrivateAssets)); + + var dependency = new LibraryDependency() { LibraryRange = new LibraryRange( name: item.Name, @@ -507,15 +567,13 @@ private static LibraryDependency ToPackageLibraryDependency(IVsReferenceItem2 it AutoReferenced = GetPropertyBoolOrFalse(item, "IsImplicitlyDefined"), GeneratePathProperty = GetPropertyBoolOrFalse(item, "GeneratePathProperty"), Aliases = GetPropertyValueOrNull(item, "Aliases"), - VersionOverride = versionOverrideRange + VersionOverride = versionOverrideRange, + NoWarn = noWarn, + IncludeType = includeType, + SuppressParent = suppressParent, + VersionCentrallyManaged = isCentrallyManaged, }; - MSBuildRestoreUtility.ApplyIncludeFlags( - dependency, - includeAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.IncludeAssets), - excludeAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.ExcludeAssets), - privateAssets: GetPropertyValueOrNull(item, ProjectBuildProperties.PrivateAssets)); - return dependency; } @@ -545,15 +603,19 @@ private static CentralPackageVersion ToCentralPackageVersion(IVsReferenceItem2 i return centralPackageVersion; } - private static void PopulateFrameworkDependencies(TargetFrameworkInformation tfi, IReadOnlyList frameworkReferences) + private static IReadOnlyCollection? PopulateFrameworkDependencies(IReadOnlyList frameworkReferences) { + HashSet? newReferences = null; foreach (var item in frameworkReferences) { - if (!tfi.FrameworkReferences.Any(e => ComparisonUtility.FrameworkReferenceNameComparer.Equals(e.Name, item.Name))) + newReferences ??= new HashSet(); + if (!newReferences.Any(e => ComparisonUtility.FrameworkReferenceNameComparer.Equals(e.Name, item.Name))) { - tfi.FrameworkReferences.Add(ToFrameworkDependency(item)); + newReferences.Add(ToFrameworkDependency(item)); } } + + return newReferences; } private static FrameworkDependency ToFrameworkDependency(IVsReferenceItem2 item) diff --git a/src/NuGet.Core/Microsoft.Build.NuGetSdkResolver/RestoreRunnerEx.cs b/src/NuGet.Core/Microsoft.Build.NuGetSdkResolver/RestoreRunnerEx.cs index 11f462c0dfa..25f5f4a73af 100644 --- a/src/NuGet.Core/Microsoft.Build.NuGetSdkResolver/RestoreRunnerEx.cs +++ b/src/NuGet.Core/Microsoft.Build.NuGetSdkResolver/RestoreRunnerEx.cs @@ -69,7 +69,7 @@ public static Task> RunWithoutCommit(LibraryIde { Dependencies = new List { - new LibraryDependency(noWarn: Array.Empty()) + new LibraryDependency() { LibraryRange = new LibraryRange( libraryIdentity.Name, diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs b/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs index 3dccf59d12d..eb4adb5d0f4 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs @@ -4,11 +4,13 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.Build.Construction; @@ -211,20 +213,26 @@ public bool WriteDependencyGraphSpec(string entryProjectFilePath, IDictionary /// The to get framework references for. /// A containing the framework references for the specified project. - internal static List GetFrameworkReferences(IMSBuildProject project) + internal static IReadOnlyCollection GetFrameworkReferences(IMSBuildProject project) { // Get the unique FrameworkReference items, ignoring duplicates List frameworkReferenceItems = GetDistinctItemsOrEmpty(project, "FrameworkReference").ToList(); + if (frameworkReferenceItems.Count == 0) + { + return null; + } + // For best performance, its better to create a list with the exact number of items needed rather than using a LINQ statement or AddRange. This is because if the list // is not allocated with enough items, the list has to be grown which can slow things down - var frameworkDependencies = new List(frameworkReferenceItems.Count); + var frameworkDependencies = new FrameworkDependency[frameworkReferenceItems.Count]; - foreach (var frameworkReferenceItem in frameworkReferenceItems) + for (int i = 0; i < frameworkReferenceItems.Count; i++) { + var frameworkReferenceItem = frameworkReferenceItems[i]; var privateAssets = MSBuildStringUtility.Split(frameworkReferenceItem.GetProperty("PrivateAssets")); - frameworkDependencies.Add(new FrameworkDependency(frameworkReferenceItem.Identity, FrameworkDependencyFlagsUtils.GetFlags(privateAssets))); + frameworkDependencies[i] = new FrameworkDependency(frameworkReferenceItem.Identity, FrameworkDependencyFlagsUtils.GetFlags(privateAssets)); } return frameworkDependencies; @@ -292,37 +300,57 @@ internal static Dictionary GetCentralPackageVersi /// The to get package references for. /// A flag for central package version management being enabled. /// A containing the package references for the specified project. - internal static List GetPackageReferences(IMSBuildProject project, bool isCentralPackageVersionManagementEnabled) + internal static ImmutableArray GetPackageReferences(IMSBuildProject project, bool isCentralPackageVersionManagementEnabled, IReadOnlyDictionary centralPackageVersions) { // Get the distinct PackageReference items, ignoring duplicates List packageReferenceItems = GetDistinctItemsOrEmpty(project, "PackageReference").ToList(); - var libraryDependencies = new List(packageReferenceItems.Count); + var libraryDependencies = new LibraryDependency[packageReferenceItems.Count]; - foreach (var packageReferenceItem in packageReferenceItems) + for (int i = 0; i < packageReferenceItems.Count; i++) { + var packageReferenceItem = packageReferenceItems[i]; + bool autoReferenced = packageReferenceItem.IsPropertyTrue("IsImplicitlyDefined"); string version = packageReferenceItem.GetProperty("Version"); - string versionOverride = packageReferenceItem.GetProperty("VersionOverride"); + VersionRange versionRange = string.IsNullOrWhiteSpace(version) ? null : VersionRange.Parse(version); + bool versionDefined = versionRange != null; + if (versionRange == null && !isCentralPackageVersionManagementEnabled) + { + versionRange = VersionRange.All; + } + + string versionOverrideString = packageReferenceItem.GetProperty("VersionOverride"); + var versionOverrideRange = string.IsNullOrWhiteSpace(versionOverrideString) ? null : VersionRange.Parse(versionOverrideString); - IList noWarn = MSBuildStringUtility.GetNuGetLogCodes(packageReferenceItem.GetProperty("NoWarn")); + CentralPackageVersion centralPackageVersion = null; + bool isCentrallyManaged = !versionDefined && !autoReferenced && isCentralPackageVersionManagementEnabled && versionOverrideRange == null && centralPackageVersions != null && centralPackageVersions.TryGetValue(packageReferenceItem.Identity, out centralPackageVersion); + if (isCentrallyManaged) + { + versionRange = centralPackageVersion.VersionRange; + } + versionRange = versionOverrideRange ?? versionRange; - libraryDependencies.Add(new LibraryDependency(noWarn) + ImmutableArray noWarn = MSBuildStringUtility.GetNuGetLogCodes(packageReferenceItem.GetProperty("NoWarn")); + + libraryDependencies[i] = new LibraryDependency() { - AutoReferenced = packageReferenceItem.IsPropertyTrue("IsImplicitlyDefined"), + AutoReferenced = autoReferenced, GeneratePathProperty = packageReferenceItem.IsPropertyTrue("GeneratePathProperty"), Aliases = packageReferenceItem.GetProperty("Aliases"), IncludeType = GetLibraryIncludeFlags(packageReferenceItem.GetProperty("IncludeAssets"), LibraryIncludeFlags.All) & ~GetLibraryIncludeFlags(packageReferenceItem.GetProperty("ExcludeAssets"), LibraryIncludeFlags.None), LibraryRange = new LibraryRange( packageReferenceItem.Identity, - string.IsNullOrWhiteSpace(version) ? isCentralPackageVersionManagementEnabled ? null : VersionRange.All : VersionRange.Parse(version), + versionRange, LibraryDependencyTarget.Package), SuppressParent = GetLibraryIncludeFlags(packageReferenceItem.GetProperty("PrivateAssets"), LibraryIncludeFlagUtils.DefaultSuppressParent), - VersionOverride = string.IsNullOrWhiteSpace(versionOverride) ? null : VersionRange.Parse(versionOverride), - }); + VersionOverride = versionOverrideRange, + NoWarn = noWarn, + VersionCentrallyManaged = isCentrallyManaged, + }; } - return libraryDependencies; + return ImmutableCollectionsMarshal.AsImmutableArray(libraryDependencies); } /// @@ -637,33 +665,36 @@ internal static List GetTargetFrameworkInfos(IReadOn clrSupport: msBuildProjectInstance.GetProperty("CLRSupport"), windowsTargetPlatformMinVersion: msBuildProjectInstance.GetProperty("WindowsTargetPlatformMinVersion")); - var targetFrameworkInformation = new TargetFrameworkInformation() - { - FrameworkName = targetFramework, - TargetAlias = targetAlias, - RuntimeIdentifierGraphPath = msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.RuntimeIdentifierGraphPath)) - }; - var packageTargetFallback = MSBuildStringUtility.Split(msBuildProjectInstance.GetProperty("PackageTargetFallback")).Select(NuGetFramework.Parse).ToList(); - var assetTargetFallback = MSBuildStringUtility.Split(msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.AssetTargetFallback))).Select(NuGetFramework.Parse).ToList(); - - AssetTargetFallbackUtility.EnsureValidFallback(packageTargetFallback, assetTargetFallback, msBuildProjectInstance.FullPath); - - AssetTargetFallbackUtility.ApplyFramework(targetFrameworkInformation, packageTargetFallback, assetTargetFallback); - - targetFrameworkInformation.Dependencies.AddRange(GetPackageReferences(msBuildProjectInstance, isCpvmEnabled)); + var assetTargetFallbackEnum = MSBuildStringUtility.Split(msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.AssetTargetFallback))).Select(NuGetFramework.Parse).ToList(); - targetFrameworkInformation.DownloadDependencies.AddRange(GetPackageDownloads(msBuildProjectInstance)); + AssetTargetFallbackUtility.EnsureValidFallback(packageTargetFallback, assetTargetFallbackEnum, msBuildProjectInstance.FullPath); - targetFrameworkInformation.FrameworkReferences.AddRange(GetFrameworkReferences(msBuildProjectInstance)); + (targetFramework, ImmutableArray imports, bool assetTargetFallback, bool warn) = AssetTargetFallbackUtility.GetFallbackFrameworkInformation(targetFramework, packageTargetFallback, assetTargetFallbackEnum); + IReadOnlyDictionary centralPackageVersions = null; if (isCpvmEnabled) { - targetFrameworkInformation.CentralPackageVersions.AddRange(GetCentralPackageVersions(msBuildProjectInstance)); - LibraryDependency.ApplyCentralVersionInformation(targetFrameworkInformation.Dependencies, targetFrameworkInformation.CentralPackageVersions); + centralPackageVersions = GetCentralPackageVersions(msBuildProjectInstance); } + var dependencies = GetPackageReferences(msBuildProjectInstance, isCpvmEnabled, centralPackageVersions); + + var targetFrameworkInformation = new TargetFrameworkInformation() + { + AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + DownloadDependencies = GetPackageDownloads(msBuildProjectInstance).ToImmutableArray(), + FrameworkName = targetFramework, + Imports = imports, + FrameworkReferences = GetFrameworkReferences(msBuildProjectInstance), + RuntimeIdentifierGraphPath = msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.RuntimeIdentifierGraphPath)), + TargetAlias = targetAlias, + Warn = warn + }; + targetFrameworkInfos.Add(targetFrameworkInformation); } diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs index 8dd7eb6e67f..6d32a0a4f45 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using NuGet.Commands; using NuGet.Common; using NuGet.Frameworks; @@ -889,7 +891,7 @@ private static void InitializeProjectDependencies( // https://github.com/NuGet/Home/issues/3891 // // For now, assume the project reference is a package dependency. - var projectDependency = new LibraryDependency(noWarn: Array.Empty()) + var projectDependency = new LibraryDependency() { LibraryRange = new LibraryRange( targetLibrary.Name, @@ -910,85 +912,143 @@ private void InitializePackageDependencies( ISet frameworkWithSuppressedDependencies) { var packageSpecificNoWarnProperties = new Dictionary>(StringComparer.OrdinalIgnoreCase); + var frameworks = assetsFile.PackageSpec.TargetFrameworks; // From the package spec, we know the direct package dependencies of this project. - foreach (TargetFrameworkInformation framework in assetsFile.PackageSpec.TargetFrameworks) + for (var i = 0; i < frameworks.Count; i++) { + var framework = frameworks[i]; + if (frameworkWithSuppressedDependencies.Contains(framework.FrameworkName)) { continue; } - IEnumerable centralTransitiveDependencies = assetsFile - .CentralTransitiveDependencyGroups - .Where(centralTDG => centralTDG.FrameworkName.Equals(framework.FrameworkName.ToString(), StringComparison.OrdinalIgnoreCase)) - .SelectMany(centralTDG => centralTDG.TransitiveDependencies); - - // First, add each of the generic package dependencies to the framework-specific list. - var packageDependencies = assetsFile - .PackageSpec - .Dependencies - .Concat(framework.Dependencies) - .Concat(centralTransitiveDependencies); + // First, add each of the generic package dependencies + AddDependencies(assetsFile.PackageSpec.Dependencies, dependenciesByFramework, framework, assetsFile, packageSpecificNoWarnProperties); - HashSet dependencies; - if (!dependenciesByFramework.TryGetValue(framework.FrameworkName, out dependencies)) - { - dependencies = new HashSet(); - dependenciesByFramework[framework.FrameworkName] = dependencies; - } + // Next, the framework-specific dependencies + var newFrameworkDependencies = AddDependencies(framework.Dependencies, dependenciesByFramework, framework, assetsFile, packageSpecificNoWarnProperties); + framework = new TargetFrameworkInformation(framework) { Dependencies = newFrameworkDependencies }; - // Add each package dependency. - foreach (var packageDependency in packageDependencies) + // Next, the central transitive dependencies + foreach (var centralTDG in assetsFile.CentralTransitiveDependencyGroups) { - // If we have a floating package dependency like 1.2.3-xyz-*, we - // use the version of the package that restore resolved it to. - if (packageDependency.LibraryRange.VersionRange.IsFloating) + if (centralTDG.FrameworkName.Equals(framework.FrameworkName.ToString(), StringComparison.OrdinalIgnoreCase)) { - var lockFileTarget = assetsFile.GetTarget(framework.FrameworkName, runtimeIdentifier: null); - var package = lockFileTarget.Libraries.First( - library => - string.Equals(library.Name, packageDependency.Name, StringComparison.OrdinalIgnoreCase)); - if (package != null) - { - if (packageDependency.LibraryRange.VersionRange.HasUpperBound) - { - packageDependency.LibraryRange.VersionRange = new VersionRange( - minVersion: package.Version, - includeMinVersion: packageDependency.LibraryRange.VersionRange.IsMinInclusive, - maxVersion: packageDependency.LibraryRange.VersionRange.MaxVersion, - includeMaxVersion: packageDependency.LibraryRange.VersionRange.IsMaxInclusive); - } - else - { - packageDependency.LibraryRange.VersionRange = new VersionRange( - minVersion: package.Version, - includeMinVersion: packageDependency.LibraryRange.VersionRange.IsMinInclusive); - } - } + AddDependencies(centralTDG.TransitiveDependencies.ToList(), dependenciesByFramework, framework, assetsFile, packageSpecificNoWarnProperties); } + } - if (packageDependency.NoWarn.Count > 0) - { - HashSet<(NuGetLogCode, NuGetFramework)> nowarnProperties = null; + frameworks[i] = framework; + } - if (!packageSpecificNoWarnProperties.TryGetValue(packageDependency.Name, out nowarnProperties)) - { - nowarnProperties = new HashSet<(NuGetLogCode, NuGetFramework)>(); - } + if (packageSpecificNoWarnProperties.Keys.Count > 0) + { + _packageSpecificWarningProperties = PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(packageSpecificNoWarnProperties); + } + } - nowarnProperties.AddRange(packageDependency.NoWarn.Select(n => (n, framework.FrameworkName))); - packageSpecificNoWarnProperties[packageDependency.Name] = nowarnProperties; - } + private static void AddDependencies( + IList packageDependencies, + Dictionary> dependenciesByFramework, + TargetFrameworkInformation framework, + LockFile assetsFile, + Dictionary> packageSpecificNoWarnProperties) + { + HashSet dependencies; + if (!dependenciesByFramework.TryGetValue(framework.FrameworkName, out dependencies)) + { + dependencies = new HashSet(); + dependenciesByFramework[framework.FrameworkName] = dependencies; + } + + // Add each package dependency. + for (int i = 0; i < packageDependencies.Count; i++) + { + var updatedPackageDependency = GetUpdatedPackageDependency(packageDependencies[i], assetsFile, framework, packageSpecificNoWarnProperties, dependencies); + packageDependencies[i] = updatedPackageDependency; + } + } - PackCommandRunner.AddLibraryDependency(packageDependency, dependencies); + private static ImmutableArray AddDependencies( + ImmutableArray packageDependencies, + Dictionary> dependenciesByFramework, + TargetFrameworkInformation framework, + LockFile assetsFile, + Dictionary> packageSpecificNoWarnProperties) + { + HashSet dependencies; + if (!dependenciesByFramework.TryGetValue(framework.FrameworkName, out dependencies)) + { + dependencies = new HashSet(); + dependenciesByFramework[framework.FrameworkName] = dependencies; + } + + LibraryDependency[] updatedDependencies = new LibraryDependency[packageDependencies.Length]; + + // Add each package dependency. + for (var i = 0; i < packageDependencies.Length; i++) + { + var updatedPackageDependency = GetUpdatedPackageDependency(packageDependencies[i], assetsFile, framework, packageSpecificNoWarnProperties, dependencies); + updatedDependencies[i] = updatedPackageDependency; + } + + return ImmutableCollectionsMarshal.AsImmutableArray(updatedDependencies); + } + + private static LibraryDependency GetUpdatedPackageDependency( + LibraryDependency packageDependency, + LockFile assetsFile, + TargetFrameworkInformation framework, + Dictionary> packageSpecificNoWarnProperties, + HashSet dependencies) + { + // If we have a floating package dependency like 1.2.3-xyz-*, we + // use the version of the package that restore resolved it to. + if (packageDependency.LibraryRange.VersionRange.IsFloating) + { + var lockFileTarget = assetsFile.GetTarget(framework.FrameworkName, runtimeIdentifier: null); + var package = lockFileTarget.Libraries.First( + library => + string.Equals(library.Name, packageDependency.Name, StringComparison.OrdinalIgnoreCase)); + + VersionRange versionRange; + if (packageDependency.LibraryRange.VersionRange.HasUpperBound) + { + versionRange = new VersionRange( + minVersion: package.Version, + includeMinVersion: packageDependency.LibraryRange.VersionRange.IsMinInclusive, + maxVersion: packageDependency.LibraryRange.VersionRange.MaxVersion, + includeMaxVersion: packageDependency.LibraryRange.VersionRange.IsMaxInclusive); } + else + { + versionRange = new VersionRange( + minVersion: package.Version, + includeMinVersion: packageDependency.LibraryRange.VersionRange.IsMinInclusive); + } + + var libraryRange = new LibraryRange(packageDependency.LibraryRange) { VersionRange = versionRange }; + packageDependency = new LibraryDependency(packageDependency) { LibraryRange = libraryRange }; } - if (packageSpecificNoWarnProperties.Keys.Count > 0) + if (packageDependency.NoWarn.Length > 0) { - _packageSpecificWarningProperties = PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(packageSpecificNoWarnProperties); + HashSet<(NuGetLogCode, NuGetFramework)> nowarnProperties = null; + + if (!packageSpecificNoWarnProperties.TryGetValue(packageDependency.Name, out nowarnProperties)) + { + nowarnProperties = new HashSet<(NuGetLogCode, NuGetFramework)>(); + } + + nowarnProperties.AddRange(packageDependency.NoWarn.Select(n => (n, framework.FrameworkName))); + packageSpecificNoWarnProperties[packageDependency.Name] = nowarnProperties; } + + PackCommandRunner.AddLibraryDependency(packageDependency, dependencies); + + return packageDependency; } private static IDictionary ParsePropertiesAsDictionary(string[] properties) diff --git a/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs b/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs index 347e1ff3e24..894795fa2ee 100644 --- a/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs +++ b/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/AddPackageReferenceCommandRunner.cs @@ -19,6 +19,7 @@ using NuGet.Packaging.Core; using NuGet.ProjectModel; using NuGet.Protocol.Core.Types; +using NuGet.Shared; using NuGet.Versioning; namespace NuGet.CommandLine.XPlat @@ -49,7 +50,7 @@ public async Task ExecuteCommand(PackageReferenceArgs packageReferenceArgs, versionRange = VersionRange.Parse(packageReferenceArgs.PackageVersion); } - var libraryDependency = new LibraryDependency(noWarn: Array.Empty()) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange( name: packageReferenceArgs.PackageId, @@ -320,31 +321,41 @@ private static LibraryDependency GenerateLibraryDependency( if (developmentDependency) { - foreach (var frameworkInfo in project.TargetFrameworks - .OrderBy(framework => framework.FrameworkName.ToString(), - StringComparer.Ordinal)) + var orderedFrameworksWithOriginalIndex = project.TargetFrameworks + .Select((frameworkInfo, originalIndex) => (frameworkInfo, originalIndex)) + .OrderBy(tuple => tuple.frameworkInfo.FrameworkName.ToString(), StringComparer.Ordinal); + + foreach (var (frameworkInfo, originalIndex) in orderedFrameworksWithOriginalIndex) { - var dependency = frameworkInfo.Dependencies.First( - dep => dep.Name.Equals(packageReferenceArgs.PackageId, StringComparison.OrdinalIgnoreCase)); + var index = frameworkInfo.Dependencies.FirstIndex(dep => dep.Name.Equals(packageReferenceArgs.PackageId, StringComparison.OrdinalIgnoreCase)); + var dependency = frameworkInfo.Dependencies[index]; + var includeType = dependency.IncludeType; + var suppressParent = dependency.SuppressParent; // if suppressParent and IncludeType aren't set by user, then only update those as per dev dependency - if (dependency?.SuppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent && - dependency?.IncludeType == LibraryIncludeFlags.All) + if (suppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent && + includeType == LibraryIncludeFlags.All) { - dependency.SuppressParent = LibraryIncludeFlags.All; - dependency.IncludeType = LibraryIncludeFlags.All & ~LibraryIncludeFlags.Compile; + suppressParent = LibraryIncludeFlags.All; + includeType = LibraryIncludeFlags.All & ~LibraryIncludeFlags.Compile; } - if (dependency != null) + dependency = new LibraryDependency(dependency) { - dependency.LibraryRange.VersionRange = version; - dependency.VersionCentrallyManaged = isCentralPackageManagementEnabled; - return dependency; - } + IncludeType = includeType, + LibraryRange = new LibraryRange(dependency.LibraryRange) { VersionRange = version }, + SuppressParent = suppressParent, + VersionCentrallyManaged = isCentralPackageManagementEnabled, + }; + + var newDependencies = frameworkInfo.Dependencies.SetItem(index, dependency); + project.TargetFrameworks[originalIndex] = new TargetFrameworkInformation(frameworkInfo) { Dependencies = newDependencies }; + + return dependency; } } - return new LibraryDependency(noWarn: Array.Empty()) + return new LibraryDependency() { LibraryRange = new LibraryRange( name: packageReferenceArgs.PackageId, diff --git a/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/RemovePackageReferenceCommandRunner.cs b/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/RemovePackageReferenceCommandRunner.cs index a6056449bf4..079ec18892d 100644 --- a/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/RemovePackageReferenceCommandRunner.cs +++ b/src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/PackageReferenceCommands/RemovePackageReferenceCommandRunner.cs @@ -1,10 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Globalization; using System.Threading.Tasks; -using NuGet.Common; using NuGet.Credentials; using NuGet.LibraryModel; using NuGet.Versioning; @@ -23,7 +21,7 @@ public Task ExecuteCommand(PackageReferenceArgs packageReferenceArgs, MSBui //Setup the Credential Service - This allows the msbuild sdk resolver to auth if needed. DefaultCredentialServiceUtility.SetupDefaultCredentialService(packageReferenceArgs.Logger, !packageReferenceArgs.Interactive); - var libraryDependency = new LibraryDependency(noWarn: Array.Empty()) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange( name: packageReferenceArgs.PackageId, diff --git a/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj b/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj index 8cb88f94ec5..35bccec8c6d 100644 --- a/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj +++ b/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj @@ -54,6 +54,7 @@ + diff --git a/src/NuGet.Core/NuGet.Commands/CommandRunners/PackCommandRunner.cs b/src/NuGet.Core/NuGet.Commands/CommandRunners/PackCommandRunner.cs index 91f4dd14300..9cdb2be425f 100644 --- a/src/NuGet.Core/NuGet.Commands/CommandRunners/PackCommandRunner.cs +++ b/src/NuGet.Core/NuGet.Commands/CommandRunners/PackCommandRunner.cs @@ -1252,7 +1252,7 @@ public static void AddLibraryDependency(LibraryDependency dependency, ISet()) + list.Add(new LibraryDependency() { LibraryRange = new LibraryRange(matchingDependency.Name, newVersionRange, LibraryDependencyTarget.All), IncludeType = dependency.IncludeType & matchingDependency.IncludeType, diff --git a/src/NuGet.Core/NuGet.Commands/GlobalSuppressions.cs b/src/NuGet.Core/NuGet.Commands/GlobalSuppressions.cs index 8fc31cbf261..975a58554a8 100644 --- a/src/NuGet.Core/NuGet.Commands/GlobalSuppressions.cs +++ b/src/NuGet.Core/NuGet.Commands/GlobalSuppressions.cs @@ -34,7 +34,6 @@ [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void MatcherExtensions.AddIncludePatterns(Matcher matcher, params IEnumerable[] includePatternsGroups)', validate parameter 'matcher' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:Microsoft.Extensions.FileSystemGlobbing.MatcherExtensions.AddIncludePatterns(Microsoft.Extensions.FileSystemGlobbing.Matcher,System.Collections.Generic.IEnumerable{System.String}[])")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'IEnumerable MatcherExtensions.GetResultsInFullPath(Matcher matcher, string directoryPath)', validate parameter 'matcher' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:Microsoft.Extensions.FileSystemGlobbing.MatcherExtensions.GetResultsInFullPath(Microsoft.Extensions.FileSystemGlobbing.Matcher,System.String)~System.Collections.Generic.IEnumerable{System.String}")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void AddSourceRunner.Run(AddSourceArgs args, Func getLogger)', validate parameter 'args' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.AddSourceRunner.Run(NuGet.Commands.AddSourceArgs,System.Func{NuGet.Common.ILogger})")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void AssetTargetFallbackUtility.ApplyFramework(TargetFrameworkInformation targetFrameworkInfo, IEnumerable packageTargetFallback, IEnumerable assetTargetFallback)', validate parameter 'targetFrameworkInfo' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.AssetTargetFallbackUtility.ApplyFramework(NuGet.ProjectModel.TargetFrameworkInformation,System.Collections.Generic.IEnumerable{NuGet.Frameworks.NuGetFramework},System.Collections.Generic.IEnumerable{NuGet.Frameworks.NuGetFramework})")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void BuildAssetsUtils.AddNuGetProperties(XDocument doc, IEnumerable packageFolders, string repositoryRoot, ProjectStyle projectStyle, string assetsFilePath, bool success)', validate parameter 'doc' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.BuildAssetsUtils.AddNuGetProperties(System.Xml.Linq.XDocument,System.Collections.Generic.IEnumerable{System.String},System.String,NuGet.ProjectModel.ProjectStyle,System.String,System.Boolean)")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'XElement BuildAssetsUtils.GenerateContentFilesItem(string path, LockFileContentFile item, string packageId, string packageVersion)', validate parameter 'item' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.BuildAssetsUtils.GenerateContentFilesItem(System.String,NuGet.ProjectModel.LockFileContentFile,System.String,System.String)~System.Xml.Linq.XElement")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'string BuildAssetsUtils.GetLanguage(string nugetLanguage)', validate parameter 'nugetLanguage' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.BuildAssetsUtils.GetLanguage(System.String)~System.String")] @@ -71,8 +70,6 @@ [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'PackageBuilder MSBuildProjectFactory.CreateBuilder(string basePath, NuGetVersion version, string suffix, bool buildIfNeeded, PackageBuilder builder)', validate parameter 'builder' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildProjectFactory.CreateBuilder(System.String,NuGet.Versioning.NuGetVersion,System.String,System.Boolean,NuGet.Packaging.PackageBuilder)~NuGet.Packaging.PackageBuilder")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'IProjectFactory MSBuildProjectFactory.ProjectCreator(PackArgs packArgs, string path)', validate parameter 'packArgs' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildProjectFactory.ProjectCreator(NuGet.Commands.PackArgs,System.String)~NuGet.Commands.IProjectFactory")] [assembly: SuppressMessage("Build", "CA1801:Parameter path of method ProjectCreator is never used. Remove the parameter or use it in the method body.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildProjectFactory.ProjectCreator(NuGet.Commands.PackArgs,System.String)~NuGet.Commands.IProjectFactory")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void MSBuildRestoreUtility.ApplyIncludeFlags(LibraryDependency dependency, string includeAssets, string excludeAssets, string privateAssets)', validate parameter 'dependency' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.LibraryModel.LibraryDependency,System.String,System.String,System.String)")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void MSBuildRestoreUtility.ApplyIncludeFlags(ProjectRestoreReference dependency, string includeAssets, string excludeAssets, string privateAssets)', validate parameter 'dependency' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.ProjectModel.ProjectRestoreReference,System.String,System.String,System.String)")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void MSBuildRestoreUtility.Dump(IEnumerable items, ILogger log)', validate parameter 'items' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildRestoreUtility.Dump(System.Collections.Generic.IEnumerable{NuGet.Commands.IMSBuildItem},NuGet.Common.ILogger)")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'string MSBuildRestoreUtility.FixSourcePath(string s)', validate parameter 's' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildRestoreUtility.FixSourcePath(System.String)~System.String")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'bool MSBuildRestoreUtility.LogErrorForClearIfInvalid(IEnumerable values, string projectPath, ILogger logger)', validate parameter 'logger' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.MSBuildRestoreUtility.LogErrorForClearIfInvalid(System.Collections.Generic.IEnumerable{System.String},System.String,NuGet.Common.ILogger)~System.Boolean")] @@ -87,8 +84,6 @@ [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'PackagesLockFile PackagesLockFileBuilder.CreateNuGetLockFile(LockFile assetsFile)', validate parameter 'assetsFile' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackagesLockFileBuilder.CreateNuGetLockFile(NuGet.ProjectModel.LockFile)~NuGet.ProjectModel.PackagesLockFile")] [assembly: SuppressMessage("Build", "CA1822:Member CreateNuGetLockFile does not access instance data and can be marked as static (Shared in VisualBasic)", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackagesLockFileBuilder.CreateNuGetLockFile(NuGet.ProjectModel.LockFile)~NuGet.ProjectModel.PackagesLockFile")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'string PackageSourceProviderExtensions.ResolveAndValidateSource(IPackageSourceProvider sourceProvider, string source)', validate parameter 'sourceProvider' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackageSourceProviderExtensions.ResolveAndValidateSource(NuGet.Configuration.IPackageSourceProvider,System.String)~System.String")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void PackageSpecificWarningProperties.AddRangeOfCodes(IEnumerable codes, string libraryId, NuGetFramework framework)', validate parameter 'codes' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackageSpecificWarningProperties.AddRangeOfCodes(System.Collections.Generic.IEnumerable{NuGet.Common.NuGetLogCode},System.String,NuGet.Frameworks.NuGetFramework)")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void PackageSpecificWarningProperties.AddRangeOfFrameworks(NuGetLogCode code, string libraryId, IEnumerable frameworks)', validate parameter 'frameworks' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackageSpecificWarningProperties.AddRangeOfFrameworks(NuGet.Common.NuGetLogCode,System.String,System.Collections.Generic.IEnumerable{NuGet.Frameworks.NuGetFramework})")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'PackageSpecificWarningProperties PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(PackageSpec packageSpec)', validate parameter 'packageSpec' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(NuGet.ProjectModel.PackageSpec)~NuGet.Commands.PackageSpecificWarningProperties")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'PackageSpecificWarningProperties PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(PackageSpec packageSpec, NuGetFramework framework)', validate parameter 'packageSpec' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackageSpecificWarningProperties.CreatePackageSpecificWarningProperties(NuGet.ProjectModel.PackageSpec,NuGet.Frameworks.NuGetFramework)~NuGet.Commands.PackageSpecificWarningProperties")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void PackCollectorLogger.Log(ILogMessage message)', validate parameter 'message' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Commands.PackCollectorLogger.Log(NuGet.Common.ILogMessage)")] diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Shipped.txt index 98dfd1823fc..67886ad9654 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Shipped.txt @@ -879,7 +879,6 @@ override NuGet.Commands.TransitiveNoWarnUtils.NodeWarningProperties.GetHashCode( override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.AddClientCertRunner.Run(NuGet.Commands.AddClientCertArgs args, System.Func getLogger) -> void ~static NuGet.Commands.AddSourceRunner.Run(NuGet.Commands.AddSourceArgs args, System.Func getLogger) -> void -~static NuGet.Commands.AssetTargetFallbackUtility.ApplyFramework(NuGet.ProjectModel.TargetFrameworkInformation targetFrameworkInfo, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.EnsureValidFallback(System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback, string filePath) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFramework(NuGet.Frameworks.NuGetFramework projectFramework, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> NuGet.Frameworks.NuGetFramework ~static NuGet.Commands.AssetTargetFallbackUtility.GetInvalidFallbackCombinationMessage(string path) -> NuGet.Common.RestoreLogMessage @@ -946,7 +945,6 @@ override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFrameworks(System.Collections.Generic.IEnumerable frameworkStrings) -> System.Collections.Generic.IEnumerable ~static NuGet.Commands.MSBuildRestoreItemGroup.Create(string rootName, System.Collections.Generic.IEnumerable items, int position, System.Collections.Generic.IEnumerable conditions) -> NuGet.Commands.MSBuildRestoreItemGroup ~static NuGet.Commands.MSBuildRestoreUtility.AggregateSources(System.Collections.Generic.IEnumerable values, System.Collections.Generic.IEnumerable excludeValues) -> System.Collections.Generic.IEnumerable -~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.LibraryModel.LibraryDependency dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.ProjectModel.ProjectRestoreReference dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ContainsClearKeyword(System.Collections.Generic.IEnumerable values) -> bool ~static NuGet.Commands.MSBuildRestoreUtility.Dump(System.Collections.Generic.IEnumerable items, NuGet.Common.ILogger log) -> void diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt index 4c2791b2d81..4b8ebd75924 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ #nullable enable NuGet.Commands.RestoreSummary.AuditRan.get -> bool +~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFrameworkInformation(NuGet.Frameworks.NuGetFramework originalFrameworkName, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallbackEnum) -> (NuGet.Frameworks.NuGetFramework frameworkName, System.Collections.Immutable.ImmutableArray imports, bool assetTargetFallback, bool warn) +~static NuGet.Commands.MSBuildRestoreUtility.GetLibraryDependencyIncludeFlags(string includeAssets, string excludeAssets, string privateAssets) -> (NuGet.LibraryModel.LibraryIncludeFlags includeType, NuGet.LibraryModel.LibraryIncludeFlags suppressParent) diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Shipped.txt index b95907e24d3..52cb34d10f4 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Shipped.txt @@ -878,7 +878,6 @@ override NuGet.Commands.TransitiveNoWarnUtils.NodeWarningProperties.GetHashCode( override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.AddClientCertRunner.Run(NuGet.Commands.AddClientCertArgs args, System.Func getLogger) -> void ~static NuGet.Commands.AddSourceRunner.Run(NuGet.Commands.AddSourceArgs args, System.Func getLogger) -> void -~static NuGet.Commands.AssetTargetFallbackUtility.ApplyFramework(NuGet.ProjectModel.TargetFrameworkInformation targetFrameworkInfo, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.EnsureValidFallback(System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback, string filePath) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFramework(NuGet.Frameworks.NuGetFramework projectFramework, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> NuGet.Frameworks.NuGetFramework ~static NuGet.Commands.AssetTargetFallbackUtility.GetInvalidFallbackCombinationMessage(string path) -> NuGet.Common.RestoreLogMessage @@ -945,7 +944,6 @@ override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFrameworks(System.Collections.Generic.IEnumerable frameworkStrings) -> System.Collections.Generic.IEnumerable ~static NuGet.Commands.MSBuildRestoreItemGroup.Create(string rootName, System.Collections.Generic.IEnumerable items, int position, System.Collections.Generic.IEnumerable conditions) -> NuGet.Commands.MSBuildRestoreItemGroup ~static NuGet.Commands.MSBuildRestoreUtility.AggregateSources(System.Collections.Generic.IEnumerable values, System.Collections.Generic.IEnumerable excludeValues) -> System.Collections.Generic.IEnumerable -~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.LibraryModel.LibraryDependency dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.ProjectModel.ProjectRestoreReference dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ContainsClearKeyword(System.Collections.Generic.IEnumerable values) -> bool ~static NuGet.Commands.MSBuildRestoreUtility.Dump(System.Collections.Generic.IEnumerable items, NuGet.Common.ILogger log) -> void diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 4c2791b2d81..4b8ebd75924 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ #nullable enable NuGet.Commands.RestoreSummary.AuditRan.get -> bool +~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFrameworkInformation(NuGet.Frameworks.NuGetFramework originalFrameworkName, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallbackEnum) -> (NuGet.Frameworks.NuGetFramework frameworkName, System.Collections.Immutable.ImmutableArray imports, bool assetTargetFallback, bool warn) +~static NuGet.Commands.MSBuildRestoreUtility.GetLibraryDependencyIncludeFlags(string includeAssets, string excludeAssets, string privateAssets) -> (NuGet.LibraryModel.LibraryIncludeFlags includeType, NuGet.LibraryModel.LibraryIncludeFlags suppressParent) diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index 37ec946cccc..9102caba71c 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -877,7 +877,6 @@ override NuGet.Commands.TransitiveNoWarnUtils.NodeWarningProperties.GetHashCode( override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.AddClientCertRunner.Run(NuGet.Commands.AddClientCertArgs args, System.Func getLogger) -> void ~static NuGet.Commands.AddSourceRunner.Run(NuGet.Commands.AddSourceArgs args, System.Func getLogger) -> void -~static NuGet.Commands.AssetTargetFallbackUtility.ApplyFramework(NuGet.ProjectModel.TargetFrameworkInformation targetFrameworkInfo, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.EnsureValidFallback(System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback, string filePath) -> void ~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFramework(NuGet.Frameworks.NuGetFramework projectFramework, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallback) -> NuGet.Frameworks.NuGetFramework ~static NuGet.Commands.AssetTargetFallbackUtility.GetInvalidFallbackCombinationMessage(string path) -> NuGet.Common.RestoreLogMessage @@ -944,7 +943,6 @@ override NuGet.Commands.WarningPropertiesCollection.GetHashCode() -> int ~static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFrameworks(System.Collections.Generic.IEnumerable frameworkStrings) -> System.Collections.Generic.IEnumerable ~static NuGet.Commands.MSBuildRestoreItemGroup.Create(string rootName, System.Collections.Generic.IEnumerable items, int position, System.Collections.Generic.IEnumerable conditions) -> NuGet.Commands.MSBuildRestoreItemGroup ~static NuGet.Commands.MSBuildRestoreUtility.AggregateSources(System.Collections.Generic.IEnumerable values, System.Collections.Generic.IEnumerable excludeValues) -> System.Collections.Generic.IEnumerable -~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.LibraryModel.LibraryDependency dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ApplyIncludeFlags(NuGet.ProjectModel.ProjectRestoreReference dependency, string includeAssets, string excludeAssets, string privateAssets) -> void ~static NuGet.Commands.MSBuildRestoreUtility.ContainsClearKeyword(System.Collections.Generic.IEnumerable values) -> bool ~static NuGet.Commands.MSBuildRestoreUtility.Dump(System.Collections.Generic.IEnumerable items, NuGet.Common.ILogger log) -> void diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 4c2791b2d81..4b8ebd75924 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ #nullable enable NuGet.Commands.RestoreSummary.AuditRan.get -> bool +~static NuGet.Commands.AssetTargetFallbackUtility.GetFallbackFrameworkInformation(NuGet.Frameworks.NuGetFramework originalFrameworkName, System.Collections.Generic.IEnumerable packageTargetFallback, System.Collections.Generic.IEnumerable assetTargetFallbackEnum) -> (NuGet.Frameworks.NuGetFramework frameworkName, System.Collections.Immutable.ImmutableArray imports, bool assetTargetFallback, bool warn) +~static NuGet.Commands.MSBuildRestoreUtility.GetLibraryDependencyIncludeFlags(string includeAssets, string excludeAssets, string privateAssets) -> (NuGet.LibraryModel.LibraryIncludeFlags includeType, NuGet.LibraryModel.LibraryIncludeFlags suppressParent) diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/DependencyGraphResolver.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/DependencyGraphResolver.cs index ecf679b895d..cae34ef4023 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/DependencyGraphResolver.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/DependencyGraphResolver.cs @@ -234,9 +234,7 @@ async static (state) => { importRefItem.LibraryRangeIndex = currentRefRangeIndex = libraryRangeInterningTable.Intern(libraryRange); - currentRef = currentRef.Clone(); - - currentRef.LibraryRange = libraryRange; + currentRef = new LibraryDependency(currentRef) { LibraryRange = libraryRange }; importRefItem.LibraryDependency = currentRef; @@ -654,9 +652,10 @@ async static (state) => if (isCentrallyPinnedTransitiveDependency) { - actualLibraryDependency = dep.Clone(); - - actualLibraryDependency.LibraryRange.VersionRange = pinnedVersionRange; + actualLibraryDependency = new LibraryDependency(dep) + { + LibraryRange = new LibraryRange(actualLibraryDependency.LibraryRange) { VersionRange = pinnedVersionRange }, + }; isCentrallyPinnedTransitiveDependency = true; diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs index a902fab36d0..bbe9dfcd8fc 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs @@ -549,7 +549,7 @@ private IEnumerable GetLibraryDependenciesForCentralTransitiv // If all assets are suppressed then the dependency should not be added if (suppressParent != LibraryIncludeFlags.All) { - yield return new LibraryDependency(noWarn: Array.Empty()) + yield return new LibraryDependency() { LibraryRange = new LibraryRange(centralPackageVersion.Name, centralPackageVersion.VersionRange, LibraryDependencyTarget.Package), ReferenceType = LibraryDependencyReferenceType.Transitive, diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs index 655e39d5875..7ac7f5d37f8 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using NuGet.Common; using NuGet.DependencyResolver; @@ -222,7 +223,7 @@ private static PackageSpecificWarningProperties ExtractTransitiveNoWarnPropertie // At the end of the graph traversal add the remaining package no warn lists into the result foreach ((var packageId, var codes) in packageNoWarn) { - resultWarningProperties.AddRangeOfCodes(codes, packageId, parentTargetFramework); + resultWarningProperties.AddRangeOfCodes(codes.ToImmutableArray(), packageId, parentTargetFramework); } return resultWarningProperties; diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs index fd5b757f6af..a046fd1a0bd 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs @@ -229,12 +229,12 @@ internal static async Task DownloadDepende async Task ResolveDownloadDependenciesAsync(RemoteWalkContext context, TargetFrameworkInformation targetFrameworkInformation, CancellationToken token) { - if (targetFrameworkInformation.DownloadDependencies.Count == 0) + if (targetFrameworkInformation.DownloadDependencies.Length == 0) { return DownloadDependencyResolutionResult.Create(targetFrameworkInformation.FrameworkName, Array.Empty>(), context.RemoteLibraryProviders); } - List>> packageDownloadTasks = new(capacity: targetFrameworkInformation.DownloadDependencies.Count); + List>> packageDownloadTasks = new(capacity: targetFrameworkInformation.DownloadDependencies.Length); foreach (var downloadDependency in targetFrameworkInformation.DownloadDependencies.NoAllocEnumerate()) { diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/LockFileUtils.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/LockFileUtils.cs index f1fa1bd1489..a1ba4b8e609 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/LockFileUtils.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/LockFileUtils.cs @@ -657,7 +657,7 @@ public static LockFileTargetLibrary CreateLockFileTargetProject( out frameworkReferencesObject)) { projectLib.FrameworkReferences.AddRange( - ((ISet)frameworkReferencesObject) + ((IReadOnlyCollection)frameworkReferencesObject) .Where(e => e.PrivateAssets != FrameworkDependencyFlags.All) .Select(f => f.Name)); } diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs index bd2ba17fef5..6a8c012e4f5 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -131,13 +132,15 @@ public static DependencyGraphSpec GetDependencySpec(IEnumerable it /// /// Insert asset flags into dependency, based on ;-delimited string args /// - public static void ApplyIncludeFlags(LibraryDependency dependency, string includeAssets, string excludeAssets, string privateAssets) + public static (LibraryIncludeFlags includeType, LibraryIncludeFlags suppressParent) GetLibraryDependencyIncludeFlags(string includeAssets, string excludeAssets, string privateAssets) { var includeFlags = GetIncludeFlags(includeAssets, LibraryIncludeFlags.All); var excludeFlags = GetIncludeFlags(excludeAssets, LibraryIncludeFlags.None); - dependency.IncludeType = includeFlags & ~excludeFlags; - dependency.SuppressParent = GetIncludeFlags(privateAssets, LibraryIncludeFlagUtils.DefaultSuppressParent); + var includeType = includeFlags & ~excludeFlags; + var suppressParent = GetIncludeFlags(privateAssets, LibraryIncludeFlagUtils.DefaultSuppressParent); + + return (includeType, suppressParent); } /// @@ -145,6 +148,7 @@ public static void ApplyIncludeFlags(LibraryDependency dependency, string includ /// public static void ApplyIncludeFlags(ProjectRestoreReference dependency, string includeAssets, string excludeAssets, string privateAssets) { + if (dependency == null) throw new ArgumentNullException(nameof(dependency)); dependency.IncludeAssets = GetIncludeFlags(includeAssets, LibraryIncludeFlags.All); dependency.ExcludeAssets = GetIncludeFlags(excludeAssets, LibraryIncludeFlags.None); dependency.PrivateAssets = GetIncludeFlags(privateAssets, LibraryIncludeFlagUtils.DefaultSuppressParent); @@ -474,11 +478,11 @@ private static IEnumerable GetTargetFrameworkInforma clrSupport: clrSupport, windowsTargetPlatformMinVersion: windowsTargetPlatformMinVersion); - var targetFrameworkInfo = new TargetFrameworkInformation() - { - FrameworkName = targetFramework, - TargetAlias = targetAlias - }; + string runtimeIdentifierGraphPath = null; + ImmutableArray imports = []; + bool assetTargetFallback = false; + bool warn = false; + if (restoreType == ProjectStyle.PackageReference || restoreType == ProjectStyle.Standalone || restoreType == ProjectStyle.DotnetToolReference) @@ -487,18 +491,29 @@ private static IEnumerable GetTargetFrameworkInforma .Select(NuGetFramework.Parse) .ToList(); - var assetTargetFallback = MSBuildStringUtility.Split(item.GetProperty(AssetTargetFallbackUtility.AssetTargetFallback)) + var assetTargetFallbackList = MSBuildStringUtility.Split(item.GetProperty(AssetTargetFallbackUtility.AssetTargetFallback)) .Select(NuGetFramework.Parse) .ToList(); // Throw if an invalid combination was used. - AssetTargetFallbackUtility.EnsureValidFallback(packageTargetFallback, assetTargetFallback, filePath); + AssetTargetFallbackUtility.EnsureValidFallback(packageTargetFallback, assetTargetFallbackList, filePath); // Update the framework appropriately - AssetTargetFallbackUtility.ApplyFramework(targetFrameworkInfo, packageTargetFallback, assetTargetFallback); + (targetFramework, imports, assetTargetFallback, warn) = AssetTargetFallbackUtility.GetFallbackFrameworkInformation(targetFramework, packageTargetFallback, assetTargetFallbackList); - targetFrameworkInfo.RuntimeIdentifierGraphPath = item.GetProperty("RuntimeIdentifierGraphPath"); + runtimeIdentifierGraphPath = item.GetProperty("RuntimeIdentifierGraphPath"); } + + var targetFrameworkInfo = new TargetFrameworkInformation() + { + AssetTargetFallback = assetTargetFallback, + FrameworkName = targetFramework, + Imports = imports, + RuntimeIdentifierGraphPath = runtimeIdentifierGraphPath, + TargetAlias = targetAlias, + Warn = warn + }; + yield return targetFrameworkInfo; } } @@ -608,38 +623,31 @@ private static Tuple, ProjectRestoreReference> GetProjectRestoreRef private static bool AddDownloadDependencyIfNotExist(PackageSpec spec, string targetAlias, DownloadDependency dependency) { - TargetFrameworkInformation frameworkInfo = spec.TargetFrameworks.Single(e => e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + var index = spec.TargetFrameworks.SingleIndex(e => e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + var frameworkInfo = spec.TargetFrameworks[index]; if (!frameworkInfo.DownloadDependencies.Contains(dependency)) { - frameworkInfo.DownloadDependencies.Add(dependency); + var newDownloadDependencies = frameworkInfo.DownloadDependencies.Add(dependency); + spec.TargetFrameworks[index] = new TargetFrameworkInformation(frameworkInfo) { DownloadDependencies = newDownloadDependencies }; return true; } return false; } - private static bool AddDependencyIfNotExist(PackageSpec spec, LibraryDependency dependency) - { - foreach (var targetAlias in spec.TargetFrameworks.Select(e => e.TargetAlias)) - { - AddDependencyIfNotExist(spec, targetAlias, dependency); - } - - return false; - } - - private static bool AddDependencyIfNotExist(PackageSpec spec, string targetAlias, LibraryDependency dependency) { - var frameworkInfo = spec.TargetFrameworks.Single(e => e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + var index = spec.TargetFrameworks.SingleIndex(e => e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + var frameworkInfo = spec.TargetFrameworks[index]; + var dependencies = frameworkInfo.Dependencies; if (!spec.Dependencies - .Concat(frameworkInfo.Dependencies) + .Concat(dependencies) .Select(d => d.Name) .Contains(dependency.Name, StringComparer.OrdinalIgnoreCase)) { - frameworkInfo.Dependencies.Add(dependency); + spec.TargetFrameworks[index] = new TargetFrameworkInformation(frameworkInfo) { Dependencies = dependencies.Add(dependency) }; return true; } @@ -649,44 +657,70 @@ private static bool AddDependencyIfNotExist(PackageSpec spec, string targetAlias private static void AddPackageReferences(PackageSpec spec, IEnumerable items, bool isCpvmEnabled) { + if (isCpvmEnabled) + { + AddCentralPackageVersions(spec, items); + } + + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var targetFramework in spec.TargetFrameworks) + { + dict.Add(targetFramework.TargetAlias, targetFramework); + } + foreach (var item in GetItemByType(items, "Dependency")) { // Get warning suppressions - IList noWarn = MSBuildStringUtility.GetNuGetLogCodes(item.GetProperty("NoWarn")); - - var dependency = new LibraryDependency(noWarn) + var noWarn = MSBuildStringUtility.GetNuGetLogCodes(item.GetProperty("NoWarn")); + (var includeType, var suppressParent) = GetLibraryDependencyIncludeFlags(item); + IEnumerable frameworks = GetFrameworks(item); + string name = item.GetProperty("Id"); + bool autoReferenced = IsPropertyTrue(item, "IsImplicitlyDefined"); + VersionRange versionOverrideRange = GetVersionRange(item, defaultValue: null, "VersionOverride"); + + VersionRange versionRange = GetVersionRange(item, defaultValue: isCpvmEnabled ? null : VersionRange.All); + bool versionDefined = versionRange != null; + if (versionRange == null && !isCpvmEnabled) { - LibraryRange = new LibraryRange( - name: item.GetProperty("Id"), - versionRange: GetVersionRange(item, defaultValue: isCpvmEnabled ? null : VersionRange.All), - typeConstraint: LibraryDependencyTarget.Package), - - AutoReferenced = IsPropertyTrue(item, "IsImplicitlyDefined"), - GeneratePathProperty = IsPropertyTrue(item, "GeneratePathProperty"), - Aliases = item.GetProperty("Aliases"), - VersionOverride = GetVersionRange(item, defaultValue: null, "VersionOverride") - }; - - ApplyIncludeFlags(dependency, item); - - var frameworks = GetFrameworks(item); + versionRange = VersionRange.All; + } - if (frameworks.Count == 0) + if (!frameworks.Any()) { - AddDependencyIfNotExist(spec, dependency); + frameworks = dict.Keys; } - else + + foreach (var framework in frameworks) { - foreach (var framework in frameworks) + dict.TryGetValue(framework, out TargetFrameworkInformation frameworkInfo); + CentralPackageVersion centralPackageVersion = null; + bool isCentrallyManaged = !versionDefined && !autoReferenced && isCpvmEnabled && versionOverrideRange == null && frameworkInfo.CentralPackageVersions != null && frameworkInfo.CentralPackageVersions.TryGetValue(name, out centralPackageVersion); + + if (centralPackageVersion != null) { - AddDependencyIfNotExist(spec, framework, dependency); + versionRange = centralPackageVersion.VersionRange; } - } - } + versionRange = versionOverrideRange ?? versionRange; - if (isCpvmEnabled) - { - AddCentralPackageVersions(spec, items); + var dependency = new LibraryDependency() + { + LibraryRange = new LibraryRange( + name: name, + versionRange: versionRange, + typeConstraint: LibraryDependencyTarget.Package), + + AutoReferenced = autoReferenced, + GeneratePathProperty = IsPropertyTrue(item, "GeneratePathProperty"), + Aliases = item.GetProperty("Aliases"), + VersionOverride = versionOverrideRange, + NoWarn = noWarn, + IncludeType = includeType, + SuppressParent = suppressParent, + VersionCentrallyManaged = isCentrallyManaged, + }; + + AddDependencyIfNotExist(spec, framework, dependency); + } } } @@ -725,9 +759,9 @@ internal static void AddPackageDownloads(PackageSpec spec, IEnumerable e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + var index = spec.TargetFrameworks.SingleIndex(e => e.TargetAlias.Equals(targetAlias, StringComparison.Ordinal)); + TargetFrameworkInformation frameworkInfo = spec.TargetFrameworks[index]; if (!frameworkInfo .FrameworkReferences @@ -770,7 +805,8 @@ private static bool AddFrameworkReferenceIfNotExists(PackageSpec spec, string ta .Contains(frameworkReference, ComparisonUtility.FrameworkReferenceNameComparer)) { var privateAssets = FrameworkDependencyFlagsUtils.GetFlags(MSBuildStringUtility.Split(privateAssetsValue)); - frameworkInfo.FrameworkReferences.Add(new FrameworkDependency(frameworkReference, privateAssets)); + FrameworkDependency[] newFrameworkReferences = [.. frameworkInfo.FrameworkReferences, new FrameworkDependency(frameworkReference, privateAssets)]; + spec.TargetFrameworks[index] = new TargetFrameworkInformation(frameworkInfo) { FrameworkReferences = newFrameworkReferences }; return true; } return false; @@ -1144,9 +1180,13 @@ private static void AddCentralPackageVersions(PackageSpec spec, IEnumerable targetAlias.Equals(f.TargetAlias, StringComparison.OrdinalIgnoreCase)); - frameworkInfo.CentralPackageVersions.AddRange(versions); - LibraryDependency.ApplyCentralVersionInformation(frameworkInfo.Dependencies, frameworkInfo.CentralPackageVersions); + var index = spec.TargetFrameworks.FirstIndex(f => targetAlias.Equals(f.TargetAlias, StringComparison.OrdinalIgnoreCase)); + var frameworkInfo = spec.TargetFrameworks[index]; + + spec.TargetFrameworks[index] = new TargetFrameworkInformation(frameworkInfo) + { + CentralPackageVersions = versions, + }; } } } diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/NoOpRestoreUtilities.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/NoOpRestoreUtilities.cs index 56dce7b684d..de7f9b11c2f 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/NoOpRestoreUtilities.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/NoOpRestoreUtilities.cs @@ -273,7 +273,7 @@ internal static List GetRestoreOutput(RestoreRequest request, LockFile l pathResolvers.Add(new VersionFolderPathResolver(restoreMetadataFallbackFolder)); } - var packageFiles = new List(lockFile.Libraries.Count + request.Project.TargetFrameworks.Sum(i => i.DownloadDependencies.Count)); + var packageFiles = new List(lockFile.Libraries.Count + request.Project.TargetFrameworks.Sum(i => i.DownloadDependencies.Length)); foreach (var library in lockFile.Libraries) { diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/ToolRestoreUtility.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/ToolRestoreUtility.cs index e6daf3eb81b..27a480dd584 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/ToolRestoreUtility.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/ToolRestoreUtility.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using NuGet.Common; using NuGet.Configuration; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -37,13 +36,13 @@ public static PackageSpec GetSpec(string projectFilePath, string id, VersionRang { TargetAlias = frameworkShortFolderName, FrameworkName = framework, - Dependencies = new List - { - new LibraryDependency(noWarn: Array.Empty()) + Dependencies = + [ + new LibraryDependency() { LibraryRange = new LibraryRange(id, versionRange, LibraryDependencyTarget.Package) } - } + ] } }, RestoreMetadata = new ProjectRestoreMetadata() diff --git a/src/NuGet.Core/NuGet.Commands/Utility/AssetTargetFallbackUtility.cs b/src/NuGet.Core/NuGet.Commands/Utility/AssetTargetFallbackUtility.cs index bd1a5e98dcf..b9997e8b26f 100644 --- a/src/NuGet.Core/NuGet.Commands/Utility/AssetTargetFallbackUtility.cs +++ b/src/NuGet.Core/NuGet.Commands/Utility/AssetTargetFallbackUtility.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using NuGet.Common; using NuGet.Frameworks; -using NuGet.ProjectModel; using NuGet.Shared; namespace NuGet.Commands @@ -57,26 +57,32 @@ public static NuGetFramework GetFallbackFramework(NuGetFramework projectFramewor /// /// Update TargetFrameworkInformation properties. /// - public static void ApplyFramework(TargetFrameworkInformation targetFrameworkInfo, IEnumerable packageTargetFallback, IEnumerable assetTargetFallback) + public static (NuGetFramework frameworkName, ImmutableArray imports, bool assetTargetFallback, bool warn) GetFallbackFrameworkInformation(NuGetFramework originalFrameworkName, IEnumerable packageTargetFallback, IEnumerable assetTargetFallbackEnum) { // Update the framework appropriately - targetFrameworkInfo.FrameworkName = GetFallbackFramework( - targetFrameworkInfo.FrameworkName, + var frameworkName = GetFallbackFramework( + originalFrameworkName, packageTargetFallback, - assetTargetFallback); + assetTargetFallbackEnum); - if (assetTargetFallback?.Any() == true) + ImmutableArray imports = []; + bool assetTargetFallback = false; + bool warn = false; + + if (assetTargetFallbackEnum?.Any() == true) { // AssetTargetFallback - targetFrameworkInfo.Imports = assetTargetFallback.AsList(); - targetFrameworkInfo.AssetTargetFallback = true; - targetFrameworkInfo.Warn = true; + imports = assetTargetFallbackEnum.ToImmutableArray(); + assetTargetFallback = true; + warn = true; } else if (packageTargetFallback?.Any() == true) { // PackageTargetFallback - targetFrameworkInfo.Imports = packageTargetFallback.AsList(); + imports = packageTargetFallback.ToImmutableArray(); } + + return (frameworkName, imports, assetTargetFallback, warn); } } } diff --git a/src/NuGet.Core/NuGet.Common/GlobalSuppressions.cs b/src/NuGet.Core/NuGet.Common/GlobalSuppressions.cs index 733fab96c85..17f2b44a9c3 100644 --- a/src/NuGet.Core/NuGet.Common/GlobalSuppressions.cs +++ b/src/NuGet.Core/NuGet.Common/GlobalSuppressions.cs @@ -17,7 +17,6 @@ [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'Task LegacyLoggerAdapter.LogAsync(ILogMessage message)', validate parameter 'message' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.LegacyLoggerAdapter.LogAsync(NuGet.Common.ILogMessage)~System.Threading.Tasks.Task")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void LocalResourceUtils.DeleteDirectoryTree(string folderPath, List failedDeletes)', validate parameter 'failedDeletes' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.LocalResourceUtils.DeleteDirectoryTree(System.String,System.Collections.Generic.List{System.String})")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'string LoggingExtensions.FormatWithCode(ILogMessage message)', validate parameter 'message' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.LoggingExtensions.FormatWithCode(NuGet.Common.ILogMessage)~System.String")] -[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'IEnumerable MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(IEnumerable> nugetLogCodeLists)', validate parameter 'nugetLogCodeLists' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{NuGet.Common.NuGetLogCode}})~System.Collections.Generic.IEnumerable{NuGet.Common.NuGetLogCode}")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'IEnumerable PathResolver.GetFilteredPackageFiles(ICollection source, Func getPath, IEnumerable wildcards)', validate parameter 'source' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.PathResolver.GetFilteredPackageFiles``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.String},System.Collections.Generic.IEnumerable{System.String})~System.Collections.Generic.IEnumerable{``0}")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'bool PathResolver.IsWildcardSearch(string filter)', validate parameter 'filter' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.PathResolver.IsWildcardSearch(System.String)~System.Boolean")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'string PathResolver.NormalizeWildcardForExcludedFiles(string basePath, string wildcard)', validate parameter 'wildcard' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.Common.PathResolver.NormalizeWildcardForExcludedFiles(System.String,System.String)~System.String")] diff --git a/src/NuGet.Core/NuGet.Common/MsBuildStringUtility.cs b/src/NuGet.Core/NuGet.Common/MsBuildStringUtility.cs index ba2b0db6eb0..8884e8953f5 100644 --- a/src/NuGet.Core/NuGet.Common/MsBuildStringUtility.cs +++ b/src/NuGet.Core/NuGet.Common/MsBuildStringUtility.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; namespace NuGet.Common @@ -89,28 +91,39 @@ public static bool IsTrueOrEmpty(string? value) /// /// A comma or semicolon delimited list of NuGet log codes. /// An containing the values that were successfully parsed from the specified string. - public static IList GetNuGetLogCodes(string s) + public static ImmutableArray GetNuGetLogCodes(string s) { // The Split() method already checks for an empty string and returns Array.Empty(). string[] split = MSBuildStringUtility.Split(s, ';', ','); if (split.Length == 0) { - return Array.Empty(); + return []; } - List logCodes = new List(capacity: split.Length); + NuGetLogCode[]? logCodes = null; + int index = 0; for (int i = 0; i < split.Length; i++) { if (split[i].StartsWith("NU", StringComparison.OrdinalIgnoreCase) && Enum.TryParse(value: split[i], ignoreCase: true, out NuGetLogCode logCode)) { - logCodes.Add(logCode); + logCodes ??= ArrayPool.Shared.Rent(split.Length); + + logCodes[index++] = logCode; } } - return logCodes; + if (logCodes == null) + { + return []; + } + + var retVal = logCodes.AsSpan(0, index).ToImmutableArray(); + ArrayPool.Shared.Return(logCodes); + + return retVal; } /// @@ -138,36 +151,5 @@ public static IList GetNuGetLogCodes(string s) return value.Replace(',', ';'); } - - /// - /// Return empty list of NuGetLogCode if all lists of NuGetLogCode are not the same. - /// - public static IEnumerable GetDistinctNuGetLogCodesOrDefault(IEnumerable?> nugetLogCodeLists) - { - if (nugetLogCodeLists.Any()) - { - var result = Enumerable.Empty(); - var first = true; - - foreach (IEnumerable? logCodeList in nugetLogCodeLists) - { - // If this is first item, assign it to result - if (first) - { - result = logCodeList; - first = false; - } - // Compare the rest items to the first one. - else if (result == null || logCodeList == null || result.Count() != logCodeList.Count() || !result.All(logCodeList.Contains)) - { - return Enumerable.Empty(); - } - } - - return result ?? Enumerable.Empty(); - } - - return Enumerable.Empty(); - } } } diff --git a/src/NuGet.Core/NuGet.Common/NuGet.Common.csproj b/src/NuGet.Core/NuGet.Common/NuGet.Common.csproj index df8a73d5945..75ed5accd26 100644 --- a/src/NuGet.Core/NuGet.Common/NuGet.Common.csproj +++ b/src/NuGet.Core/NuGet.Common/NuGet.Common.csproj @@ -26,6 +26,10 @@ + + + + True diff --git a/src/NuGet.Core/NuGet.Common/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.Common/PublicAPI.Shipped.txt index 1eca5c91000..36a90fb4e04 100644 --- a/src/NuGet.Core/NuGet.Common/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.Common/PublicAPI.Shipped.txt @@ -571,8 +571,6 @@ static NuGet.Common.LoggingExtensions.GetName(this NuGet.Common.NuGetLogCode cod static NuGet.Common.LoggingExtensions.TryGetName(this NuGet.Common.NuGetLogCode code, out string? codeString) -> bool static NuGet.Common.MSBuildStringUtility.Convert(string? value) -> string? static NuGet.Common.MSBuildStringUtility.GetBooleanOrNull(string? value) -> bool? -static NuGet.Common.MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(System.Collections.Generic.IEnumerable?>! nugetLogCodeLists) -> System.Collections.Generic.IEnumerable! -static NuGet.Common.MSBuildStringUtility.GetNuGetLogCodes(string! s) -> System.Collections.Generic.IList! static NuGet.Common.MSBuildStringUtility.IsTrue(string? value) -> bool static NuGet.Common.MSBuildStringUtility.IsTrueOrEmpty(string? value) -> bool static NuGet.Common.MSBuildStringUtility.Split(string! s) -> string![]! diff --git a/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt index 7dc5c58110b..be1fa37e5ad 100644 --- a/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static NuGet.Common.MSBuildStringUtility.GetNuGetLogCodes(string! s) -> System.Collections.Immutable.ImmutableArray diff --git a/src/NuGet.Core/NuGet.DependencyResolver.Core/PackagingUtility.cs b/src/NuGet.Core/NuGet.DependencyResolver.Core/PackagingUtility.cs index 560b0d191ca..1260646ed04 100644 --- a/src/NuGet.Core/NuGet.DependencyResolver.Core/PackagingUtility.cs +++ b/src/NuGet.Core/NuGet.DependencyResolver.Core/PackagingUtility.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using NuGet.Common; using NuGet.LibraryModel; namespace NuGet.DependencyResolver @@ -33,7 +31,7 @@ public static LibraryDependency GetLibraryDependencyFromNuspec(Packaging.Core.Pa // Create the library // Nuspec references cannot contain suppress parent flags - var libraryDependency = new LibraryDependency(noWarn: Array.Empty()) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange { diff --git a/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs b/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs index 6ad733df9cf..cafd520b4db 100644 --- a/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs +++ b/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using NuGet.Common; using NuGet.Frameworks; using NuGet.LibraryModel; using NuGet.Packaging; @@ -260,7 +259,7 @@ public static bool EvaluateRuntimeDependencies(ref LibraryRange libraryRange, st // Look up any additional dependencies for this package foreach (var runtimeDependency in runtimeGraph.FindRuntimeDependencies(runtimeName, libraryRange.Name).NoAllocEnumerate()) { - var libraryDependency = new LibraryDependency(noWarn: Array.Empty()) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange() { diff --git a/src/NuGet.Core/NuGet.LibraryModel/LibraryDependency.cs b/src/NuGet.Core/NuGet.LibraryModel/LibraryDependency.cs index d9bd69ded0a..91dd4434879 100644 --- a/src/NuGet.Core/NuGet.LibraryModel/LibraryDependency.cs +++ b/src/NuGet.Core/NuGet.LibraryModel/LibraryDependency.cs @@ -2,9 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; -using System.Linq; using NuGet.Common; using NuGet.Shared; using NuGet.Versioning; @@ -13,55 +12,56 @@ namespace NuGet.LibraryModel { public class LibraryDependency : IEquatable { - public required LibraryRange LibraryRange { get; set; } + // private fields to allow for validating initialization values + private ImmutableArray _noWarn = []; - public LibraryIncludeFlags IncludeType { get; set; } = LibraryIncludeFlags.All; + public required LibraryRange LibraryRange { get; init; } - public LibraryIncludeFlags SuppressParent { get; set; } = LibraryIncludeFlagUtils.DefaultSuppressParent; + public LibraryIncludeFlags IncludeType { get; init; } = LibraryIncludeFlags.All; - public IList NoWarn { get; set; } + public LibraryIncludeFlags SuppressParent { get; init; } = LibraryIncludeFlagUtils.DefaultSuppressParent; + + public ImmutableArray NoWarn + { + get => _noWarn; + init + { + _noWarn = value.IsDefault ? ImmutableArray.Empty : value; + } + } public string Name => LibraryRange.Name; /// /// True if the PackageReference is added by the SDK and not the user. /// - public bool AutoReferenced { get; set; } + public bool AutoReferenced { get; init; } /// /// True if the dependency has the version set through CentralPackageVersionManagement file. /// - public bool VersionCentrallyManaged { get; set; } + public bool VersionCentrallyManaged { get; init; } /// /// Information regarding if the dependency is direct or transitive. /// - public LibraryDependencyReferenceType ReferenceType { get; set; } = LibraryDependencyReferenceType.Direct; + public LibraryDependencyReferenceType ReferenceType { get; init; } = LibraryDependencyReferenceType.Direct; - public bool GeneratePathProperty { get; set; } + public bool GeneratePathProperty { get; init; } - public string? Aliases { get; set; } + public string? Aliases { get; init; } /// /// Gets or sets a value indicating a version override for any centrally defined version. /// - public VersionRange? VersionOverride { get; set; } + public VersionRange? VersionOverride { get; init; } /// Initializes a new instance of the LibraryDependency class. /// Required properties must be set when using this constructor. public LibraryDependency() - : this(new List()) { } - /// Initializes a new instance of the LibraryDependency class with the specified NoWarn codes. - /// Specifies a containing values. - /// Required properties must be set when using this constructor. - public LibraryDependency(IList noWarn) - { - NoWarn = noWarn; - } - /// Initializes a new instance of the LibraryDependency class. /// The to use with the new instance. /// is @@ -76,7 +76,7 @@ internal LibraryDependency( LibraryRange libraryRange, LibraryIncludeFlags includeType, LibraryIncludeFlags suppressParent, - IList noWarn, + ImmutableArray noWarn, bool autoReferenced, bool generatePathProperty, bool versionCentrallyManaged, @@ -96,6 +96,21 @@ internal LibraryDependency( VersionOverride = versionOverride; } + [SetsRequiredMembers] + public LibraryDependency(LibraryDependency other) + { + LibraryRange = other.LibraryRange; + IncludeType = other.IncludeType; + SuppressParent = other.SuppressParent; + NoWarn = other.NoWarn; + AutoReferenced = other.AutoReferenced; + GeneratePathProperty = other.GeneratePathProperty; + VersionCentrallyManaged = other.VersionCentrallyManaged; + ReferenceType = other.ReferenceType; + Aliases = other.Aliases; + VersionOverride = other.VersionOverride; + } + public override string ToString() { // Explicitly call .ToString() to ensure string.Concat(string, string, string) overload is called. @@ -110,7 +125,12 @@ public override int GetHashCode() hashCode.AddStruct(IncludeType); hashCode.AddStruct(SuppressParent); hashCode.AddObject(AutoReferenced); - hashCode.AddSequence(NoWarn); + + foreach (var item in NoWarn) + { + hashCode.AddStruct(item); + } + hashCode.AddObject(GeneratePathProperty); hashCode.AddObject(VersionCentrallyManaged); hashCode.AddObject(Aliases); @@ -147,47 +167,5 @@ public bool Equals(LibraryDependency? other) EqualityUtility.EqualsWithNullCheck(VersionOverride, other.VersionOverride) && ReferenceType == other.ReferenceType; } - - public LibraryDependency Clone() - { - var clonedLibraryRange = new LibraryRange(LibraryRange.Name, LibraryRange.VersionRange, LibraryRange.TypeConstraint); - var clonedNoWarn = new List(NoWarn); - - return new LibraryDependency(clonedLibraryRange, IncludeType, SuppressParent, clonedNoWarn, AutoReferenced, GeneratePathProperty, VersionCentrallyManaged, ReferenceType, Aliases, VersionOverride); - } - - /// - /// Merge the CentralVersion information to the package reference information. - /// - public static void ApplyCentralVersionInformation(IList packageReferences, IDictionary centralPackageVersions) - { - if (packageReferences == null) - { - throw new ArgumentNullException(nameof(packageReferences)); - } - if (centralPackageVersions == null) - { - throw new ArgumentNullException(nameof(centralPackageVersions)); - } - if (centralPackageVersions.Count > 0) - { - foreach (LibraryDependency d in packageReferences.Where(d => !d.AutoReferenced && d.LibraryRange.VersionRange == null)) - { - if (d.VersionOverride != null) - { - d.LibraryRange.VersionRange = d.VersionOverride; - - continue; - } - - if (centralPackageVersions.TryGetValue(d.Name, out CentralPackageVersion? centralPackageVersion)) - { - d.LibraryRange.VersionRange = centralPackageVersion.VersionRange; - } - - d.VersionCentrallyManaged = true; - } - } - } } } diff --git a/src/NuGet.Core/NuGet.LibraryModel/LibraryRange.cs b/src/NuGet.Core/NuGet.LibraryModel/LibraryRange.cs index 1ce89227294..d3d90195fc1 100644 --- a/src/NuGet.Core/NuGet.LibraryModel/LibraryRange.cs +++ b/src/NuGet.Core/NuGet.LibraryModel/LibraryRange.cs @@ -33,12 +33,20 @@ public LibraryRange(string name, VersionRange? versionRange, LibraryDependencyTa TypeConstraint = typeConstraint; } - public required string Name { get; set; } + [SetsRequiredMembers] + public LibraryRange(LibraryRange other) + { + Name = other.Name; + VersionRange = other.VersionRange; + TypeConstraint = other.TypeConstraint; + } + + public required string Name { get; init; } // Null is used for all, CLI still has code expecting this - public VersionRange? VersionRange { get; set; } + public VersionRange? VersionRange { get; init; } - public LibraryDependencyTarget TypeConstraint { get; set; } = LibraryDependencyTarget.All; + public LibraryDependencyTarget TypeConstraint { get; init; } = LibraryDependencyTarget.All; public override string ToString() { diff --git a/src/NuGet.Core/NuGet.LibraryModel/NuGet.LibraryModel.csproj b/src/NuGet.Core/NuGet.LibraryModel/NuGet.LibraryModel.csproj index ac3d77a56c2..34cb783114b 100644 --- a/src/NuGet.Core/NuGet.LibraryModel/NuGet.LibraryModel.csproj +++ b/src/NuGet.Core/NuGet.LibraryModel/NuGet.LibraryModel.csproj @@ -16,6 +16,10 @@ $(NETFXTargetFramework) + + + + diff --git a/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Shipped.txt index 94c06f6699d..22cb400e361 100644 --- a/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Shipped.txt @@ -44,31 +44,18 @@ NuGet.LibraryModel.Library.this[string! key].get -> object! NuGet.LibraryModel.Library.this[string! key].set -> void NuGet.LibraryModel.LibraryDependency NuGet.LibraryModel.LibraryDependency.Aliases.get -> string? -NuGet.LibraryModel.LibraryDependency.Aliases.set -> void NuGet.LibraryModel.LibraryDependency.AutoReferenced.get -> bool -NuGet.LibraryModel.LibraryDependency.AutoReferenced.set -> void -NuGet.LibraryModel.LibraryDependency.Clone() -> NuGet.LibraryModel.LibraryDependency! NuGet.LibraryModel.LibraryDependency.Equals(NuGet.LibraryModel.LibraryDependency? other) -> bool NuGet.LibraryModel.LibraryDependency.GeneratePathProperty.get -> bool -NuGet.LibraryModel.LibraryDependency.GeneratePathProperty.set -> void NuGet.LibraryModel.LibraryDependency.IncludeType.get -> NuGet.LibraryModel.LibraryIncludeFlags -NuGet.LibraryModel.LibraryDependency.IncludeType.set -> void NuGet.LibraryModel.LibraryDependency.LibraryDependency() -> void NuGet.LibraryModel.LibraryDependency.LibraryDependency(NuGet.LibraryModel.LibraryRange! libraryRange) -> void -NuGet.LibraryModel.LibraryDependency.LibraryDependency(System.Collections.Generic.IList! noWarn) -> void NuGet.LibraryModel.LibraryDependency.LibraryRange.get -> NuGet.LibraryModel.LibraryRange! -NuGet.LibraryModel.LibraryDependency.LibraryRange.set -> void NuGet.LibraryModel.LibraryDependency.Name.get -> string! -NuGet.LibraryModel.LibraryDependency.NoWarn.get -> System.Collections.Generic.IList! -NuGet.LibraryModel.LibraryDependency.NoWarn.set -> void NuGet.LibraryModel.LibraryDependency.ReferenceType.get -> NuGet.LibraryModel.LibraryDependencyReferenceType -NuGet.LibraryModel.LibraryDependency.ReferenceType.set -> void NuGet.LibraryModel.LibraryDependency.SuppressParent.get -> NuGet.LibraryModel.LibraryIncludeFlags -NuGet.LibraryModel.LibraryDependency.SuppressParent.set -> void NuGet.LibraryModel.LibraryDependency.VersionCentrallyManaged.get -> bool -NuGet.LibraryModel.LibraryDependency.VersionCentrallyManaged.set -> void NuGet.LibraryModel.LibraryDependency.VersionOverride.get -> NuGet.Versioning.VersionRange? -NuGet.LibraryModel.LibraryDependency.VersionOverride.set -> void NuGet.LibraryModel.LibraryDependencyInfo NuGet.LibraryModel.LibraryDependencyInfo.Dependencies.get -> System.Collections.Generic.IEnumerable! NuGet.LibraryModel.LibraryDependencyInfo.Framework.get -> NuGet.Frameworks.NuGetFramework! @@ -120,14 +107,11 @@ NuGet.LibraryModel.LibraryRange.LibraryRange(string! name) -> void NuGet.LibraryModel.LibraryRange.LibraryRange(string! name, NuGet.LibraryModel.LibraryDependencyTarget typeConstraint) -> void NuGet.LibraryModel.LibraryRange.LibraryRange(string! name, NuGet.Versioning.VersionRange? versionRange, NuGet.LibraryModel.LibraryDependencyTarget typeConstraint) -> void NuGet.LibraryModel.LibraryRange.Name.get -> string! -NuGet.LibraryModel.LibraryRange.Name.set -> void NuGet.LibraryModel.LibraryRange.ToLockFileDependencyGroupString() -> string! NuGet.LibraryModel.LibraryRange.TypeConstraint.get -> NuGet.LibraryModel.LibraryDependencyTarget -NuGet.LibraryModel.LibraryRange.TypeConstraint.set -> void NuGet.LibraryModel.LibraryRange.TypeConstraintAllows(NuGet.LibraryModel.LibraryDependencyTarget flag) -> bool NuGet.LibraryModel.LibraryRange.TypeConstraintAllowsAnyOf(NuGet.LibraryModel.LibraryDependencyTarget flag) -> bool NuGet.LibraryModel.LibraryRange.VersionRange.get -> NuGet.Versioning.VersionRange? -NuGet.LibraryModel.LibraryRange.VersionRange.set -> void NuGet.LibraryModel.LibraryType NuGet.LibraryModel.LibraryType.Equals(NuGet.LibraryModel.LibraryType other) -> bool NuGet.LibraryModel.LibraryType.IsKnown.get -> bool @@ -158,7 +142,6 @@ static NuGet.LibraryModel.DownloadDependency.implicit operator NuGet.LibraryMode static NuGet.LibraryModel.FrameworkDependencyFlagsUtils.GetFlagString(NuGet.LibraryModel.FrameworkDependencyFlags flags) -> string! static NuGet.LibraryModel.FrameworkDependencyFlagsUtils.GetFlags(System.Collections.Generic.IEnumerable? values) -> NuGet.LibraryModel.FrameworkDependencyFlags static NuGet.LibraryModel.FrameworkDependencyFlagsUtils.GetFlags(string? flags) -> NuGet.LibraryModel.FrameworkDependencyFlags -static NuGet.LibraryModel.LibraryDependency.ApplyCentralVersionInformation(System.Collections.Generic.IList! packageReferences, System.Collections.Generic.IDictionary! centralPackageVersions) -> void static NuGet.LibraryModel.LibraryDependencyInfo.Create(NuGet.LibraryModel.LibraryIdentity! library, NuGet.Frameworks.NuGetFramework! framework, System.Collections.Generic.IEnumerable! dependencies) -> NuGet.LibraryModel.LibraryDependencyInfo! static NuGet.LibraryModel.LibraryDependencyInfo.CreateUnresolved(NuGet.LibraryModel.LibraryIdentity! library, NuGet.Frameworks.NuGetFramework! framework) -> NuGet.LibraryModel.LibraryDependencyInfo! static NuGet.LibraryModel.LibraryDependencyTargetUtils.AsString(this NuGet.LibraryModel.LibraryDependencyTarget includeFlags) -> string! diff --git a/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Unshipped.txt index 7dc5c58110b..42d1c3e8df6 100644 --- a/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.LibraryModel/PublicAPI.Unshipped.txt @@ -1 +1,17 @@ #nullable enable +NuGet.LibraryModel.LibraryDependency.Aliases.init -> void +NuGet.LibraryModel.LibraryDependency.AutoReferenced.init -> void +NuGet.LibraryModel.LibraryDependency.GeneratePathProperty.init -> void +NuGet.LibraryModel.LibraryDependency.IncludeType.init -> void +NuGet.LibraryModel.LibraryDependency.LibraryDependency(NuGet.LibraryModel.LibraryDependency! other) -> void +NuGet.LibraryModel.LibraryDependency.LibraryRange.init -> void +NuGet.LibraryModel.LibraryDependency.NoWarn.get -> System.Collections.Immutable.ImmutableArray +NuGet.LibraryModel.LibraryDependency.NoWarn.init -> void +NuGet.LibraryModel.LibraryDependency.ReferenceType.init -> void +NuGet.LibraryModel.LibraryDependency.SuppressParent.init -> void +NuGet.LibraryModel.LibraryDependency.VersionCentrallyManaged.init -> void +NuGet.LibraryModel.LibraryDependency.VersionOverride.init -> void +NuGet.LibraryModel.LibraryRange.LibraryRange(NuGet.LibraryModel.LibraryRange! other) -> void +NuGet.LibraryModel.LibraryRange.Name.init -> void +NuGet.LibraryModel.LibraryRange.TypeConstraint.init -> void +NuGet.LibraryModel.LibraryRange.VersionRange.init -> void diff --git a/src/NuGet.Core/NuGet.PackageManagement/BuildIntegration/BuildIntegratedRestoreUtility.cs b/src/NuGet.Core/NuGet.PackageManagement/BuildIntegration/BuildIntegratedRestoreUtility.cs index 2e8f5935f4c..3d0b843cdc6 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/BuildIntegration/BuildIntegratedRestoreUtility.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/BuildIntegration/BuildIntegratedRestoreUtility.cs @@ -164,18 +164,25 @@ public static void UpdatePackageReferenceMetadata( if (developmentDependency) { - foreach (var frameworkInfo in lockFile.PackageSpec.TargetFrameworks - .OrderBy(framework => framework.FrameworkName.ToString(), - StringComparer.Ordinal)) + for (var i = 0; i < lockFile.PackageSpec.TargetFrameworks.Count; i++) { - var dependency = frameworkInfo.Dependencies.First(dep => dep.Name.Equals(package.Id, StringComparison.OrdinalIgnoreCase)); + var frameworkInfo = lockFile.PackageSpec.TargetFrameworks[i]; - if (dependency?.SuppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent && - dependency?.IncludeType == LibraryIncludeFlags.All) + var index = frameworkInfo.Dependencies.FirstIndex(dep => dep.Name.Equals(package.Id, StringComparison.OrdinalIgnoreCase)); + var dependency = frameworkInfo.Dependencies[index]; + + if (dependency.SuppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent && + dependency.IncludeType == LibraryIncludeFlags.All) { var includeType = LibraryIncludeFlags.All & ~LibraryIncludeFlags.Compile; - dependency.SuppressParent = LibraryIncludeFlags.All; - dependency.IncludeType = includeType; + dependency = new LibraryDependency(dependency) + { + IncludeType = includeType, + SuppressParent = LibraryIncludeFlags.All + }; + + var newDependencies = frameworkInfo.Dependencies.SetItem(index, dependency); + lockFile.PackageSpec.TargetFrameworks[i] = new TargetFrameworkInformation(frameworkInfo) { Dependencies = newDependencies }; // update lock file target libraries foreach (var target in lockFile.Targets diff --git a/src/NuGet.Core/NuGet.PackageManagement/Projects/MSBuildNuGetProject.cs b/src/NuGet.Core/NuGet.PackageManagement/Projects/MSBuildNuGetProject.cs index 5a80f1effec..a28ba19f842 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/Projects/MSBuildNuGetProject.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/Projects/MSBuildNuGetProject.cs @@ -659,7 +659,7 @@ public async Task> GetPackageSpecsAsync(DependencyGra { packageSpec = new PackageSpec(new List { - new TargetFrameworkInformation + new TargetFrameworkInformation() { FrameworkName = ProjectSystem.TargetFramework } diff --git a/src/NuGet.Core/NuGet.PackageManagement/Projects/ProjectJsonNuGetProject.cs b/src/NuGet.Core/NuGet.PackageManagement/Projects/ProjectJsonNuGetProject.cs index 55361d53052..d59b3306373 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/Projects/ProjectJsonNuGetProject.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/Projects/ProjectJsonNuGetProject.cs @@ -200,8 +200,8 @@ public override async Task> GetPackageSpecsAsync(Depe // Ensure the project json has only one target framework if (packageSpec.TargetFrameworks != null && packageSpec.TargetFrameworks.Count == 1) { - var tfi = packageSpec.TargetFrameworks.First(); - if (tfi.Imports.Count > 0) + var tfi = packageSpec.TargetFrameworks[0]; + if (tfi.Imports.Length > 0) { if (tfi.AssetTargetFallback) { @@ -212,7 +212,7 @@ public override async Task> GetPackageSpecsAsync(Depe nuGetFramework = new FallbackFramework(nuGetFramework, tfi.Imports.AsList()); } } - tfi.FrameworkName = nuGetFramework; + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(tfi) { FrameworkName = nuGetFramework }; } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/GlobalSuppressions.cs b/src/NuGet.Core/NuGet.ProjectModel/GlobalSuppressions.cs index 668c89eeb6c..54ff7107054 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/GlobalSuppressions.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/GlobalSuppressions.cs @@ -14,7 +14,6 @@ [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'DependencyGraphSpec DependencyGraphSpec.WithReplacedSpec(PackageSpec project)', validate parameter 'project' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.DependencyGraphSpec.WithReplacedSpec(NuGet.ProjectModel.PackageSpec)~NuGet.ProjectModel.DependencyGraphSpec")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'FileFormatException FileFormatException.Create(Exception exception, JToken value, string path)', validate parameter 'exception' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.FileFormatException.Create(System.Exception,Newtonsoft.Json.Linq.JToken,System.String)~NuGet.ProjectModel.FileFormatException")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'PackageSpec JsonPackageSpecReader.GetPackageSpec(JObject rawPackageSpec, string name, string packageSpecPath, string snapshotValue)', validate parameter 'rawPackageSpec' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.JsonPackageSpecReader.GetPackageSpec(Newtonsoft.Json.Linq.JObject,System.String,System.String,System.String)~NuGet.ProjectModel.PackageSpec")] -[assembly: SuppressMessage("Build", "CA1303:Method 'void JsonPackageSpecReader.ReadDownloadDependencies(JsonTextReader jsonReader, IList downloadDependencies, string packageSpecPath)' passes a literal string as parameter 'message' of a call to 'FileFormatException FileFormatException.Create(string message, int line, int column, string path)'. Retrieve the following string(s) from a resource table instead: \"The version cannot be null or empty\".", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.JsonPackageSpecReader.ReadDownloadDependencies(Newtonsoft.Json.JsonTextReader,System.Collections.Generic.IList{NuGet.LibraryModel.DownloadDependency},System.String)")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'bool LockFile.IsValidForPackageSpec(PackageSpec spec, int requestLockFileVersion)', validate parameter 'spec' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.LockFile.IsValidForPackageSpec(NuGet.ProjectModel.PackageSpec,System.Int32)~System.Boolean")] [assembly: SuppressMessage("Build", "CA1062:In externally visible method 'int LockFileDependencyIdVersionComparer.GetHashCode(LockFileDependency obj)', validate parameter 'obj' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.LockFileDependencyIdVersionComparer.GetHashCode(NuGet.ProjectModel.LockFileDependency)~System.Int32")] [assembly: SuppressMessage("Build", "CA1031:Modify 'Read' to catch a more specific allowed exception type, or rethrow the exception.", Justification = "", Scope = "member", Target = "~M:NuGet.ProjectModel.LockFileFormat.Read(System.IO.TextReader,NuGet.Common.ILogger,System.String,NuGet.ProjectModel.LockFileReadFlags)~NuGet.ProjectModel.LockFile")] diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs index cd616b26208..b884175bef0 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -428,7 +430,7 @@ private static void ReadDependencies( var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - List noWarn = null; + ImmutableArray noWarn = []; // This method handles both the dependencies and framework assembly sections. // Framework references should be limited to references. @@ -571,14 +573,10 @@ private static void ReadDependencies( // The ReferenceType is not persisted to the assets file // Default to LibraryDependencyReferenceType.Direct on Read ReferenceType = LibraryDependencyReferenceType.Direct, - VersionOverride = versionOverride + VersionOverride = versionOverride, + NoWarn = noWarn, }; - if (noWarn != null) - { - libraryDependency.NoWarn = noWarn; - } - results.Add(libraryDependency); } } @@ -817,7 +815,7 @@ private static void ReadFrameworks(ref Utf8JsonStreamReader reader, PackageSpec } } - private static void ReadImports(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + private static void ReadImports(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader, List importFrameworks) { IReadOnlyList imports = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); @@ -838,7 +836,7 @@ private static void ReadImports(PackageSpec packageSpec, ref Utf8JsonStreamReade packageSpec.FilePath); } - targetFrameworkInformation.Imports.Add(framework); + importFrameworks.Add(framework); } } } @@ -1311,9 +1309,10 @@ private static void ReadNuGetLogCodes(ref Utf8JsonStreamReader jsonReader, HashS } } - private static List ReadNuGetLogCodesList(ref Utf8JsonStreamReader jsonReader) + private static ImmutableArray ReadNuGetLogCodesList(ref Utf8JsonStreamReader jsonReader) { - List items = null; + NuGetLogCode[] items = null; + var index = 0; if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartArray) { @@ -1321,13 +1320,34 @@ private static List ReadNuGetLogCodesList(ref Utf8JsonStreamReader { if (jsonReader.TokenType == JsonTokenType.String && Enum.TryParse(jsonReader.GetString(), out NuGetLogCode code)) { - items ??= []; + if (items == null) + { + items = ArrayPool.Shared.Rent(16); + } + else if (items.Length == index) + { + var oldItems = items; + + items = ArrayPool.Shared.Rent(items.Length * 2); + oldItems.CopyTo(items, index: 0); + + ArrayPool.Shared.Return(oldItems); + } - items.Add(code); + items[index++] = code; } } } - return items; + + if (items == null) + { + return []; + } + + var retVal = items.AsSpan(0, index).ToImmutableArray(); + ArrayPool.Shared.Return(items); + + return retVal; } private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader) @@ -1789,7 +1809,16 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt { var frameworkName = NuGetFramework.Parse(jsonReader.GetString()); - var targetFrameworkInformation = new TargetFrameworkInformation(); + bool assetTargetFallback = false; + Dictionary centralPackageVersions = null; + List dependencies = null; + List downloadDependencies = null; + HashSet frameworkReferences = null; + List imports = null; + string runtimeIdentifierGraphPath = null; + string targetAlias = string.Empty; + bool warn = false; + NuGetFramework secondaryFramework = default; if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) @@ -1798,7 +1827,7 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt { if (jsonReader.ValueTextEquals(AssetTargetFallbackPropertyName)) { - targetFrameworkInformation.AssetTargetFallback = jsonReader.ReadNextTokenAsBoolOrFalse(); + assetTargetFallback = jsonReader.ReadNextTokenAsBoolOrFalse(); } else if (jsonReader.ValueTextEquals(SecondaryFrameworkPropertyName)) { @@ -1810,56 +1839,62 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt } else if (jsonReader.ValueTextEquals(CentralPackageVersionsPropertyName)) { + centralPackageVersions ??= new Dictionary(); ReadCentralPackageVersions( ref jsonReader, - targetFrameworkInformation.CentralPackageVersions, + centralPackageVersions, packageSpec.FilePath); } else if (jsonReader.ValueTextEquals(DependenciesPropertyName)) { + dependencies ??= new List(); ReadDependencies( ref jsonReader, - targetFrameworkInformation.Dependencies, + dependencies, packageSpec.FilePath, isGacOrFrameworkReference: false); } else if (jsonReader.ValueTextEquals(DownloadDependenciesPropertyName)) { + downloadDependencies ??= new List(); ReadDownloadDependencies( ref jsonReader, - targetFrameworkInformation.DownloadDependencies, + downloadDependencies, packageSpec.FilePath); } else if (jsonReader.ValueTextEquals(FrameworkAssembliesPropertyName)) { + dependencies ??= new List(); ReadDependencies( ref jsonReader, - targetFrameworkInformation.Dependencies, + dependencies, packageSpec.FilePath, isGacOrFrameworkReference: true); } else if (jsonReader.ValueTextEquals(FrameworkReferencesPropertyName)) { + frameworkReferences ??= new HashSet(); ReadFrameworkReferences( ref jsonReader, - targetFrameworkInformation.FrameworkReferences, + frameworkReferences, packageSpec.FilePath); } else if (jsonReader.ValueTextEquals(ImportsPropertyName)) { - ReadImports(packageSpec, ref jsonReader, targetFrameworkInformation); + imports ??= new List(); + ReadImports(packageSpec, ref jsonReader, imports); } else if (jsonReader.ValueTextEquals(RuntimeIdentifierGraphPathPropertyName)) { - targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); + runtimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); } else if (jsonReader.ValueTextEquals(TargetAliasPropertyName)) { - targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); + targetAlias = jsonReader.ReadNextTokenAsString(); } else if (jsonReader.ValueTextEquals(WarnPropertyName)) { - targetFrameworkInformation.Warn = jsonReader.ReadNextTokenAsBoolOrFalse(); + warn = jsonReader.ReadNextTokenAsBoolOrFalse(); } else { @@ -1868,6 +1903,19 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt } } + var targetFrameworkInformation = new TargetFrameworkInformation() + { + AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies != null ? dependencies.ToImmutableArray() : [], + DownloadDependencies = downloadDependencies != null ? downloadDependencies.ToImmutableArray() : [], + FrameworkReferences = frameworkReferences, + Imports = imports != null ? imports.ToImmutableArray() : [], + RuntimeIdentifierGraphPath = runtimeIdentifierGraphPath, + TargetAlias = targetAlias, + Warn = warn + }; + #pragma warning disable CS0612 // Type or member is obsolete AddTargetFramework(packageSpec, frameworkName, secondaryFramework, targetFrameworkInformation); #pragma warning restore CS0612 // Type or member is obsolete diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index c6b658c7d5f..31eaa78f763 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -376,7 +378,7 @@ private static void ReadDependencies( var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - IList noWarn = Array.Empty(); + ImmutableArray noWarn = []; // This method handles both the dependencies and framework assembly sections. // Framework references should be limited to references. @@ -510,7 +512,7 @@ private static void ReadDependencies( // the dependency flags are: Include flags - Exclude flags var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency(noWarn) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange() { @@ -527,7 +529,8 @@ private static void ReadDependencies( // The ReferenceType is not persisted to the assets file // Default to LibraryDependencyReferenceType.Direct on Read ReferenceType = LibraryDependencyReferenceType.Direct, - VersionOverride = versionOverride + VersionOverride = versionOverride, + NoWarn = noWarn }; results.Add(libraryDependency); @@ -638,7 +641,7 @@ internal static void ReadCentralTransitiveDependencyGroup( // the dependency flags are: Include flags - Exclude flags var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency(noWarn: Array.Empty()) + var libraryDependency = new LibraryDependency() { LibraryRange = new LibraryRange() { @@ -813,7 +816,7 @@ private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packag } [Obsolete] - private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, List importFrameworks) { int lineNumber = jsonReader.LineNumber; int linePosition = jsonReader.LinePosition; @@ -839,7 +842,7 @@ private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonRead packageSpec.FilePath); } - targetFrameworkInformation.Imports.Add(framework); + importFrameworks.Add(framework); } } } @@ -1331,9 +1334,10 @@ private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet ReadNuGetLogCodesList(JsonTextReader jsonReader) + private static ImmutableArray ReadNuGetLogCodesList(JsonTextReader jsonReader) { - IList items = null; + NuGetLogCode[] items = null; + var index = 0; if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) { @@ -1341,14 +1345,34 @@ private static IList ReadNuGetLogCodesList(JsonTextReader jsonRead { if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) { - items = items ?? new List(); + if (items == null) + { + items = ArrayPool.Shared.Rent(16); + } + else if (items.Length == index) + { + var oldItems = items; + + items = ArrayPool.Shared.Rent(items.Length * 2); + oldItems.CopyTo(items, index: 0); - items.Add(code); + ArrayPool.Shared.Return(oldItems); + } + + items[index++] = code; } } } - return items ?? Array.Empty(); + if (items == null) + { + return []; + } + + var retVal = items.AsSpan(0, index).ToImmutableArray(); + ArrayPool.Shared.Return(items); + + return retVal; } [Obsolete] @@ -1788,14 +1812,24 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader NuGetFramework frameworkName = NuGetFramework.Parse((string)jsonReader.Value); - var targetFrameworkInformation = new TargetFrameworkInformation(); + bool assetTargetFallback = false; + Dictionary centralPackageVersions = null; + List dependencies = null; + List downloadDependencies = null; + HashSet frameworkReferences = null; + List imports = null; + string runtimeIdentifierGraphPath = null; + string targetAlias = string.Empty; + bool warn = false; + NuGetFramework secondaryFramework = default; + jsonReader.ReadObject(propertyName => { switch (propertyName) { case "assetTargetFallback": - targetFrameworkInformation.AssetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + assetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); break; case "secondaryFramework": @@ -1807,60 +1841,79 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader break; case "centralPackageVersions": + centralPackageVersions ??= new Dictionary(); ReadCentralPackageVersions( jsonReader, - targetFrameworkInformation.CentralPackageVersions, + centralPackageVersions, packageSpec.FilePath); break; case "dependencies": + dependencies ??= new List(); ReadDependencies( jsonReader, - targetFrameworkInformation.Dependencies, + dependencies, packageSpec.FilePath, isGacOrFrameworkReference: false); break; case "downloadDependencies": + downloadDependencies ??= new List(); ReadDownloadDependencies( jsonReader, - targetFrameworkInformation.DownloadDependencies, + downloadDependencies, packageSpec.FilePath); break; case "frameworkAssemblies": + dependencies ??= new List(); ReadDependencies( jsonReader, - targetFrameworkInformation.Dependencies, + dependencies, packageSpec.FilePath, isGacOrFrameworkReference: true); break; case "frameworkReferences": + frameworkReferences ??= new HashSet(); ReadFrameworkReferences( jsonReader, - targetFrameworkInformation.FrameworkReferences, + frameworkReferences, packageSpec.FilePath); break; case "imports": - ReadImports(packageSpec, jsonReader, targetFrameworkInformation); + imports ??= new List(); + ReadImports(packageSpec, jsonReader, imports); break; case "runtimeIdentifierGraphPath": - targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); + runtimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); break; case "targetAlias": - targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); + targetAlias = jsonReader.ReadNextTokenAsString(); break; case "warn": - targetFrameworkInformation.Warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); break; } }, out frameworkLine, out frameworkColumn); + var targetFrameworkInformation = new TargetFrameworkInformation() + { + AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies != null ? dependencies.ToImmutableArray() : [], + DownloadDependencies = downloadDependencies != null ? downloadDependencies.ToImmutableArray() : [], + FrameworkReferences = frameworkReferences, + Imports = imports != null ? imports.ToImmutableArray() : [], + RuntimeIdentifierGraphPath = runtimeIdentifierGraphPath, + TargetAlias = targetAlias, + Warn = warn + }; + AddTargetFramework(packageSpec, frameworkName, secondaryFramework, targetFrameworkInformation); } @@ -1869,7 +1922,7 @@ private static void AddTargetFramework(PackageSpec packageSpec, NuGetFramework f { NuGetFramework updatedFramework = frameworkName; - if (targetFrameworkInformation.Imports.Count > 0) + if (targetFrameworkInformation.Imports.Length > 0) { NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); @@ -1887,7 +1940,7 @@ private static void AddTargetFramework(PackageSpec packageSpec, NuGetFramework f updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); } - targetFrameworkInformation.FrameworkName = updatedFramework; + targetFrameworkInformation = new TargetFrameworkInformation(targetFrameworkInformation) { FrameworkName = updatedFramework }; packageSpec.TargetFrameworks.Add(targetFrameworkInformation); } diff --git a/src/NuGet.Core/NuGet.ProjectModel/NuGet.ProjectModel.csproj b/src/NuGet.Core/NuGet.ProjectModel/NuGet.ProjectModel.csproj index ac1dbd978ed..bec334cd413 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/NuGet.ProjectModel.csproj +++ b/src/NuGet.Core/NuGet.ProjectModel/NuGet.ProjectModel.csproj @@ -19,6 +19,10 @@ + + + + True diff --git a/src/NuGet.Core/NuGet.ProjectModel/PackageSpec.cs b/src/NuGet.Core/NuGet.ProjectModel/PackageSpec.cs index bff97d66249..ea9fe1909d3 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PackageSpec.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/PackageSpec.cs @@ -258,12 +258,12 @@ public PackageSpec Clone() else { targetFrameworks = new List(TargetFrameworks.Count); - targetFrameworks.AddRange(TargetFrameworks.Select(item => item.Clone())); + targetFrameworks.AddRange(TargetFrameworks); } return new PackageSpec( targetFrameworks, - Dependencies?.Select(item => item.Clone()).ToList(), + Dependencies?.ToList(), RuntimeGraph?.Clone(), RestoreSettings?.Clone(), #pragma warning disable CS0612 // Type or member is obsolete diff --git a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecOperations.cs b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecOperations.cs index bd23f60eebf..ca94685cc53 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecOperations.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecOperations.cs @@ -3,8 +3,9 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; -using NuGet.Common; +using System.Runtime.InteropServices; using NuGet.Frameworks; using NuGet.LibraryModel; using NuGet.Packaging.Core; @@ -29,32 +30,73 @@ public static void AddOrUpdateDependency(PackageSpec spec, PackageDependency dep if (spec == null) throw new ArgumentNullException(nameof(spec)); if (dependency == null) throw new ArgumentNullException(nameof(dependency)); - var existing = GetExistingDependencies(spec, dependency.Id); - + var foundExistingDependency = false; var range = dependency.VersionRange; + var dependencyId = dependency.Id; + + for (var i = 0; i < spec.Dependencies.Count; i++) + { + var existingDependency = spec.Dependencies[i]; + + bool updateVersionOverride = spec.RestoreMetadata?.CentralPackageVersionsEnabled == true && !existingDependency.VersionCentrallyManaged && existingDependency.VersionOverride is not null; + + if (IsMatchingDependencyName(existingDependency, dependencyId)) + { + var libraryRange = new LibraryRange(existingDependency.LibraryRange) { VersionRange = range }; + spec.Dependencies[i] = new LibraryDependency(existingDependency) { LibraryRange = libraryRange, VersionOverride = updateVersionOverride ? range : null }; + + foundExistingDependency = true; + } + } - foreach (var existingDependency in existing) + for (var i = 0; i < spec.TargetFrameworks.Count; i++) { - if (spec.RestoreMetadata?.CentralPackageVersionsEnabled == true && !existingDependency.VersionCentrallyManaged && existingDependency.VersionOverride is not null) + var targetFramework = spec.TargetFrameworks[i]; + + // Don't allocate a new dependencies array if there aren't any matching dependencies + if (!targetFramework.Dependencies.Any(dep => IsMatchingDependencyName(dep, dependencyId))) + { + continue; + } + + foundExistingDependency = true; + var newDependencies = new LibraryDependency[targetFramework.Dependencies.Length]; + for (var j = 0; j < targetFramework.Dependencies.Length; j++) { - existingDependency.VersionOverride = range; + var existingDependency = targetFramework.Dependencies[j]; + var libraryRange = existingDependency.LibraryRange; + + if (IsMatchingDependencyName(existingDependency, dependencyId)) + { + libraryRange = new LibraryRange(libraryRange) { VersionRange = range }; + existingDependency = new LibraryDependency(existingDependency) { LibraryRange = libraryRange }; + } + + newDependencies[j] = existingDependency; } - existingDependency.LibraryRange.VersionRange = range; + var newDependenciesImmutable = ImmutableCollectionsMarshal.AsImmutableArray(newDependencies); + spec.TargetFrameworks[i] = new TargetFrameworkInformation(targetFramework) { Dependencies = newDependenciesImmutable }; } - if (!existing.Any()) + if (!foundExistingDependency) { if (spec.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference) // PackageReference does not use the `Dependencies` list in the PackageSpec. { - foreach (var dependenciesList in spec.TargetFrameworks.Select(e => e.Dependencies)) + for (var i = 0; i < spec.TargetFrameworks.Count; i++) { - AddDependency(dependenciesList, dependency.Id, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); + var framework = spec.TargetFrameworks[i]; + var newDependency = CreateDependency(dependencyId, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); + + var newDependencies = framework.Dependencies.Add(newDependency); + spec.TargetFrameworks[i] = new TargetFrameworkInformation(framework) { Dependencies = newDependencies }; } } else { - AddDependency(spec.Dependencies, dependency.Id, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); + var newDependency = CreateDependency(dependencyId, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); + + spec.Dependencies.Add(newDependency); } } } @@ -79,7 +121,17 @@ public static void AddOrUpdateDependency(PackageSpec spec, PackageIdentity ident public static bool HasPackage(PackageSpec spec, string packageId) { - return GetExistingDependencies(spec, packageId).Any(); + if (spec.Dependencies.Any(library => IsMatchingDependencyName(library, packageId))) + { + return true; + } + + if (spec.TargetFrameworks.Any(tf => tf.Dependencies.Any(library => IsMatchingDependencyName(library, packageId)))) + { + return true; + } + + return false; } /// @@ -97,20 +149,44 @@ public static void AddOrUpdateDependency( if (spec == null) throw new ArgumentNullException(nameof(spec)); if (dependency == null) throw new ArgumentNullException(nameof(dependency)); - var lists = GetDependencyLists( - spec, - includeGenericDependencies: false, - frameworksToConsider: frameworksToAdd); + for (var i = 0; i < spec.TargetFrameworks.Count; i++) + { + var targetFramework = spec.TargetFrameworks[i]; + if (frameworksToAdd == null || frameworksToAdd.Contains(targetFramework.FrameworkName)) + { + var newDependencies = AddOrUpdateDependencyInDependencyList(spec, targetFramework.Dependencies, dependency.Id, dependency.VersionRange); + spec.TargetFrameworks[i] = new TargetFrameworkInformation(targetFramework) { Dependencies = newDependencies }; + } + } - foreach (var list in lists) + if (spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false) { - AddOrUpdateDependencyInDependencyList(spec, list, dependency.Id, dependency.VersionRange); + for (var i = 0; i < spec.TargetFrameworks.Count; i++) + { + var targetFramework = spec.TargetFrameworks[i]; + if (frameworksToAdd == null || frameworksToAdd.Contains(targetFramework.FrameworkName)) + { + var newCentralPackageVersion = new KeyValuePair(dependency.Id, new CentralPackageVersion(dependency.Id, dependency.VersionRange)); + var newCentralPackageVersionsEnum = targetFramework.CentralPackageVersions + .Where(kvp => !string.Equals(kvp.Key, dependency.Id, StringComparison.OrdinalIgnoreCase)) + .Append(newCentralPackageVersion); + var newCentralPackageVersions = CreateCentralPackageVersions(newCentralPackageVersionsEnum); + + spec.TargetFrameworks[i] = new TargetFrameworkInformation(targetFramework) { CentralPackageVersions = newCentralPackageVersions }; + } + } } + } - foreach (IDictionary centralPackageVersionList in GetCentralPackageVersionLists(spec, frameworksToAdd)) + static IReadOnlyDictionary CreateCentralPackageVersions(IEnumerable> versions) + { + Dictionary result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var kvp in versions) { - centralPackageVersionList[dependency.Id] = new CentralPackageVersion(dependency.Id, dependency.VersionRange); + result.Add(kvp.Key, kvp.Value); } + + return result; } /// @@ -138,115 +214,87 @@ public static void RemoveDependency( if (spec == null) throw new ArgumentNullException(nameof(spec)); if (packageId == null) throw new ArgumentNullException(nameof(packageId)); - var lists = GetDependencyLists( - spec, - includeGenericDependencies: true, - frameworksToConsider: null); - - foreach (var list in lists) + for (var i = spec.Dependencies.Count - 1; i >= 0; i--) { - var matchingDependencies = list - .Where(e => StringComparer.OrdinalIgnoreCase.Equals(e.Name, packageId)) - .ToList(); - - foreach (var dependency in matchingDependencies) + var dependency = spec.Dependencies[i]; + if (IsMatchingDependencyName(dependency, packageId)) { - list.Remove(dependency); + spec.Dependencies.RemoveAt(i); } } - } - - /// - /// Get the list of dependencies in the package spec. Unless null is provided, the - /// set can be used to get the dependency lists for only for the - /// provided target frameworks. If null is provided, all framework dependency lists are returned. - /// - /// The package spec. - /// - /// Whether or not the generic dependency list should be returned (dependencies that apply to all target - /// frameworks. - /// - /// The frameworks to consider. - /// The sequence of dependency lists. - private static IEnumerable> GetDependencyLists( - PackageSpec spec, - IEnumerable frameworksToConsider, - bool includeGenericDependencies) - { - if (includeGenericDependencies) - { - yield return spec.Dependencies; - } - foreach (var targetFramework in spec.TargetFrameworks) + for (var i = 0; i < spec.TargetFrameworks.Count; i++) { - if (frameworksToConsider == null || frameworksToConsider.Contains(targetFramework.FrameworkName)) + var framework = spec.TargetFrameworks[i]; + var matchingDependencyCount = framework.Dependencies.Count(dep => IsMatchingDependencyName(dep, packageId)); + if (matchingDependencyCount == 0) { - yield return targetFramework.Dependencies; + continue; } - } - } - private static IEnumerable> GetCentralPackageVersionLists( - PackageSpec spec, - IEnumerable frameworksToConsider) - { - if (spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false) - { - foreach (var targetFramework in spec.TargetFrameworks) + var remainingDependencies = new LibraryDependency[framework.Dependencies.Length - matchingDependencyCount]; + var dependencyIndex = 0; + foreach (var dep in framework.Dependencies) { - if (frameworksToConsider == null || frameworksToConsider.Contains(targetFramework.FrameworkName)) + if (!IsMatchingDependencyName(dep, packageId)) { - yield return targetFramework.CentralPackageVersions; + remainingDependencies[dependencyIndex++] = dep; } } + + var remainingDependenciesImmutable = ImmutableCollectionsMarshal.AsImmutableArray(remainingDependencies); + spec.TargetFrameworks[i] = new TargetFrameworkInformation(framework) { Dependencies = remainingDependenciesImmutable }; } } - private static List GetExistingDependencies(PackageSpec spec, string packageId) + private static bool IsMatchingDependencyName(LibraryDependency dependency, string dependencyName) { - return GetDependencyLists(spec, frameworksToConsider: null, includeGenericDependencies: true) - .SelectMany(list => list) - .Where(library => StringComparer.OrdinalIgnoreCase.Equals(library.Name, packageId)) - .ToList(); + return StringComparer.OrdinalIgnoreCase.Equals(dependency.Name, dependencyName); } - private static void AddOrUpdateDependencyInDependencyList( + private static ImmutableArray AddOrUpdateDependencyInDependencyList( PackageSpec spec, - IList list, + ImmutableArray list, string packageId, VersionRange range) { + var existingDependency = list.Any(dep => IsMatchingDependencyName(dep, packageId)); - var dependencies = list.Where(e => StringComparer.OrdinalIgnoreCase.Equals(e.Name, packageId)).ToList(); - - if (dependencies.Count != 0) + if (existingDependency) { - foreach (var library in dependencies) + var result = new LibraryDependency[list.Length]; + for (var i = 0; i < list.Length; i++) { - library.LibraryRange.VersionRange = range; + var libraryDependency = list[i]; + if (IsMatchingDependencyName(libraryDependency, packageId)) + { + var libraryRange = new LibraryRange(libraryDependency.LibraryRange) { VersionRange = range }; + libraryDependency = new LibraryDependency(libraryDependency) { LibraryRange = libraryRange }; + } + + result[i] = libraryDependency; } + + return ImmutableCollectionsMarshal.AsImmutableArray(result); } else { - AddDependency(list, packageId, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); - } + var newDependency = CreateDependency(packageId, range, spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false); + return list.Add(newDependency); + } } - private static void AddDependency( - IList list, + private static LibraryDependency CreateDependency( string packageId, VersionRange range, bool centralPackageVersionsEnabled) { - var dependency = new LibraryDependency(noWarn: Array.Empty()) + return new LibraryDependency() { LibraryRange = new LibraryRange(packageId, range, LibraryDependencyTarget.Package), VersionCentrallyManaged = centralPackageVersionsEnabled }; - - list.Add(dependency); } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecReferenceDependencyProvider.cs b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecReferenceDependencyProvider.cs index 69899bcfe8a..aa5e70df663 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecReferenceDependencyProvider.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecReferenceDependencyProvider.cs @@ -264,7 +264,7 @@ private List GetDependenciesFromSpecRestoreMetadata(PackageSp } } - var dependency = new LibraryDependency(noWarn: Array.Empty()) + var dependency = new LibraryDependency() { IncludeType = (reference.IncludeAssets & ~reference.ExcludeAssets), SuppressParent = reference.PrivateAssets, @@ -309,10 +309,17 @@ private List GetDependenciesFromExternalReference( // Set all dependencies from project.json to external if an external match was passed in // This is viral and keeps p2ps from looking into directories when we are going down // a path already resolved by msbuild. - foreach (var dependency in dependencies.Where(d => IsProject(d) - && filteredExternalDependencies.Contains(d.Name))) + for (int i = 0; i < dependencies.Count; i++) { - dependency.LibraryRange.TypeConstraint = LibraryDependencyTarget.ExternalProject; + var d = dependencies[i]; + if (IsProject(d) && filteredExternalDependencies.Contains(d.Name)) + { + var libraryRange = new LibraryRange(d.LibraryRange) { TypeConstraint = LibraryDependencyTarget.ExternalProject }; + + // Do not push the dependency changes here upwards, as the original package + // spec should not be modified. + dependencies[i] = new LibraryDependency(d) { LibraryRange = libraryRange }; + } } // Add dependencies passed in externally @@ -321,7 +328,7 @@ private List GetDependenciesFromExternalReference( // Note: Only add in dependencies that are in the filtered list to avoid getting the wrong TxM dependencies.AddRange(childReferences .Where(reference => filteredExternalDependencies.Contains(reference.ProjectName)) - .Select(reference => new LibraryDependency(noWarn: Array.Empty()) + .Select(reference => new LibraryDependency() { LibraryRange = new LibraryRange { @@ -365,7 +372,7 @@ internal List GetSpecDependencies( var dependencyNamesSet = new HashSet(targetFrameworkInfo.Dependencies.Select(d => d.Name), StringComparer.OrdinalIgnoreCase); dependencies.AddRange(targetFrameworkInfo.CentralPackageVersions .Where(item => !dependencyNamesSet.Contains(item.Key)) - .Select(item => new LibraryDependency(noWarn: Array.Empty()) + .Select(item => new LibraryDependency() { LibraryRange = new LibraryRange(item.Value.Name, item.Value.VersionRange, LibraryDependencyTarget.Package), VersionCentrallyManaged = true, @@ -378,13 +385,15 @@ internal List GetSpecDependencies( for (var i = 0; i < dependencies.Count; i++) { - // Clone the library dependency so we can safely modify it. The instance cloned here is from the - // original package spec, which should not be modified. - dependencies[i] = dependencies[i].Clone(); + // Do not push the dependency changes here upwards, as the original package + // spec should not be modified. + // Remove "project" from the allowed types for this dependency // This will require that projects referenced by an msbuild project // must be external projects. - dependencies[i].LibraryRange.TypeConstraint &= ~LibraryDependencyTarget.Project; + var dependency = dependencies[i]; + var libraryRange = new LibraryRange(dependency.LibraryRange) { TypeConstraint = dependency.LibraryRange.TypeConstraint & ~LibraryDependencyTarget.Project }; + dependencies[i] = new LibraryDependency(dependency) { LibraryRange = libraryRange }; } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecWriter.cs b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecWriter.cs index f16cda1ec3b..d1986014e7f 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PackageSpecWriter.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/PackageSpecWriter.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using Newtonsoft.Json; @@ -438,7 +439,7 @@ private static void SetPackOptions(IObjectWriter writer, PackageSpec packageSpec writer.WriteObjectEnd(); } - private static void SetDependencies(IObjectWriter writer, IList libraryDependencies) + private static void SetDependencies(IObjectWriter writer, IEnumerable libraryDependencies) { SetDependencies(writer, "dependencies", libraryDependencies.Where(dependency => dependency.LibraryRange.TypeConstraint != LibraryDependencyTarget.Reference)); SetDependencies(writer, "frameworkAssemblies", libraryDependencies.Where(dependency => dependency.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference)); @@ -510,7 +511,7 @@ internal static void SetDependencies(IObjectWriter writer, string name, IEnumera SetValueIfTrue(writer, "autoReferenced", dependency.AutoReferenced); - if (dependency.NoWarn.Count > 0) + if (dependency.NoWarn.Length > 0) { SetArrayValue(writer, "noWarn", dependency .NoWarn @@ -573,9 +574,9 @@ internal static void SetCentralTransitveDependencyGroup(IObjectWriter writer, st writer.WriteObjectEnd(); } - private static void SetImports(IObjectWriter writer, IList frameworks) + private static void SetImports(IObjectWriter writer, ImmutableArray frameworks) { - if (frameworks?.Count > 0) + if (frameworks.Length > 0) { var imports = frameworks.Select(framework => framework.GetShortFolderName()); @@ -583,9 +584,9 @@ private static void SetImports(IObjectWriter writer, IList frame } } - private static void SetDownloadDependencies(IObjectWriter writer, IList downloadDependencies) + private static void SetDownloadDependencies(IObjectWriter writer, ImmutableArray downloadDependencies) { - if (!(downloadDependencies.Count > 0)) + if (downloadDependencies.Length == 0) { return; } @@ -616,7 +617,7 @@ private static void SetFrameworks(IObjectWriter writer, IList frameworkReferences) + private static void SetFrameworkReferences(IObjectWriter writer, IReadOnlyCollection frameworkReferences) { if (frameworkReferences?.Count > 0) { @@ -664,9 +665,9 @@ private static void SetFrameworkReferences(IObjectWriter writer, ISet centralPackageVersions, bool hashing) + private static void SetCentralDependencies(IObjectWriter writer, int count, IEnumerable centralPackageVersions, bool hashing) { - if (!(centralPackageVersions.Count > 0)) + if (count == 0) { return; } diff --git a/src/NuGet.Core/NuGet.ProjectModel/ProjectLockFile/PackagesLockFileUtilities.cs b/src/NuGet.Core/NuGet.ProjectModel/ProjectLockFile/PackagesLockFileUtilities.cs index b225b152b46..5024109e92a 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/ProjectLockFile/PackagesLockFileUtilities.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/ProjectLockFile/PackagesLockFileUtilities.cs @@ -519,7 +519,7 @@ private static (bool, string) HasP2PDependencyChanged(IEnumerable private static (bool, string) HasProjectTransitiveDependencyChanged( - IDictionary centralPackageVersions, + IReadOnlyDictionary centralPackageVersions, IList lockFileCentralTransitiveDependencies, IList lockTransitiveDependencies) { diff --git a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Shipped.txt b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Shipped.txt index 5cd28cf6f71..319cadd5c6c 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Shipped.txt +++ b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Shipped.txt @@ -571,25 +571,12 @@ NuGet.ProjectModel.RestoreLockProperties.RestoreLockedMode.get -> bool ~NuGet.ProjectModel.RestoreLockProperties.RestorePackagesWithLockFile.get -> string NuGet.ProjectModel.TargetFrameworkInformation NuGet.ProjectModel.TargetFrameworkInformation.AssetTargetFallback.get -> bool -NuGet.ProjectModel.TargetFrameworkInformation.AssetTargetFallback.set -> void -~NuGet.ProjectModel.TargetFrameworkInformation.CentralPackageVersions.get -> System.Collections.Generic.IDictionary -~NuGet.ProjectModel.TargetFrameworkInformation.Clone() -> NuGet.ProjectModel.TargetFrameworkInformation -~NuGet.ProjectModel.TargetFrameworkInformation.Dependencies.get -> System.Collections.Generic.IList -~NuGet.ProjectModel.TargetFrameworkInformation.Dependencies.set -> void -~NuGet.ProjectModel.TargetFrameworkInformation.DownloadDependencies.get -> System.Collections.Generic.IList ~NuGet.ProjectModel.TargetFrameworkInformation.Equals(NuGet.ProjectModel.TargetFrameworkInformation other) -> bool ~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkName.get -> NuGet.Frameworks.NuGetFramework -~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkName.set -> void -~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkReferences.get -> System.Collections.Generic.ISet -~NuGet.ProjectModel.TargetFrameworkInformation.Imports.get -> System.Collections.Generic.IList -~NuGet.ProjectModel.TargetFrameworkInformation.Imports.set -> void ~NuGet.ProjectModel.TargetFrameworkInformation.RuntimeIdentifierGraphPath.get -> string -~NuGet.ProjectModel.TargetFrameworkInformation.RuntimeIdentifierGraphPath.set -> void ~NuGet.ProjectModel.TargetFrameworkInformation.TargetAlias.get -> string -~NuGet.ProjectModel.TargetFrameworkInformation.TargetAlias.set -> void NuGet.ProjectModel.TargetFrameworkInformation.TargetFrameworkInformation() -> void NuGet.ProjectModel.TargetFrameworkInformation.Warn.get -> bool -NuGet.ProjectModel.TargetFrameworkInformation.Warn.set -> void NuGet.ProjectModel.ToolPathResolver ~NuGet.ProjectModel.ToolPathResolver.GetBestToolDirectoryPath(string packageId, NuGet.Versioning.VersionRange versionRange, NuGet.Frameworks.NuGetFramework framework) -> string ~NuGet.ProjectModel.ToolPathResolver.GetLockFilePath(string packageId, NuGet.Versioning.NuGetVersion version, NuGet.Frameworks.NuGetFramework framework) -> string @@ -731,8 +718,6 @@ static NuGet.ProjectModel.BuildAction.operator ==(NuGet.ProjectModel.BuildAction ~static NuGet.ProjectModel.ProjectLockFile.LockFileDependencyComparerWithoutContentHash.Default.get -> NuGet.ProjectModel.ProjectLockFile.LockFileDependencyComparerWithoutContentHash static NuGet.ProjectModel.RestoreAuditProperties.operator !=(NuGet.ProjectModel.RestoreAuditProperties? x, NuGet.ProjectModel.RestoreAuditProperties? y) -> bool static NuGet.ProjectModel.RestoreAuditProperties.operator ==(NuGet.ProjectModel.RestoreAuditProperties? x, NuGet.ProjectModel.RestoreAuditProperties? y) -> bool -~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, System.Collections.Generic.IEnumerable warningsAsErrors, System.Collections.Generic.IEnumerable noWarn) -> NuGet.ProjectModel.WarningProperties -~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, System.Collections.Generic.IEnumerable warningsAsErrors, System.Collections.Generic.IEnumerable noWarn, System.Collections.Generic.IEnumerable warningsNotAsErrors) -> NuGet.ProjectModel.WarningProperties ~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, string warningsAsErrors, string noWarn) -> NuGet.ProjectModel.WarningProperties ~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, string warningsAsErrors, string noWarn, string warningsNotAsErrors) -> NuGet.ProjectModel.WarningProperties static readonly NuGet.ProjectModel.BuildAction.AndroidAsset -> NuGet.ProjectModel.BuildAction diff --git a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt index 7dc5c58110b..c13bc777d67 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt @@ -1 +1,19 @@ #nullable enable +NuGet.ProjectModel.TargetFrameworkInformation.AssetTargetFallback.init -> void +NuGet.ProjectModel.TargetFrameworkInformation.Warn.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.CentralPackageVersions.get -> System.Collections.Generic.IReadOnlyDictionary +~NuGet.ProjectModel.TargetFrameworkInformation.CentralPackageVersions.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.Dependencies.get -> System.Collections.Immutable.ImmutableArray +~NuGet.ProjectModel.TargetFrameworkInformation.Dependencies.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.DownloadDependencies.get -> System.Collections.Immutable.ImmutableArray +~NuGet.ProjectModel.TargetFrameworkInformation.DownloadDependencies.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkName.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkReferences.get -> System.Collections.Generic.IReadOnlyCollection +~NuGet.ProjectModel.TargetFrameworkInformation.FrameworkReferences.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.Imports.get -> System.Collections.Immutable.ImmutableArray +~NuGet.ProjectModel.TargetFrameworkInformation.Imports.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.RuntimeIdentifierGraphPath.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.TargetAlias.init -> void +~NuGet.ProjectModel.TargetFrameworkInformation.TargetFrameworkInformation(NuGet.ProjectModel.TargetFrameworkInformation cloneFrom) -> void +~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, System.Collections.Immutable.ImmutableArray warningsAsErrors, System.Collections.Immutable.ImmutableArray noWarn) -> NuGet.ProjectModel.WarningProperties +~static NuGet.ProjectModel.WarningProperties.GetWarningProperties(string treatWarningsAsErrors, System.Collections.Immutable.ImmutableArray warningsAsErrors, System.Collections.Immutable.ImmutableArray noWarn, System.Collections.Immutable.ImmutableArray warningsNotAsErrors) -> NuGet.ProjectModel.WarningProperties diff --git a/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs b/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs index ebe68b5b1cb..e667d597737 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Collections.Immutable; using NuGet.Common; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -13,80 +13,112 @@ namespace NuGet.ProjectModel { public class TargetFrameworkInformation : IEquatable { - public string TargetAlias { get; set; } + // private fields to allow for validating initialization values + private IReadOnlyDictionary _centralPackageVersions; + private ImmutableArray _dependencies; + private ImmutableArray _downloadDependencies; + private IReadOnlyCollection _frameworkReferences; + private ImmutableArray _imports; - public NuGetFramework FrameworkName { get; set; } + public string TargetAlias { get; init; } - public IList Dependencies { get; set; } + public NuGetFramework FrameworkName { get; init; } + + public ImmutableArray Dependencies + { + get => _dependencies; + init + { + _dependencies = value.IsDefault ? ImmutableArray.Empty : value; + } + } /// /// A fallback PCL framework to use when no compatible items /// were found for . /// - public IList Imports { get; set; } + public ImmutableArray Imports + { + get => _imports; + init + { + _imports = value.IsDefault ? ImmutableArray.Empty : value; + } + } /// /// If True AssetTargetFallback behavior will be used for Imports. /// - public bool AssetTargetFallback { get; set; } + public bool AssetTargetFallback { get; init; } /// /// Display warnings when the Imports framework is used. /// - public bool Warn { get; set; } + public bool Warn { get; init; } /// /// List of dependencies that are not part of the graph resolution. /// - public IList DownloadDependencies { get; } + public ImmutableArray DownloadDependencies + { + get => _downloadDependencies; + init + { + _downloadDependencies = value.IsDefault ? ImmutableArray.Empty : value; + } + } /// - /// List of the package versions defined in the Central package versions management file. + /// Package versions defined in the Central package versions management file. /// - public IDictionary CentralPackageVersions { get; } + public IReadOnlyDictionary CentralPackageVersions + { + get => _centralPackageVersions; + init + { + _centralPackageVersions = value ?? ImmutableDictionary.Empty; + } + } /// /// A set of unique FrameworkReferences /// - public ISet FrameworkReferences { get; } + public IReadOnlyCollection FrameworkReferences + { + get => _frameworkReferences; + init + { + _frameworkReferences = value ?? ImmutableHashSet.Empty; + } + } /// /// The project provided runtime.json /// - public string RuntimeIdentifierGraphPath { get; set; } + public string RuntimeIdentifierGraphPath { get; init; } public TargetFrameworkInformation() { TargetAlias = string.Empty; - Dependencies = new List(); - Imports = new List(); - DownloadDependencies = new List(); - CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase); - FrameworkReferences = new HashSet(); + Dependencies = []; + Imports = []; + DownloadDependencies = []; + CentralPackageVersions = ImmutableDictionary.Empty; + FrameworkReferences = ImmutableHashSet.Empty; } - internal TargetFrameworkInformation(TargetFrameworkInformation cloneFrom) + public TargetFrameworkInformation(TargetFrameworkInformation cloneFrom) { TargetAlias = cloneFrom.TargetAlias; FrameworkName = cloneFrom.FrameworkName; - Dependencies = CloneList(cloneFrom.Dependencies, static dep => dep.Clone()); - Imports = new List(cloneFrom.Imports); + Dependencies = cloneFrom.Dependencies; + Imports = cloneFrom.Imports; AssetTargetFallback = cloneFrom.AssetTargetFallback; Warn = cloneFrom.Warn; - DownloadDependencies = cloneFrom.DownloadDependencies.ToList(); - CentralPackageVersions = new Dictionary(cloneFrom.CentralPackageVersions, StringComparer.OrdinalIgnoreCase); - FrameworkReferences = new HashSet(cloneFrom.FrameworkReferences); + DownloadDependencies = cloneFrom.DownloadDependencies; + CentralPackageVersions = cloneFrom.CentralPackageVersions; + FrameworkReferences = cloneFrom.FrameworkReferences; RuntimeIdentifierGraphPath = cloneFrom.RuntimeIdentifierGraphPath; - - static IList CloneList(IList source, Func cloneFunc) - { - var clone = new List(capacity: source.Count); - for (int i = 0; i < source.Count; i++) - { - clone.Add(cloneFunc(source[i])); - } - return clone; - } } public override string ToString() @@ -101,7 +133,7 @@ public override int GetHashCode() hashCode.AddObject(FrameworkName); hashCode.AddObject(AssetTargetFallback); hashCode.AddUnorderedSequence(Dependencies); - hashCode.AddSequence(Imports); + hashCode.AddSequence((IReadOnlyList)Imports); hashCode.AddObject(Warn); hashCode.AddUnorderedSequence(DownloadDependencies); hashCode.AddUnorderedSequence(FrameworkReferences); @@ -142,10 +174,5 @@ public bool Equals(TargetFrameworkInformation other) PathUtility.GetStringComparerBasedOnOS().Equals(RuntimeIdentifierGraphPath, other.RuntimeIdentifierGraphPath) && StringComparer.OrdinalIgnoreCase.Equals(TargetAlias, other.TargetAlias); } - - public TargetFrameworkInformation Clone() - { - return new TargetFrameworkInformation(this); - } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/WarningProperties.cs b/src/NuGet.Core/NuGet.ProjectModel/WarningProperties.cs index 3f7cf27563e..ab044c58cd1 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/WarningProperties.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/WarningProperties.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Collections.Immutable; using NuGet.Common; using NuGet.Shared; @@ -116,7 +116,7 @@ public static WarningProperties GetWarningProperties(string treatWarningsAsError /// /// Create warning properties from NuGetLogCode collection. /// - public static WarningProperties GetWarningProperties(string treatWarningsAsErrors, IEnumerable warningsAsErrors, IEnumerable noWarn, IEnumerable warningsNotAsErrors) + public static WarningProperties GetWarningProperties(string treatWarningsAsErrors, ImmutableArray warningsAsErrors, ImmutableArray noWarn, ImmutableArray warningsNotAsErrors) { var props = new WarningProperties() { @@ -133,9 +133,9 @@ public static WarningProperties GetWarningProperties(string treatWarningsAsError /// Create warning properties from NuGetLogCode collection. /// [Obsolete] - public static WarningProperties GetWarningProperties(string treatWarningsAsErrors, IEnumerable warningsAsErrors, IEnumerable noWarn) + public static WarningProperties GetWarningProperties(string treatWarningsAsErrors, ImmutableArray warningsAsErrors, ImmutableArray noWarn) { - return GetWarningProperties(treatWarningsAsErrors, warningsAsErrors, noWarn, Enumerable.Empty()); + return GetWarningProperties(treatWarningsAsErrors, warningsAsErrors, noWarn, []); } } } diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreNETCoreTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreNETCoreTest.cs index 5b60567a32c..a0716433dcc 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreNETCoreTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreNETCoreTest.cs @@ -6787,7 +6787,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var lockFile = LockFileUtilities.GetLockFile(projectA.AssetsFileOutputPath, Common.NullLogger.Instance); Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); Assert.True(Directory.Exists(Path.Combine(pathContext.UserPackagesFolder, packageX.Identity.Id, packageX.Version)), $"{packageX.ToString()} is not installed"); } @@ -6841,7 +6841,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var lockFile = LockFileUtilities.GetLockFile(projectA.AssetsFileOutputPath, Common.NullLogger.Instance); Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks[0].DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks[0].DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks[0].DownloadDependencies[0].Name); Assert.Equal($"[{packageX1.Version}, {packageX1.Version}]", lockFile.PackageSpec.TargetFrameworks[0].DownloadDependencies[0].VersionRange.ToNormalizedString()); @@ -6910,7 +6910,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var lockFile = LockFileUtilities.GetLockFile(projectA.AssetsFileOutputPath, Common.NullLogger.Instance); Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); + Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); Assert.Equal($"[{packageX1.Version}, {packageX1.Version}]", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().VersionRange.ToNormalizedString()); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Last().Name); @@ -6971,8 +6971,8 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( Assert.Equal(1, lockFile.Libraries.Count); Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().Dependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().Dependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); Assert.Equal($"[{packageX2.Version}, {packageX2.Version}]", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().VersionRange.ToNormalizedString()); @@ -7036,10 +7036,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.First().Dependencies.Count); - Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.Last().Dependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.First().Dependencies.Length); + Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.Last().Dependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); Assert.Equal($"[{packageX2.Version}, {packageX2.Version}]", @@ -7146,7 +7146,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var lockFile = LockFileUtilities.GetLockFile(projectA.AssetsFileOutputPath, Common.NullLogger.Instance); Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); var packagePath = Path.Combine(pathContext.UserPackagesFolder, packageX.Identity.Id, packageX.Version); Assert.True(Directory.Exists(packagePath), $"{packageX.ToString()} is not installed"); @@ -7204,7 +7204,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var lockFile = LockFileUtilities.GetLockFile(projectA.AssetsFileOutputPath, Common.NullLogger.Instance); Assert.Equal(0, lockFile.Libraries.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); var packagePath = Path.Combine(pathContext.UserPackagesFolder, packageX.Identity.Id, packageX.Version); Assert.True(Directory.Exists(packagePath), $"{packageX.ToString()} is not installed"); @@ -7498,8 +7498,8 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( Assert.Equal(1, lockFile.Targets.First().Libraries.Count); Assert.Equal("FrameworkRef", string.Join(",", lockFile.Targets.First().Libraries.First().FrameworkReferences)); Assert.True(Directory.Exists(Path.Combine(pathContext.UserPackagesFolder, packageX.Identity.Id, packageX.Version)), $"{packageX.ToString()} is not installed"); - Assert.Equal("all", FrameworkDependencyFlagsUtils.GetFlagString(lockFile.PackageSpec.TargetFrameworks.Single().FrameworkReferences.First().PrivateAssets)); - Assert.Equal("none", FrameworkDependencyFlagsUtils.GetFlagString(lockFile.PackageSpec.TargetFrameworks.Single().FrameworkReferences.Last().PrivateAssets)); + Assert.True(1 == lockFile.PackageSpec.TargetFrameworks.Single().FrameworkReferences.Count(dep => FrameworkDependencyFlagsUtils.GetFlagString(dep.PrivateAssets) == "all")); + Assert.True(1 == lockFile.PackageSpec.TargetFrameworks.Single().FrameworkReferences.Count(dep => FrameworkDependencyFlagsUtils.GetFlagString(dep.PrivateAssets) == "none")); // Assert 2 Assert.True(File.Exists(projectB.AssetsFileOutputPath), r.AllOutput); diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/CpsPackageReferenceProjectTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/CpsPackageReferenceProjectTests.cs index 954931225ee..ab1c094ea41 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/CpsPackageReferenceProjectTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/CpsPackageReferenceProjectTests.cs @@ -564,7 +564,9 @@ await nuGetPackageManager.ExecuteNuGetProjectActionsAsync( typeConstraint: LibraryDependencyTarget.Package), }; - packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -675,7 +677,9 @@ await nuGetPackageManager.ExecuteNuGetProjectActionsAsync( typeConstraint: LibraryDependencyTarget.Package), }; - packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -809,7 +813,10 @@ await nuGetPackageManager.ExecuteNuGetProjectActionsAsync( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -937,7 +944,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -972,7 +982,10 @@ await nuGetPackageManager.ExecuteNuGetProjectActionsAsync( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Insert(0, installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1091,7 +1104,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1228,7 +1244,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1377,7 +1396,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1527,7 +1549,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1677,7 +1702,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1827,7 +1855,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -1965,7 +1996,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -2099,7 +2133,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -2232,7 +2269,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -2580,7 +2620,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -2735,7 +2778,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; var packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + var projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); var projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -3052,7 +3098,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; PackageSpec packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); ProjectNames projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -3194,7 +3243,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; PackageSpec packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); ProjectNames projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -3339,7 +3391,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; PackageSpec packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); ProjectNames projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -3483,7 +3538,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; PackageSpec packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); ProjectNames projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); @@ -3629,7 +3687,10 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( }; PackageSpec packageSpec = packageSpecs[i]; - packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(installed); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); ProjectNames projectNames = GetTestProjectNames(projectFullPaths[i], $"project{i}"); projectCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, new List()); diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs index 62bcb42a03a..6c04bd11f9b 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs @@ -8,6 +8,7 @@ using System.Threading; using FluentAssertions; using Microsoft.VisualStudio.ComponentModelHost; +using Microsoft.VisualStudio.ProjectSystem; using Microsoft.VisualStudio.Sdk.TestFramework; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Threading; @@ -1821,6 +1822,111 @@ public async Task GetPackageSpec_WithUseLegacyDependencyResolver(string restoreU actualRestoreSpec.RestoreMetadata.UseLegacyDependencyResolver.Should().Be(expected); } + [Fact] + public async Task GetPackageSpecAsync_WithVariousCentralPackageVersions_AppliesFlagsCorreclty() + { + // Arrange + var tfm = NuGetFramework.Parse("net472"); + var packageA = (PackageId: "packageA", Version: "1.2.3"); + var packageB = (PackageId: "packageB", Version: "3.4.5"); + var packageC = (PackageId: "packageC", Version: "6.7.8"); + var packageD = (PackageId: "packageD", Version: "9.9.9"); + + var projectNames = new ProjectNames( + fullName: "projectName", + uniqueName: "projectName", + shortName: "projectName", + customUniqueName: "projectName", + projectId: Guid.NewGuid().ToString()); + + var projectServices = new TestProjectSystemServices(); + projectServices.SetupInstalledPackages( + tfm, + new LibraryDependency + { + LibraryRange = new LibraryRange( + packageA.PackageId, + null, + LibraryDependencyTarget.Package), + }, + new LibraryDependency + { + LibraryRange = new LibraryRange( + packageB.PackageId, + null, + LibraryDependencyTarget.Package), + }, + new LibraryDependency + { + LibraryRange = new LibraryRange( + packageC.PackageId, + VersionRange.Parse("2.0.0"), + LibraryDependencyTarget.Package), + AutoReferenced = true, + }, + new LibraryDependency + { + LibraryRange = new LibraryRange( + packageD.PackageId, + null, + LibraryDependencyTarget.Package), + VersionOverride = VersionRange.Parse("3.0.0"), + }); + + var vsProjectAdapter = new TestVSProjectAdapter( + "projectPath", + projectNames, + "net472", + restorePackagesWithLockFile: null, + nuGetLockFilePath: null, + restoreLockedMode: false, + projectPackageVersions: new List<(string Id, string Version)>() { packageA, packageB, packageC, packageD }, + isCentralPackageVersionOverrideEnabled: "true"); + + var legacyPRProject = new LegacyPackageReferenceProject( + vsProjectAdapter, + Guid.NewGuid().ToString(), + projectServices, + _threadingService); + + var settings = NullSettings.Instance; + var context = new DependencyGraphCacheContext(NullLogger.Instance, settings); + + var packageSpecs = await legacyPRProject.GetPackageSpecsAsync(context); + + packageSpecs.Should().HaveCount(1); + PackageSpec spec = packageSpecs[0]; + spec.TargetFrameworks.Should().HaveCount(1); + TargetFrameworkInformation tfi = spec.TargetFrameworks[0]; + tfi.FrameworkName.Should().Be(tfm); + tfi.CentralPackageVersions.Should().HaveCount(4); + tfi.Dependencies.Should().HaveCount(4); + + tfi.Dependencies[0].Name.Should().Be(packageA.PackageId); + tfi.Dependencies[0].VersionCentrallyManaged.Should().BeTrue(); + tfi.Dependencies[0].LibraryRange.VersionRange.Should().Be(VersionRange.Parse(packageA.Version)); + tfi.Dependencies[0].VersionOverride.Should().BeNull(); + + tfi.Dependencies[1].Name.Should().Be(packageB.PackageId); + tfi.Dependencies[1].VersionCentrallyManaged.Should().BeTrue(); + tfi.Dependencies[1].LibraryRange.VersionRange.Should().Be(VersionRange.Parse(packageB.Version)); + tfi.Dependencies[1].VersionOverride.Should().BeNull(); + + tfi.Dependencies[2].Name.Should().Be(packageC.PackageId); + tfi.Dependencies[2].VersionCentrallyManaged.Should().BeFalse(); + tfi.Dependencies[2].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("2.0.0")); + tfi.Dependencies[2].AutoReferenced.Should().BeTrue(); + tfi.Dependencies[2].VersionOverride.Should().BeNull(); + + tfi.Dependencies[2].LibraryRange.VersionRange.Should().NotBe(tfi.CentralPackageVersions[packageC.PackageId].VersionRange); + + tfi.Dependencies[3].Name.Should().Be(packageD.PackageId); + tfi.Dependencies[3].VersionCentrallyManaged.Should().BeFalse(); + tfi.Dependencies[3].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("3.0.0")); + tfi.Dependencies[3].AutoReferenced.Should().BeFalse(); + tfi.Dependencies[3].VersionOverride.Should().Be(VersionRange.Parse("3.0.0")); + } + private LegacyPackageReferenceProject CreateLegacyPackageReferenceProject(TestDirectory testDirectory, string range) { return ProjectFactories.CreateLegacyPackageReferenceProject(testDirectory, Guid.NewGuid().ToString(), range, _threadingService); diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs index e5d310b3205..f70d140674a 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs @@ -2309,7 +2309,7 @@ public async Task DependencyGraphRestoreUtility_LegacyPackageRef_CPVM_Restore() } } - Assert.Equal(1, targetFramework.Dependencies.Count); + Assert.Equal(1, targetFramework.Dependencies.Length); Assert.Equal(packageA.PackageId, targetFramework.Dependencies.First().Name); Assert.Equal(VersionRange.Parse(packageA.Version), targetFramework.Dependencies.First().LibraryRange.VersionRange); Assert.True(targetFramework.Dependencies.First().VersionCentrallyManaged); diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs index 6cec5bd1576..ffb26e13bad 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs @@ -26,7 +26,7 @@ internal class TestVSProjectAdapter : IVsProjectAdapter private readonly bool _isCPVMEnabled; private readonly IEnumerable<(string PackageId, string Version)> _projectPackageVersions; private readonly string _isCentralPackageVersionOverrideEnabled; - private readonly string _CentralPackageTransitivePinningEnabled; + private readonly string _isCentralPackageTransitivePinningEnabled; public TestVSProjectAdapter( string fullProjectPath, @@ -49,7 +49,7 @@ public TestVSProjectAdapter( _isCPVMEnabled = projectPackageVersions?.Any() == true; _projectPackageVersions = projectPackageVersions; _isCentralPackageVersionOverrideEnabled = isCentralPackageVersionOverrideEnabled; - _CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; + _isCentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; #pragma warning disable CS0618 // Type or member is obsolete Mock.Get(BuildProperties) @@ -62,7 +62,7 @@ public TestVSProjectAdapter( Mock.Get(BuildProperties) .Setup(x => x.GetPropertyValueWithDteFallback(It.Is(x => x.Equals(ProjectBuildProperties.CentralPackageTransitivePinningEnabled)))) - .Returns(_CentralPackageTransitivePinningEnabled ?? string.Empty); + .Returns(_isCentralPackageTransitivePinningEnabled ?? string.Empty); Mock.Get(BuildProperties) .Setup(x => x.GetPropertyValueWithDteFallback(It.Is(x => x.Equals(ProjectBuildProperties.NuGetLockFilePath)))) diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/Services/NuGetProjectManagerServiceTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/Services/NuGetProjectManagerServiceTests.cs index a63ae2360fc..ccef2fd6cda 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/Services/NuGetProjectManagerServiceTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/Services/NuGetProjectManagerServiceTests.cs @@ -1641,7 +1641,9 @@ private static void AddPackageDependency(ProjectSystemCache projectSystemCache, typeConstraint: LibraryDependencyTarget.Package) }; - packageSpec.TargetFrameworks.First().Dependencies.Add(dependency); + var newDependencies = packageSpec.TargetFrameworks.First().Dependencies.Add(dependency); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; + DependencyGraphSpec projectRestoreInfo = ProjectTestHelpers.GetDGSpecForAllProjects(packageSpec); projectSystemCache.AddProjectRestoreInfo(projectNames, projectRestoreInfo, Array.Empty()); } diff --git a/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VSNominationUtilitiesTests.cs b/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VSNominationUtilitiesTests.cs index 72455c11da7..4407bb2ee29 100644 --- a/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VSNominationUtilitiesTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VSNominationUtilitiesTests.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using FluentAssertions; +using NuGet.Common; using NuGet.ProjectManagement; using NuGet.Versioning; using Xunit; @@ -396,5 +398,93 @@ public void GetPackageSpec_WithUseLegacyDependencyResolver_DoesNotSupportPerFram InvalidOperationException exception = Assert.Throws(() => VSNominationUtilities.GetUseLegacyDependencyResolver(targetFrameworks)); exception.Message.Should().Contain(ProjectBuildProperties.RestoreUseLegacyDependencyResolver); } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_SameLogCodes() + { + // Arrange + ImmutableArray logCodes1 = [NuGetLogCode.NU1000, NuGetLogCode.NU1001]; + ImmutableArray logCodes2 = [NuGetLogCode.NU1001, NuGetLogCode.NU1000]; + + ImmutableArray> logCodesList = [logCodes1, logCodes2]; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(2, result.Length); + Assert.True(result.All(logCodes2.Contains)); + } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_EmptyLogCodes() + { + // Arrange + ImmutableArray> logCodesList = []; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(0, result.Length); + } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_DiffLogCodes() + { + // Arrange + ImmutableArray logCodes1 = [NuGetLogCode.NU1000]; + ImmutableArray logCodes2 = [NuGetLogCode.NU1001, NuGetLogCode.NU1000]; + + ImmutableArray> logCodesList = [logCodes1, logCodes2]; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(0, result.Length); + } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_OneDefaultCode() + { + // Arrange + ImmutableArray logCodes1 = [NuGetLogCode.NU1001, NuGetLogCode.NU1000]; + + ImmutableArray> logCodesList = [default, logCodes1]; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(0, result.Length); + } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_AllDefaultCodes() + { + // Arrange + ImmutableArray> logCodesList = [default, default]; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(0, result.Length); + } + + [Fact] + public void GetDistinctNuGetLogCodesOrDefault_DefaultCodesAfterFirst() + { + // Arrange + ImmutableArray logCodes1 = [NuGetLogCode.NU1001, NuGetLogCode.NU1000]; + ImmutableArray> logCodesList = [logCodes1, default]; + + // Act + var result = VSNominationUtilities.GetDistinctNuGetLogCodesOrDefault(logCodesList); + + // Assert + Assert.Equal(0, result.Length); + } } } diff --git a/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VsSolutionRestoreServiceTests.cs b/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VsSolutionRestoreServiceTests.cs index 6e93f53cec5..907b751f019 100644 --- a/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VsSolutionRestoreServiceTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.SolutionRestoreManager.Test/VsSolutionRestoreServiceTests.cs @@ -21,6 +21,7 @@ using NuGet.ProjectManagement; using NuGet.ProjectModel; using NuGet.Test.Utility; +using NuGet.Versioning; using NuGet.VisualStudio; using NuGet.VisualStudio.Telemetry; using Test.Utility.ProjectManagement; @@ -880,7 +881,7 @@ public async Task DifferingPackageIdsFailsWithUsableErrorMessage() Assert.Equal(NuGetLogCode.NU1105, additionalMessage.Code); Assert.Equal(projectFullPath, additionalMessage.ProjectPath); Assert.Equal(projectFullPath, additionalMessage.FilePath); - Assert.Contains(string.Format(CultureInfo.CurrentCulture, Resources.PropertyDoesNotHaveSingleValue, "PackageId", "PackageId.net46, PackageId.netcoreapp1.0"), additionalMessage.Message); + additionalMessage.Message.Should().Contain(string.Format(CultureInfo.CurrentCulture, Resources.PropertyDoesNotHaveSingleValue, "PackageId", "PackageId.netcoreapp1.0, PackageId.net46")); } [Fact] @@ -2093,7 +2094,7 @@ public void ToPackageSpec_CentralVersions_AreNotAddedToThePackageSpecIfCPVMIsNot var tfm = result.TargetFrameworks.First(); var expectedPackageReferenceVersion = packRefVersion == null ? "(, )" : "[1.0.0, )"; Assert.Equal(0, tfm.CentralPackageVersions.Count); - Assert.Equal(1, tfm.Dependencies.Count); + Assert.Equal(1, tfm.Dependencies.Length); Assert.Equal(expectedPackageReferenceVersion, tfm.Dependencies.First().LibraryRange.VersionRange.ToNormalizedString()); Assert.False(result.RestoreMetadata.CentralPackageVersionsEnabled); } @@ -2591,6 +2592,108 @@ await CaptureNominateResultAsync(projectFullPath, builder.ProjectRestoreInfo2) : actualProjectSpec.RestoreMetadata.UseLegacyDependencyResolver.Should().BeTrue(); } + [Fact] + public void ToPackageSpec_WithCPMAndAutoReferencedPackages_SkipsAddingVersion() + { + // Arrange + ProjectNames projectName = new ProjectNames(@"f:\project\project.csproj", "project", "project.csproj", "projectC", Guid.NewGuid().ToString()); + var emptyReferenceItems = Array.Empty(); + var projectProperties = ProjectRestoreInfoBuilder.GetTargetFrameworkProperties(CommonFrameworks.NetStandard20); + projectProperties["ManagePackageVersionsCentrally"] = "true"; + + var targetFrameworks = new VsTargetFrameworkInfo4[] { new VsTargetFrameworkInfo4( + items: new Dictionary>() + { + [ProjectItems.PackageReference] = [new VsReferenceItem2("foo", EmptyProperties), + new VsReferenceItem2("bar", new Dictionary { { "IsImplicitlyDefined", "true" }, { "Version", "10.0.1" } })], + [ProjectItems.PackageVersion] = + [ + new VsReferenceItem2("foo", new Dictionary() { ["Version"] = "2.0.0"}), + ] + }, + properties: projectProperties) + }; + + var pri = new VsProjectRestoreInfo3 + { + MSBuildProjectExtensionsPath = string.Empty, + TargetFrameworks = targetFrameworks, + OriginalTargetFrameworks = CommonFrameworks.NetStandard20.ToString(), + }; + + // Act + var result = VsSolutionRestoreService.ToPackageSpec(projectName, pri); + + // Assert + var tfm = result.TargetFrameworks.First(); + + tfm.CentralPackageVersions.Should().HaveCount(1); + tfm.CentralPackageVersions.Single().Value.Name.Should().Be("foo"); + result.RestoreMetadata.CentralPackageVersionsEnabled.Should().BeTrue(); + tfm.Dependencies.Should().HaveCount(2); + tfm.Dependencies[0].Name.Should().Be("foo"); + tfm.Dependencies[0].VersionCentrallyManaged.Should().BeTrue(); + tfm.Dependencies[0].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("2.0.0")); + tfm.Dependencies[0].AutoReferenced.Should().BeFalse(); + + tfm.Dependencies[1].Name.Should().Be("bar"); + tfm.Dependencies[1].VersionCentrallyManaged.Should().BeFalse(); + tfm.Dependencies[1].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("10.0.1")); + tfm.Dependencies[1].AutoReferenced.Should().BeTrue(); + } + + [Fact] + public void ToPackageSpec_WithCPMAndVersionOverride_SetsVersionToVersionOverride() + { + // Arrange + ProjectNames projectName = new ProjectNames(@"f:\project\project.csproj", "project", "project.csproj", "projectC", Guid.NewGuid().ToString()); + var emptyReferenceItems = Array.Empty(); + var projectProperties = ProjectRestoreInfoBuilder.GetTargetFrameworkProperties(CommonFrameworks.NetStandard20); + projectProperties[ProjectBuildProperties.ManagePackageVersionsCentrally] = "true"; + projectProperties[ProjectBuildProperties.CentralPackageVersionOverrideEnabled] = "true"; + + var targetFrameworks = new VsTargetFrameworkInfo4[] { new VsTargetFrameworkInfo4( + items: new Dictionary>() + { + [ProjectItems.PackageReference] = [new VsReferenceItem2("foo", EmptyProperties), + new VsReferenceItem2("bar", new Dictionary { { "VersionOverride", "10.0.1" } })], + [ProjectItems.PackageVersion] = + [ + new VsReferenceItem2("foo", new Dictionary() { ["Version"] = "2.0.0"}), + new VsReferenceItem2("bar", new Dictionary() { ["Version"] = "3.0.0"}), + ] + }, + properties: projectProperties) + }; + + var pri = new VsProjectRestoreInfo3 + { + MSBuildProjectExtensionsPath = string.Empty, + TargetFrameworks = targetFrameworks, + OriginalTargetFrameworks = CommonFrameworks.NetStandard20.ToString(), + }; + + // Act + var result = VsSolutionRestoreService.ToPackageSpec(projectName, pri); + + // Assert + var tfm = result.TargetFrameworks.First(); + + tfm.CentralPackageVersions.Should().HaveCount(2); + result.RestoreMetadata.CentralPackageVersionsEnabled.Should().BeTrue(); + tfm.Dependencies.Should().HaveCount(2); + tfm.Dependencies[0].Name.Should().Be("foo"); + tfm.Dependencies[0].VersionCentrallyManaged.Should().BeTrue(); + tfm.Dependencies[0].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("2.0.0")); + tfm.Dependencies[0].AutoReferenced.Should().BeFalse(); + + tfm.Dependencies[1].Name.Should().Be("bar"); + tfm.Dependencies[1].VersionCentrallyManaged.Should().BeFalse(); + tfm.Dependencies[1].LibraryRange.VersionRange.Should().Be(VersionRange.Parse("10.0.1")); + tfm.Dependencies[1].VersionOverride.Should().Be(VersionRange.Parse("10.0.1")); + tfm.Dependencies[1].AutoReferenced.Should().BeFalse(); + } + private static IVsTargetFrameworkInfo FrameworkWithProperty(bool isV2Nominate, string propertyName, string propertyValue) { return isV2Nominate ? diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs index 9fe7a0133fb..40b0c2b702c 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs @@ -1862,5 +1862,50 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( result.Success.Should().BeTrue(because: result.AllOutput); project.AssetsFile.PackageSpec.RestoreMetadata.UseLegacyDependencyResolver.Should().BeTrue(because: result.AllOutput); } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task MsbuildRestore_WithMissingCPMVersions_RaisesNU1008(bool useStaticGraphRestore) + { + // Arrange + using var pathContext = new SimpleTestPathContext(); + + var packageX = new SimpleTestPackageContext("x", "1.0.0"); + + await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageX); + + SimpleTestProjectContext projectA = SimpleTestProjectContext.CreateNETCoreWithSDK("a", pathContext.SolutionRoot, FrameworkConstants.CommonFrameworks.Net472.GetShortFolderName()); + + // Since we're using CPM, add a PackageReference without a Version. + projectA.AddPackageToAllFrameworks(new SimpleTestPackageContext() + { + Id = packageX.Id, + Version = "1.0.0" + }); + + var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); + solution.Projects.Add(projectA); + solution.Create(pathContext.SolutionRoot); + + var directoryPackagesProps = $@" + + true + + + + +"; + var directoryPackagesPropsPath = Path.Combine(pathContext.SolutionRoot, "Directory.Packages.props"); + File.WriteAllText(directoryPackagesPropsPath, directoryPackagesProps); + + // Act + CommandRunnerResult result = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, $"/t:restore /p:RestoreUseStaticGraphEvaluation={useStaticGraphRestore} {projectA.ProjectPath}", ignoreExitCode: true, testOutputHelper: _testOutputHelper); + + // Assert + result.Success.Should().BeFalse(because: result.AllOutput); + projectA.AssetsFile.LogMessages.Should().HaveCount(1); + projectA.AssetsFile.LogMessages[0].Code.Should().Be(NuGetLogCode.NU1008); + } } } diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs index 2e4e4c07eee..c654d372f2e 100644 --- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs +++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs @@ -3505,20 +3505,18 @@ public async Task RestoreCommand_WithPackageNamesacesConfiguredDownloadsPackageF new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange(packageA, VersionRange.Parse(version), - LibraryDependencyTarget.Package) - }, - new LibraryDependency - { - LibraryRange = new LibraryRange(packageB, VersionRange.Parse(version), - LibraryDependencyTarget.Package) - }, - }) + LibraryRange = new LibraryRange(packageA, VersionRange.Parse(version), + LibraryDependencyTarget.Package) + }, + new LibraryDependency + { + LibraryRange = new LibraryRange(packageB, VersionRange.Parse(version), + LibraryDependencyTarget.Package) + }, + ] } }) .Build(); @@ -3595,20 +3593,18 @@ public async Task RestoreCommand_WithPackageNamespacesConfiguredAndNoMatchingSou new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange(packageA, VersionRange.Parse(version), - LibraryDependencyTarget.Package) - }, - new LibraryDependency - { - LibraryRange = new LibraryRange(packageB, VersionRange.Parse(version), - LibraryDependencyTarget.Package) - }, - }) + LibraryRange = new LibraryRange(packageA, VersionRange.Parse(version), + LibraryDependencyTarget.Package) + }, + new LibraryDependency + { + LibraryRange = new LibraryRange(packageB, VersionRange.Parse(version), + LibraryDependencyTarget.Package) + }, + ] } }) .Build(); diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_AlgorithmEquivalencyTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_AlgorithmEquivalencyTests.cs index b5923d7d304..9ef889a5db7 100644 --- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_AlgorithmEquivalencyTests.cs +++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_AlgorithmEquivalencyTests.cs @@ -949,7 +949,10 @@ public async Task RestoreCommand_WithProjectReferenceWithSuppressedDependencies_ // Setup project var projectSpec = ProjectTestHelpers.GetPackageSpec("Project1", pathContext.SolutionRoot, framework: "net5.0"); var projectSpec2 = ProjectTestHelpers.GetPackageSpec("Project2", pathContext.SolutionRoot, framework: "net5.0", dependencyName: "a"); - projectSpec2.TargetFrameworks[0].Dependencies[0].SuppressParent = LibraryIncludeFlags.All; + projectSpec2.TargetFrameworks[0] = new TargetFrameworkInformation(projectSpec2.TargetFrameworks[0]) + { + Dependencies = [new LibraryDependency(projectSpec2.TargetFrameworks[0].Dependencies[0]) { SuppressParent = LibraryIncludeFlags.All }] + }; projectSpec = projectSpec.WithTestProjectReference(projectSpec2); // Act & Assert @@ -1015,9 +1018,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( // Setup project var project1 = ProjectTestHelpers.GetPackageSpec("Project1", pathContext.SolutionRoot, framework: "net5.0"); var project2 = ProjectTestHelpers.GetPackageSpec("Project2", pathContext.SolutionRoot, framework: "net5.0"); - var project3 = ProjectTestHelpers.GetPackageSpec("Project3", pathContext.SolutionRoot, framework: "net5.0", dependencyName: "a"); - // todo NK - Add a better method - project3.TargetFrameworks[0].Dependencies[0].LibraryRange = new LibraryRange(project3.TargetFrameworks[0].Dependencies[0].LibraryRange.Name, VersionRange.Parse("3.0.0"), project3.TargetFrameworks[0].Dependencies[0].LibraryRange.TypeConstraint); + var project3 = ProjectTestHelpers.GetPackageSpec("Project3", pathContext.SolutionRoot, framework: "net5.0", dependencyName: "a", dependencyVersion: "3.0.0"); var projectA = ProjectTestHelpers.GetPackageSpec("a", pathContext.SolutionRoot, framework: "net5.0"); projectA.Version = new NuGetVersion("2.0.0"); @@ -1130,11 +1131,15 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.SolutionRoot, framework: "net472"); - project2spec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency( - new LibraryRange( - "a", - versionRange: isCPMEnabled ? null : VersionRange.All, - LibraryDependencyTarget.PackageProjectExternal))); + project2spec.TargetFrameworks[0] = new TargetFrameworkInformation(project2spec.TargetFrameworks[0]) + { + Dependencies = [ + new LibraryDependency(new LibraryRange( + "a", + versionRange: isCPMEnabled ? null : VersionRange.All, + LibraryDependencyTarget.PackageProjectExternal)) + ] + }; var project1spec = ProjectTestHelpers.GetPackageSpec("Project1", pathContext.SolutionRoot, diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_PackagesLockFileTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_PackagesLockFileTests.cs index 9d0898cee01..73cfacf3eea 100644 --- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_PackagesLockFileTests.cs +++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommand_PackagesLockFileTests.cs @@ -661,7 +661,8 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( LibraryRange = new LibraryRange(packageA.Id, VersionRange.Parse("1.0.*"), LibraryDependencyTarget.Package) }; - childProject.TargetFrameworks.FirstOrDefault().Dependencies.Add(dependency); + var newDependencies = childProject.TargetFrameworks.FirstOrDefault().Dependencies.Add(dependency); + childProject.TargetFrameworks[0] = new TargetFrameworkInformation(childProject.TargetFrameworks[0]) { Dependencies = newDependencies }; // Enable lock file childProject.RestoreMetadata.RestoreLockProperties = new RestoreLockProperties( diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Console.Test/MSBuildStaticGraphRestoreTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Console.Test/MSBuildStaticGraphRestoreTests.cs index 216d92feba2..d732504ea87 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Console.Test/MSBuildStaticGraphRestoreTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Console.Test/MSBuildStaticGraphRestoreTests.cs @@ -182,7 +182,7 @@ public void GetPackageReferences_WhenDuplicatesOrMetadataSpecified_DuplicatesIgn } }; - var actual = MSBuildStaticGraphRestore.GetPackageReferences(project, false); + var actual = MSBuildStaticGraphRestore.GetPackageReferences(project, false, centralPackageVersions: null); actual.Should().BeEquivalentTo(new List { @@ -223,7 +223,7 @@ public void GetPackageReferences_WhenDuplicatesOrMetadataSpecified_DuplicatesIgn new LibraryDependency { LibraryRange = new LibraryRange("PackageH", VersionRange.Parse("1.2.3"), LibraryDependencyTarget.Package), - NoWarn = new List { NuGetLogCode.NU1001, NuGetLogCode.NU1006, NuGetLogCode.NU3017 } + NoWarn = [NuGetLogCode.NU1001, NuGetLogCode.NU1006, NuGetLogCode.NU3017] }, new LibraryDependency { @@ -828,21 +828,29 @@ public void GetTargetFrameworkInfos_TheCentralVersionInformationIsAdded() var innerNodes = new Dictionary { [netstandard20] = new MockMSBuildProject("Project-netstandard2.0", - new Dictionary(), + new Dictionary + { + { "ManagePackageVersionsCentrally", "true"} + }, new Dictionary> { ["PackageReference"] = new List { new MSBuildItem("PackageA", new Dictionary { ["IsImplicitlyDefined"] = bool.TrueString }), + new MSBuildItem("PackageC", new Dictionary { ["VersionOverride"] = "4.0.0" }), }, ["PackageVersion"] = new List { new MSBuildItem("PackageA", new Dictionary { ["Version"] = "2.0.0" }), new MSBuildItem("PackageB", new Dictionary { ["Version"] = "3.0.0" }), + new MSBuildItem("PackageC", new Dictionary { ["Version"] = "3.0.0" }), }, }), [netstandard22] = new MockMSBuildProject("Project-netstandard2.2", - new Dictionary(), + new Dictionary + { + { "ManagePackageVersionsCentrally", "true"} + }, new Dictionary> { ["PackageReference"] = new List @@ -856,7 +864,11 @@ public void GetTargetFrameworkInfos_TheCentralVersionInformationIsAdded() }, }), [netstandard23] = new MockMSBuildProject("Project-netstandard2.3", - new Dictionary(), + new Dictionary + { + { "ManagePackageVersionsCentrally", "true"} + }, + new Dictionary> { ["PackageReference"] = new List @@ -870,7 +882,10 @@ public void GetTargetFrameworkInfos_TheCentralVersionInformationIsAdded() }, }), [netstandard24] = new MockMSBuildProject("Project-netstandard2.4", - new Dictionary(), + new Dictionary + { + { "ManagePackageVersionsCentrally", "true"} + }, new Dictionary> { ["PackageVersion"] = new List @@ -890,29 +905,37 @@ public void GetTargetFrameworkInfos_TheCentralVersionInformationIsAdded() var framework23 = targetFrameworkInfos.Single(f => f.TargetAlias == netstandard23); var framework24 = targetFrameworkInfos.Single(f => f.TargetAlias == netstandard24); - Assert.Equal(1, framework20.Dependencies.Count); - Assert.Equal("PackageA", framework20.Dependencies.First().Name); - Assert.Null(framework20.Dependencies.First().LibraryRange.VersionRange); + Assert.Equal(2, framework20.Dependencies.Length); + Assert.Equal("PackageA", framework20.Dependencies[0].Name); + Assert.Null(framework20.Dependencies[0].LibraryRange.VersionRange); + Assert.False(framework20.Dependencies[0].VersionCentrallyManaged); + Assert.Equal("PackageC", framework20.Dependencies[1].Name); + Assert.Equal("4.0.0", framework20.Dependencies[1].LibraryRange.VersionRange.OriginalString); + Assert.Equal("4.0.0", framework20.Dependencies[1].VersionOverride.OriginalString); + Assert.False(framework20.Dependencies[1].VersionCentrallyManaged); - Assert.Equal(2, framework20.CentralPackageVersions.Count); + Assert.Equal(3, framework20.CentralPackageVersions.Count); Assert.Equal("2.0.0", framework20.CentralPackageVersions["PackageA"].VersionRange.OriginalString); Assert.Equal("3.0.0", framework20.CentralPackageVersions["PackageB"].VersionRange.OriginalString); + Assert.Equal("3.0.0", framework20.CentralPackageVersions["PackageC"].VersionRange.OriginalString); - Assert.Equal(1, framework22.Dependencies.Count); - Assert.Equal("PackageA", framework22.Dependencies.First().Name); - Assert.Equal("11.0.0", framework22.Dependencies.First().LibraryRange.VersionRange.OriginalString); + Assert.Equal(1, framework22.Dependencies.Length); + Assert.Equal("PackageA", framework22.Dependencies[0].Name); + Assert.Equal("11.0.0", framework22.Dependencies[0].LibraryRange.VersionRange.OriginalString); + Assert.False(framework22.Dependencies[0].VersionCentrallyManaged); Assert.Equal(2, framework22.CentralPackageVersions.Count); Assert.Equal("2.2.2", framework22.CentralPackageVersions["PackageA"].VersionRange.OriginalString); Assert.Equal("3.2.0", framework22.CentralPackageVersions["PackageB"].VersionRange.OriginalString); - Assert.Equal(1, framework23.Dependencies.Count); - Assert.Equal("PackageA", framework23.Dependencies.First().Name); - Assert.Equal("2.0.0", framework23.Dependencies.First().LibraryRange.VersionRange.OriginalString); + Assert.Equal(1, framework23.Dependencies.Length); + Assert.Equal("PackageA", framework23.Dependencies[0].Name); + Assert.Equal("2.0.0", framework23.Dependencies[0].LibraryRange.VersionRange.OriginalString); + Assert.True(framework23.Dependencies[0].VersionCentrallyManaged); // Information about central package versions is necessary for implementation of "transitive dependency pinning". // thus even, when there are no explicit dependencies, information about central package versions still should be included. - Assert.Equal(0, framework24.Dependencies.Count); + Assert.Equal(0, framework24.Dependencies.Length); Assert.Equal(2, framework24.CentralPackageVersions.Count); Assert.Equal("2.0.0", framework24.CentralPackageVersions["PackageA"].VersionRange.OriginalString); Assert.Equal("3.0.0", framework24.CentralPackageVersions["PackageB"].VersionRange.OriginalString); diff --git a/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/MSBuildAPIUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/MSBuildAPIUtilityTests.cs index fce13029353..377087e7dbc 100644 --- a/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/MSBuildAPIUtilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/MSBuildAPIUtilityTests.cs @@ -620,13 +620,13 @@ public void GetResolvedVersions_WithAPackageInDirectoryBuildProps_GetsVersion() new TargetFrameworkInformation { FrameworkName = net8, - Dependencies = new[] - { + Dependencies = + [ new LibraryDependency { LibraryRange = new LibraryRange("myPackage") } - } + ] } }) { @@ -695,13 +695,13 @@ public void GetResolvedVersions_WithAPackageInDirectoryPackageProps_GetsVersion( new TargetFrameworkInformation { FrameworkName = net8, - Dependencies = new[] - { + Dependencies = + [ new LibraryDependency { LibraryRange = new LibraryRange("myPackage") } - } + ] } }) { diff --git a/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/NETCoreRestoreTestUtility.cs b/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/NETCoreRestoreTestUtility.cs index 51a6e2a2c66..0be72f61129 100644 --- a/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/NETCoreRestoreTestUtility.cs +++ b/test/NuGet.Core.Tests/NuGet.CommandLine.Xplat.Tests/NETCoreRestoreTestUtility.cs @@ -64,8 +64,10 @@ public static async Task> RunRestore( public static PackageSpec GetProject(string projectName, string framework) { - var targetFrameworkInfo = new TargetFrameworkInformation(); - targetFrameworkInfo.FrameworkName = NuGetFramework.Parse(framework); + var targetFrameworkInfo = new TargetFrameworkInformation() + { + FrameworkName = NuGetFramework.Parse(framework) + }; var frameworks = new[] { targetFrameworkInfo }; // Create two net45 projects diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/CollectorLoggerTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/CollectorLoggerTests.cs index c1eb6f6aea3..9b43b1d8faa 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/CollectorLoggerTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/CollectorLoggerTests.cs @@ -628,7 +628,7 @@ public void CollectorLogger_DoesNotLogsWarningsForPackageSpecificNoWarnSetWithLi var warningsNotAsErrors = new HashSet(); var allWarningsAsErrors = false; var packageSpecificWarningProperties = new PackageSpecificWarningProperties(); - packageSpecificWarningProperties.AddRangeOfCodes(new List { NuGetLogCode.NU1500, NuGetLogCode.NU1601, NuGetLogCode.NU1605 }, libraryId, targetFramework); + packageSpecificWarningProperties.AddRangeOfCodes([NuGetLogCode.NU1500, NuGetLogCode.NU1601, NuGetLogCode.NU1605], libraryId, targetFramework); var innerLogger = new Mock(); var collector = new RestoreCollectorLogger(innerLogger.Object) @@ -669,7 +669,7 @@ public void CollectorLogger_DoesNotLogsWarningsForPackageSpecificNoWarnSetWithLi var warningsNotAsErrors = new HashSet(); var allWarningsAsErrors = false; var packageSpecificWarningProperties = new PackageSpecificWarningProperties(); - packageSpecificWarningProperties.AddRangeOfCodes(new List { NuGetLogCode.NU1500 }, libraryId, targetFramework); + packageSpecificWarningProperties.AddRangeOfCodes([NuGetLogCode.NU1500], libraryId, targetFramework); var innerLogger = new Mock(); var collector = new RestoreCollectorLogger(innerLogger.Object) diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/CycleTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/CycleTests.cs index 0a38f66aa99..dcabbc96a33 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/CycleTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/CycleTests.cs @@ -34,10 +34,11 @@ public async Task Cycle_PackageWithSameNameAsProjectVerifyCycleDetectedAsync() }; var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); - spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() + var newDependencies = spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("projectA", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = newDependencies }; var specs = new[] { spec1 }; @@ -127,10 +128,11 @@ public async Task Cycle_PackageWithSameNameAsProjectVerifyCycleDetectedTwoLevels }; var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); - spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() + var newDependencies = spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = newDependencies }; var specs = new[] { spec1 }; @@ -178,10 +180,11 @@ public async Task Cycle_PackageWithSameNameAsProjectVerifyCycleDetectedAtEndAsyn }; var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); - spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() + var newDependencies = spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = newDependencies }; var specs = new[] { spec1 }; @@ -232,10 +235,11 @@ public async Task Cycle_PackageCircularDependencyVerifyCycleDetectedAsync() }; var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); - spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() + var newDependencies = spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("X", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = newDependencies }; var specs = new[] { spec1 }; @@ -292,10 +296,11 @@ public async Task Cycle_TransitiveProjectWithSameNameAsPackageVerifyCycleDetecte var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectB", framework: "netstandard1.6"); - spec2.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() + var newDependencies = spec2.TargetFrameworks[0].Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange(packageId, VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec2.TargetFrameworks[0] = new TargetFrameworkInformation(spec2.TargetFrameworks[0]) { Dependencies = newDependencies }; var specs = new[] { spec1, spec2 }; diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/IncludeTypeTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/IncludeTypeTests.cs index 292529613c7..dbbaa8e09ba 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/IncludeTypeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/IncludeTypeTests.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -1782,16 +1783,18 @@ public async Task IncludeType_FlowsIntoCentralTransitiveDependencies(LibraryIncl new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List( - new[] - { + Dependencies = + [ new LibraryDependency { LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.All), VersionCentrallyManaged = true, }, - }), - CentralPackageVersions = { new KeyValuePair("PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0"))) }, + ], + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0")) } + } } }) .WithCentralPackageVersionsEnabled() @@ -1805,8 +1808,11 @@ public async Task IncludeType_FlowsIntoCentralTransitiveDependencies(LibraryIncl new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List(), - CentralPackageVersions = { new KeyValuePair("PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0"))) }, + Dependencies = [], + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0")) } + } } }) .WithCentralPackageVersionsEnabled() @@ -1822,9 +1828,11 @@ public async Task IncludeType_FlowsIntoCentralTransitiveDependencies(LibraryIncl new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List(), - CentralPackageVersions = { new KeyValuePair("PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0"))) }, - } + Dependencies = [], + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0")) } + } } }) .WithCentralPackageVersionsEnabled() .WithCentralPackageTransitivePinningEnabled() diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/MSBuildRestoreUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/MSBuildRestoreUtilityTests.cs index d316a468050..956341cf11b 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/MSBuildRestoreUtilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/MSBuildRestoreUtilityTests.cs @@ -963,7 +963,7 @@ public void MSBuildRestoreUtility_GetPackageSpec_Tool() // Assert // Dependency counts - Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("netcoreapp1.0")).Dependencies.Count); + Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("netcoreapp1.0")).Dependencies.Length); } } @@ -1458,8 +1458,8 @@ public void MSBuildRestoreUtility_GetPackageSpec_NetCoreVerifyImports() var netTFM = project1Spec.GetTargetFramework(NuGetFramework.Parse("net46")); // Assert - Assert.Equal(2, nsTFM.Imports.Count); - Assert.Equal(0, netTFM.Imports.Count); + Assert.Equal(2, nsTFM.Imports.Length); + Assert.Equal(0, netTFM.Imports.Length); Assert.Equal(NuGetFramework.Parse("portable-net45+win8"), nsTFM.Imports[0]); Assert.Equal(NuGetFramework.Parse("dnxcore50"), nsTFM.Imports[1]); @@ -1550,8 +1550,8 @@ public void MSBuildRestoreUtility_GetPackageSpec_NetCoreVerifyImportsEmpty() var netTFM = project1Spec.GetTargetFramework(NuGetFramework.Parse("net46")); // Assert - Assert.Equal(0, nsTFM.Imports.Count); - Assert.Equal(0, netTFM.Imports.Count); + Assert.Equal(0, nsTFM.Imports.Length); + Assert.Equal(0, netTFM.Imports.Length); // Verify no fallback frameworks var fallbackFrameworks = project1Spec.TargetFrameworks.Select(e => e.FrameworkName as FallbackFramework); @@ -1628,8 +1628,8 @@ public void MSBuildRestoreUtility_GetPackageSpec_NetCoreVerifyWhitespaceRemoved( // Assert Assert.Equal("a", project1Spec.RestoreMetadata.ProjectName); - Assert.Equal(2, nsTFM.Imports.Count); - Assert.Equal(0, netTFM.Imports.Count); + Assert.Equal(2, nsTFM.Imports.Length); + Assert.Equal(0, netTFM.Imports.Length); Assert.Equal(NuGetFramework.Parse("portable-net45+win8"), nsTFM.Imports[0]); Assert.Equal(NuGetFramework.Parse("dnxcore50"), nsTFM.Imports[1]); @@ -1975,11 +1975,11 @@ public void MSBuildRestoreUtility_GetPackageSpec_NetCore_Conditionals() Assert.Equal(0, project1Spec.Dependencies.Count); Assert.Equal(0, project2Spec.Dependencies.Count); - Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("net46")).Dependencies.Count); - Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("netstandard1.6")).Dependencies.Count); + Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("net46")).Dependencies.Length); + Assert.Equal(1, project1Spec.GetTargetFramework(NuGetFramework.Parse("netstandard1.6")).Dependencies.Length); - Assert.Equal(1, project2Spec.GetTargetFramework(NuGetFramework.Parse("net45")).Dependencies.Count); - Assert.Equal(1, project2Spec.GetTargetFramework(NuGetFramework.Parse("netstandard1.0")).Dependencies.Count); + Assert.Equal(1, project2Spec.GetTargetFramework(NuGetFramework.Parse("net45")).Dependencies.Length); + Assert.Equal(1, project2Spec.GetTargetFramework(NuGetFramework.Parse("netstandard1.0")).Dependencies.Length); // Verify dependencies var xDep = project1Spec.GetTargetFramework(NuGetFramework.Parse("net46")).Dependencies.Single(e => e.Name == "x"); @@ -3282,7 +3282,7 @@ public void MSBuildRestoreUtility_AddPackageDownloads_SinglePackageSingleVersion // Assert var framework = spec.GetTargetFramework(targetFramework); - Assert.Equal(1, framework.DownloadDependencies.Count); + Assert.Equal(1, framework.DownloadDependencies.Length); Assert.Equal("x", framework.DownloadDependencies[0].Name); Assert.Equal("[1.0.0]", framework.DownloadDependencies[0].VersionRange.ToShortString()); } @@ -3338,7 +3338,7 @@ public void MSBuildRestoreUtility_AddPackageDownloads_SinglePackageMultipleVersi // Assert var framework = spec.GetTargetFramework(targetFramework); - Assert.Equal(2, framework.DownloadDependencies.Count); + Assert.Equal(2, framework.DownloadDependencies.Length); Assert.Equal(1, framework.DownloadDependencies.Count(d => d.Name == "x" && d.VersionRange.ToShortString() == "[1.0.0]")); Assert.Equal(1, framework.DownloadDependencies.Count(d => d.Name == "x" && d.VersionRange.ToShortString() == "[2.0.0]")); } @@ -3515,7 +3515,7 @@ public void MSBuildRestoreUtility_GetDependencySpec_CentralVersionIsMergedWhenCP // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(2, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(2, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(3, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); var dependencyX = project1Spec.TargetFrameworks.First().Dependencies.Where(d => d.Name == "x").First(); @@ -3615,7 +3615,7 @@ public void MSBuildRestoreUtility_GetDependencySpec_HandlesDuplicatesWhenCPVMEna // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(1, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); var dependencyX = project1Spec.TargetFrameworks.First().Dependencies.Where(d => d.Name == "x").First(); @@ -3705,7 +3705,7 @@ public void MSBuildRestoreUtility_GetPackageSpec_CPVM_EnabledLegacyProjectsMerge // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(2, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); Assert.Equal("[1.0.0, )", project1Spec.TargetFrameworks.First().Dependencies[0].LibraryRange.VersionRange.ToNormalizedString()); @@ -3801,7 +3801,7 @@ public void MSBuildRestoreUtility_GetPackageSpec_CPVM_VersionOverrideCanBeDisabl // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(2, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); Assert.Equal("[1.0.0, )", project1Spec.TargetFrameworks.First().Dependencies[0].LibraryRange.VersionRange.ToNormalizedString()); @@ -3906,7 +3906,7 @@ public void MSBuildRestoreUtility_GetPackageSpec_CPVM_FloatingVersionsCanBeEnabl // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(2, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); Assert.Equal("[1.0.0, )", project1Spec.TargetFrameworks.First().Dependencies[0].LibraryRange.VersionRange.ToNormalizedString()); @@ -4041,7 +4041,7 @@ public void MSBuildRestoreUtility_GetDependencySpec_CPVM_NotEnabledProjectDoesNo // Assert // Dependency counts Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Count); + Assert.Equal(1, project1Spec.TargetFrameworks.First().Dependencies.Length); Assert.Equal(0, project1Spec.TargetFrameworks.First().CentralPackageVersions.Count); Assert.Equal("(, )", project1Spec.TargetFrameworks.First().Dependencies.First().LibraryRange.VersionRange.ToNormalizedString()); } @@ -4296,7 +4296,7 @@ public void MSBuildRestoreUtility_GetDependencySpec_VersionOverrideAppliesWhenCP // Assert Assert.Equal(1, project1Spec.TargetFrameworks.Count()); - Assert.Equal(3, targetFrameworkInformation.Dependencies.Count); + Assert.Equal(3, targetFrameworkInformation.Dependencies.Length); Assert.Equal(isCentralPackageManagementEnabled ? 3 : 0, targetFrameworkInformation.CentralPackageVersions.Count); var dependencyX = targetFrameworkInformation.Dependencies.First(d => d.Name == "x"); diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreProject2ProjectTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreProject2ProjectTests.cs index 2111248a8b2..01dddd11776 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreProject2ProjectTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreProject2ProjectTests.cs @@ -243,10 +243,11 @@ public async Task NETCoreProject2Project_IgnoreXproj() var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6"); var specs = new[] { spec }; - spec.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() + var newDependencies = spec.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); + spec.TargetFrameworks[0] = new TargetFrameworkInformation(spec.TargetFrameworks[0]) { Dependencies = newDependencies }; // Create fake projects, the real data is in the specs var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec); diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreRestoreTestUtility.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreRestoreTestUtility.cs index c1885c71f1f..7374db0b3de 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreRestoreTestUtility.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/NETCoreRestoreTestUtility.cs @@ -62,8 +62,10 @@ public static async Task> RunRestore( public static PackageSpec GetProject(string projectName, string framework) { - var targetFrameworkInfo = new TargetFrameworkInformation(); - targetFrameworkInfo.FrameworkName = NuGetFramework.Parse(framework); + var targetFrameworkInfo = new TargetFrameworkInformation() + { + FrameworkName = NuGetFramework.Parse(framework) + }; var frameworks = new[] { targetFrameworkInfo }; // Create two net45 projects diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/LockFileBuilderCacheTest.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/LockFileBuilderCacheTest.cs index 694be23f964..1adb27e0332 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/LockFileBuilderCacheTest.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/LockFileBuilderCacheTest.cs @@ -56,15 +56,13 @@ public async Task LockFileBuilderCache_DifferentPackagePath_WillNotCache(bool di new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ] } }) .Build(); @@ -75,15 +73,13 @@ public async Task LockFileBuilderCache_DifferentPackagePath_WillNotCache(bool di new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ] } }) .Build(); @@ -176,15 +172,13 @@ public async Task LockFileBuilderCache_DifferentAssetTargetFallback_WillNotCache new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ] } }) .Build(); @@ -197,15 +191,13 @@ public async Task LockFileBuilderCache_DifferentAssetTargetFallback_WillNotCache FrameworkName = withFallbackFramework ? new AssetTargetFallbackFramework(NuGetFramework.Parse("net5.0"), new[] {NuGetFramework.Parse("net461")}) : NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ] } }) .Build(); @@ -313,15 +305,13 @@ public async Task LockFileBuilderCache_DifferentRuntimeGraph_WillNotCache() new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }), + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ], RuntimeIdentifierGraphPath = runtimeJson1, }, }) @@ -342,15 +332,13 @@ public async Task LockFileBuilderCache_DifferentRuntimeGraph_WillNotCache() new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net5.0"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }), + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ], RuntimeIdentifierGraphPath = runtimeJson2, } }) @@ -477,15 +465,13 @@ bool cachingIsExpected new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net471"), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), - LibraryDependencyTarget.All) - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), + LibraryDependencyTarget.All) + }, + ] } }) .Build(); @@ -496,17 +482,15 @@ bool cachingIsExpected new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse(framework), - Dependencies = new List( - new[] + Dependencies = [ + new LibraryDependency { - new LibraryDependency - { - LibraryRange = new LibraryRange("PackageA", VersionRange.Parse(version), - LibraryDependencyTarget.All), - Aliases = aliases, - IncludeType = includeFlags, - }, - }) + LibraryRange = new LibraryRange("PackageA", VersionRange.Parse(version), + LibraryDependencyTarget.All), + Aliases = aliases, + IncludeType = includeFlags, + }, + ] } }) .Build(); diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs index 8e5778b4b88..c5e908ec743 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using FluentAssertions; @@ -1479,7 +1481,7 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenDependenciesHaveVersion var dependencyBar = new LibraryDependency(new LibraryRange("bar", VersionRange.Parse("3.0.0"), LibraryDependencyTarget.All), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -1490,7 +1492,7 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenDependenciesHaveVersion var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); - var tfi = CreateTargetFrameworkInformation(new List() { dependencyBar }, new List() { centralVersionFoo, centralVersionBar }); + var tfi = CreateTargetFrameworkInformation([dependencyBar], new List() { centralVersionFoo, centralVersionBar }); var packageSpec = new PackageSpec(new List() { tfi }); packageSpec.RestoreMetadata = new ProjectRestoreMetadata() { @@ -1543,7 +1545,7 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenCentralPackageVersionFi LibraryDependencyTarget.All), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: true, generatePathProperty: true, versionCentrallyManaged: false, @@ -1554,7 +1556,7 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenCentralPackageVersionFi var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); var centralVersionBar = new CentralPackageVersion(autoreferencedpackageId.ToLowerInvariant(), VersionRange.Parse("2.0.0")); - var tfi = CreateTargetFrameworkInformation(new List() { dependencyBar }, new List() { centralVersionFoo, centralVersionBar }); + var tfi = CreateTargetFrameworkInformation([dependencyBar], new List() { centralVersionFoo, centralVersionBar }); var packageSpec = new PackageSpec(new List() { tfi }); packageSpec.RestoreMetadata = new ProjectRestoreMetadata() { @@ -1618,7 +1620,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( LibraryDependencyTarget.All), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: false, versionCentrallyManaged: false, @@ -1628,7 +1630,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); - var tfi = CreateTargetFrameworkInformation(new List() { dependencyBar }, new List() { centralVersionFoo }); + var tfi = CreateTargetFrameworkInformation([dependencyBar], new List() { centralVersionFoo }); var packageSpec = new PackageSpec(new List() { tfi }) { FilePath = projectPath, @@ -1700,7 +1702,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( LibraryDependencyTarget.All), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: false, versionCentrallyManaged: false, @@ -1710,7 +1712,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); - var tfi = CreateTargetFrameworkInformation(new List() { dependencyBar }, new List() { centralVersionFoo }); + var tfi = CreateTargetFrameworkInformation([dependencyBar], new List() { centralVersionFoo }); var packageSpec = new PackageSpec(new List() { tfi }) { FilePath = projectPath, @@ -2013,7 +2015,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.*", allowFloating: true)); var tfi = CreateTargetFrameworkInformation( - new List() { packageRefDependecyFoo }, + [packageRefDependecyFoo], new List() { centralVersionFoo }); var packageSpec = new PackageSpec(new List() { tfi }) @@ -2081,7 +2083,7 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenNotAllPRItemsHaveCoresp var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); var tfi = CreateTargetFrameworkInformation( - new List() { packageRefDependecyBar }, + [packageRefDependecyBar], new List() { centralVersionFoo }); var packageSpec = new PackageSpec(new List() { tfi }); @@ -2236,7 +2238,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_VerifyProjectsReferen await SimpleTestPackageUtility.CreateFullPackageAsync(pathContext.PackageSource, packageDummyontext); var tfi = CreateTargetFrameworkInformation( - new List() { dependencyFoo }, + [dependencyFoo], new List() { centralVersionFoo, centralVersionDummy }, framework); @@ -2325,8 +2327,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP await SimpleTestPackageUtility.CreateFullPackageAsync(pathContext.PackageSource, packageAContext); var tfi = CreateTargetFrameworkInformation( - new List - { + [ new LibraryDependency() { LibraryRange = new LibraryRange() @@ -2347,7 +2348,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP VersionCentrallyManaged = true, SuppressParent = LibraryIncludeFlags.Build } - }, + ], new List { new CentralPackageVersion(packageA.Id, new VersionRange(packageA.Version)), @@ -2443,8 +2444,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP await SimpleTestPackageUtility.CreateFullPackageAsync(pathContext.PackageSource, packageAContext); var tfi = CreateTargetFrameworkInformation( - new List - { + [ new LibraryDependency() { LibraryRange = new LibraryRange() @@ -2455,7 +2455,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP VersionCentrallyManaged = true, SuppressParent = LibraryIncludeFlags.Runtime | LibraryIncludeFlags.Compile }, - }, + ], new List { new CentralPackageVersion(packageA.Id, new VersionRange(packageA.Version)), @@ -2529,15 +2529,18 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net46"), - Dependencies = new List(new[] - { + Dependencies = + [ new LibraryDependency { LibraryRange = new LibraryRange("PackageA", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.All), VersionCentrallyManaged = true, }, - }), - CentralPackageVersions = { new KeyValuePair("PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0"))) }, + ], + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0")) }, + } } }) .WithCentralPackageVersionsEnabled() @@ -2551,8 +2554,11 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net46"), - Dependencies = new List(), - CentralPackageVersions = { new KeyValuePair("PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0"))) }, + Dependencies = [], + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "PackageA", new CentralPackageVersion("PackageA", VersionRange.Parse("1.0.0")) }, + } } }) .WithCentralPackageVersionsEnabled() @@ -2637,8 +2643,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP await SimpleTestPackageUtility.CreateFullPackageAsync(pathContext.PackageSource, packageAContext); var tfi = CreateTargetFrameworkInformation( - new List - { + [ new LibraryDependency() { LibraryRange = new LibraryRange() @@ -2659,7 +2664,7 @@ public async Task RestoreCommand_CentralVersion_AssetsFile_PrivateAssetsFlowsToP VersionCentrallyManaged = true, SuppressParent = suppressParent2, }, - }, + ], new List { new CentralPackageVersion(packageA.Id, new VersionRange(packageA.Version)), @@ -2737,19 +2742,13 @@ public async Task RestoreCommand_CentralVersion_ErrorWhenVersionOverrideUsedButI var packageRefDependencyFoo = new LibraryDependency() { LibraryRange = new LibraryRange(packageName, versionRange: null, typeConstraint: LibraryDependencyTarget.Package), + VersionOverride = isVersionOverrideUsed ? new VersionRange(NuGetVersion.Parse("2.0.0")) : null }; - if (isVersionOverrideUsed) - { - packageRefDependencyFoo.VersionOverride = new VersionRange(NuGetVersion.Parse("2.0.0")); - } var packageVersion = new CentralPackageVersion(packageName, VersionRange.Parse("1.0.0")); TargetFrameworkInformation targetFrameworkInformation = CreateTargetFrameworkInformation( - new List - { - packageRefDependencyFoo - }, + [packageRefDependencyFoo], new List { packageVersion @@ -3168,17 +3167,17 @@ public async Task ExecuteAsync_TransitiveDependenciesFromNonRootLibraries_AreIgn await SimpleTestPackageUtility.CreateFullPackageAsync(pathContext.PackageSource, package3Context); var tfiA = CreateTargetFrameworkInformation( - new List(), // no direct dependencies + [], // no direct dependencies new List() { centralVersion1 }, framework); var tfiB = CreateTargetFrameworkInformation( - new List(), // no direct dependencies + [], // no direct dependencies new List() { centralVersion3 }, framework); var tfiC = CreateTargetFrameworkInformation( - new List() { dependencyD }, // direct dependency + [dependencyD], // direct dependency new List() { centralVersion2 }, framework); @@ -3339,24 +3338,60 @@ public async Task ExecuteAsync_WithLegacyAlgorithmOptIn_ExecutesLegacyAlgorithm( result.LockFile.PackageSpec.RestoreMetadata.UseLegacyDependencyResolver.Should().BeTrue(); } - private static TargetFrameworkInformation CreateTargetFrameworkInformation(List dependencies, List centralVersionsDependencies, NuGetFramework framework = null) + private static TargetFrameworkInformation CreateTargetFrameworkInformation(ImmutableArray dependencies, List centralVersionsDependencies, NuGetFramework framework = null) { NuGetFramework nugetFramework = framework ?? new NuGetFramework("net40"); + var centralPackageVersions = centralVersionsDependencies.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase); + var newDependencies = ApplyCentralVersionInformation(dependencies, centralPackageVersions); + TargetFrameworkInformation tfi = new TargetFrameworkInformation() { AssetTargetFallback = true, - Warn = false, + CentralPackageVersions = centralPackageVersions, + Dependencies = newDependencies, FrameworkName = nugetFramework, - Dependencies = dependencies, + Warn = false, }; - foreach (var cvd in centralVersionsDependencies) + return tfi; + + static ImmutableArray ApplyCentralVersionInformation(ImmutableArray packageReferences, IReadOnlyDictionary centralPackageVersions) { - tfi.CentralPackageVersions.Add(cvd.Name, cvd); - } - LibraryDependency.ApplyCentralVersionInformation(tfi.Dependencies, tfi.CentralPackageVersions); + LibraryDependency[] result = new LibraryDependency[packageReferences.Length]; + for (int i = 0; i < packageReferences.Length; i++) + { + LibraryDependency d = packageReferences[i]; + if (!d.AutoReferenced && d.LibraryRange.VersionRange == null) + { + var libraryRange = d.LibraryRange; + var versionCentrallyManaged = d.VersionCentrallyManaged; - return tfi; + if (d.VersionOverride != null) + { + libraryRange = new LibraryRange(d.LibraryRange) { VersionRange = d.VersionOverride }; + } + else + { + if (centralPackageVersions.TryGetValue(d.Name, out CentralPackageVersion centralPackageVersion)) + { + libraryRange = new LibraryRange(d.LibraryRange) { VersionRange = centralPackageVersion.VersionRange }; + } + + versionCentrallyManaged = true; + } + + d = new LibraryDependency(d) + { + LibraryRange = libraryRange, + VersionCentrallyManaged = versionCentrallyManaged + }; + } + + result[i] = d; + } + + return ImmutableCollectionsMarshal.AsImmutableArray(result); + } } private static PackageSpec CreatePackageSpec(List tfis, NuGetFramework framework, string projectName, string projectPath, bool centralPackageManagementEnabled, bool centralPackageTransitivePinningEnabled = false) diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreRunnerTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreRunnerTests.cs index 6627efff165..8252c718c31 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreRunnerTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreRunnerTests.cs @@ -241,7 +241,7 @@ public async Task RestoreRunner_BasicRestore_VerifyFailureWritesFiles_NETCoreAsy var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); - spec1.TargetFrameworks.Single().TargetAlias = "net45"; + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks.Single()) { TargetAlias = "net45" }; spec1.RestoreMetadata = new ProjectRestoreMetadata { OutputPath = Path.Combine(project1.FullName, "obj"), @@ -462,7 +462,7 @@ public async Task RestoreRunner_RestoreWithExternalFileAsync() var lockPath2 = Path.Combine(objPath2, "project.assets.json"); // Link projects - spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() + var spec1TargetFrameworkDependencies = spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange() { @@ -470,6 +470,7 @@ public async Task RestoreRunner_RestoreWithExternalFileAsync() TypeConstraint = LibraryDependencyTarget.ExternalProject } }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = spec1TargetFrameworkDependencies }; spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45"))); spec1.RestoreMetadata.TargetFrameworks @@ -613,7 +614,7 @@ public async Task RestoreRunner_RestoreWithExternalFile_NetCoreOutputAsync() var lockPath2 = Path.Combine(objPath2, "project.assets.json"); // Link projects - spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() + var spec1TargetFrameworkDependencies = spec1.TargetFrameworks.Single().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange() { @@ -621,6 +622,7 @@ public async Task RestoreRunner_RestoreWithExternalFile_NetCoreOutputAsync() TypeConstraint = LibraryDependencyTarget.ExternalProject } }); + spec1.TargetFrameworks[0] = new TargetFrameworkInformation(spec1.TargetFrameworks[0]) { Dependencies = spec1TargetFrameworkDependencies }; spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45")) { TargetAlias = "net45" }); spec1.RestoreMetadata.TargetFrameworks @@ -937,7 +939,7 @@ public async Task RestoreRunner_MultiplePackageDownloadRestoreAsync() Assert.Equal("x", lockFile.Targets.First().Libraries.First().Name); Assert.Equal(0, lockFile.LogMessages.Count); Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); + Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); Assert.Equal("y", lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.First().Name); Assert.Equal("y", lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Last().Name); Assert.True(Directory.Exists(Path.Combine(globalPackagesFolder.FullName, "y", "1.0.0"))); // Y 1.0.0 is installed @@ -1230,8 +1232,8 @@ public async Task RestoreRunner_MultiTfmPackageDownloadRestoreAsync() Assert.Equal("x", lockFile.Targets.First().Libraries.First().Name); Assert.Equal(0, lockFile.LogMessages.Count); Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal("y", lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.First().Name); Assert.Equal("z", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); @@ -1331,8 +1333,8 @@ public async Task RestoreRunner_MultiTfmPackageDownloadUnresolved_BothTfmsLogErr Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal("y", lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.First().Name); Assert.Equal("y", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); @@ -1440,8 +1442,8 @@ public async Task RestoreRunner_MultiTfmPackageDownloadRestore_OnlyMatchingPacka Assert.Equal(1, lockFile.Libraries.Count); // Only X is written in the libraries section. Assert.Equal("x", lockFile.Targets.First().Libraries.First().Name); Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); - Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); + Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal(1, lockFile.LogMessages.Count); var logMessage = lockFile.LogMessages.First(); @@ -1538,8 +1540,8 @@ public async Task RestoreRunner_MultiTfmPDandPR_LogsWarningsAsync() Assert.Equal(1, lockFile.Libraries.Count); Assert.Equal("x", lockFile.Targets.First().Libraries.First().Name); Assert.Equal(2, lockFile.PackageSpec.TargetFrameworks.Count); - Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Count); - Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Count); + Assert.Equal(0, lockFile.PackageSpec.TargetFrameworks.First().DownloadDependencies.Length); + Assert.Equal(1, lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.Length); Assert.Equal("x", lockFile.PackageSpec.TargetFrameworks.Last().DownloadDependencies.First().Name); Assert.Equal(1, lockFile.LogMessages.Count); diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/SpecValidationUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/SpecValidationUtilityTests.cs index 38e6f007c1c..5b71031819d 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/SpecValidationUtilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/SpecValidationUtilityTests.cs @@ -171,10 +171,11 @@ public void SpecValidationUtility_VerifyProjectReferences_TFMLevel_Pass() ProjectUniqueName = "b" }); - spec.Projects.First().TargetFrameworks.First().Dependencies.Add(new LibraryDependency() + var newDependencies = spec.Projects.First().TargetFrameworks.First().Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("b", LibraryDependencyTarget.PackageProjectExternal) }); + spec.Projects[0].TargetFrameworks[0] = new TargetFrameworkInformation(spec.Projects[0].TargetFrameworks[0]) { Dependencies = newDependencies }; // Act && Assert no errors SpecValidationUtility.ValidateDependencySpec(spec); @@ -242,8 +243,14 @@ public void SpecValidationUtility_VerifyProjectMetadata_SameNameAsSpecName() var spec = new DependencyGraphSpec(); spec.AddRestore("a"); + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.PackageProjectExternal) + }; + var targetFramework1 = new TargetFrameworkInformation() { + Dependencies = [libraryDependency], FrameworkName = NuGetFramework.Parse("net45") }; @@ -261,11 +268,6 @@ public void SpecValidationUtility_VerifyProjectMetadata_SameNameAsSpecName() project.RestoreMetadata.ProjectPath = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj"); project.RestoreMetadata.ProjectStyle = ProjectStyle.Unknown; - targetFramework1.Dependencies.Add(new LibraryDependency() - { - LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.PackageProjectExternal) - }); - spec.AddProject(project); // Act && Assert @@ -407,8 +409,14 @@ public void SpecValidationUtility_UnknownType_DisallowDependencies() var spec = new DependencyGraphSpec(); spec.AddRestore("a"); + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.PackageProjectExternal) + }; + var targetFramework1 = new TargetFrameworkInformation() { + Dependencies = [libraryDependency], FrameworkName = NuGetFramework.Parse("net45") }; @@ -423,11 +431,6 @@ public void SpecValidationUtility_UnknownType_DisallowDependencies() project.RestoreMetadata.ProjectPath = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj"); project.RestoreMetadata.ProjectStyle = ProjectStyle.Unknown; - targetFramework1.Dependencies.Add(new LibraryDependency() - { - LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.PackageProjectExternal) - }); - spec.AddProject(project); // Act && Assert diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs index cb8f2f1e645..85931780490 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs @@ -220,7 +220,7 @@ public void MergePackageSpecificWarningProperties_MergesNonEmptyCollections() var netcoreapp = NuGetFramework.Parse("netcoreapp2.0"); var expectedResult = new PackageSpecificWarningProperties(); expectedResult.AddRangeOfCodes( - new List { NuGetLogCode.NU1601, NuGetLogCode.NU1605 }, + [NuGetLogCode.NU1601, NuGetLogCode.NU1605], packageId1, net461); expectedResult.AddRangeOfFrameworks( @@ -243,7 +243,7 @@ public void MergePackageSpecificWarningProperties_MergesNonEmptyCollections() var first = new PackageSpecificWarningProperties(); first.AddRangeOfCodes( - new List { NuGetLogCode.NU1601, NuGetLogCode.NU1605 }, + [NuGetLogCode.NU1601, NuGetLogCode.NU1605], packageId1, net461); first.AddRangeOfFrameworks( @@ -417,7 +417,7 @@ public void ExtractPackageSpecificNoWarnForFrameworks_InputWithProperties() var netcoreapp = NuGetFramework.Parse("netcoreapp2.0"); var input = new PackageSpecificWarningProperties(); input.AddRangeOfCodes( - new List { NuGetLogCode.NU1601, NuGetLogCode.NU1605 }, + [NuGetLogCode.NU1601, NuGetLogCode.NU1605], packageId1, net461); input.AddRangeOfFrameworks( @@ -514,7 +514,7 @@ public void ExtractPackageSpecificNoWarnForFramework_InputWithProperties() var netcoreapp = NuGetFramework.Parse("netcoreapp2.0"); var input = new PackageSpecificWarningProperties(); input.AddRangeOfCodes( - new List { NuGetLogCode.NU1601, NuGetLogCode.NU1605 }, + [NuGetLogCode.NU1601, NuGetLogCode.NU1605], packageId1, net461); input.AddRangeOfFrameworks( diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/UnexpectedDependencyMessagesTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/UnexpectedDependencyMessagesTests.cs index ee20daed319..01d7ae3694c 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/UnexpectedDependencyMessagesTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/UnexpectedDependencyMessagesTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; using FluentAssertions; @@ -926,7 +927,7 @@ private static List GetTFI(NuGetFramework framework, new TargetFrameworkInformation() { FrameworkName = framework, - Dependencies = dependencies.Select(e => new LibraryDependency(){ LibraryRange = e }).ToList() + Dependencies = dependencies.Select(e => new LibraryDependency(){ LibraryRange = e }).ToImmutableArray() } }; } diff --git a/test/NuGet.Core.Tests/NuGet.Common.Test/MSBuildStringUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.Common.Test/MSBuildStringUtilityTests.cs index a0f4d65fbd8..4ddbc417d39 100644 --- a/test/NuGet.Core.Tests/NuGet.Common.Test/MSBuildStringUtilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Common.Test/MSBuildStringUtilityTests.cs @@ -1,99 +1,9 @@ -using System.Collections.Generic; -using System.Linq; using Xunit; namespace NuGet.Common.Test { public class MSBuildStringUtilityTests { - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_SameLogCodes() - { - // Arrange - var logCodes1 = new List() { NuGetLogCode.NU1000, NuGetLogCode.NU1001 }; - var logCodes2 = new List() { NuGetLogCode.NU1001, NuGetLogCode.NU1000, }; - - var logCodesList = new List>() { logCodes1, logCodes2 }; - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(2, result.Count()); - Assert.True(result.All(logCodes2.Contains)); - } - - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_EmptyLogCodes() - { - // Arrange - var logCodesList = new List>(); - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(0, result.Count()); - } - - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_DiffLogCodes() - { - // Arrange - var logCodes1 = new List() { NuGetLogCode.NU1000 }; - var logCodes2 = new List() { NuGetLogCode.NU1001, NuGetLogCode.NU1000 }; - - var logCodesList = new List>() { logCodes1, logCodes2 }; - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(0, result.Count()); - } - - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_OneNullCode() - { - // Arrange - var logCodes1 = new List() { NuGetLogCode.NU1001, NuGetLogCode.NU1000 }; - - var logCodesList = new List>() { null!, logCodes1 }; - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(0, result.Count()); - } - - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_AllNullCodes() - { - // Arrange - var logCodesList = new List>() { null!, null! }; - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(0, result.Count()); - } - - [Fact] - public void GetDistinctNuGetLogCodesOrDefault_NullCodesAfterFirst() - { - // Arrange - var logCodes1 = new List() { NuGetLogCode.NU1001, NuGetLogCode.NU1000 }; - var logCodesList = new List>() { logCodes1, null! }; - - // Act - var result = MSBuildStringUtility.GetDistinctNuGetLogCodesOrDefault(logCodesList); - - // Assert - Assert.Equal(0, result.Count()); - } - [Theory] [InlineData("true", true)] [InlineData("false", false)] diff --git a/test/NuGet.Core.Tests/NuGet.Common.Test/PackageSpecificWanringPropertiesTests.cs b/test/NuGet.Core.Tests/NuGet.Common.Test/PackageSpecificWanringPropertiesTests.cs index a11f7d0890e..5e007f85bd9 100644 --- a/test/NuGet.Core.Tests/NuGet.Common.Test/PackageSpecificWanringPropertiesTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Common.Test/PackageSpecificWanringPropertiesTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Collections.Immutable; using NuGet.Commands; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -48,7 +49,7 @@ public void PackageSpecificWarningProperties_AddsRangeValueWithGlobalTFM() { // Arrange - var codes = new List { NuGetLogCode.NU1500, NuGetLogCode.NU1601, NuGetLogCode.NU1701 }; + ImmutableArray codes = [NuGetLogCode.NU1500, NuGetLogCode.NU1601, NuGetLogCode.NU1701]; var libraryId = "test_libraryId"; var targetFramework = NuGetFramework.Parse("net45"); var properties = new PackageSpecificWarningProperties(); @@ -71,11 +72,6 @@ public void PackageSpecificWarningProperties_CreatesPackageSpecificWarningProper var netcoreappFramework = NuGetFramework.Parse("netcoreapp1.1"); var libraryId = "test_library"; var libraryVersion = "1.0.0"; - var NoWarnList = new List - { - NuGetLogCode.NU1603, - NuGetLogCode.NU1605 - }; var targetFrameworkInformation = new List { @@ -101,7 +97,7 @@ public void PackageSpecificWarningProperties_CreatesPackageSpecificWarningProper TypeConstraint = LibraryDependencyTarget.Package, VersionRange = VersionRange.Parse(libraryVersion) }, - NoWarn = NoWarnList + NoWarn = [NuGetLogCode.NU1603, NuGetLogCode.NU1605] } } }; @@ -139,11 +135,7 @@ public void PackageSpecificWarningProperties_CreatesPackageSpecificWarningProper TypeConstraint = LibraryDependencyTarget.Package, VersionRange = VersionRange.Parse("1.0.0") }, - NoWarn = new List - { - NuGetLogCode.NU1603, - NuGetLogCode.NU1107 - } + NoWarn = [NuGetLogCode.NU1603, NuGetLogCode.NU1107] }; var dependency2 = new LibraryDependency() @@ -154,11 +146,7 @@ public void PackageSpecificWarningProperties_CreatesPackageSpecificWarningProper TypeConstraint = LibraryDependencyTarget.Package, VersionRange = VersionRange.Parse("1.0.0") }, - NoWarn = new List - { - NuGetLogCode.NU1603, - NuGetLogCode.NU1605 - } + NoWarn = [NuGetLogCode.NU1603, NuGetLogCode.NU1605] }; var targetFrameworkInformation = new List @@ -166,18 +154,12 @@ public void PackageSpecificWarningProperties_CreatesPackageSpecificWarningProper new TargetFrameworkInformation() { FrameworkName = net45Framework, - Dependencies = new List - { - dependency1 - } + Dependencies = [dependency1] }, new TargetFrameworkInformation() { FrameworkName = netcoreappFramework, - Dependencies = new List - { - dependency2 - } + Dependencies = [dependency2] } }; diff --git a/test/NuGet.Core.Tests/NuGet.DependencyResolver.Core.Tests/RemoteDependencyWalkerTests.cs b/test/NuGet.Core.Tests/NuGet.DependencyResolver.Core.Tests/RemoteDependencyWalkerTests.cs index 05ed53f52e9..30f4f2e03ac 100644 --- a/test/NuGet.Core.Tests/NuGet.DependencyResolver.Core.Tests/RemoteDependencyWalkerTests.cs +++ b/test/NuGet.Core.Tests/NuGet.DependencyResolver.Core.Tests/RemoteDependencyWalkerTests.cs @@ -383,7 +383,7 @@ public async Task TryResolveConflicts_WorksWhenVersionRangeIsNotSpecified() // Restore doesn't actually support null versions so fake a resolved dependency var cNode = node.Path("A", "C"); - cNode.Key.TypeConstraint = LibraryDependencyTarget.Package; + cNode.Key = new LibraryRange(cNode.Key) { TypeConstraint = LibraryDependencyTarget.Package }; cNode.Item = new GraphItem(new LibraryIdentity { Name = "C", diff --git a/test/NuGet.Core.Tests/NuGet.LibraryModel.Tests/LibraryDependencyTests.cs b/test/NuGet.Core.Tests/NuGet.LibraryModel.Tests/LibraryDependencyTests.cs index aaaeb4d9a55..a2a0a407ed7 100644 --- a/test/NuGet.Core.Tests/NuGet.LibraryModel.Tests/LibraryDependencyTests.cs +++ b/test/NuGet.Core.Tests/NuGet.LibraryModel.Tests/LibraryDependencyTests.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; using NuGet.Versioning; using Xunit; @@ -17,7 +15,7 @@ public void LibraryDependency_Clone_Equals() var target = GetTarget(); // Act - var clone = target.Clone(); + var clone = new LibraryDependency(target) { ReferenceType = target.ReferenceType }; // Assert Assert.NotSame(target, clone); @@ -31,63 +29,14 @@ public void LibraryDependency_Clone_ClonesLibraryRange() var target = GetTarget(); // Act - var clone = target.Clone(); - clone.LibraryRange.Name = "SomethingElse"; + var libraryRange = new LibraryRange(target.LibraryRange) { Name = "SomethingElse" }; + var clone = new LibraryDependency(target) { LibraryRange = libraryRange }; // Assert Assert.NotSame(target.LibraryRange, clone.LibraryRange); Assert.NotEqual(target.LibraryRange.Name, clone.LibraryRange.Name); } - [Fact] - public void LibraryDependency_ApplyCentralVersionInformation_NullArgumentCheck() - { - // Arrange - List packageReferences = new List(); - Dictionary centralPackageVersions = new Dictionary(); - - // Act + Assert - Assert.Throws(() => LibraryDependency.ApplyCentralVersionInformation(null!, centralPackageVersions)); - Assert.Throws(() => LibraryDependency.ApplyCentralVersionInformation(packageReferences, null!)); - } - - [Fact] - public void LibraryDependency_ApplyCentralVersionInformation_CPVIsMergedTpPackageVersions() - { - var dep1 = new LibraryDependency() - { - LibraryRange = new LibraryRange() { Name = "fooMerged" }, - }; - var dep2 = new LibraryDependency() - { - LibraryRange = new LibraryRange() { Name = "barNotMerged", VersionRange = VersionRange.Parse("1.0.0") }, - }; - var dep3 = new LibraryDependency() - { - LibraryRange = new LibraryRange() { Name = "bazNotMerged" }, - AutoReferenced = true - }; - List deps = new List() { dep1, dep2, dep3 }; - - var cpv1 = new CentralPackageVersion(dep1.Name.ToLower(), VersionRange.Parse("2.0.0")); - var cpv2 = new CentralPackageVersion(dep2.Name.ToLower(), VersionRange.Parse("2.0.0")); - var cpv3 = new CentralPackageVersion(dep3.Name.ToLower(), VersionRange.Parse("2.0.0")); - Dictionary cpvs = new Dictionary(StringComparer.OrdinalIgnoreCase) - { [cpv1.Name] = cpv1, [cpv2.Name] = cpv2, [cpv3.Name] = cpv3 }; - - // Act - LibraryDependency.ApplyCentralVersionInformation(deps, cpvs); - - // Assert - Assert.True(dep1.VersionCentrallyManaged); - Assert.False(dep2.VersionCentrallyManaged); - Assert.False(dep3.VersionCentrallyManaged); - - Assert.Equal("[2.0.0, )", dep1.LibraryRange.VersionRange!.ToNormalizedString()); - Assert.Equal("[1.0.0, )", dep2.LibraryRange.VersionRange!.ToNormalizedString()); - Assert.Null(dep3.LibraryRange.VersionRange); - } - public LibraryDependency GetTarget() { return new LibraryDependency diff --git a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/DependencyGraphRestoreUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/DependencyGraphRestoreUtilityTests.cs index aaf642a7b0a..0d922668446 100644 --- a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/DependencyGraphRestoreUtilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/DependencyGraphRestoreUtilityTests.cs @@ -472,7 +472,9 @@ public async Task RestoreAsync_WithProgressReporter_WithIncrementalRestore_Progr SimpleTestPackageContext packageA = new("a", "1.0.0"); packageA.AddFile("lib/netstandard2.0/a.dll"); await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); - packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + + var newDependencies = packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; // Act IReadOnlyList result = await DependencyGraphRestoreUtility.RestoreAsync( @@ -514,7 +516,9 @@ public async Task RestoreAsync_WithProgressReporter_WithIncrementalRestoreAndPac var progressReporter = new Mock(); SimpleTestPackageContext packageA = new("a", "1.0.0"); await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); - packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + + var newDependencies = packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; // Act IReadOnlyList result = await DependencyGraphRestoreUtility.RestoreAsync( @@ -557,7 +561,9 @@ public async Task RestoreAsync_WithProgressReporter_WithIncrementalRestoreAndPac SimpleTestPackageContext packageA = new("a", "1.0.0"); packageA.AddFile("build/netstandard2.0/a.targets"); await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); - packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + + var newDependencies = packageSpec.TargetFrameworks[0].Dependencies.Add(new LibraryDependency(new LibraryRange(packageA.Id, VersionRange.Parse(packageA.Version), LibraryDependencyTarget.All))); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Dependencies = newDependencies }; // Act IReadOnlyList result = await DependencyGraphRestoreUtility.RestoreAsync( diff --git a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/ProjectManagement/BuildIntegratedNuGetProjectTests.cs b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/ProjectManagement/BuildIntegratedNuGetProjectTests.cs index 9d4ea128742..d06112d5cc1 100644 --- a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/ProjectManagement/BuildIntegratedNuGetProjectTests.cs +++ b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/ProjectManagement/BuildIntegratedNuGetProjectTests.cs @@ -424,7 +424,7 @@ public async Task BuildIntegratedNuGetProject_GetPackageSpec_WithImports() Assert.Equal(projectFilePath, actual.RestoreMetadata.ProjectUniqueName); Assert.Equal(1, actual.TargetFrameworks.Count); Assert.Equal(projectTargetFramework, actual.TargetFrameworks[0].FrameworkName); - Assert.Equal(1, actual.TargetFrameworks[0].Imports.Count); + Assert.Equal(1, actual.TargetFrameworks[0].Imports.Length); Assert.Equal(FallbackTargetFramework, actual.TargetFrameworks[0].Imports[0]); Assert.Empty(actual.Dependencies); @@ -478,7 +478,7 @@ public async Task BuildIntegratedNuGetProject_GetPackageSpec_UAPWithImports() Assert.Equal(projectFilePath, actual.RestoreMetadata.ProjectUniqueName); Assert.Equal(1, actual.TargetFrameworks.Count); Assert.Equal(projectTargetFramework, actual.TargetFrameworks[0].FrameworkName); - Assert.Equal(1, actual.TargetFrameworks[0].Imports.Count); + Assert.Equal(1, actual.TargetFrameworks[0].Imports.Length); Assert.Equal(FallbackTargetFramework, actual.TargetFrameworks[0].Imports[0]); Assert.Empty(actual.Dependencies); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/AssetTargetFallbackTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/AssetTargetFallbackTests.cs index e789eae1f38..0f7b30638de 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/AssetTargetFallbackTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/AssetTargetFallbackTests.cs @@ -12,8 +12,7 @@ public class AssetTargetFallbackTests [Fact] public void GivenAssetTargetFallbackTrueVerifyValuePersisted() { - var spec = PackageSpecTestUtility.GetSpec(NuGetFramework.Parse("netcoreapp2.0")); - spec.TargetFrameworks[0].AssetTargetFallback = true; + var spec = PackageSpecTestUtility.GetSpec(assetTargetFallback: true, NuGetFramework.Parse("netcoreapp2.0")); var outSpec = spec.RoundTrip(); outSpec.TargetFrameworks[0].AssetTargetFallback.Should().BeTrue(); @@ -22,8 +21,7 @@ public void GivenAssetTargetFallbackTrueVerifyValuePersisted() [Fact] public void GivenAssetTargetFallbackFalseVerifyValuePersisted() { - var spec = PackageSpecTestUtility.GetSpec(NuGetFramework.Parse("netcoreapp2.0")); - spec.TargetFrameworks[0].AssetTargetFallback = false; + var spec = PackageSpecTestUtility.GetSpec(assetTargetFallback: false, NuGetFramework.Parse("netcoreapp2.0")); var outSpec = spec.RoundTrip(); outSpec.TargetFrameworks[0].AssetTargetFallback.Should().BeFalse(); @@ -33,9 +31,8 @@ public void GivenAssetTargetFallbackFalseVerifyValuePersisted() public void GivenImportsVerifyValuePersisted() { var net461 = NuGetFramework.Parse("net461"); - var spec = PackageSpecTestUtility.GetSpec(NuGetFramework.Parse("netcoreapp2.0")); - spec.TargetFrameworks[0].AssetTargetFallback = true; - spec.TargetFrameworks[0].Imports.Add(net461); + var spec = PackageSpecTestUtility.GetSpec(assetTargetFallback: true, NuGetFramework.Parse("netcoreapp2.0")); + spec.TargetFrameworks[0] = new TargetFrameworkInformation(spec.TargetFrameworks[0]) { Imports = [net461] }; var outSpec = spec.RoundTrip(); outSpec.TargetFrameworks[0].Imports.Should().BeEquivalentTo(new[] { net461 }); @@ -46,9 +43,8 @@ public void GivenAssetTargetFallbackVerifyFrameworkIsAssetTargetFallbackFramewor { var net461 = NuGetFramework.Parse("net461"); var projectFramework = NuGetFramework.Parse("netcoreapp2.0"); - var spec = PackageSpecTestUtility.GetSpec(projectFramework); - spec.TargetFrameworks[0].AssetTargetFallback = true; - spec.TargetFrameworks[0].Imports.Add(net461); + var spec = PackageSpecTestUtility.GetSpec(assetTargetFallback: true, projectFramework); + spec.TargetFrameworks[0] = new TargetFrameworkInformation(spec.TargetFrameworks[0]) { Imports = [net461] }; var outSpec = spec.RoundTrip(); @@ -60,10 +56,8 @@ public void GivenAssetTargetFallbackVerifyFrameworkIsAssetTargetFallbackFramewor [Fact] public void GivenAssetTargetFallbackDiffersVerifyEquality() { - var spec1 = PackageSpecTestUtility.GetSpec("netcoreapp2.0"); - spec1.TargetFrameworks[0].AssetTargetFallback = true; - var spec2 = PackageSpecTestUtility.GetSpec("netcoreapp2.0"); - spec2.TargetFrameworks[0].AssetTargetFallback = false; + var spec1 = PackageSpecTestUtility.GetSpec(assetTargetFallback: true, "netcoreapp2.0"); + var spec2 = PackageSpecTestUtility.GetSpec(assetTargetFallback: false, "netcoreapp2.0"); spec1.Should().NotBe(spec2); spec1.GetHashCode().Should().NotBe(spec2.GetHashCode()); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/CentralTransitiveDependencyGroupTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/CentralTransitiveDependencyGroupTests.cs index c447d3d1208..d380bf21c2d 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/CentralTransitiveDependencyGroupTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/CentralTransitiveDependencyGroupTests.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using FluentAssertions; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -22,7 +21,7 @@ public void CentralTransitiveDependencyGroup_ConstructorNullArgumentCheck(bool n { // Arrange var nuGetFramework = nullFramework ? null : NuGetFramework.Parse("NETStandard2.0"); - var dependencies = nullDependencies ? null : Enumerable.Empty(); + var dependencies = nullDependencies ? null : Array.Empty(); // Act + Assert Assert.Throws(() => new CentralTransitiveDependencyGroup(nuGetFramework, dependencies)); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyGraphSpecTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyGraphSpecTests.cs index e7a359bc5e7..602996da850 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyGraphSpecTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyGraphSpecTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using NuGet.Configuration; @@ -436,125 +437,13 @@ public void Save_WithCentralVersionDependencies_SerializesMembersAsJson() string expectedJson = GetResourceAsJson(DgSpecWithCentralDependencies); // Act - DependencyGraphSpec dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(); + DependencyGraphSpec dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(CreateTargetFrameworkInformation()); string actualJson = GetJson(dependencyGraphSpec); // Assert Assert.Equal(expectedJson, actualJson); } - [Fact] - public void AddProject_WhenDependencyVersionIsNull_CentralPackageVersionAppliesOnlyWhenAutoReferencedIsFalse() - { - // Arrange - var dependencyFoo = new LibraryDependency( - new LibraryRange("foo", versionRange: null, LibraryDependencyTarget.Package), - LibraryIncludeFlags.All, - LibraryIncludeFlags.All, - new List(), - autoReferenced: false, - generatePathProperty: true, - versionCentrallyManaged: false, - LibraryDependencyReferenceType.Direct, - aliases: null, - versionOverride: null); - var dependencyBar = new LibraryDependency( - new LibraryRange("bar", VersionRange.Parse("3.0.0"), LibraryDependencyTarget.Package), - LibraryIncludeFlags.All, - LibraryIncludeFlags.All, - new List(), - autoReferenced: true, - generatePathProperty: true, - versionCentrallyManaged: false, - LibraryDependencyReferenceType.Direct, - aliases: null, - versionOverride: null); - var dependencyBoom = new LibraryDependency( - new LibraryRange("boom", versionRange: null, LibraryDependencyTarget.Package), - LibraryIncludeFlags.All, - LibraryIncludeFlags.All, - new List(), - autoReferenced: true, - generatePathProperty: true, - versionCentrallyManaged: false, - LibraryDependencyReferenceType.Direct, - aliases: null, - versionOverride: null); - var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); - var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); - var centralVersionBoom = new CentralPackageVersion("boom", VersionRange.Parse("4.0.0")); - - var tfi = CreateTargetFrameworkInformation( - new List() { dependencyFoo, dependencyBar, dependencyBoom }, - new List() { centralVersionFoo, centralVersionBar, centralVersionBoom }); - - // Act - DependencyGraphSpec dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(tfi); - - // Assert - Assert.Equal(1, dependencyGraphSpec.Projects.Count); - PackageSpec packSpec = dependencyGraphSpec.Projects[0]; - IList tfms = packSpec.TargetFrameworks; - IList dependencies = tfms[0].Dependencies; - - Assert.Equal(1, tfms.Count); - Assert.Equal(3, dependencies.Count); - Assert.Equal("[1.0.0, )", dependencies.Where(d => d.Name == "foo").First().LibraryRange.VersionRange.ToNormalizedString()); - Assert.True(dependencies.Where(d => d.Name == "foo").First().VersionCentrallyManaged); - Assert.Equal("[3.0.0, )", dependencies.Where(d => d.Name == "bar").First().LibraryRange.VersionRange.ToNormalizedString()); - Assert.False(dependencies.Where(d => d.Name == "bar").First().VersionCentrallyManaged); - Assert.Null(dependencies.Where(d => d.Name == "boom").First().LibraryRange.VersionRange); - } - - [Fact] - public void AddProject_WhenDependencyIsNotInCentralPackageVersions_DependencyVersionIsAllVersions() - { - // Arrange - var dependencyFoo = new LibraryDependency( - new LibraryRange("foo", versionRange: null, LibraryDependencyTarget.Package), - LibraryIncludeFlags.All, - LibraryIncludeFlags.All, - new List(), - autoReferenced: false, - generatePathProperty: true, - versionCentrallyManaged: false, - LibraryDependencyReferenceType.Direct, - aliases: null, - versionOverride: null); - var dependencyBar = new LibraryDependency( - new LibraryRange("bar", VersionRange.Parse("3.0.0"), LibraryDependencyTarget.Package), - LibraryIncludeFlags.All, - LibraryIncludeFlags.All, - new List(), - autoReferenced: false, - generatePathProperty: true, - versionCentrallyManaged: false, - LibraryDependencyReferenceType.Direct, - aliases: null, - versionOverride: null); - - // only a central dependency for bar not for foo - // foo will have null VersionRange - var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); - - TargetFrameworkInformation tfi = CreateTargetFrameworkInformation( - new List() { dependencyFoo, dependencyBar }, - new List() { centralVersionBar }); - - // Act - DependencyGraphSpec dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(tfi); - - // Assert - PackageSpec packSpec = dependencyGraphSpec.Projects[0]; - IList tfms = packSpec.TargetFrameworks; - IList dependencies = tfms[0].Dependencies; - - Assert.Equal(1, tfms.Count); - Assert.Equal(2, dependencies.Count); - Assert.Null(dependencies.Where(d => d.Name == "foo").First().LibraryRange.VersionRange); - Assert.True(dependencies.Where(d => d.Name == "foo").First().VersionCentrallyManaged); - } - [Fact] public void AddProject_WhenRestoreMetadataIsNull_AddsProject() { @@ -577,6 +466,7 @@ public void AddProject_DoesNotClone(bool cpvmEnabled) var dependencyFoo = new LibraryDependency() { LibraryRange = new LibraryRange("foo", versionRange: cpvmEnabled ? null : VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), + VersionCentrallyManaged = cpvmEnabled }; var centralVersions = cpvmEnabled @@ -584,7 +474,7 @@ public void AddProject_DoesNotClone(bool cpvmEnabled) : new List(); var tfi = CreateTargetFrameworkInformation( - new List() { dependencyFoo }, + [dependencyFoo], centralVersions); var packageSpec = new PackageSpec(new List() { tfi }); @@ -691,11 +581,6 @@ private static DependencyGraphSpec CreateDependencyGraphSpec() return dgSpec; } - private static DependencyGraphSpec CreateDependencyGraphSpecWithCentralDependencies(int centralVersionsDummyLoadCount = 0) - { - return CreateDependencyGraphSpecWithCentralDependencies(CreateTargetFrameworkInformation(centralVersionsDummyLoadCount)); - } - private static DependencyGraphSpec CreateDependencyGraphSpecWithCentralDependencies(params TargetFrameworkInformation[] tfis) { var packageSpec = new PackageSpec(tfis); @@ -707,67 +592,62 @@ private static DependencyGraphSpec CreateDependencyGraphSpecWithCentralDependenc return dgSpec; } - private static TargetFrameworkInformation CreateTargetFrameworkInformation(int centralVersionsDummyLoadCount = 0) + private static TargetFrameworkInformation CreateTargetFrameworkInformation() { var nugetFramework = new NuGetFramework("net40"); + + var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); + var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); + var dependencyFoo = new LibraryDependency( - new LibraryRange("foo", versionRange: null, LibraryDependencyTarget.Package), + new LibraryRange("foo", versionRange: centralVersionFoo.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: null, versionOverride: null); - var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")); - var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); - - var dependencies = new List() { dependencyFoo }; var assetTargetFallback = true; var warn = false; + var centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + {centralVersionFoo.Name, centralVersionFoo }, + { centralVersionBar.Name, centralVersionBar }, + }; + + ImmutableArray dependencies = [dependencyFoo]; + var tfi = new TargetFrameworkInformation() { AssetTargetFallback = assetTargetFallback, + CentralPackageVersions = centralPackageVersions, Dependencies = dependencies, Warn = warn, FrameworkName = nugetFramework, }; - tfi.CentralPackageVersions.Add(centralVersionFoo.Name, centralVersionFoo); - tfi.CentralPackageVersions.Add(centralVersionBar.Name, centralVersionBar); - LibraryDependency.ApplyCentralVersionInformation(tfi.Dependencies, tfi.CentralPackageVersions); - - for (int i = 0; i < centralVersionsDummyLoadCount; i++) - { - var dummy = new CentralPackageVersion($"Dummy{i}", VersionRange.Parse("1.0.0")); - tfi.CentralPackageVersions.Add(dummy.Name, dummy); - } - return tfi; } - private static TargetFrameworkInformation CreateTargetFrameworkInformation(List dependencies, List centralVersionsDependencies) + private static TargetFrameworkInformation CreateTargetFrameworkInformation(ImmutableArray dependencies, List centralVersionsDependencies) { var nugetFramework = new NuGetFramework("net40"); + var centralPackageVersions = centralVersionsDependencies.ToDictionary(cvd => cvd.Name, StringComparer.OrdinalIgnoreCase); var tfi = new TargetFrameworkInformation() { AssetTargetFallback = true, - Warn = false, - FrameworkName = nugetFramework, + CentralPackageVersions = centralPackageVersions, Dependencies = dependencies, + FrameworkName = nugetFramework, + Warn = false, }; - foreach (CentralPackageVersion cvd in centralVersionsDependencies) - { - tfi.CentralPackageVersions.Add(cvd.Name, cvd); - } - LibraryDependency.ApplyCentralVersionInformation(tfi.Dependencies, tfi.CentralPackageVersions); - return tfi; } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index d1d0b7857a2..74373b885ec 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -533,10 +533,9 @@ public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn(IEnvironmentVari // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 2); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1107)); + Assert.Equal(dep.NoWarn.Length, 2); + Assert.Contains(NuGetLogCode.NU1500, dep.NoWarn); + Assert.Contains(NuGetLogCode.NU1107, dep.NoWarn); } [Theory] @@ -564,9 +563,8 @@ public void PackageSpecReader_ReadsDependencyWithSingleNoWarn(IEnvironmentVariab // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 1); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); + Assert.Equal(dep.NoWarn.Length, 1); + Assert.Contains(NuGetLogCode.NU1500, dep.NoWarn); } [Theory] @@ -593,8 +591,7 @@ public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn(IEnvironmentV // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 0); + Assert.Equal(dep.NoWarn.Length, 0); } [Theory] diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs index 59c6aecbaa3..42ea06716a9 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs @@ -723,8 +723,8 @@ public void LockFileFormat_ReadsPackageSpec() { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, TargetAlias = "netcoreapp10", - Dependencies = new[] - { + Dependencies = + [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -744,7 +744,7 @@ public void LockFileFormat_ReadsPackageSpec() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -2465,14 +2465,13 @@ public void LockFileFormat_WritesCentralTransitiveDependencyGroups() libraryRange: new LibraryRange("Newtonsoft.Json", VersionRange.Parse("[12.0.3, )"), LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.Compile | LibraryIncludeFlags.BuildTransitive | LibraryIncludeFlags.Native, suppressParent: LibraryIncludeFlags.All, - noWarn: new List(), + noWarn: [], autoReferenced: true, generatePathProperty: false, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: null, versionOverride: null); - newtonSoftDependency.VersionCentrallyManaged = true; lockFile.CentralTransitiveDependencyGroups .Add(new CentralTransitiveDependencyGroup(framework, new List() { newtonSoftDependency })); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileTests.cs index 8875d8e0ddd..6d242681fe8 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileTests.cs @@ -32,8 +32,7 @@ public void LockFile_ConsidersEquivalentPackageSpec() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -53,7 +52,7 @@ public void LockFile_ConsidersEquivalentPackageSpec() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -99,8 +98,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithEmptyLogsAsSame() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -120,7 +118,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithEmptyLogsAsSame() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -170,8 +168,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithMinimalLogsAsSame() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -191,7 +188,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithMinimalLogsAsSame() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -256,8 +253,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithFullLogsAsSame() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -277,7 +273,7 @@ public void LockFile_ConsidersEquivalentLockFilesWithFullLogsAsSame() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -379,8 +375,7 @@ public void LockFile_ConsidersLockFilesWithDifferentlyOrderedLogsAsSame() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -400,7 +395,7 @@ public void LockFile_ConsidersLockFilesWithDifferentlyOrderedLogsAsSame() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -466,8 +461,7 @@ public void LockFile_ConsidersLockFilesWithLogsWithDifferentMessagesAsDifferent( new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -487,7 +481,7 @@ public void LockFile_ConsidersLockFilesWithLogsWithDifferentMessagesAsDifferent( LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -551,8 +545,7 @@ public void LockFile_ConsidersLockFilesWithDifferentErrorsAsDifferent() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -572,7 +565,7 @@ public void LockFile_ConsidersLockFilesWithDifferentErrorsAsDifferent() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { @@ -666,8 +659,7 @@ public void LockFile_ConsidersLockFilesWithDifferentLogsAsDifferent() new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetCoreApp10, - Dependencies = new[] - { + Dependencies = [ new LibraryDependency { LibraryRange = new LibraryRange( @@ -687,7 +679,7 @@ public void LockFile_ConsidersLockFilesWithDifferentLogsAsDifferent() LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All } - } + ] } }) { diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecOperationsTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecOperationsTests.cs index afe8a7e2ae6..05444f57bea 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecOperationsTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecOperationsTests.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using FluentAssertions; using NuGet.Frameworks; @@ -81,7 +82,7 @@ public void AddOrUpdateDependency_WithPackageReferenceProjectStyle_AddsNewPackag // Assert Assert.Empty(spec.Dependencies); - Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Length); Assert.Equal(identity.Id, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name); Assert.Equal(identity.Version, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion); } @@ -141,7 +142,7 @@ public void AddOrUpdateDependency_WithExistingPackageDependencies_UpdatesOnlyFra new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.Net45, - Dependencies = new List() { dependency } + Dependencies = [dependency] }, new TargetFrameworkInformation @@ -164,7 +165,7 @@ public void AddOrUpdateDependency_WithExistingPackageDependencies_UpdatesOnlyFra // Assert Assert.Empty(spec.Dependencies); - Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Length); Assert.Equal(identity.Id, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name); Assert.Equal(identity.Version, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion); } @@ -177,28 +178,28 @@ public void AddOrUpdateDependency_WithExistingPackages_UpdatesAllPackageDependen // Arrange var frameworkA = new TargetFrameworkInformation { + Dependencies = [new LibraryDependency + { + LibraryRange = new LibraryRange + { + Name = "nuget.versioning", + VersionRange = new VersionRange(new NuGetVersion("0.9.0")) + } + }], FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; - frameworkA.Dependencies.Add(new LibraryDependency - { - LibraryRange = new LibraryRange - { - Name = "nuget.versioning", - VersionRange = new VersionRange(new NuGetVersion("0.9.0")) - } - }); var frameworkB = new TargetFrameworkInformation { + Dependencies = [new LibraryDependency + { + LibraryRange = new LibraryRange + { + Name = "NUGET.VERSIONING", + VersionRange = new VersionRange(new NuGetVersion("0.8.0")) + } + }], FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16 }; - frameworkB.Dependencies.Add(new LibraryDependency - { - LibraryRange = new LibraryRange - { - Name = "NUGET.VERSIONING", - VersionRange = new VersionRange(new NuGetVersion("0.8.0")) - } - }); var spec = new PackageSpec(new[] { frameworkA, frameworkB }); var identity = new PackageIdentity("NuGet.Versioning", new NuGetVersion("1.0.0")); var packageDependency = new PackageDependency(identity.Id, new VersionRange(identity.Version)); @@ -216,13 +217,13 @@ public void AddOrUpdateDependency_WithExistingPackages_UpdatesAllPackageDependen // Assert Assert.Empty(spec.Dependencies); - Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Length); Assert.Equal("nuget.versioning", spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name); Assert.Equal( identity.Version, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion); - Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Length); Assert.Equal("NUGET.VERSIONING", spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name); Assert.Equal( identity.Version, @@ -250,7 +251,7 @@ public void AddOrUpdateDependency_ToSpecificFrameworks_UpdatesExistingDependenci var frameworkB = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16, - Dependencies = new List() { ld } + Dependencies = [ld] }; var spec = new PackageSpec(new[] { frameworkA, frameworkB }); @@ -284,7 +285,7 @@ public void AddOrUpdateDependency_ToSpecificFrameworks_UpdatesExistingDependenci Assert.Empty(spec.TargetFrameworks[0].Dependencies); - Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Length); Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name); Assert.Equal( identity.Version, @@ -312,7 +313,7 @@ public void AddOrUpdateDependency_ToSpecificFrameworks_AddsNewDependency(bool us var frameworkB = new TargetFrameworkInformation { FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16, - Dependencies = new List() { ld } + Dependencies = [ld] }; var spec = new PackageSpec(new[] { frameworkA, frameworkB }); @@ -345,7 +346,7 @@ public void AddOrUpdateDependency_ToSpecificFrameworks_AddsNewDependency(bool us Assert.Empty(spec.TargetFrameworks[0].Dependencies); - Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Length); Assert.Equal(identity.Id, spec.TargetFrameworks[1].Dependencies[0].LibraryRange.Name); Assert.Equal( identity.Version, @@ -391,7 +392,7 @@ public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_AddsDepend } // Assert - Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[0].Dependencies.Length); Assert.Equal(packageIdentity.Id, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.Name); Assert.Equal(packageIdentity.Version, spec.TargetFrameworks[0].Dependencies[0].LibraryRange.VersionRange.MinVersion); Assert.True(spec.TargetFrameworks[0].Dependencies[0].VersionCentrallyManaged); @@ -423,12 +424,14 @@ public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_UpdatesDep var frameworkB = new TargetFrameworkInformation { + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { ld.Name, new CentralPackageVersion(ld.Name, ld.LibraryRange.VersionRange) }, + }, FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16, - Dependencies = new List() { ld }, + Dependencies = [ld], }; - frameworkB.CentralPackageVersions[ld.Name] = new CentralPackageVersion(ld.Name, ld.LibraryRange.VersionRange); - var spec = new PackageSpec(new[] { frameworkA, frameworkB }) { RestoreMetadata = new ProjectRestoreMetadata @@ -465,7 +468,7 @@ public void AddOrUpdateDependency_WithCentralPackageManagementEnabled_UpdatesDep Assert.Empty(spec.TargetFrameworks[0].Dependencies); - Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Count); + Assert.Equal(1, spec.TargetFrameworks[1].Dependencies.Length); 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); @@ -480,28 +483,28 @@ public void RemoveDependency_RemovesFromAllFrameworkLists() // Arrange var frameworkA = new TargetFrameworkInformation { + Dependencies = [new LibraryDependency + { + LibraryRange = new LibraryRange + { + Name = "nuget.versioning", + VersionRange = new VersionRange(new NuGetVersion("0.9.0")) + } + }], FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; - frameworkA.Dependencies.Add(new LibraryDependency - { - LibraryRange = new LibraryRange - { - Name = "nuget.versioning", - VersionRange = new VersionRange(new NuGetVersion("0.9.0")) - } - }); var frameworkB = new TargetFrameworkInformation { + Dependencies = [new LibraryDependency + { + LibraryRange = new LibraryRange + { + Name = "NUGET.VERSIONING", + VersionRange = new VersionRange(new NuGetVersion("0.8.0")) + } + }], FrameworkName = FrameworkConstants.CommonFrameworks.NetStandard16 }; - frameworkB.Dependencies.Add(new LibraryDependency - { - LibraryRange = new LibraryRange - { - Name = "NUGET.VERSIONING", - VersionRange = new VersionRange(new NuGetVersion("0.8.0")) - } - }); var spec = new PackageSpec(new[] { frameworkA, frameworkB }); spec.Dependencies.Add(new LibraryDependency { @@ -528,16 +531,16 @@ public void HasPackage_ReturnsTrueWhenIdIsInFramework() // Arrange var framework = new TargetFrameworkInformation { + Dependencies = [new LibraryDependency + { + LibraryRange = new LibraryRange + { + Name = "nuget.versioning", + VersionRange = new VersionRange(new NuGetVersion("0.9.0")) + } + }], FrameworkName = FrameworkConstants.CommonFrameworks.Net45 }; - framework.Dependencies.Add(new LibraryDependency - { - LibraryRange = new LibraryRange - { - Name = "nuget.versioning", - VersionRange = new VersionRange(new NuGetVersion("0.9.0")) - } - }); var spec = new PackageSpec(new[] { framework }); var id = "NuGet.Versioning"; diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecReferenceDependencyProviderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecReferenceDependencyProviderTests.cs index 221c497fc95..2432c4b0e3f 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecReferenceDependencyProviderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecReferenceDependencyProviderTests.cs @@ -1,7 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using FluentAssertions; using NuGet.Commands.Test; @@ -28,22 +30,22 @@ public class PackageSpecReferenceDependencyProviderTests public void GetSpecDependencies_AddsCentralPackageVersionsIfDefined(bool cpvmEnabled, bool CentralPackageTransitivePinningEnabled, bool useLegacyDependencyGraphResolution) { // Arrange + var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("2.0.0")); + var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); + var dependencyFoo = new LibraryDependency( - libraryRange: new LibraryRange("foo", versionRange: null, LibraryDependencyTarget.Package), + libraryRange: new LibraryRange("foo", versionRange: cpvmEnabled ? centralVersionFoo.VersionRange : null, LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.All, suppressParent: LibraryIncludeFlags.None, - noWarn: new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: cpvmEnabled, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - var centralVersionFoo = new CentralPackageVersion("foo", VersionRange.Parse("2.0.0")); - var centralVersionBar = new CentralPackageVersion("bar", VersionRange.Parse("2.0.0")); - - var tfi = CreateTargetFrameworkInformation(new List() { dependencyFoo }, new List() { centralVersionFoo, centralVersionBar }, cpvmEnabled); + var tfi = CreateTargetFrameworkInformation([dependencyFoo], new List() { centralVersionFoo, centralVersionBar }); var dependencyGraphSpec = CreateDependencyGraphSpecWithCentralDependencies(cpvmEnabled, CentralPackageTransitivePinningEnabled, true, tfi); var packSpec = dependencyGraphSpec.Projects[0]; @@ -108,28 +110,20 @@ public void GetSpecDependencies_WithAssetTargetFallback_AndDependencyResolutionV } } - private static TargetFrameworkInformation CreateTargetFrameworkInformation(List dependencies, List centralVersionsDependencies, bool cpvmEnabled) + private static TargetFrameworkInformation CreateTargetFrameworkInformation(ImmutableArray dependencies, List centralVersionsDependencies) { NuGetFramework nugetFramework = new NuGetFramework("net40"); + var centralPackageVersions = centralVersionsDependencies.ToDictionary(cvd => cvd.Name, StringComparer.OrdinalIgnoreCase); TargetFrameworkInformation tfi = new TargetFrameworkInformation() { AssetTargetFallback = true, + CentralPackageVersions = centralPackageVersions, Warn = false, FrameworkName = nugetFramework, Dependencies = dependencies, }; - foreach (var cvd in centralVersionsDependencies) - { - tfi.CentralPackageVersions.Add(cvd.Name, cvd); - } - - if (cpvmEnabled) - { - LibraryDependency.ApplyCentralVersionInformation(tfi.Dependencies, tfi.CentralPackageVersions); - } - return tfi; } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTestUtility.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTestUtility.cs index 0e21266b564..672e8deb9a6 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTestUtility.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTestUtility.cs @@ -99,23 +99,24 @@ internal static JObject ToJObject(this PackageSpec spec) public static PackageSpec GetSpec() { - return GetSpec("netcoreapp2.0"); + return GetSpec(assetTargetFallback: false, "netcoreapp2.0"); } - public static PackageSpec GetSpec(params NuGetFramework[] frameworks) + public static PackageSpec GetSpec(bool assetTargetFallback, params NuGetFramework[] frameworks) { var tfis = new List( frameworks.Select(e => new TargetFrameworkInformation() { + AssetTargetFallback = assetTargetFallback, FrameworkName = e })); return new PackageSpec(tfis); } - public static PackageSpec GetSpec(params string[] frameworks) + public static PackageSpec GetSpec(bool assetTargetFallback, params string[] frameworks) { - return GetSpec(frameworks.Select(NuGetFramework.Parse).ToArray()); + return GetSpec(assetTargetFallback: assetTargetFallback, frameworks.Select(NuGetFramework.Parse).ToArray()); } } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTests.cs index dfa63f50f59..44a252a61aa 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecTests.cs @@ -132,7 +132,7 @@ internal static LibraryDependency CreateLibraryDependency() libraryRange: new LibraryRange(Guid.NewGuid().ToString(), LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.None, suppressParent: LibraryIncludeFlags.ContentFiles, - noWarn: new List() { NuGetLogCode.NU1000, NuGetLogCode.NU1001, NuGetLogCode.NU1002 }, + noWarn: [NuGetLogCode.NU1000, NuGetLogCode.NU1001, NuGetLogCode.NU1002], autoReferenced: false, generatePathProperty: false, versionCentrallyManaged: false, @@ -275,12 +275,14 @@ public static void ModifyOriginalTargetFrameworkInformationAdd(PackageSpec packa public static void ModifyOriginalTargetFrameworkInformationEdit(PackageSpec packageSpec) { - packageSpec.TargetFrameworks[0].Imports.Add(NuGetFramework.Parse("net461")); + var newImports = packageSpec.TargetFrameworks[0].Imports.Add(NuGetFramework.Parse("net461")); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Imports = newImports }; } public static void ModifyRestoreMetadata(PackageSpec packageSpec) { - packageSpec.TargetFrameworks[0].Imports.Add(NuGetFramework.Parse("net461")); + var newImports = packageSpec.TargetFrameworks[0].Imports.Add(NuGetFramework.Parse("net461")); + packageSpec.TargetFrameworks[0] = new TargetFrameworkInformation(packageSpec.TargetFrameworks[0]) { Imports = newImports }; } public static void ModifyVersion(PackageSpec packageSpec) @@ -714,7 +716,7 @@ internal static TargetFrameworkInformation CreateTargetFrameworkInformation(stri libraryRange: new LibraryRange("Dependency", LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.None, suppressParent: LibraryIncludeFlags.ContentFiles, - noWarn: new List() { NuGetLogCode.NU1000, NuGetLogCode.NU1001 }, + noWarn: [NuGetLogCode.NU1000, NuGetLogCode.NU1001], autoReferenced: false, generatePathProperty: false, versionCentrallyManaged: false, @@ -723,17 +725,25 @@ internal static TargetFrameworkInformation CreateTargetFrameworkInformation(stri versionOverride: null); var imports = NuGetFramework.Parse("net45"); // This makes no sense in the context of fallback, just for testing :) - var originalTargetFrameworkInformation = new TargetFrameworkInformation(); - originalTargetFrameworkInformation.TargetAlias = alias ?? Guid.NewGuid().ToString(); - originalTargetFrameworkInformation.FrameworkName = framework; - originalTargetFrameworkInformation.Dependencies = new List() { dependency }; - originalTargetFrameworkInformation.AssetTargetFallback = false; - originalTargetFrameworkInformation.Imports = new List() { imports }; - originalTargetFrameworkInformation.DownloadDependencies.Add(new DownloadDependency("X", VersionRange.Parse("1.0.0"))); - originalTargetFrameworkInformation.FrameworkReferences.Add(new FrameworkDependency("frameworkRef", FrameworkDependencyFlags.All)); - originalTargetFrameworkInformation.FrameworkReferences.Add(new FrameworkDependency("FrameworkReference", FrameworkDependencyFlags.None)); - originalTargetFrameworkInformation.RuntimeIdentifierGraphPath = @"path/to/dotnet/sdk/3.0.100/runtime.json"; - originalTargetFrameworkInformation.CentralPackageVersions.Add("CVD", new CentralPackageVersion("CVD", VersionRange.Parse("1.0.0"))); + var originalTargetFrameworkInformation = new TargetFrameworkInformation() + { + AssetTargetFallback = false, + CentralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "CVD", new CentralPackageVersion("CVD", VersionRange.Parse("1.0.0")) }, + }, + Dependencies = [dependency], + DownloadDependencies = [new DownloadDependency("X", VersionRange.Parse("1.0.0"))], + FrameworkName = framework, + FrameworkReferences = [ + new FrameworkDependency("frameworkRef", FrameworkDependencyFlags.All), + new FrameworkDependency("FrameworkReference", FrameworkDependencyFlags.None) + ], + Imports = [imports], + RuntimeIdentifierGraphPath = @"path/to/dotnet/sdk/3.0.100/runtime.json", + TargetAlias = alias ?? Guid.NewGuid().ToString() + }; + return originalTargetFrameworkInformation; } @@ -744,7 +754,7 @@ public void TargetFrameworkInformationCloneTest() var originalTargetFrameworkInformation = CreateTargetFrameworkInformation(); // Act - var clone = originalTargetFrameworkInformation.Clone(); + var clone = new TargetFrameworkInformation(originalTargetFrameworkInformation); // Assert Assert.Equal(originalTargetFrameworkInformation, clone); @@ -752,68 +762,71 @@ public void TargetFrameworkInformationCloneTest() Assert.Equal(originalTargetFrameworkInformation.GetHashCode(), clone.GetHashCode()); // Act - originalTargetFrameworkInformation.Imports.Clear(); + originalTargetFrameworkInformation = new TargetFrameworkInformation(originalTargetFrameworkInformation) { Imports = [] }; // Assert Assert.NotEqual(originalTargetFrameworkInformation, clone); - Assert.Equal(1, clone.Imports.Count); + Assert.Equal(1, clone.Imports.Length); //Act - var cloneToTestDependencies = originalTargetFrameworkInformation.Clone(); + var cloneToTestDependencies = new TargetFrameworkInformation(originalTargetFrameworkInformation); // Assert Assert.Equal(originalTargetFrameworkInformation, cloneToTestDependencies); Assert.False(ReferenceEquals(originalTargetFrameworkInformation, cloneToTestDependencies)); // Act - originalTargetFrameworkInformation.Dependencies.Clear(); + originalTargetFrameworkInformation = new TargetFrameworkInformation(originalTargetFrameworkInformation) { Dependencies = [] }; // Assert Assert.NotEqual(originalTargetFrameworkInformation, cloneToTestDependencies); - Assert.Equal(1, cloneToTestDependencies.Dependencies.Count); + Assert.Equal(1, cloneToTestDependencies.Dependencies.Length); //Act - var cloneToTestDownloadDependencies = originalTargetFrameworkInformation.Clone(); + var cloneToTestDownloadDependencies = new TargetFrameworkInformation(originalTargetFrameworkInformation); // Assert Assert.Equal(originalTargetFrameworkInformation, cloneToTestDownloadDependencies); Assert.False(ReferenceEquals(originalTargetFrameworkInformation, cloneToTestDownloadDependencies)); // Act - originalTargetFrameworkInformation.DownloadDependencies.Clear(); + originalTargetFrameworkInformation = new TargetFrameworkInformation(originalTargetFrameworkInformation) { DownloadDependencies = [] }; //Assert Assert.NotEqual(originalTargetFrameworkInformation, cloneToTestDownloadDependencies); - Assert.Equal(1, cloneToTestDownloadDependencies.DownloadDependencies.Count); + Assert.Equal(1, cloneToTestDownloadDependencies.DownloadDependencies.Length); //Setup - var cloneToTestFrameworkReferenceEquality = originalTargetFrameworkInformation.Clone(); - cloneToTestFrameworkReferenceEquality.FrameworkReferences.Clear(); - cloneToTestFrameworkReferenceEquality.FrameworkReferences.Add(new FrameworkDependency("frameworkRef", FrameworkDependencyFlags.All)); - cloneToTestFrameworkReferenceEquality.FrameworkReferences.Add(new FrameworkDependency("frameworkReference", FrameworkDependencyFlags.None)); + var cloneToTestFrameworkReferenceEquality = new TargetFrameworkInformation(originalTargetFrameworkInformation) + { + FrameworkReferences = [ + new FrameworkDependency("frameworkRef", FrameworkDependencyFlags.All), + new FrameworkDependency("frameworkReference", FrameworkDependencyFlags.None) + ] + }; // Assert Assert.Equal(originalTargetFrameworkInformation, cloneToTestFrameworkReferenceEquality); Assert.False(ReferenceEquals(originalTargetFrameworkInformation, cloneToTestFrameworkReferenceEquality)); //Act - var cloneToTestFrameworkReferences = originalTargetFrameworkInformation.Clone(); + var cloneToTestFrameworkReferences = new TargetFrameworkInformation(originalTargetFrameworkInformation); // Assert Assert.Equal(originalTargetFrameworkInformation, cloneToTestFrameworkReferences); Assert.False(ReferenceEquals(originalTargetFrameworkInformation, cloneToTestFrameworkReferences)); // Act - originalTargetFrameworkInformation.FrameworkReferences.Clear(); + originalTargetFrameworkInformation = new TargetFrameworkInformation(originalTargetFrameworkInformation) { FrameworkReferences = [] }; //Assert Assert.NotEqual(originalTargetFrameworkInformation, cloneToTestFrameworkReferences); Assert.Equal(2, cloneToTestFrameworkReferences.FrameworkReferences.Count); - var cloneToTestRuntimeIdentifierGraphPath = originalTargetFrameworkInformation.Clone(); + var cloneToTestRuntimeIdentifierGraphPath = new TargetFrameworkInformation(originalTargetFrameworkInformation); // Act - originalTargetFrameworkInformation.RuntimeIdentifierGraphPath = "new/path/to/runtime.json"; + originalTargetFrameworkInformation = new TargetFrameworkInformation(originalTargetFrameworkInformation) { RuntimeIdentifierGraphPath = "new/path/to/runtime.json" }; //Assert Assert.NotEqual(originalTargetFrameworkInformation, cloneToTestRuntimeIdentifierGraphPath); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecWriterTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecWriterTests.cs index 616372c68b9..479c8d5142b 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecWriterTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/PackageSpecWriterTests.cs @@ -857,14 +857,14 @@ private static PackageSpec CreatePackageSpec(bool withRestoreSettings, WarningPr { IncludeType = LibraryIncludeFlags.Build, LibraryRange = libraryRangeWithNoWarn, - NoWarn = new List { NuGetLogCode.NU1500, NuGetLogCode.NU1601 } + NoWarn = [NuGetLogCode.NU1500, NuGetLogCode.NU1601] }; var libraryDependencyWithNoWarnGlobal = new LibraryDependency() { IncludeType = LibraryIncludeFlags.Build, LibraryRange = libraryRangeWithNoWarnGlobal, - NoWarn = new List { NuGetLogCode.NU1500, NuGetLogCode.NU1608 } + NoWarn = [NuGetLogCode.NU1500, NuGetLogCode.NU1608] }; var nugetFramework = new NuGetFramework("frameworkIdentifier", new Version("1.2.3"), "frameworkProfile"); @@ -969,16 +969,16 @@ private static PackageSpec CreatePackageSpec(bool withRestoreSettings, WarningPr packageSpec.TargetFrameworks.Add(new TargetFrameworkInformation() { - Dependencies = new List(), + Dependencies = [], FrameworkName = nugetFramework, - Imports = new List() { nugetFramework }, + Imports = [nugetFramework], }); packageSpec.TargetFrameworks.Add(new TargetFrameworkInformation() { - Dependencies = new List() { libraryDependencyWithNoWarn }, + Dependencies = [libraryDependencyWithNoWarn], FrameworkName = nugetFrameworkWithNoWarn, - Imports = new List() { nugetFrameworkWithNoWarn }, + Imports = [nugetFrameworkWithNoWarn], Warn = true }); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/ProjectLockFile/LockFileUtilitiesTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/ProjectLockFile/LockFileUtilitiesTests.cs index ee9af144e7f..654a15fba29 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/ProjectLockFile/LockFileUtilitiesTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/ProjectLockFile/LockFileUtilitiesTests.cs @@ -1,7 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using NuGet.Commands.Test; using NuGet.LibraryModel; @@ -166,7 +168,7 @@ public void IsLockFileStillValid_DifferentTargetFrameworksInDgspec_InvalidateLoc new LibraryRange("library1", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -176,9 +178,9 @@ public void IsLockFileStillValid_DifferentTargetFrameworksInDgspec_InvalidateLoc var tfm1 = new TargetFrameworkInformation { + Dependencies = [dependency1], FrameworkName = framework }; - tfm1.Dependencies.Add(dependency1); var tfm2 = new TargetFrameworkInformation { @@ -224,7 +226,7 @@ public void IsLockFileStillValid_NewTargetFrameworksInDgspec_InvalidateLockFile( new LibraryRange("library1", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -234,9 +236,9 @@ public void IsLockFileStillValid_NewTargetFrameworksInDgspec_InvalidateLockFile( var tfm = new TargetFrameworkInformation { + Dependencies = [dependency1], FrameworkName = framework }; - tfm.Dependencies.Add(dependency1); var project = new PackageSpec(new List() { tfm }) { @@ -274,23 +276,30 @@ public void IsLockFileStillValid_RemovedCentralTransitivePackageVersions_Invalid 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), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -332,23 +341,30 @@ public void IsLockFileStillValid_DifferentCentralTransitivePackageVersions_Inval var cpvm1 = new CentralPackageVersion("cpvm1", VersionRange.Parse("1.0.0")); var cpvm2 = new CentralPackageVersion("cpvm2", VersionRange.Parse("2.0.0")); var dependency1 = new LibraryDependency( - new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework, + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -386,23 +402,30 @@ public void IsLockFileStillValid_DifferentDirectPackageVersions_InvalidateLockFi var cpvm1 = new CentralPackageVersion("cpvm1", VersionRange.Parse("2.0.0")); var cpvm2 = new CentralPackageVersion("cpvm2", VersionRange.Parse("1.0.0")); var dependency1 = new LibraryDependency( - new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -439,23 +462,30 @@ public void IsLockFileStillValid_TransitiveVersionsMovedToCentralFile_Invalidate 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), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework, + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -492,23 +522,30 @@ public void IsLockFileStillValid_NoChangeInCentralTransitivePackageVersions_Does 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), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -549,23 +586,30 @@ public void IsLockFileStillValid_TransitiveDependencyNotCentrallyManaged_DoesNot 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), + new LibraryRange("cpvm1", versionRange: cpvm1.VersionRange, LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, - versionCentrallyManaged: false, + versionCentrallyManaged: true, LibraryDependencyReferenceType.Direct, aliases: "stuff", versionOverride: null); - 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 centralPackageVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "cpvm1", cpvm1 }, + { "cpvm2", cpvm2 }, + }; + ImmutableArray dependencies = [dependency1]; + + var tfm = new TargetFrameworkInformation() + { + CentralPackageVersions = centralPackageVersions, + Dependencies = dependencies, + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true }; @@ -624,7 +668,7 @@ public void IsLockFileStillValid_NoCentralPackageVersions_DoesNotInvalidateLockF new LibraryRange("cpvm1", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -632,9 +676,11 @@ public void IsLockFileStillValid_NoCentralPackageVersions_DoesNotInvalidateLockF aliases: "stuff", versionOverride: null); - var tfm = new TargetFrameworkInformation(); - tfm.FrameworkName = framework; - tfm.Dependencies.Add(dependency1); + var tfm = new TargetFrameworkInformation() + { + Dependencies = [dependency1], + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = false }; @@ -674,7 +720,7 @@ public void IsLockFileStillValid_VersionValidationCheck() new LibraryRange("cpvm1", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), LibraryIncludeFlags.All, LibraryIncludeFlags.All, - new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -682,9 +728,11 @@ public void IsLockFileStillValid_VersionValidationCheck() aliases: "stuff", versionOverride: null); - var tfm = new TargetFrameworkInformation(); - tfm.FrameworkName = framework; - tfm.Dependencies.Add(dependency1); + var tfm = new TargetFrameworkInformation() + { + Dependencies = [dependency1], + FrameworkName = framework + }; var project = new PackageSpec(new List() { tfm }); project.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = projectName, CentralPackageVersionsEnabled = false }; @@ -834,7 +882,7 @@ public void IsLockFileStillValid_WithChangeInP2PPackageDependency_InvalidateLock new LibraryRange("packageC", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.All, suppressParent: LibraryIncludeFlagUtils.DefaultSuppressParent, - noWarn: new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -842,7 +890,10 @@ public void IsLockFileStillValid_WithChangeInP2PPackageDependency_InvalidateLock aliases: null, versionOverride: null); - projectB.TargetFrameworks.First().Dependencies.Add(packageC); + var projectBFirstTargetFramework = projectB.TargetFrameworks.First(); + var projectBFirstTargetFrameworkDependencies = projectBFirstTargetFramework.Dependencies.Add(packageC); + projectBFirstTargetFramework = new TargetFrameworkInformation(projectBFirstTargetFramework) { Dependencies = projectBFirstTargetFrameworkDependencies }; + projectB.TargetFrameworks[0] = projectBFirstTargetFramework; var dgSpec = ProjectTestHelpers.GetDGSpecForFirstProject(projectA, projectB); @@ -922,7 +973,7 @@ public void IsLockFileStillValid_WithProjectToProject_MultipleEdgesWithDifferent new LibraryRange("packageC", versionRange: VersionRange.Parse("2.0.0"), LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.All, suppressParent: LibraryIncludeFlagUtils.DefaultSuppressParent, - noWarn: new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -943,7 +994,8 @@ public void IsLockFileStillValid_WithProjectToProject_MultipleEdgesWithDifferent projectD = projectD.WithTestProjectReference(projectC); // C -> PackageC - projectC.TargetFrameworks.First().Dependencies.Add(packageC); + var projectCTargetFrameworkDependencies = projectC.TargetFrameworks.First().Dependencies.Add(packageC); + projectC.TargetFrameworks[0] = new TargetFrameworkInformation(projectC.TargetFrameworks[0]) { Dependencies = projectCTargetFrameworkDependencies }; var dgSpec = ProjectTestHelpers.GetDGSpecForFirstProject(projectA, projectB, projectC, projectD); @@ -995,7 +1047,7 @@ public void IsLockFileStillValid_WithProjectToProjectPackagesConfig_IncludesAllD new LibraryRange("packageC", versionRange: VersionRange.Parse("2.0.0"), LibraryDependencyTarget.Package), includeType: LibraryIncludeFlags.All, suppressParent: LibraryIncludeFlagUtils.DefaultSuppressParent, - noWarn: new List(), + noWarn: [], autoReferenced: false, generatePathProperty: true, versionCentrallyManaged: false, @@ -1010,7 +1062,8 @@ public void IsLockFileStillValid_WithProjectToProjectPackagesConfig_IncludesAllD projectA = projectA.WithTestProjectReference(projectB); // C -> PackageC - projectC.TargetFrameworks.First().Dependencies.Add(packageC); + var projectCTargetFrameworkDependencies = projectC.TargetFrameworks.First().Dependencies.Add(packageC); + projectC.TargetFrameworks[0] = new TargetFrameworkInformation(projectC.TargetFrameworks[0]) { Dependencies = projectCTargetFrameworkDependencies }; var dgSpec = ProjectTestHelpers.GetDGSpecForFirstProject(projectA, projectB, projectC); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/TargetFrameworkInformationTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/TargetFrameworkInformationTests.cs index 68e3879d3fe..e797a7334e4 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/TargetFrameworkInformationTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/TargetFrameworkInformationTests.cs @@ -1,12 +1,13 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using FluentAssertions; using NuGet.Frameworks; using NuGet.LibraryModel; -using NuGet.Packaging; using NuGet.Test.Utility; using NuGet.Versioning; using Xunit; @@ -52,16 +53,16 @@ public void Equals_OnClone_ReturnsTrue() { // Arrange var tfi = CreateTargetFrameworkInformation(); - var tfiClone = tfi.Clone(); + var tfiClone = new TargetFrameworkInformation(tfi); // Act & Assert tfi.Equals(tfiClone).Should().BeTrue(); Assert.NotSame(tfi, tfiClone); - Assert.NotSame(tfi.CentralPackageVersions, tfiClone.CentralPackageVersions); - Assert.NotSame(tfi.Dependencies, tfiClone.Dependencies); - Assert.NotSame(tfi.Imports, tfiClone.Imports); - Assert.NotSame(tfi.DownloadDependencies, tfiClone.DownloadDependencies); - Assert.NotSame(tfi.FrameworkReferences, tfiClone.FrameworkReferences); + Assert.Same(tfi.CentralPackageVersions, tfiClone.CentralPackageVersions); + Assert.True(tfi.Dependencies.Equals(tfiClone.Dependencies)); + Assert.True(tfi.Imports.Equals(tfiClone.Imports)); + Assert.True(tfi.DownloadDependencies.Equals(tfiClone.DownloadDependencies)); + Assert.Same(tfi.FrameworkReferences, tfiClone.FrameworkReferences); } [Theory] @@ -115,13 +116,13 @@ public void Equals_WithImports(string left, string right, bool expected) var leftSide = new TargetFrameworkInformation() { FrameworkName = NuGetFramework.AnyFramework, - Imports = left.Split(';').Select(e => NuGetFramework.Parse(e)).ToList() + Imports = left.Split(';').Select(e => NuGetFramework.Parse(e)).ToImmutableArray() }; var rightSide = new TargetFrameworkInformation() { FrameworkName = NuGetFramework.AnyFramework, - Imports = right.Split(';').Select(e => NuGetFramework.Parse(e)).ToList() + Imports = right.Split(';').Select(e => NuGetFramework.Parse(e)).ToImmutableArray() }; AssertEquality(expected, leftSide, rightSide); @@ -233,7 +234,7 @@ public void Equals_WithDependencies(string left, string right, bool expected) Name = e, VersionRange = VersionRange.Parse("1.0.0") } - }).ToList() + }).ToImmutableArray() }; var rightSide = new TargetFrameworkInformation() @@ -246,7 +247,7 @@ public void Equals_WithDependencies(string left, string right, bool expected) Name = e, VersionRange = VersionRange.Parse("1.0.0") } - }).ToList() + }).ToImmutableArray() }; AssertEquality(expected, leftSide, rightSide); @@ -260,11 +261,15 @@ public void Equals_WithDependencies(string left, string right, bool expected) [InlineData("B;a", "A;b;c", false)] public void Equals_WithDownloadDependencies(string left, string right, bool expected) { - var leftSide = new TargetFrameworkInformation(); - leftSide.DownloadDependencies.AddRange(left.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0")))); + var leftSide = new TargetFrameworkInformation() + { + DownloadDependencies = left.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0"))).ToImmutableArray() + }; - var rightSide = new TargetFrameworkInformation(); - rightSide.DownloadDependencies.AddRange(right.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0")))); + var rightSide = new TargetFrameworkInformation() + { + DownloadDependencies = right.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0"))).ToImmutableArray() + }; AssertEquality(expected, leftSide, rightSide); } @@ -277,13 +282,19 @@ public void Equals_WithDownloadDependencies(string left, string right, bool expe [InlineData("B;a", "A;b;c", false)] public void Equals_WithFrameworkReferences(string left, string right, bool expected) { - var leftSide = new TargetFrameworkInformation(); - leftSide.FrameworkReferences.AddRange(left.Split(';') - .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All))); + var leftSide = new TargetFrameworkInformation() + { + FrameworkReferences = left.Split(';') + .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All)) + .ToHashSet() + }; - var rightSide = new TargetFrameworkInformation(); - rightSide.FrameworkReferences.AddRange(right.Split(';') - .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All))); + var rightSide = new TargetFrameworkInformation() + { + FrameworkReferences = right.Split(';') + .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All)) + .ToHashSet() + }; AssertEquality(expected, leftSide, rightSide); } @@ -296,23 +307,20 @@ public void Equals_WithFrameworkReferences(string left, string right, bool expec [InlineData("B;a", "A;b;c", false)] public void Equals_WithCentralDependencies(string left, string right, bool expected) { + var leftVersions = left.Split(';').ToDictionary(entry => entry, entry => new CentralPackageVersion(entry, VersionRange.All), StringComparer.OrdinalIgnoreCase); + var leftSide = new TargetFrameworkInformation() { + CentralPackageVersions = leftVersions, FrameworkName = NuGetFramework.AnyFramework }; - foreach (var entry in left.Split(';')) - { - leftSide.CentralPackageVersions.Add(entry, new CentralPackageVersion(entry, VersionRange.All)); - } + var rightVersions = right.Split(';').ToDictionary(entry => entry, entry => new CentralPackageVersion(entry, VersionRange.All), StringComparer.OrdinalIgnoreCase); var rightSide = new TargetFrameworkInformation() { + CentralPackageVersions = rightVersions, FrameworkName = NuGetFramework.AnyFramework }; - foreach (var entry in right.Split(';')) - { - rightSide.CentralPackageVersions.Add(entry, new CentralPackageVersion(entry, VersionRange.All)); - } AssertEquality(expected, leftSide, rightSide); } @@ -368,13 +376,13 @@ public void HashCode_WithImports(string left, string right, bool expected) var leftSide = new TargetFrameworkInformation() { FrameworkName = NuGetFramework.AnyFramework, - Imports = left.Split(';').Select(e => NuGetFramework.Parse(e)).ToList() + Imports = left.Split(';').Select(e => NuGetFramework.Parse(e)).ToImmutableArray() }; var rightSide = new TargetFrameworkInformation() { FrameworkName = NuGetFramework.AnyFramework, - Imports = right.Split(';').Select(e => NuGetFramework.Parse(e)).ToList() + Imports = right.Split(';').Select(e => NuGetFramework.Parse(e)).ToImmutableArray() }; AssertHashCode(expected, leftSide, rightSide); @@ -484,7 +492,7 @@ public void HashCode_WithDependencies(string left, string right, bool expected) Name = e, VersionRange = VersionRange.Parse("1.0.0") } - }).ToList() + }).ToImmutableArray() }; var rightSide = new TargetFrameworkInformation() @@ -497,7 +505,7 @@ public void HashCode_WithDependencies(string left, string right, bool expected) Name = e, VersionRange = VersionRange.Parse("1.0.0") } - }).ToList() + }).ToImmutableArray() }; AssertHashCode(expected, leftSide, rightSide); @@ -511,11 +519,15 @@ public void HashCode_WithDependencies(string left, string right, bool expected) [InlineData("B;a", "A;b;c", false)] public void HashCode_WithDownloadDependencies(string left, string right, bool expected) { - var leftSide = new TargetFrameworkInformation(); - leftSide.DownloadDependencies.AddRange(left.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0")))); + var leftSide = new TargetFrameworkInformation() + { + DownloadDependencies = left.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0"))).ToImmutableArray() + }; - var rightSide = new TargetFrameworkInformation(); - rightSide.DownloadDependencies.AddRange(right.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0")))); + var rightSide = new TargetFrameworkInformation() + { + DownloadDependencies = right.Split(';').Select(e => new DownloadDependency(e, VersionRange.Parse("1.0.0"))).ToImmutableArray() + }; AssertHashCode(expected, leftSide, rightSide); } @@ -528,13 +540,19 @@ public void HashCode_WithDownloadDependencies(string left, string right, bool ex [InlineData("B;a", "A;b;c", false)] public void HashCode_WithFrameworkReferences(string left, string right, bool expected) { - var leftSide = new TargetFrameworkInformation(); - leftSide.FrameworkReferences.AddRange(left.Split(';') - .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All))); + var leftSide = new TargetFrameworkInformation() + { + FrameworkReferences = left.Split(';') + .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All)) + .ToHashSet() + }; - var rightSide = new TargetFrameworkInformation(); - rightSide.FrameworkReferences.AddRange(right.Split(';') - .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All))); + var rightSide = new TargetFrameworkInformation() + { + FrameworkReferences = right.Split(';') + .Select(e => new FrameworkDependency(e, FrameworkDependencyFlags.All)) + .ToHashSet() + }; AssertHashCode(expected, leftSide, rightSide); } @@ -547,23 +565,19 @@ public void HashCode_WithFrameworkReferences(string left, string right, bool exp [InlineData("B;a", "A;b;c", false)] public void HashCode_WithCentralDependencies(string left, string right, bool expected) { + var leftVersions = left.Split(';').ToDictionary(entry => entry, entry => new CentralPackageVersion(entry, VersionRange.All), StringComparer.OrdinalIgnoreCase); var leftSide = new TargetFrameworkInformation() { + CentralPackageVersions = leftVersions, FrameworkName = NuGetFramework.AnyFramework }; - foreach (var entry in left.Split(';')) - { - leftSide.CentralPackageVersions.Add(entry, new CentralPackageVersion(entry, VersionRange.All)); - } + var rightVersions = right.Split(';').ToDictionary(entry => entry, entry => new CentralPackageVersion(entry, VersionRange.All), StringComparer.OrdinalIgnoreCase); var rightSide = new TargetFrameworkInformation() { + CentralPackageVersions = rightVersions, FrameworkName = NuGetFramework.AnyFramework }; - foreach (var entry in right.Split(';')) - { - rightSide.CentralPackageVersions.Add(entry, new CentralPackageVersion(entry, VersionRange.All)); - } AssertHashCode(expected, leftSide, rightSide); } @@ -579,7 +593,7 @@ private TargetFrameworkInformation CreateTargetFrameworkInformation(List(), + noWarn: [], autoReferenced: true, generatePathProperty: true, versionCentrallyManaged: false, @@ -590,26 +604,21 @@ private TargetFrameworkInformation CreateTargetFrameworkInformation(List() { dependencyFoo }; var assetTargetFallback = true; var warn = false; + var versions = centralVersionDependencies.ToDictionary(cdep => cdep.Name, StringComparer.OrdinalIgnoreCase); TargetFrameworkInformation tfi = new TargetFrameworkInformation() { AssetTargetFallback = assetTargetFallback, - Dependencies = dependencies, - Warn = warn, + CentralPackageVersions = versions, + Dependencies = [dependencyFoo], + DownloadDependencies = [downloadDependency], FrameworkName = nugetFramework, + FrameworkReferences = [frameworkDependency], + Warn = warn, }; - foreach (var cdep in centralVersionDependencies) - { - tfi.CentralPackageVersions.Add(cdep.Name, cdep); - } - - tfi.DownloadDependencies.Add(downloadDependency); - tfi.FrameworkReferences.Add(frameworkDependency); - return tfi; } @@ -643,8 +652,8 @@ private static void AssertHashCode(bool expected, TargetFrameworkInformation lef private static void AssertClone(bool expected, TargetFrameworkInformation leftSide, TargetFrameworkInformation rightSide) { - var leftClone = leftSide.Clone(); - var rightClone = rightSide.Clone(); + var leftClone = new TargetFrameworkInformation(leftSide); + var rightClone = new TargetFrameworkInformation(rightSide); if (expected) { diff --git a/test/NuGet.Tests.Apex/NuGet.Tests.Apex/Utility/CommonUtility.cs b/test/NuGet.Tests.Apex/NuGet.Tests.Apex/Utility/CommonUtility.cs index 7a9ce3ff8b9..4b2bb374dbe 100644 --- a/test/NuGet.Tests.Apex/NuGet.Tests.Apex/Utility/CommonUtility.cs +++ b/test/NuGet.Tests.Apex/NuGet.Tests.Apex/Utility/CommonUtility.cs @@ -15,7 +15,6 @@ using Microsoft.Test.Apex.Services; using Microsoft.Test.Apex.VisualStudio; using Microsoft.Test.Apex.VisualStudio.Solution; -using NuGet.Common; using NuGet.LibraryModel; using NuGet.Packaging.Signing; using NuGet.ProjectModel; @@ -227,7 +226,7 @@ public static List GetPackageReferences(ProjectTestExtension LibraryRange = new LibraryRange(e.Attribute(XName.Get("Include")).Value, VersionRange.Parse(e.Attribute(XName.Get("Version")).Value), LibraryDependencyTarget.Package), IncludeType = LibraryIncludeFlags.All, SuppressParent = LibraryIncludeFlags.None, - NoWarn = new List(), + NoWarn = [], AutoReferenced = false, GeneratePathProperty = false }) diff --git a/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs b/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs index c8dfdc14efa..714d25ea56a 100644 --- a/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs +++ b/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs @@ -147,13 +147,15 @@ public static PackageSpec WithTestRestoreMetadata(this PackageSpec spec) }; // Update the Target Alias. - foreach (var framework in updated.TargetFrameworks) + for (int i = 0; i < updated.TargetFrameworks.Count; i++) { + var framework = updated.TargetFrameworks[i]; if (string.IsNullOrEmpty(framework.TargetAlias)) { - framework.TargetAlias = framework.FrameworkName.GetShortFolderName(); + updated.TargetFrameworks[i] = new TargetFrameworkInformation(framework) { TargetAlias = framework.FrameworkName.GetShortFolderName() }; } } + foreach (var framework in updated.TargetFrameworks) { updated.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(framework.FrameworkName) { TargetAlias = framework.TargetAlias }); @@ -274,7 +276,7 @@ public static PackageSpec GetPackageSpec(ISettings settings, string projectName, public static PackageSpec GetPackageSpec(ISettings settings, string projectName, string rootPath, string framework, string dependencyName, bool useAssetTargetFallback = false, string assetTargetFallbackFrameworks = "", bool asAssetTargetFallback = true) { - var packageSpec = GetPackageSpec(projectName, rootPath, framework, dependencyName, useAssetTargetFallback, assetTargetFallbackFrameworks, asAssetTargetFallback); + var packageSpec = GetPackageSpec(projectName, rootPath, framework, dependencyName, "1.0.0", useAssetTargetFallback, assetTargetFallbackFrameworks, asAssetTargetFallback); return packageSpec.WithSettingsBasedRestoreMetadata(settings); } @@ -290,7 +292,7 @@ public static PackageSpec WithSettingsBasedRestoreMetadata(this PackageSpec pack return packageSpec; } - public static PackageSpec GetPackageSpec(string projectName, string rootPath, string framework, string dependencyName, bool useAssetTargetFallback = false, string assetTargetFallbackFrameworks = "", bool asAssetTargetFallback = true) + public static PackageSpec GetPackageSpec(string projectName, string rootPath, string framework, string dependencyName, string dependencyVersion = "1.0.0", bool useAssetTargetFallback = false, string assetTargetFallbackFrameworks = "", bool asAssetTargetFallback = true) { var actualAssetTargetFallback = GetFallbackString(useAssetTargetFallback, assetTargetFallbackFrameworks, asAssetTargetFallback); @@ -299,14 +301,14 @@ public static PackageSpec GetPackageSpec(string projectName, string rootPath, st ""frameworks"": { ""TARGET_FRAMEWORK"": { ""dependencies"": { - ""DEPENDENCY_NAME"" : ""1.0.0"" + ""DEPENDENCY_NAME"" : ""VERSION"" } ASSET_TARGET_FALLBACK } } }"; - var spec = referenceSpec.Replace("TARGET_FRAMEWORK", framework).Replace("DEPENDENCY_NAME", dependencyName).Replace("ASSET_TARGET_FALLBACK", actualAssetTargetFallback); + var spec = referenceSpec.Replace("TARGET_FRAMEWORK", framework).Replace("DEPENDENCY_NAME", dependencyName).Replace("VERSION", dependencyVersion).Replace("ASSET_TARGET_FALLBACK", actualAssetTargetFallback); return GetPackageSpecWithProjectNameAndSpec(projectName, rootPath, spec); } diff --git a/test/TestUtilities/Test.Utility/DependencyResolver/DependencyProvider.cs b/test/TestUtilities/Test.Utility/DependencyResolver/DependencyProvider.cs index 9cea6b1c7a1..ad8c7fd9143 100644 --- a/test/TestUtilities/Test.Utility/DependencyResolver/DependencyProvider.cs +++ b/test/TestUtilities/Test.Utility/DependencyResolver/DependencyProvider.cs @@ -153,6 +153,8 @@ public TestPackage DependsOn(string id, LibraryDependencyTarget target = Library public TestPackage DependsOn(string id, string version, LibraryDependencyTarget target = LibraryDependencyTarget.All, bool versionCentrallyManaged = false, LibraryDependencyReferenceType? libraryDependencyReferenceType = null, LibraryIncludeFlags? privateAssets = null) { + var suppressParent = privateAssets != null ? privateAssets.Value : LibraryIncludeFlagUtils.DefaultSuppressParent; + var referenceType = libraryDependencyReferenceType != null ? libraryDependencyReferenceType.Value : LibraryDependencyReferenceType.Direct; var libraryDependency = new LibraryDependency { LibraryRange = @@ -162,19 +164,11 @@ public TestPackage DependsOn(string id, string version, LibraryDependencyTarget VersionRange = VersionRange.Parse(version), TypeConstraint = target }, + ReferenceType = referenceType, + SuppressParent = suppressParent, VersionCentrallyManaged = versionCentrallyManaged, }; - if (privateAssets != null) - { - libraryDependency.SuppressParent = privateAssets.Value; - } - - if (libraryDependencyReferenceType != null) - { - libraryDependency.ReferenceType = libraryDependencyReferenceType.Value; - } - _dependencies.Add(libraryDependency); return this; diff --git a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestProjectContext.cs b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestProjectContext.cs index 34fb6babcd8..aeaac25638d 100644 --- a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestProjectContext.cs +++ b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestProjectContext.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Xml.Linq; @@ -243,7 +244,7 @@ public PackageSpec PackageSpec .Select(f => new TargetFrameworkInformation() { FrameworkName = f.Framework, - Dependencies = f.PackageReferences.Select(e => new LibraryDependency() { LibraryRange = new LibraryRange(e.Id, VersionRange.Parse(e.Version), LibraryDependencyTarget.Package) }).ToList(), + Dependencies = f.PackageReferences.Select(e => new LibraryDependency() { LibraryRange = new LibraryRange(e.Id, VersionRange.Parse(e.Version), LibraryDependencyTarget.Package) }).ToImmutableArray(), TargetAlias = f.TargetAlias, }).ToList()); _packageSpec.RestoreMetadata = new ProjectRestoreMetadata();