This repository has been archived by the owner on Dec 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
DocFxIssuesProvider.cs
145 lines (126 loc) · 5.14 KB
/
DocFxIssuesProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
namespace Cake.Issues.DocFx
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using Cake.Core;
using Cake.Core.Diagnostics;
using Cake.Core.IO;
/// <summary>
/// Provider for warnings reported by DocFx.
/// </summary>
internal class DocFxIssuesProvider : BaseConfigurableIssueProvider<DocFxIssuesSettings>
{
/// <summary>
/// Initializes a new instance of the <see cref="DocFxIssuesProvider"/> class.
/// </summary>
/// <param name="log">The Cake log context.</param>
/// <param name="issueProviderSettings">Settings for the issue provider.</param>
public DocFxIssuesProvider(ICakeLog log, DocFxIssuesSettings issueProviderSettings)
: base(log, issueProviderSettings)
{
}
/// <summary>
/// Gets the name of the DocFx issue provider.
/// This name can be used to identify issues based on the <see cref="IIssue.ProviderType"/> property.
/// </summary>
public static string ProviderTypeName => typeof(DocFxIssuesProvider).FullName;
/// <inheritdoc />
public override string ProviderName => "DocFX";
/// <inheritdoc />
protected override IEnumerable<IIssue> InternalReadIssues()
{
// Determine path of the doc root.
var docRootPath = this.IssueProviderSettings.DocRootPath;
if (docRootPath.IsRelative)
{
docRootPath = docRootPath.MakeAbsolute(this.Settings.RepositoryRoot);
}
IEnumerable<LogEntryDataContract> logFileEntries = null;
var logFileContent = this.IssueProviderSettings.LogFileContent.ToStringUsingEncoding(true);
logFileContent =
"[" +
string.Join(",", logFileContent.SplitLines()) +
"]";
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(logFileContent)))
{
var jsonSerializer = new DataContractJsonSerializer(typeof(LogEntryDataContract[]));
logFileEntries = jsonSerializer.ReadObject(ms) as LogEntryDataContract[];
}
return
from logEntry in logFileEntries
let file = this.TryGetFile(logEntry.file, docRootPath)
let line = TryGetLine(logEntry.line)
where
(logEntry.message_severity == "warning" || logEntry.message_severity == "suggestion") &&
!string.IsNullOrWhiteSpace(logEntry.message)
select
IssueBuilder
.NewIssue(logEntry.message, this)
.InFile(file, line)
.OfRule(logEntry.source)
.WithPriority(GetPriority(logEntry.message_severity))
.Create();
}
/// <summary>
/// Converts the severity to a priority.
/// </summary>
/// <param name="severity">Severity as reported by DocFX.</param>
/// <returns>Priority.</returns>
private static IssuePriority GetPriority(string severity)
{
switch (severity.ToLower())
{
case "warning":
return IssuePriority.Warning;
case "suggestion":
return IssuePriority.Suggestion;
default:
return IssuePriority.Undefined;
}
}
/// <summary>
/// Reads the affected line from a issue logged in a DocFx log file.
/// </summary>
/// <param name="line">The line in the current log entry.</param>
/// <returns>The line of the issue.</returns>
private static int? TryGetLine(
int? line)
{
// Convert negative line numbers or line number 0 to null
if (line.HasValue && line.Value <= 0)
{
return null;
}
return line;
}
/// <summary>
/// Reads the affected file path from a issue logged in a DocFx log file.
/// </summary>
/// <param name="fileName">The file name in the current log entry.</param>
/// <param name="docRootPath">Absolute path to the root of the DocFx project.</param>
/// <returns>The full path to the affected file.</returns>
private string TryGetFile(
string fileName,
DirectoryPath docRootPath)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return null;
}
// Add path to repository root
fileName = docRootPath.CombineWithFilePath(fileName).FullPath;
// Make path relative to repository root.
fileName = fileName.Substring(this.Settings.RepositoryRoot.FullPath.Length);
// Remove leading directory separator.
if (fileName.StartsWith("/", StringComparison.InvariantCulture))
{
fileName = fileName.Substring(1);
}
return fileName;
}
}
}