-
Notifications
You must be signed in to change notification settings - Fork 701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for AssetTargetFallback #1436
Conversation
eee7e9b
to
01df9f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small changes then when ready!
.Select(NuGetFramework.Parse) | ||
.ToList(); | ||
var ptf = MSBuildStringUtility.Split(GetPropertyValueOrNull(targetFrameworkInfo.Properties, PackageTargetFallback)) | ||
.Select(NuGetFramework.Parse) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix indenting.
// These are only used for framework/RID combinations where content model handles everything. | ||
// AssetTargetFallback frameworks will provide multiple criteria since all assets need to be | ||
// evaluated before selecting the TFM to use. | ||
var orderedCriteriaSets = new List<IReadOnlyList<SelectionCriteria>>(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use named parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
irrelevant to the context here
/// AssetTargetFallbackFramework only fallback when zero assets are selected. These do not | ||
/// auto fallback during GetNearest as FallbackFramework would. | ||
/// </summary> | ||
#if NUGET_FRAMEWORKS_INTERNAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's up? This is so NuGet.Frameworks can be compiled into NuGet.Core without exposing new API surface area.
/// <summary> | ||
/// Returns the fallback framework or the original. | ||
/// </summary> | ||
public static NuGetFramework GetFramework(NuGetFramework projectFramework, IEnumerable<NuGetFramework> packageTargetFallback, IEnumerable<NuGetFramework> assetTargetFallback) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming to GetFallBackFramework
else if (packageTargetFallback?.Any() == true) | ||
{ | ||
// PackageTargetFallback | ||
return new FallbackFramework(projectFramework, packageTargetFallback.AsList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider renaming to PackageTargetFallbackFramework
packageTargetFallback, | ||
assetTargetFallback); | ||
|
||
if (assetTargetFallback?.Any() == true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Count
, it does not create an enumerator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is an IEnumerable
targetFrameworkInfo.Imports = assetTargetFallback.AsList(); | ||
targetFrameworkInfo.AssetTargetFallback = true; | ||
} | ||
else if (packageTargetFallback?.Any() == true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Count
, it does not create an enumerator.
var r = Util.RestoreSolution(pathContext, expectedExitCode: 1); | ||
|
||
// Assert | ||
r.AllOutput.Should().Contain("AssetTargetFallback"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert on the error would be a better practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update this
{ | ||
public static class PackageSpecTestUtility | ||
{ | ||
public static PackageSpec RoundTrip(this PackageSpec spec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -12,6 +13,19 @@ public class CommandRunnerResult | |||
public string Item2 { get; } | |||
public string Item3 { get; } | |||
|
|||
public int ExitCode => Item1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
AssetTargetFallback allows falling back to another project framework only if no compatible assets are found in the package. Fixes NuGet/Home#5192 Fixes NuGet/Home#5268
01df9f3
to
2be8291
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also adding/enhancing tests for the projects would be great.
@@ -295,21 +295,26 @@ private static PackageReference ToPackageReference(LibraryDependency library, Nu | |||
.GetPackageReferencesAsync(targetFramework, CancellationToken.None)) | |||
.ToList(); | |||
|
|||
var packageTargetFallback = _vsProjectAdapter.PackageTargetFallback?.Split(new[] { ';' }) | |||
var splitChars = new[] { ';' }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static readonly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm mixed on this. I'm not sure that the benefit of making this static out weighs creating this every time the assembly is loaded.
.Select(NuGetFramework.Parse) | ||
.ToList(); | ||
.ToList() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it wasn't covered there before, what happens in case of empty or invalid entries in the list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NuGetFramework.Parse returns the Unsupported framework since it isn't unusual for future frameworks to come in. For fallback frameworks there is a check to verify that unsupported isn't passed and it will throw.
.ToList(); | ||
var ptf = MSBuildStringUtility.Split(GetPropertyValueOrNull(targetFrameworkInfo.Properties, PackageTargetFallback)) | ||
.Select(NuGetFramework.Parse) | ||
.ToList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same question here about empty/invalid entries.
/// <summary> | ||
/// List framework to fall back to. | ||
/// </summary> | ||
public FallbackList Fallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The convention is to name a collection bearing property with a plural noun to avoid confusion when reading the code. Maybe FallbackList
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept this the same as the existing convention in FallbackFramework. I think we should look at removing this and support for net40 now that it is very unlikely that NuGet 2.x will ship again.
{ | ||
if (framework == null) | ||
{ | ||
throw new ArgumentNullException("framework"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nameof
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nameof
isn't allowed in net40 unfortunately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exactly. nameof
is a C#6 language syntax it can be used when targeting net40.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not according to Visual Studio 😄
|
||
if (fallbackFrameworks == null) | ||
{ | ||
throw new ArgumentNullException("fallbackFrameworks"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nameof
|
||
if (fallbackFrameworks.Count == 0) | ||
{ | ||
throw new ArgumentException("Empty fallbackFrameworks is invalid", "fallbackFrameworks"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the error message be localized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would be due to an internal issue, a user can't fix this
var combiner = new HashCodeCombiner(); | ||
|
||
// Ensure that this is different from a FallbackFramework; | ||
combiner.AddStringIgnoreCase("assettargetfallback"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also could be nameof(AssetTargetFallbackFramework)
@@ -22,6 +22,11 @@ public class TargetFrameworkInformation : IEquatable<TargetFrameworkInformation> | |||
public IList<NuGetFramework> Imports { get; set; } = new List<NuGetFramework>(); | |||
|
|||
/// <summary> | |||
/// If True AssetTargetFallback behavior will be used for Imports. | |||
/// </summary> | |||
public bool AssetTargetFallback { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a flag not an actual value. Maybe UseAssetTargetFallback
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is written to the project.json equivalent, the rest of the properties aren't in this style currently. I'm going to leave this as the msbuild property equivalent for now.
AssetTargetFallback allows falling back to another project framework only if no compatible assets are found in the package.
The changes to lock file creation are almost all to refactor the code into smaller methods. The main change is to loop through creating the library.
Fixes NuGet/Home#5192