forked from jenkinsci/analysis-model
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParserRegistry.java
More file actions
356 lines (332 loc) · 12.5 KB
/
Copy pathParserRegistry.java
File metadata and controls
356 lines (332 loc) · 12.5 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
package edu.hm.hafner.analysis.registry;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import edu.hm.hafner.analysis.IssueParser;
import j2html.tags.ContainerTag;
import j2html.tags.DomContent;
import static j2html.TagCreator.*;
/**
* Provides a registry for all available {@link IssueParser parsers}.
*
* @author Lorenz Munsch
*/
@SuppressWarnings({"checkstyle:ClassDataAbstractionCoupling", "checkstyle:ClassFanOutComplexity"})
public class ParserRegistry {
private static final String BULB_EMOJI = ":bulb:";
private static final ParserDescriptor[] ALL_DESCRIPTORS = {
new AcuCobolDescriptor(),
new AjcDescriptor(),
new AnchoreCtlDescriptor(),
new AndroidLintDescriptor(),
new AnsibleLintDescriptor(),
new AnsibleLaterDescriptor(),
new AquaScannerDescriptor(),
new ArmccCompilerDescriptor(),
new BanditDescriptor(),
new BluePearlDescriptor(),
new BrakemanDescriptor(),
new BuckminsterDescriptor(),
new CadenceIncisiveDescriptor(),
new CargoDescriptor(),
new CargoClippyDescriptor(),
new CargoAuditDescriptor(),
new CcmDescriptor(),
new CfnLintDescriptor(),
new CfnNagDescriptor(),
new CheckovDescriptor(),
new CheckStyleDescriptor(),
new ClairDescriptor(),
new ClangAnalyzerDescriptor(),
new ClangDescriptor(),
new ClangTidyDescriptor(),
new CmakeDescriptor(),
new CodeAnalysisDescriptor(),
new CodeCheckerDescriptor(),
new CodeGuruSecurityDescriptor(),
new CodeClimateDescriptor(),
new CodeGeneratorDescriptor(),
new CodeNarcDescriptor(),
new CoolfluxChessccDescriptor(),
new CoverityDescriptor(),
new CpdDescriptor(),
new CppCheckDescriptor(),
new CppLintDescriptor(),
new CrossCoreEmbeddedStudioDescriptor(),
new CssLintDescriptor(),
new DartAnalyzeDescriptor(),
new DetektDescriptor(),
new DiabCDescriptor(),
new DocFxDescriptor(),
new DockerLintDescriptor(),
new DoxygenDescriptor(),
new DrMemoryDescriptor(),
new DScannerDescriptor(),
new DupfinderDescriptor(),
new EclipseDescriptor(),
new EmbeddedEngineerDescriptor(),
new ErlcDescriptor(),
new ErrorProneDescriptor(),
new EsLintDescriptor(),
new FindBugsDescriptor(),
new Flake8Descriptor(),
new FlawfinderDescriptor(),
new FlexSdkDescriptor(),
new FlowDescriptor(),
new FoodCriticDescriptor(),
new FxcopDescriptor(),
new Gcc4Descriptor(),
new GccDescriptor(),
new GendarmeDescriptor(),
new GhsMultiDescriptor(),
new GitGuardianDescriptor(),
new GitleaksDescriptor(),
new GnatDescriptor(),
new GnuFortranDescriptor(),
new GolangCiLintDescriptor(),
new GosecDescriptor(),
new GoLintDescriptor(),
new GoVetDescriptor(),
new GrypeDescriptor(),
new HadoLintDescriptor(),
new IarCstatDescriptor(),
new IarDescriptor(),
new IbLinterDescriptor(),
new IdeaInspectionDescriptor(),
new InferDescriptor(),
new IntelDescriptor(),
new InvalidsDescriptor(),
new JavaDescriptor(),
new JavaDocDescriptor(),
new JcreportDescriptor(),
new JsHintDescriptor(),
new JsLintDescriptor(),
new JUnitDescriptor(),
new KlocWorkDescriptor(),
new KotlinDescriptor(),
new KtLintDescriptor(),
new KubesecDescriptor(),
new KubeLinterDescriptor(),
new KubeScoreDescriptor(),
new KyvernoDescriptor(),
new MarkdownLintDescriptor(),
new MavenConsoleDescriptor(),
new MentorGraphicsDescriptor(),
new MetrowerksCodeWarriorDescriptor(),
new MsBuildDescriptor(),
new MyPyDescriptor(),
new NagFortranDescriptor(),
new NativeFormatDescriptor(),
new NixDescriptor(),
new NpmAuditDescriptor(),
new OeLintAdvDescriptor(),
new OtDockerLintDescriptor(),
new OwaspDependencyCheckDescriptor(),
new PcLintDescriptor(),
new Pep8Descriptor(),
new PerforceDescriptor(),
new PerlCriticDescriptor(),
new PhpCodeSnifferDescriptor(),
new PhpDescriptor(),
new PhanDescriptor(),
new PhpStanDescriptor(),
new PhpMdDescriptor(),
new PitDescriptor(),
new PmdDescriptor(),
new PnpmAuditDescriptor(),
new PolyspaceDescriptor(),
new PreFastDescriptor(),
new ProtoLintDescriptor(),
new PuppetLintDescriptor(),
new PsalmDescriptor(),
new PvsStudioDescriptor(),
new PyDocStyleDescriptor(),
new PyLintDescriptor(),
new QacSourceCodeAnalyserDescriptor(),
new QtTranslationDescriptor(),
new ResharperDescriptor(),
new RevApiDescriptor(),
new ReviveDescriptor(),
new RfLintDescriptor(),
new RoboCopyDescriptor(),
new RuboCopDescriptor(),
new RuffDescriptor(),
new SarifDescriptor(),
new ScalaDescriptor(),
new SemgrepDescriptor(),
new ShellCheckDescriptor(),
new SimianDescriptor(),
new SimulinkCheckDescriptor(),
new SnykDescriptor(),
new SqlFluffDescriptor(),
new StaticcheckDescriptor(),
new SonarQubeDescriptor(),
new SpectralDescriptor(),
new SphinxBuildDescriptor(),
new SpotBugsDescriptor(),
new StyleCopDescriptor(),
new StyleLintDescriptor(),
new SunCDescriptor(),
new SwiftLintDescriptor(),
new TaglistDescriptor(),
new TaskingVxCompilerDescriptor(),
new TerraformLintDescriptor(),
new TfsecDescriptor(),
new TiCcsDescriptor(),
new TnsdlDescriptor(),
new TrivyDescriptor(),
new TruffleHogDescriptor(),
new TsLintDescriptor(),
new ValeDescriptor(),
new ValgrindDescriptor(),
new VeraCodePipelineScannerDescriptor(),
new XlcDescriptor(),
new YamlLintDescriptor(),
new YoctoScannerDescriptor(),
new XmlLintDescriptor(),
new YuiCompressorDescriptor(),
new ZptLintDescriptor()
};
private final Map<String, ParserDescriptor> descriptors;
/**
* Creates a new registry instance.
*/
public ParserRegistry() {
descriptors = Arrays.stream(ALL_DESCRIPTORS)
.collect(Collectors.toMap(ParserDescriptor::getId, Function.identity()));
}
/**
* Returns the IDs of all available parsers.
*
* @return a set of all IDs
*/
public Set<String> getIds() {
return new HashSet<>(descriptors.keySet());
}
/**
* Returns the names of all available parsers.
*
* @return a set of all names
*/
public Set<String> getNames() {
return descriptors.values().stream().map(ParserDescriptor::getName).collect(Collectors.toSet());
}
/**
* Returns whether a parser with the specified ID exists.
*
* @param id
* the ID to check
*
* @return {@code true} if the parser exists, {@code false} otherwise
*/
public boolean contains(final String id) {
return descriptors.containsKey(id);
}
/**
* Returns the {@link ParserDescriptor} with the specified ID.
*
* @param id
* the ID of the parser
*
* @return the requested descriptor
* @throws NoSuchElementException
* if no such parser exists
*/
public ParserDescriptor get(final String id) {
if (descriptors.containsKey(id)) {
return descriptors.get(id);
}
throw new NoSuchElementException("No such parser registered: " + id);
}
/**
* Returns all descriptors.
*
* @return all supported descriptors
*/
public List<ParserDescriptor> getAllDescriptors() {
return new ArrayList<>(descriptors.values());
}
/**
* Utility to create a report with all available descriptors. The report will be stored in the file
* "SUPPORTED-FORMATS.md" in the top level directory.
*
* @param unused
* not used
*
* @throws IOException
* of the file `SUPPORTED-FORMATS.md` cannot be written locally
*/
public static void main(final String... unused) throws IOException {
List<ParserDescriptor> descriptors = new ParserRegistry().getAllDescriptors();
descriptors.sort(Comparator.comparing(ParserDescriptor::getName));
try (var file = new PrintWriter("SUPPORTED-FORMATS.md", StandardCharsets.UTF_8)) {
file.printf("<!--- DO NOT EDIT -- Generated at %s - Run the `main` method of `%s` to regenerate after changing parsers -- DO NOT EDIT --->%n",
LocalDateTime.now(ZoneId.of("Europe/Berlin")),
ParserRegistry.class.getSimpleName());
file.println("""
# Supported Report Formats
The static analysis model supports the following report formats.
If your tool is not yet supported, you can
1. export the issues of your tool to the native XML or JSON format (or any other format).
2. provide a [pull request](https://github.com/jenkinsci/analysis-model/pulls) with a new parser.
If your tool is supported, but some properties are missing (icon, URL, etc.), please file a \
[pull request](https://github.com/jenkinsci/analysis-model/pulls).
""");
List<ContainerTag> lines = descriptors.stream()
.map(ParserRegistry::getTableRows)
.flatMap(List::stream)
.collect(Collectors.toList());
file.println(table().with(thead().with(tr().with(
th("ID"),
th("Icons"),
th("Name"),
th("Default Pattern"))),
tbody().with(lines)).renderFormatted());
}
}
private static List<ContainerTag> getTableRows(final ParserDescriptor descriptor) {
List<ContainerTag> rows = new ArrayList<>();
rows.add(tr().with(
td(descriptor.getId()),
td(getIcon(descriptor)),
td(getName(descriptor)),
td(StringUtils.defaultIfBlank(descriptor.getPattern(), "-"))));
if (descriptor.hasHelp()) {
rows.add(tr().with(td()
.attr("colspan", "4")
.with(join(BULB_EMOJI, rawHtml(descriptor.getHelp())))));
}
return rows;
}
private static DomContent getName(final ParserDescriptor descriptor) {
var name = descriptor.getName();
var url = descriptor.getUrl();
if (url.isEmpty()) {
return text(name);
}
return a(name).withHref(url);
}
private static DomContent getIcon(final ParserDescriptor descriptor) {
var url = descriptor.getIconUrl();
if (url.isEmpty()) {
return text("-");
}
return img().withSrc(url)
.withAlt(descriptor.getName())
.attr("height", "64")
.attr("width", 64);
}
}