Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

emgarten
Copy link
Member

@emgarten emgarten commented Jun 2, 2017

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

Copy link
Contributor

@mishra14 mishra14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small changes then :shipit: when ready!

.Select(NuGetFramework.Parse)
.ToList();
var ptf = MSBuildStringUtility.Split(GetPropertyValueOrNull(targetFrameworkInfo.Properties, PackageTargetFallback))
.Select(NuGetFramework.Parse)
Copy link
Contributor

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use named parameter.

Copy link
Member Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

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)
Copy link
Contributor

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());
Copy link
Contributor

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)
Copy link
Contributor

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.

Copy link
Member Author

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)
Copy link
Contributor

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");
Copy link
Contributor

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.

Copy link
Member Author

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)
Copy link
Contributor

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;
Copy link
Contributor

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
Copy link
Contributor

@alpaix alpaix left a 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[] { ';' };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static readonly?

Copy link
Member Author

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()
Copy link
Contributor

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?

Copy link
Member Author

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();
Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Member Author

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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof

Copy link
Member Author

@emgarten emgarten Jun 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update these

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Member Author

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");
Copy link
Contributor

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");
Copy link
Contributor

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?

Copy link
Member Author

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");
Copy link
Contributor

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; }
Copy link
Contributor

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?

Copy link
Member Author

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.

@emgarten emgarten closed this Jun 2, 2017
@emgarten emgarten deleted the dev-feature-logging-atf branch June 2, 2017 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants