/
AnalysisScaffolding.cs
139 lines (122 loc) · 7.45 KB
/
AnalysisScaffolding.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
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2023 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System.IO;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.Text;
using Moq;
using SonarAnalyzer.AnalysisContext;
using RoslynAnalysisContext = Microsoft.CodeAnalysis.Diagnostics.AnalysisContext;
namespace SonarAnalyzer.UnitTest
{
internal static class AnalysisScaffolding
{
public static SonarAnalysisContext CreateSonarAnalysisContext() =>
new(Mock.Of<RoslynAnalysisContext>(), Enumerable.Empty<DiagnosticDescriptor>());
public static AnalyzerOptions CreateOptions() =>
new(ImmutableArray<AdditionalText>.Empty);
public static AnalyzerOptions CreateOptions(string relativePath)
{
var text = File.Exists(relativePath) ? SourceText.From(File.ReadAllText(relativePath)) : null;
return CreateOptions(relativePath, text);
}
public static AnalyzerOptions CreateOptions(string relativePath, SourceText text)
{
var additionalText = new Mock<AdditionalText>();
additionalText.Setup(x => x.Path).Returns(relativePath);
additionalText.Setup(x => x.GetText(default)).Returns(text);
return new AnalyzerOptions(ImmutableArray.Create(additionalText.Object));
}
public static DiagnosticDescriptor CreateDescriptorMain(string id = "Sxxxx") =>
CreateDescriptor(id, DiagnosticDescriptorFactory.MainSourceScopeTag);
public static DiagnosticDescriptor CreateDescriptor(string id, params string[] customTags) =>
new(id, "Title", "Message for " + id, "Category", DiagnosticSeverity.Warning, true, customTags: customTags);
public static string CreateAnalysisConfig(TestContext context, IEnumerable<string> unchangedFiles) =>
CreateAnalysisConfig(context, "UnchangedFilesPath", TestHelper.WriteFile(context, "UnchangedFiles.txt", unchangedFiles.JoinStr(Environment.NewLine)));
public static string CreateAnalysisConfig(TestContext context, string settingsId, string settingValue) =>
TestHelper.WriteFile(context, "SonarQubeAnalysisConfig.xml", $"""
<?xml version="1.0" encoding="utf-8"?>
<AnalysisConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
<AdditionalConfig>
<ConfigSetting Id="{settingsId}" Value="{settingValue}" />
</AdditionalConfig>
</AnalysisConfig>
""");
public static string CreateSonarProjectConfigWithFilesToAnalyze(TestContext context, params string[] filesToAnalyze)
{
var filesToAnalyzePath = TestHelper.TestPath(context, "FilesToAnalyze.txt");
File.WriteAllLines(filesToAnalyzePath, filesToAnalyze);
return CreateSonarProjectConfig(context, "FilesToAnalyzePath", filesToAnalyzePath, true);
}
public static string CreateSonarProjectConfigWithUnchangedFiles(TestContext context, params string[] unchangedFiles) =>
CreateSonarProjectConfig(context, "NotImportant", null, true, CreateAnalysisConfig(context, unchangedFiles));
public static string CreateSonarProjectConfig(TestContext context, ProjectType projectType, bool isScannerRun = true) =>
CreateSonarProjectConfig(context, "ProjectType", projectType.ToString(), isScannerRun);
public static string CreateSonarLintXml(
TestContext context,
string language = LanguageNames.CSharp,
bool analyzeGeneratedCode = false,
string[] exclusions = null,
string[] inclusions = null,
string[] globalExclusions = null,
string[] testExclusions = null,
string[] testInclusions = null,
string[] globalTestExclusions = null) =>
TestHelper.WriteFile(context, "SonarLint.xml", GenerateSonarLintXmlContent(language, analyzeGeneratedCode, exclusions, inclusions, globalExclusions, testExclusions, testInclusions, globalTestExclusions));
public static string GenerateSonarLintXmlContent(
string language = LanguageNames.CSharp,
bool analyzeGeneratedCode = false,
string[] exclusions = null,
string[] inclusions = null,
string[] globalExclusions = null,
string[] testExclusions = null,
string[] testInclusions = null,
string[] globalTestExclusions = null) =>
new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("AnalysisInput",
new XElement("Settings",
CreateSetting($"sonar.{(language == LanguageNames.CSharp ? "cs" : "vbnet")}.analyzeGeneratedCode", analyzeGeneratedCode.ToString()),
CreateSetting("sonar.exclusions", ConcatenateStringArray(exclusions)),
CreateSetting("sonar.inclusions", ConcatenateStringArray(inclusions)),
CreateSetting("sonar.global.exclusions", ConcatenateStringArray(globalExclusions)),
CreateSetting("sonar.test.exclusions", ConcatenateStringArray(testExclusions)),
CreateSetting("sonar.test.inclusions", ConcatenateStringArray(testInclusions)),
CreateSetting("sonar.global.test.exclusions", ConcatenateStringArray(globalTestExclusions))))).ToString();
private static XElement CreateSetting(string key, string value) =>
new("Setting", new XElement("Key", key), new XElement("Value", value));
private static string ConcatenateStringArray(string[] array) =>
string.Join(",", array ?? Array.Empty<string>());
private static string CreateSonarProjectConfig(TestContext context, string element, string value, bool isScannerRun, string analysisConfigPath = null)
{
var sonarProjectConfigPath = TestHelper.TestPath(context, "SonarProjectConfig.xml");
var outPath = isScannerRun ? Path.GetDirectoryName(sonarProjectConfigPath) : null;
analysisConfigPath ??= CreateAnalysisConfig(context, "NotImportant", null);
var projectConfigContent = $"""
<SonarProjectConfig xmlns="http://www.sonarsource.com/msbuild/analyzer/2021/1">
<AnalysisConfigPath>{analysisConfigPath}</AnalysisConfigPath>
<OutPath>{outPath}</OutPath>
<{element}>{value}</{element}>
</SonarProjectConfig>
""";
File.WriteAllText(sonarProjectConfigPath, projectConfigContent);
return sonarProjectConfigPath;
}
}
}