Clean up diagnostics output from compile

- Show a build summary
- Parse the msbuild format (the one that most compilers output) into a diagnostic message and then print that.
- Fixed formatting of LibraryRange in dependency diagnostics
This commit is contained in:
David Fowler 2015-10-21 00:26:57 -07:00
parent 18fbd3efe7
commit 62e586549d
4 changed files with 528 additions and 38 deletions

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -77,36 +77,17 @@ namespace Microsoft.DotNet.Tools.Compiler
private static bool Compile(ProjectContext context, string configuration, string outputPath, bool buildProjectReferences)
{
Reporter.Output.WriteLine($"Building {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
// Create the library exporter
var exporter = context.CreateExporter(configuration);
var diagnostics = new List<DiagnosticMessage>();
bool success = true;
// Print out dependency diagnostics
foreach (var diag in context.LibraryManager.GetAllDiagnostics())
{
switch (diag.Severity)
{
case DiagnosticMessageSeverity.Info:
Reporter.Error.WriteLine(diag.FormattedMessage);
break;
case DiagnosticMessageSeverity.Warning:
Reporter.Error.WriteLine(diag.FormattedMessage.Yellow().Bold());
break;
case DiagnosticMessageSeverity.Error:
success = false;
Reporter.Error.WriteLine(diag.FormattedMessage.Red().Bold());
break;
}
}
// If there were dependency errors don't bother compiling
if (!success)
{
return false;
}
// Collect dependency diagnostics
diagnostics.AddRange(context.LibraryManager.GetAllDiagnostics());
// Gather exports for the project
var dependencies = exporter.GetCompilationDependencies().ToList();
@ -137,7 +118,6 @@ namespace Microsoft.DotNet.Tools.Compiler
if (compileResult.ExitCode != 0)
{
Console.Error.WriteLine($"Failed to compile dependency: {projectDependency.Identity.Name.Red()}");
return false;
}
}
@ -223,19 +203,68 @@ namespace Microsoft.DotNet.Tools.Compiler
File.WriteAllLines(rsp, compilerArgs);
var result = Command.Create($"dotnet-compile-{compiler}", $"\"{rsp}\"")
.ForwardStdErr()
.ForwardStdOut()
.OnErrorLine(line =>
{
var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
if (diagnostic != null)
{
diagnostics.Add(diagnostic);
}
else
{
Console.Error.WriteLine(line);
}
})
.OnOutputLine(line =>
{
var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
if (diagnostic != null)
{
diagnostics.Add(diagnostic);
}
else
{
Console.Out.WriteLine(line);
}
})
.RunAsync()
.GetAwaiter()
.GetResult();
if (result.ExitCode == 0)
foreach (var diag in diagnostics)
{
Reporter.Output.WriteLine($"Compiled {context.ProjectFile.Name} successfully!".Green());
return true;
success &= diag.Severity != DiagnosticMessageSeverity.Error;
PrintDiagnostic(diag);
}
success &= result.ExitCode == 0;
PrintSummary(diagnostics);
return success;
}
private static void PrintSummary(List<DiagnosticMessage> diagnostics)
{
Reporter.Output.Writer.WriteLine();
var errorCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Error);
var warningCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Warning);
if (errorCount > 0)
{
Reporter.Output.WriteLine("Compilation failed.".Red());
}
else
{
Reporter.Output.WriteLine("Compilation succeeded.".Green());
}
return false;
Reporter.Output.WriteLine($" {warningCount} Warning(s)");
Reporter.Output.WriteLine($" {errorCount} Error(s)");
Reporter.Output.Writer.WriteLine();
}
private static bool AddResources(Project project, List<string> compilerArgs, string intermediateOutputPath)
@ -323,6 +352,47 @@ namespace Microsoft.DotNet.Tools.Compiler
outputs.Add(project);
}
private static DiagnosticMessage ParseDiagnostic(string projectRootPath, string line)
{
var error = CanonicalError.Parse(line);
if (error != null)
{
var severity = error.category == CanonicalError.Parts.Category.Error ?
DiagnosticMessageSeverity.Error : DiagnosticMessageSeverity.Warning;
return new DiagnosticMessage(
error.code,
error.text,
Path.IsPathRooted(error.origin) ? line : projectRootPath + Path.DirectorySeparatorChar + line,
Path.Combine(projectRootPath, error.origin),
severity,
error.line,
error.column,
error.endColumn,
error.endLine,
source: null);
}
return null;
}
private static void PrintDiagnostic(DiagnosticMessage diag)
{
switch (diag.Severity)
{
case DiagnosticMessageSeverity.Info:
Reporter.Error.WriteLine(diag.FormattedMessage);
break;
case DiagnosticMessageSeverity.Warning:
Reporter.Error.WriteLine(diag.FormattedMessage.Yellow().Bold());
break;
case DiagnosticMessageSeverity.Error:
Reporter.Error.WriteLine(diag.FormattedMessage.Red().Bold());
break;
}
}
private static void ApplyCompilationOptions(CompilerOptions compilationOptions, List<string> cscArgs, bool bootstrappingWithMono)
{
// TODO: Move compilation arguments into the compiler itself