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

Parse invalid property under target #8190

Merged
merged 18 commits into from Dec 13, 2022
Merged

Parse invalid property under target #8190

merged 18 commits into from Dec 13, 2022

Conversation

JaynieBai
Copy link
Member

@JaynieBai JaynieBai commented Nov 25, 2022

Fixes #5773

Context

Put a property inside a target without an enclosing PropertyGroup and build. Error informing me that is an invalid child element of .

Changes Made

Add one condition when parse the element under target. If the element has inner text and no other child elements except text, then this should be a property and throw invalid child element of

Tests

ReadInvalidPropertyUnderTarget

Notes

@JaynieBai JaynieBai changed the title parse invalid property under target Parse invalid property under target Nov 25, 2022
@JaynieBai JaynieBai marked this pull request as ready for review November 25, 2022 08:20
@JaynieBai
Copy link
Member Author

JaynieBai commented Nov 25, 2022

The current error after change is error MSB4067: The element beneath element is unrecognized
Not sure if we need to define a new error message to suggest author propertyName is an invalid child element of target.

Copy link
Member

@Forgind Forgind left a comment

Choose a reason for hiding this comment

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

Two questions:
Should we add a change wave?
Should we have a custom message so we can suggest that they probably intended to wrap it in a PropertyGroup?

src/Build/Evaluation/ProjectParser.cs Outdated Show resolved Hide resolved
format equals

Co-authored-by: Forgind <12969783+Forgind@users.noreply.github.com>
@JaynieBai
Copy link
Member Author

Should we add a change wave?
Should we have a custom message so we can suggest that they probably intended to wrap it in a PropertyGroup?

What's the change wave?
How to add a custom message? From build output message?

Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

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

Should we add a change wave?
Should we have a custom message so we can suggest that they probably intended to wrap it in a PropertyGroup?

What's the change wave? How to add a custom message? From build output message?

I like @Forgind's suggestions.

For change waves, please read https://github.com/dotnet/msbuild/blob/main/documentation/wiki/ChangeWaves-Dev.md and ask any follow-up questions--I'm sure that doc can be improved.

For the new error message, I commented in the PR.

I would also like to see a test added, probably like this one and in this file:

/// <summary>
/// Read a target with a missing name
/// </summary>
[Fact]
public void ReadInvalidMissingName()
{
Assert.Throws<InvalidProjectFileException>(() =>
{
string content = @"
<Project>
<Target/>
</Project>
";
ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
}
);
}

src/Build/Evaluation/ProjectParser.cs Show resolved Hide resolved
if (childElement.ChildNodes.Count == 1 && childElement.FirstChild.NodeType == XmlNodeType.Text)
{
// If the element has inner text and no other child elements except text, then this should be a property and throw invalid child element of <Target>
ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, childElement.ParentNode.Name, childElement.Location);
Copy link
Member

Choose a reason for hiding this comment

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

To get a new, custom error message for this case, change this to something like

Suggested change
ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, childElement.ParentNode.Name, childElement.Location);
ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "PropertyOutsidePropertyGroupInTarget", childElement.Name);

and add a new string near here:

<data name="UnrecognizedChildElement" xml:space="preserve">
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized.</value>
<comment>{StrBegin="MSB4067: "}</comment>
</data>

Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

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

This is starting to look great, just a few more things to wrap up!

documentation/wiki/ChangeWaves-Dev.md Show resolved Hide resolved
src/Build/Resources/Strings.resx Outdated Show resolved Hide resolved
Copy link
Member

@Forgind Forgind left a comment

Choose a reason for hiding this comment

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

Looks pretty good to me! Just a couple little things.

src/Build/Resources/Strings.resx Outdated Show resolved Hide resolved
@@ -1271,6 +1271,10 @@
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized.</value>
<comment>{StrBegin="MSB4067: "}</comment>
</data>
<data name="PropertyOutsidePropertyGroupInTarget" xml:space="preserve" Condition="$([MSBuild]::AreFeaturesEnabled('17.6'))">
<value>MSB4070: The property &lt;{0}&gt; beneath target &lt;{1}&gt; is unrecognized. Properties must be inside a &lt;PropertyGroup&gt; element.</value>
Copy link
Member

Choose a reason for hiding this comment

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

Maybe:

Suggested change
<value>MSB4070: The property &lt;{0}&gt; beneath target &lt;{1}&gt; is unrecognized. Properties must be inside a &lt;PropertyGroup&gt; element.</value>
<value>MSB4070: The property &lt;{0}&gt; beneath target &lt;{1}&gt; is unrecognized. If you intended this to be a property, it must be inside a &lt;PropertyGroup&gt; element.</value>

? They might have been trying to do something else.

Copy link
Member

Choose a reason for hiding this comment

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

Ping on this point, which I think is the only outstanding issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

Should we add hint "If you intended this to be a property" for the new MSB4067?

Copy link
Member

Choose a reason for hiding this comment

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

Yes please.

@@ -1271,6 +1271,10 @@
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized.</value>
<comment>{StrBegin="MSB4067: "}</comment>
</data>
<data name="PropertyOutsidePropertyGroupInTarget" xml:space="preserve" Condition="$([MSBuild]::AreFeaturesEnabled('17.6'))">
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized. If you intended this to be a property, it must be inside a &lt;PropertyGroup&gt; element.</value>
Copy link
Member

@danmoseley danmoseley Dec 6, 2022

Choose a reason for hiding this comment

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

Suggested change
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized. If you intended this to be a property, it must be inside a &lt;PropertyGroup&gt; element.</value>
<value>MSB4067: The element &lt;{0}&gt; beneath element &lt;{1}&gt; is unrecognized. If you intended this to be a property, enclose it within a &lt;PropertyGroup&gt; element.</value>

Otherwise you might interpret this to mean properties can't be inside targets, when they can.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated

collection.LoadProject(file.Path).Build().ShouldBeTrue();
});

var expectedString = "If you intended this to be a property, enclose it within a <PropertyGroup> element";
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I think I missed this before. Please don't check against English strings in unit tests, because that will make them fail on non-English OSes (after we get a translation for this specific string).

There aren't any tests in this assembly that do the check the most-correct way (extracting the resource by name).

Can you instead check for the code (MSB4067) outside the if, and only if the new stuff is enabled additionally check that the message contains PropertyGroup? That part of the string shouldn't be localized so I think that'd be a pretty good test.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Update expected string in case the localization
@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Dec 12, 2022
@JaynieBai JaynieBai merged commit fd7cd72 into main Dec 13, 2022
@JaynieBai JaynieBai deleted the jennybai/issue5773 branch December 13, 2022 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid Child Element at wrong level
5 participants