/// <summary> /// Determines if the specified warning should be treated as an error. /// </summary> /// <param name="warningEvent">A <see cref="BuildWarningEventArgs"/> that specifies the warning.</param> /// <returns><code>true</code> if the warning should be treated as an error, otherwise <code>false</code>.</returns> private bool ShouldTreatWarningAsError(BuildWarningEventArgs warningEvent) { // This only applies if the user specified /warnaserror from the command-line or added an empty set through the object model // if (WarningsAsErrors != null) { // Global warnings as errors apply to all projects. If the list is empty or contains the code, the warning should be treated as an error // if (WarningsAsErrors.Count == 0 || WarningsAsErrors.Contains(warningEvent.Code)) { return(true); } } // This only applies if the user specified <MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors or <MSBuildWarningsAsErrors /> // and there is a valid ProjectInstanceId for the warning. // if (WarningsAsErrorsByProject != null && warningEvent.BuildEventContext != null && warningEvent.BuildEventContext.ProjectInstanceId != BuildEventContext.InvalidProjectInstanceId) { ISet <string> codesByProject; // Attempt to get the list of warnings to treat as errors for the current project // if (WarningsAsErrorsByProject.TryGetValue(warningEvent.BuildEventContext.ProjectInstanceId, out codesByProject) && codesByProject != null) { // We create an empty set if all warnings should be treated as errors so that should be checked first. // If the set is not empty, check the specific code. // return(codesByProject.Count == 0 || codesByProject.Contains(warningEvent.Code)); } } return(false); }
/// <summary> /// Raises the given event to all registered loggers. This method up-cast the events /// extracted from the queue. /// </summary> public void Consume(BuildEventArgs buildEvent) { // FXCop may complain that there are unecessary casts here, and there are, but // using "as" and allocating another variable for each event is extremely costly // and is much slower then this approach even with the additional casts if (buildEvent is BuildMessageEventArgs) { this.RaiseMessageEvent(null, (BuildMessageEventArgs)buildEvent); } else if (buildEvent is TaskStartedEventArgs) { this.RaiseTaskStartedEvent(null, (TaskStartedEventArgs)buildEvent); } else if (buildEvent is TaskFinishedEventArgs) { this.RaiseTaskFinishedEvent(null, (TaskFinishedEventArgs)buildEvent); } else if (buildEvent is TargetStartedEventArgs) { this.RaiseTargetStartedEvent(null, (TargetStartedEventArgs)buildEvent); } else if (buildEvent is TargetFinishedEventArgs) { this.RaiseTargetFinishedEvent(null, (TargetFinishedEventArgs)buildEvent); } else if (buildEvent is ProjectStartedEventArgs) { this.RaiseProjectStartedEvent(null, (ProjectStartedEventArgs)buildEvent); } else if (buildEvent is ProjectFinishedEventArgs) { this.RaiseProjectFinishedEvent(null, (ProjectFinishedEventArgs)buildEvent); if (buildEvent.BuildEventContext != null && buildEvent.BuildEventContext.ProjectInstanceId != BuildEventContext.InvalidProjectInstanceId) { WarningsAsErrorsByProject?.Remove(buildEvent.BuildEventContext.ProjectInstanceId); WarningsAsMessagesByProject?.Remove(buildEvent.BuildEventContext.ProjectInstanceId); } } else if (buildEvent is BuildStartedEventArgs) { HaveLoggedBuildStartedEvent = true; this.RaiseBuildStartedEvent(null, (BuildStartedEventArgs)buildEvent); } else if (buildEvent is BuildFinishedEventArgs) { HaveLoggedBuildFinishedEvent = true; this.RaiseBuildFinishedEvent(null, (BuildFinishedEventArgs)buildEvent); } else if (buildEvent is CustomBuildEventArgs) { this.RaiseCustomEvent(null, (CustomBuildEventArgs)buildEvent); } else if (buildEvent is BuildStatusEventArgs) { this.RaiseStatusEvent(null, (BuildStatusEventArgs)buildEvent); } else if (buildEvent is BuildWarningEventArgs) { BuildWarningEventArgs warningEvent = (BuildWarningEventArgs)buildEvent; if (ShouldTreatWarningAsMessage(warningEvent)) { // Treat this warning as a message with low importance if its in the list BuildMessageEventArgs errorEvent = new BuildMessageEventArgs( warningEvent.Subcategory, warningEvent.Code, warningEvent.File, warningEvent.LineNumber, warningEvent.ColumnNumber, warningEvent.EndLineNumber, warningEvent.EndColumnNumber, warningEvent.Message, warningEvent.HelpKeyword, warningEvent.SenderName, MessageImportance.Low, warningEvent.Timestamp) { BuildEventContext = warningEvent.BuildEventContext, ProjectFile = warningEvent.ProjectFile, }; this.RaiseMessageEvent(null, errorEvent); } else if (ShouldTreatWarningAsError(warningEvent)) { // Treat this warning as an error if an empty set of warnings was specified or this code was specified BuildErrorEventArgs errorEvent = new BuildErrorEventArgs( warningEvent.Subcategory, warningEvent.Code, warningEvent.File, warningEvent.LineNumber, warningEvent.ColumnNumber, warningEvent.EndLineNumber, warningEvent.EndColumnNumber, warningEvent.Message, warningEvent.HelpKeyword, warningEvent.SenderName, warningEvent.Timestamp) { BuildEventContext = warningEvent.BuildEventContext, ProjectFile = warningEvent.ProjectFile, }; this.RaiseErrorEvent(null, errorEvent); } else { this.RaiseWarningEvent(null, warningEvent); } } else if (buildEvent is BuildErrorEventArgs) { this.RaiseErrorEvent(null, (BuildErrorEventArgs)buildEvent); } else if (buildEvent is TelemetryEventArgs) { this.RaiseTelemetryEvent(null, (TelemetryEventArgs)buildEvent); } else { ErrorUtilities.VerifyThrow(false, "Unknown event args type."); } }