Implement warnnotaserror Fixes #3062#7309
Conversation
Should now work for: TaskHosts If set via property (and then only for that project)
rainersigwald
left a comment
There was a problem hiding this comment.
Is there a way to override the command line switch?
I'd like to see tests for the properties and the interaction between properties and the CLI switches (specifically around msbuild -warnaserror + <MSBuildWarningsNotAsErrors>).
src/MSBuild/Resources/Strings.resx
Outdated
| </comment> | ||
| </data> | ||
| <data name="MissingWarnNotAsErrorParameterError" UESanitized="true" Visibility="Public"> | ||
| <value>MSBUILD : error MSB1060: Specify one or more warning codes to keep as warnings despite a global -warnaserror when using the -warnNotAsError switch.</value> |
There was a problem hiding this comment.
| <value>MSBUILD : error MSB1060: Specify one or more warning codes to keep as warnings despite a global -warnaserror when using the -warnNotAsError switch.</value> | |
| <value>MSBUILD : error MSB1060: Specify one or more warning codes when using the -warnNotAsError switch.</value> |
| multiple warning codes. Has no effect if the -warnaserror | ||
| switch is not set. |
There was a problem hiding this comment.
Why not error if -warnaserror is not on?
There was a problem hiding this comment.
If warnaserror is not set at all, no warnings are promoted to errors anyway, so there's nothing to revert to a warning.
More generally, you can clear the warnaserror switch, so I thought of this as only important if the user asked all warnings to be promoted. That said, I'm not opposed to make it revert error codes even if there are only a few warnings promoted to errors. I'm curious as to whether it's more confusing, if someone is unaware of the WarningsNotAsErrors switch, to have a switch clearly set but not doing anything versus rely on all warnings to be promoted and have one just not be.
There was a problem hiding this comment.
I'm proposing emitting a new warning at command-line-parsing time that says " you said warnnotaserror but didn't have any warnaserrors"
There was a problem hiding this comment.
You could still have a project-level warnaserror that you wanted not promoted, right?
|
|
||
| // An empty set means all warnings are errors. | ||
| return WarningsAsErrors.Count == 0 || WarningsAsErrors.Contains(warningCode); | ||
| return (WarningsAsErrors.Count == 0 && (WarningsNotAsErrors == null || !WarningsNotAsErrors.Contains(warningCode))) || WarningsAsErrors.Contains(warningCode); |
There was a problem hiding this comment.
This is fairly confusing. Extract to a named local function and add comments?
There was a problem hiding this comment.
I'll hold off on this for now until we've nailed down whether -warnaserror:FOR123 -warnnotaserror:FOR123 should have the warning promoted to an error or not. This should clean itself up if we go with it being just a warning.
src/MSBuild/CommandLineSwitches.cs
Outdated
| new ParameterizedSwitchInfo( new string[] { "preprocess", "pp" }, ParameterizedSwitch.Preprocess, null, false, null, true, false ), | ||
| new ParameterizedSwitchInfo( new string[] { "targets", "ts" }, ParameterizedSwitch.Targets, null, false, null, true, false ), | ||
| new ParameterizedSwitchInfo( new string[] { "warnaserror", "err" }, ParameterizedSwitch.WarningsAsErrors, null, true, null, true, true ), | ||
| new ParameterizedSwitchInfo( new string[] { "warnnotaserror", "noerr" }, ParameterizedSwitch.WarningsNotAsErrors, null, true, "MissingWarnNotAsErrorParameterError", true, true ), |
There was a problem hiding this comment.
| new ParameterizedSwitchInfo( new string[] { "warnnotaserror", "noerr" }, ParameterizedSwitch.WarningsNotAsErrors, null, true, "MissingWarnNotAsErrorParameterError", true, true ), | |
| new ParameterizedSwitchInfo( new string[] { "warnnotaserror", "noerr" }, ParameterizedSwitch.WarningsNotAsErrors, null, true, "MissingWarnNotAsErrorParameterError", true, false ), |
| } | ||
|
|
||
| /// <summary> | ||
| /// Set of warnings to not treat as errors. Only has any effect if WarningsAsErrors is non-null but empty. |
There was a problem hiding this comment.
Sounds like you're making a decision that it's invalid to build with -warnaserrors:AB1234,CD5678 and then in a project set <MSBuildWarningsNotAsErrors>AB1234</MSBuildWarningsNotAsErrors>. Do you think that's right? I'm not sure myself.
src/MSBuild/XMake.cs
Outdated
| // TODO: Parse an environment variable as well? | ||
|
|
There was a problem hiding this comment.
| // TODO: Parse an environment variable as well? |
| // An empty /warnaserror is added as "null". In this case, the list is cleared | ||
| // so that all warnings are treated errors | ||
| warningsAsErrors.Clear(); | ||
| warningSwitches.Clear(); |
There was a problem hiding this comment.
This behavior wasn't present on warnasmessage before. Should it be now?
There was a problem hiding this comment.
Good catch, but also, I'd vote yes. It could theoretically break someone who has /warnasmessage:FOR123 /warnasmessage:, but if you were doing something bad, I'd say you deserve that. It's very logical to assume that converting warnings to errors/messages should work the same way, so we should do that.
| Microsoft.Build.FileSystem.IDirectoryCacheFactory | ||
| Microsoft.Build.FileSystem.IDirectoryCacheFactory.GetDirectoryCacheForEvaluation(int evaluationId) -> Microsoft.Build.FileSystem.IDirectoryCache | ||
| static Microsoft.Build.Globbing.CompositeGlob.Create(System.Collections.Generic.IEnumerable<Microsoft.Build.Globbing.IMSBuildGlob> globs) -> Microsoft.Build.Globbing.IMSBuildGlob No newline at end of file | ||
| static Microsoft.Build.Globbing.CompositeGlob.Create(System.Collections.Generic.IEnumerable<Microsoft.Build.Globbing.IMSBuildGlob> globs) -> Microsoft.Build.Globbing.IMSBuildGlob |
There was a problem hiding this comment.
Hm. Starting to wonder if the public API promotion should be in main rather than the release branch, since it will be an annoying merge here. But we also just checked in a revert that changed public API after forking so maybe not?
| private IDictionary<int, ISet<string>> _warningsAsErrorsByProject; | ||
|
|
||
| /// <summary> | ||
| /// A list of warnings to treat as errors for an associated <see cref="BuildEventContext"/>. If an empty set, all warnings are treated as errors. |
| return GetWarningsForProject(context, _warningsAsMessagesByProject, WarningsAsMessages); | ||
| } | ||
|
|
||
| private ICollection<string> GetWarningsForProject(BuildEventContext context, IDictionary<int, ISet<string>> warningsByProject, ISet<string> warnings) |
rainersigwald
left a comment
There was a problem hiding this comment.
LGTM with those added comments.
…into warn-not-as-error
I really don't know how this is even vaguely possible—but it looks like main is wrong?
Fixes #3062
Context
We previously had warnaserror (and a property for it) that, when you specified error codes, upgraded those error codes from warnings to errors. If you just left it empty, it upgraded all warnings to errors. (Null meant don't upgrade.)
This adds that you can ask for all error codes to be upgraded, then downgrade just a few of them (via codes) back to warnings.
Changes Made
Implement WarnNotAsError both as a command line switch and as a property.
Testing
Added a unit test. Tried it out from the command line.
Notes