diff --git a/src/Docfx.Common/Loggers/ReportLogListener.cs b/src/Docfx.Common/Loggers/ReportLogListener.cs index abdde3e5226..5471d9afc7b 100644 --- a/src/Docfx.Common/Loggers/ReportLogListener.cs +++ b/src/Docfx.Common/Loggers/ReportLogListener.cs @@ -1,20 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text.Json.Serialization; -using Newtonsoft.Json; - namespace Docfx.Common; public sealed class ReportLogListener : ILoggerListener { - private readonly string _repoRoot; - private readonly string _root; private readonly StreamWriter _writer; - private const LogLevel LogLevelThreshold = LogLevel.Diagnostic; - - public ReportLogListener(string reportPath, string repoRoot, string root) + public ReportLogListener(string reportPath) { var dir = Path.GetDirectoryName(reportPath); if (!string.IsNullOrEmpty(dir)) @@ -22,31 +15,21 @@ public ReportLogListener(string reportPath, string repoRoot, string root) Directory.CreateDirectory(dir); } _writer = new StreamWriter(reportPath, true); - _repoRoot = repoRoot; - _root = root; } public void WriteLine(ILogItem item) { ArgumentNullException.ThrowIfNull(item); - var level = item.LogLevel; - var message = item.Message; - var file = item.File; - var line = item.Line; - if (level < LogLevelThreshold) return; - - var reportItem = new ReportItem + _writer.WriteLine(JsonUtility.Serialize(new { - Severity = GetSeverity(level), - Message = message, - File = TransformFile(file), - Line = line, - DateTime = DateTime.UtcNow, - Code = item.Code, - }; - - _writer.WriteLine(JsonUtility.Serialize(reportItem)); + severity = item.LogLevel, + message = item.Message, + file = item.File, + line = item.Line, + date_time = DateTime.UtcNow, + code = item.Code, + })); } public void Dispose() @@ -54,83 +37,8 @@ public void Dispose() _writer.Dispose(); } - private static MessageSeverity GetSeverity(LogLevel level) - { - switch (level) - { - case LogLevel.Diagnostic: - return MessageSeverity.Diagnostic; - case LogLevel.Verbose: - return MessageSeverity.Verbose; - case LogLevel.Info: - return MessageSeverity.Info; - case LogLevel.Suggestion: - return MessageSeverity.Suggestion; - case LogLevel.Warning: - return MessageSeverity.Warning; - case LogLevel.Error: - return MessageSeverity.Error; - default: - throw new NotSupportedException(level.ToString()); - } - } - - private string TransformFile(string fileFromRoot) - { - if (fileFromRoot == null) - { - return null; - } - if (string.IsNullOrEmpty(_repoRoot)) - { - return fileFromRoot; - } - - string file = ((RelativePath)fileFromRoot).RemoveWorkingFolder(); - string basePath = Path.GetFullPath(_repoRoot); - string fullPath = Path.GetFullPath(Path.Combine(_root, file)); - return PathUtility.MakeRelativePath(basePath, fullPath); - } - public void Flush() { _writer.Flush(); } - - public class ReportItem - { - [JsonProperty("message")] - [JsonPropertyName("message")] - public string Message { get; set; } - - [JsonProperty("file")] - [JsonPropertyName("file")] - public string File { get; set; } - - [JsonProperty("line")] - [JsonPropertyName("line")] - public string Line { get; set; } - - [JsonProperty("date_time")] - [JsonPropertyName("date_time")] - public DateTime DateTime { get; set; } - - [JsonProperty("message_severity")] - [JsonPropertyName("message_severity")] - public MessageSeverity Severity { get; set; } - - [JsonProperty("code")] - [JsonPropertyName("code")] - public string Code { get; set; } - } - - public enum MessageSeverity - { - Error, - Warning, - Suggestion, - Info, - Verbose, - Diagnostic - } } diff --git a/src/docfx/Models/CommandHelper.cs b/src/docfx/Models/CommandHelper.cs index 057a2ec2ebb..798e23aa52b 100644 --- a/src/docfx/Models/CommandHelper.cs +++ b/src/docfx/Models/CommandHelper.cs @@ -25,18 +25,19 @@ public static int Run(LogOptions options, Action run) var consoleLogListener = new ConsoleLogListener(); Logger.RegisterListener(consoleLogListener); - var buildOption = options as BuildCommandOptions; - var root = Path.GetDirectoryName(buildOption?.ConfigFile ?? Directory.GetCurrentDirectory()); - if (!string.IsNullOrWhiteSpace(options.LogFilePath)) { - Logger.RegisterListener(new ReportLogListener(options.LogFilePath, options.RepoRoot ?? string.Empty, root)); + Logger.RegisterListener(new ReportLogListener(options.LogFilePath)); } if (options.LogLevel.HasValue) { Logger.LogLevelThreshold = options.LogLevel.Value; } + else if (options.Verbose) + { + Logger.LogLevelThreshold = LogLevel.Verbose; + } Logger.WarningsAsErrors = options.WarningsAsErrors; diff --git a/src/docfx/Models/LogOptions.cs b/src/docfx/Models/LogOptions.cs index d74f7679164..0201f4ea1fa 100644 --- a/src/docfx/Models/LogOptions.cs +++ b/src/docfx/Models/LogOptions.cs @@ -10,19 +10,19 @@ namespace Docfx; internal class LogOptions : CommandSettings { - [Description("Specify the file name to save processing log")] + [Description("Save log as structured JSON to the specified file")] [CommandOption("-l|--log")] public string LogFilePath { get; set; } - [Description("Specify to which log level will be logged. By default log level >= Info will be logged. The acceptable value could be Verbose, Info, Warning, Error.")] + [Description("Set log level to error, warning, info, verbose or diagnostic")] [CommandOption("--logLevel")] public LogLevel? LogLevel { get; set; } - [Description("Specify the GIT repository root folder.")] - [CommandOption("--repositoryRoot")] - public string RepoRoot { get; set; } + [Description("Set log level to verbose")] + [CommandOption("--verbose")] + public bool Verbose { get; set; } - [Description("Specify if warnings should be treated as errors.")] + [Description("Treats warnings as errors")] [CommandOption("--warningsAsErrors")] public bool WarningsAsErrors { get; set; } } diff --git a/test/Docfx.Common.Tests/ReportLoggerListenerTest.cs b/test/Docfx.Common.Tests/ReportLoggerListenerTest.cs deleted file mode 100644 index 31ac75d1ace..00000000000 --- a/test/Docfx.Common.Tests/ReportLoggerListenerTest.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Docfx.Tests.Common; - -using Xunit; - -namespace Docfx.Common.Tests; - -[Collection("docfx STA")] -public class ReportLoggerListenerTest : TestBase -{ - private readonly string _workingDirectory; - private readonly string _repoRoot; - - public ReportLoggerListenerTest() - { - _workingDirectory = GetRandomFolder(); - _repoRoot = Path.GetFullPath(GetRandomFolder()); - } - - [Fact] - public void TestFilePath() - { - // - RepoRoot/ - // |- A.ps1 - // |- B/ - // |- Root - // |- C.cs - // |- docfx.json - // |- D/ - // |- E.md - var logFilePath = Path.Combine(_workingDirectory, "report.txt"); - var files = new string[] - { - "A.ps1", - "B/Root/C.cs", - "B/Root/docfx.json", - "B/Root/D/E.md", - }; - CreateFilesOrFolders(_repoRoot, files); - var listener = new ReportLogListener(logFilePath, _repoRoot, Path.Combine(_repoRoot, "B/Root/")); - Logger.RegisterListener(listener); - Logger.LogInfo("Test file path1", file: "~/C.cs"); - Logger.LogInfo("Test file path2", file: "D/E.md"); - Logger.UnregisterListener(listener); - var lines = File.ReadAllLines(logFilePath); - var reportItems = (from line in lines - select line.FromJsonString()).ToList(); - var item1 = reportItems.SingleOrDefault(r => r.Message == "Test file path1"); - Assert.NotNull(item1); - Assert.Equal("B/Root/C.cs", item1.File); - var item2 = reportItems.SingleOrDefault(r => r.Message == "Test file path2"); - Assert.NotNull(item2); - Assert.Equal("B/Root/D/E.md", item2.File); - } - - private static void CreateFilesOrFolders(string cwd, params string[] items) - { - if (string.IsNullOrEmpty(cwd)) cwd = "."; - foreach (var i in items) - { - var item = cwd + "/" + i; - if (item.EndsWith("/")) - { - Directory.CreateDirectory(item); - } - else - { - var dir = Path.GetDirectoryName(item); - if (dir != string.Empty) Directory.CreateDirectory(dir); - File.WriteAllText(item, string.Empty); - } - } - } -}