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

warn on missing dots for net5.0+ TFMs #3692

Merged
merged 1 commit into from
Oct 13, 2020

Conversation

zkat
Copy link
Contributor

@zkat zkat commented Sep 28, 2020

Bug

Fixes: NuGet/Home#9215
Regression:No

  • How are we preventing it in future: tests added

Fix

This makes it so we warn when a user uses something like net50 instead of net5.0. We want customers to start getting used to (and will eventually enforce) including dots in .NET version numbers.

Testing/Validation

Tests Added: Yes

@zkat zkat force-pushed the dev-zkat-net5-missing-dot-warning branch 3 times, most recently from 6e70c2f to 08ed72d Compare September 30, 2020 00:02
@zkat zkat marked this pull request as ready for review September 30, 2020 18:49
@zkat zkat requested a review from a team as a code owner September 30, 2020 18:49
@zkat zkat force-pushed the dev-zkat-net5-missing-dot-warning branch from 50d8a97 to 1b1ae62 Compare September 30, 2020 18:50
src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs Outdated Show resolved Hide resolved
{
try
{
var parsedAlias = NuGetFramework.Parse(alias);
Copy link
Member

Choose a reason for hiding this comment

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

Can you remind me why we're doing this check in PackTask?

My memory is that we agreed that the SDK should warn on the same scenario on restore (or evaluation). Restore creates the assets file, and this pack task reads the assets file. Therefore, to get to this code, the customer must already have got the warning from the SDK (once it's implemented).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought we were doing this in case they packed a long time after doing a restore?

Copy link
Member

Choose a reason for hiding this comment

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

I think the SDK should be warning here not NuGet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @wli3 is there an issue on your end to track this? Should we create one for you?

@nkolev92 @zivkan When you say we shouldn't do this check in PackTask, do you mean I should also not add the rule? Like, to be clear, are you saying this entire PR is unnecessary?

Copy link
Member

Choose a reason for hiding this comment

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

I think we're referring to this particular check.
This is validating the TargetFramework in the csproj property value. NuGet shouldn't do that.
We should validate the missing dots for anything the customers might have created manually for one or another reason (such as validating the nuspec + files in the package).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright. So we'll have to make sure the SDK agrees with the assessment and takes the time to implement this on their end before we can say we're complete. Would it make sense to do it on our end now, since it's implemented, and our timeline is so short, and switch to an SDK-sourced error later? /cc @aortiz-msft

Copy link
Member

Choose a reason for hiding this comment

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

I really don't think NuGet should get in the business of raising a warning for the TargetFramework property even temporarily. We spent lots of time getting away from it :)

The way I see it, that specific warning is a nice to have.

  • The warning for the TargetFramework property only impacts the project author.
  • The warning on the package assets can affect all consumers of that package.

I'd argue the latter group is larger.

Copy link

Choose a reason for hiding this comment

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

Do I still need to do anything on my side?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nkolev92 wait, do the validation rules run when you install/restore, too?...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wli3 most likely, yes. You'd have to warn when, for example, someone does <TargetFramework>net50</TargetFramework> (that is, when you're resolving an alias that looks like a concrete targetframework).

{
try
{
var parsedAlias = NuGetFramework.Parse(alias);
Copy link
Member

Choose a reason for hiding this comment

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

I think the SDK should be warning here not NuGet.

src/NuGet.Core/NuGet.Packaging/PackagingConstants.cs Outdated Show resolved Hide resolved
@zkat zkat force-pushed the dev-zkat-net5-missing-dot-warning branch from 35f35c1 to b1822e3 Compare October 6, 2020 21:41
@zkat zkat requested review from nkolev92 and zivkan October 6, 2020 21:50
@zkat zkat force-pushed the dev-zkat-net5-missing-dot-warning branch from b1822e3 to e59ea92 Compare October 6, 2020 22:23
zkat added a commit to NuGet/docs.microsoft.com-nuget that referenced this pull request Oct 6, 2020
@zkat
Copy link
Contributor Author

zkat commented Oct 6, 2020

PR for docs page: NuGet/docs.microsoft.com-nuget#2178

Copy link
Member

@nkolev92 nkolev92 left a comment

Choose a reason for hiding this comment

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

I think this looks a lot better, more scoped and just neater overall!

I left a few comments, but don't wait on me obviously :)

src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkUtility.cs Outdated Show resolved Hide resolved
src/NuGet.Core/NuGet.Packaging/GlobalSuppressions.cs Outdated Show resolved Hide resolved
@@ -169,6 +169,10 @@
<data name="InvalidPrereleaseDependencyWarning" xml:space="preserve">
<value>A stable release of a package should not have a prerelease dependency. Either modify the version spec of dependency "{0}" or update the version field in the nuspec.</value>
</data>
<data name="InvalidUndottedFrameworkWarning" xml:space="preserve">
<value>Packaged folders must include dots in their framework version numbers. This is required as of .NET 5.0. Please rename the following folder(s) to include dots as needed (e.g. 'net50' to 'net5.0'): {0}</value>
Copy link
Member

Choose a reason for hiding this comment

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

The first sentence in this message sounds a bit like 'net47' should be changed to 'net4.7'. It won't be in the list of folder names failing the rule, but to me that's what it sounds like.

Just an idea: What about, instead of doing string parsing to find if the framework version part of the TFM has a dot, we compare the input's string to NuGetFramework.Parse(tfm).ToShortFolderName(), then we can have an error message something along the lines of:

Error NU5501: The following folders do not have the expected target framework folder name:
net50 (under lib/) should be net5.0
net50-windows7.0 (under build/) should be net5.0-windows7.0

I don't know if it's better to only report a folder once, like above, or for each file?

net50 (in build/net50/packageId.props) should be net5.0
net50 (in build/net50/packageId.targets) should be net5.0
net50 (in build/net50/myTasks.dll) should be net5.0
net50 (in build/net50/Newtonsoft.Json.dll) should be net5.0

We can still consider only .netcoreapp version >= 5.0, but perhaps this may minimise the potential for misunderstanding which tfm folders need to be renamed.

@@ -1 +1,5 @@
static NuGet.Packaging.Rules.AnalysisResources.InvalidUndottedFrameworkInDependencyGroupsWarning.get -> string
Copy link
Member

Choose a reason for hiding this comment

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

scope creep: It's just a guess, but I guess that AnalysisResources are public only so tests can access the message text without using InternalsVisibleTo. These strings are not useful to customers using the SDK, because we could change the {x} placeholders at any time.

What do you think about making a new resx file that's internal, so we stop getting these public API changes just because we're adding messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm gonna treat this as scope creep. Maybe we can create an issue to find a better solution for AnalysisResources in general?

@zkat zkat requested review from nkolev92 and zivkan October 9, 2020 23:47
@zkat
Copy link
Contributor Author

zkat commented Oct 12, 2020

Note: Tests are green, but GH apparently didn't update properly.

@zivkan
Copy link
Member

zivkan commented Oct 12, 2020

Note: Tests are green, but GH apparently didn't update properly.

We don't use CI integration with github, because .... reasons. We call GitHub's REST API from our own build scripts. Our builds recently to work a little bit differently, and now the "update github status" script doesn't correctly handle windows unit tests failing :(

This means if unit tests fail, we have to spin a new build until windows unit tests are green. Any other failure can be retried, but windws unit test failures will "break" github check status. I've already created a CI initiative task.

Copy link
Member

@zivkan zivkan left a comment

Choose a reason for hiding this comment

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

I know there are time pressures to get this in, so it's acceptable to me that it gets merged as-is. But particularly my test comments should be considered for normal developments. Maybe my other comments are a bit nit-picky

Comment on lines 42 to 45
// IPackageRule expects to get messages passed in, but we output
// different kinds of messages, so each individual validator is
// responsible for its own messaging.
MessageFormat = messageFormat;
Copy link
Member

Choose a reason for hiding this comment

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

Why not remove the parameter from the constructor?

There are already 3 rules that use the default constructor

@@ -9,6 +9,7 @@
using NuGet.Commands;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
Copy link
Member

Choose a reason for hiding this comment

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

this is unnecessary, given there are no other changes in the file

@@ -117,5 +117,6 @@ public void NuGetFrameworkUtility_GetNearest_Duplicates()
Assert.Null(nearestWithSelector);
Assert.Null(nearest);
}

Copy link
Member

Choose a reason for hiding this comment

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

there are no other changes in this file. Ideally it's reverted.


namespace NuGet.Packaging.Test
{
public class InvalidUndottedFrameworkRuleTests
Copy link
Member

Choose a reason for hiding this comment

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

Apart from the FrameworkVersionHasDesiredDots test, the others are missing tests to ensure they don't generate the warning when:

  • The package correctly dots net5.0
  • The package doesn't contain any TFM that should have dots (for example, contains only netfx, netstandard or netcoreapp tfms)

I can't think of any other missing test cases, but particularly when you have easy to write unit tests, please remember to have tests for: happy case, error case, edge cases.

Another missing thing from the tests are validating that they generate the correct number of warnings. If any of the XML elements has both net50 and net50-windows7.0, will it generate the correct number of warnings? Taking a look at the code, it appears that you'll be generating one warning per TFM, whereas I thought that an earlier comment requested that we generate one message per "message format", with a list of all the TFMs failing the validation.

Finally, and this one is much more subjective, but particularly when generating messages with multiple generated parts, I think it might be useful to have a test to ensure the generated message looks correct:

var expectedMessage = "- At least one .props file was found in 'build/net45/', but 'build/net45/packageId.props' was not." + Environment.NewLine +
"- At least one .props file was found in 'build/net462/', but 'build/net462/packageId.props' was not." + Environment.NewLine +
"- At least one .props file was found in 'build/net471/', but 'build/net471/packageId.props' was not." + Environment.NewLine +
"- At least one .props file was found in 'build/netstandard1.3/', but 'build/netstandard1.3/packageId.props' was not." + Environment.NewLine +
"- At least one .props file was found in 'build/netcoreapp1.1/', but 'build/netcoreapp1.1/packageId.props' was not." + Environment.NewLine;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Taking a look at the code, it appears that you'll be generating one warning per TFM, whereas I thought that an earlier comment requested that we generate one message per "message format", with a list of all the TFMs failing the validation.

The code actually generates one message per "check type", each with all relevant TFMed values concatenated together into a single message. Additionally, a general "oops you got a NU5501" message is appended if any of these generate a warning.

Re: tests, working on those now, should be ready soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've omitted the tests that check specific messages, and that the right number of messages is displayed, but I've also done a small refactor so that even more stuff is unit-testable, so this can be done later, after the current rush.

@zkat zkat force-pushed the dev-zkat-net5-missing-dot-warning branch from 829ffe9 to ccd07af Compare October 12, 2020 23:40
@aortiz-msft aortiz-msft merged commit 35126a1 into dev Oct 13, 2020
@aortiz-msft aortiz-msft deleted the dev-zkat-net5-missing-dot-warning branch October 13, 2020 18:20
zkat added a commit that referenced this pull request Oct 26, 2020
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Apr 17, 2021
nkolev92 pushed a commit to NuGet/docs.microsoft.com-nuget that referenced this pull request Mar 31, 2022
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Oct 23, 2022
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Oct 23, 2022
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Oct 23, 2022
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Oct 23, 2022
jagilber added a commit to jagilber/CollectServiceFabricData that referenced this pull request Oct 23, 2022
jagilber added a commit to microsoft/CollectServiceFabricData that referenced this pull request Oct 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NuGet pack should catch incorrect omitting of the dot in version numbers
5 participants