Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

Commit 64f8d3f

Browse files
authored
feat: support report to the json file option for the analyze command (#1042)
1 parent 267cc4f commit 64f8d3f

File tree

8 files changed

+64
-10
lines changed

8 files changed

+64
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* feat: support report to the json file option for the `analyze` command.
56
* feat: make CliRunner a part of public API in order to support transitive executable calls use-case.
67
* feat: add static code diagnostic [`avoid-cascade-after-if-null`](https://dartcodemetrics.dev/docs/rules/common/avoid-cascade-after-if-null).
78

lib/src/analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:convert';
22
import 'dart:io';
33

4+
import 'package:path/path.dart';
45
import 'package:source_span/source_span.dart';
56

67
import '../../../../../reporters/models/json_reporter.dart';
@@ -20,6 +21,15 @@ class LintJsonReporter extends JsonReporter<LintFileReport,
2021
SummaryLintReportRecord<Object>, LintReportParams> {
2122
const LintJsonReporter(IOSink output) : super(output, 2);
2223

24+
factory LintJsonReporter.toFile(String path, String rootFolder) {
25+
final isAbsolutePath = isAbsolute(path);
26+
final filePath = isAbsolutePath ? path : normalize(join(rootFolder, path));
27+
28+
final file = File(filePath.endsWith('.json') ? filePath : '$filePath.json');
29+
30+
return LintJsonReporter(file.openWrite());
31+
}
32+
2333
@override
2434
Future<void> report(
2535
Iterable<LintFileReport> records, {

lib/src/cli/commands/analyze_command.dart

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import 'package:collection/collection.dart';
77
import '../../analyzers/lint_analyzer/lint_analyzer.dart';
88
import '../../analyzers/lint_analyzer/metrics/metrics_factory.dart';
99
import '../../analyzers/lint_analyzer/metrics/models/metric_value_level.dart';
10+
import '../../analyzers/lint_analyzer/models/lint_file_report.dart';
1011
import '../../analyzers/lint_analyzer/models/severity.dart';
1112
import '../../analyzers/lint_analyzer/reporters/lint_report_params.dart';
13+
import '../../analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart';
1214
import '../../analyzers/lint_analyzer/utils/report_utils.dart';
1315
import '../../config_builder/config_builder.dart';
1416
import '../../config_builder/models/deprecated_option.dart';
@@ -44,26 +46,29 @@ class AnalyzeCommand extends BaseCommand {
4446
..isVerbose = isVerbose
4547
..progress.start('Analyzing');
4648

47-
final parsedArgs = ParsedArguments(
48-
excludePath: argResults[FlagNames.exclude] as String,
49-
metricsConfig: {
50-
for (final metric in getMetrics(config: {}))
51-
if (argResults.wasParsed(metric.id))
52-
metric.id: argResults[metric.id] as Object,
53-
},
54-
);
49+
final parsedArgs = ParsedArguments.fromArgs(argResults);
5550

5651
final config = ConfigBuilder.getLintConfigFromArgs(parsedArgs);
5752

5853
final lintAnalyzerResult = await _analyzer.runCliAnalysis(
5954
argResults.rest,
60-
argResults[FlagNames.rootFolder] as String,
55+
parsedArgs.rootFolder,
6156
config,
6257
sdkPath: findSdkPath(),
6358
);
6459

6560
_logger.progress.complete('Analysis is completed. Preparing the results:');
6661

62+
final jsonReportPath = parsedArgs.jsonReportPath;
63+
if (jsonReportPath != null) {
64+
final jsonReporter =
65+
LintJsonReporter.toFile(jsonReportPath, parsedArgs.rootFolder);
66+
await jsonReporter.report(
67+
lintAnalyzerResult,
68+
summary: _analyzer.getSummary(lintAnalyzerResult),
69+
);
70+
}
71+
6772
await _analyzer
6873
.getReporter(
6974
name: argResults[FlagNames.reporter] as String,
@@ -76,6 +81,10 @@ class AnalyzeCommand extends BaseCommand {
7681
additionalParams: LintReportParams(congratulate: !isNoCongratulate),
7782
);
7883

84+
_checkSeverity(lintAnalyzerResult);
85+
}
86+
87+
void _checkSeverity(Iterable<LintFileReport> lintAnalyzerResult) {
7988
if (hasIssueWithSeverity(lintAnalyzerResult, Severity.error)) {
8089
exit(3);
8190
} else if ((argResults[FlagNames.fatalWarnings] as bool) &&
@@ -133,6 +142,12 @@ class AnalyzeCommand extends BaseCommand {
133142
help: 'Write HTML output to OUTPUT.',
134143
valueHelp: 'OUTPUT',
135144
defaultsTo: 'metrics',
145+
)
146+
..addOption(
147+
FlagNames.jsonReportPath,
148+
help: 'Path to the JSON file with the output of the analysis.',
149+
valueHelp: 'path/to/file.json',
150+
defaultsTo: null,
136151
);
137152
}
138153

lib/src/cli/models/flag_names.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class FlagNames {
2626
static const gitlabCodeClimateReporter = CodeClimateReporter.alternativeId;
2727

2828
static const reportFolder = 'output-directory';
29+
static const jsonReportPath = 'json-path';
2930
static const setExitOnViolationLevel = 'set-exit-on-violation-level';
3031
static const fatalStyle = 'fatal-style';
3132
static const fatalPerformance = 'fatal-performance';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
1+
import 'package:args/args.dart';
2+
3+
import '../../analyzers/lint_analyzer/metrics/metrics_factory.dart';
4+
import 'flag_names.dart';
5+
16
/// Represents the arguments parsed from raw cli arguments.
27
class ParsedArguments {
38
final String excludePath;
9+
final String rootFolder;
10+
final String? jsonReportPath;
411
final Map<String, Object> metricsConfig;
512

613
const ParsedArguments({
714
required this.excludePath,
15+
required this.rootFolder,
816
required this.metricsConfig,
17+
this.jsonReportPath,
918
});
19+
20+
factory ParsedArguments.fromArgs(ArgResults argResults) => ParsedArguments(
21+
excludePath: argResults[FlagNames.exclude] as String,
22+
rootFolder: argResults[FlagNames.rootFolder] as String,
23+
jsonReportPath: argResults[FlagNames.jsonReportPath] as String?,
24+
metricsConfig: {
25+
for (final metric in getMetrics(config: {}))
26+
if (argResults.wasParsed(metric.id))
27+
metric.id: argResults[metric.id] as Object,
28+
},
29+
);
1030
}

test/src/analyzers/lint_analyzer/lint_config_test.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,11 @@ void main() {
139139
group('fromArgs constructs instance from passed', () {
140140
test('empty arguments', () {
141141
final config = LintConfig.fromArgs(
142-
const ParsedArguments(excludePath: '', metricsConfig: {}),
142+
const ParsedArguments(
143+
excludePath: '',
144+
metricsConfig: {},
145+
rootFolder: '',
146+
),
143147
);
144148

145149
expect(config.excludePatterns, isEmpty);
@@ -159,6 +163,7 @@ void main() {
159163
'maximum-nesting-level': '5',
160164
'metric-id4': '0',
161165
},
166+
rootFolder: '',
162167
),
163168
);
164169

test/src/cli/commands/analyze_command_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const _usage = 'Collect code metrics, rules and anti-patterns violations.\n'
1212
' [console (default), console-verbose, checkstyle, codeclimate, github, gitlab, html, json]\n'
1313
'-o, --output-directory=<OUTPUT> Write HTML output to OUTPUT.\n'
1414
' (defaults to "metrics")\n'
15+
' --json-path=<path/to/file.json> Path to the JSON file with the output of the analysis.\n'
1516
'\n'
1617
'\n'
1718
' --cyclomatic-complexity=<20> Cyclomatic Complexity threshold.\n'

website/docs/cli/analyze.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Usage: metrics analyze [arguments...] <directories>
2121
[console (default), console-verbose, checkstyle, codeclimate, github, gitlab, html, json]
2222
-o, --output-directory=<OUTPUT> Write HTML output to OUTPUT
2323
(defaults to "metrics/")
24+
--json-path=<path/to/file.json> Path to the JSON file with the output of the analysis.
2425
2526
2627
--cyclomatic-complexity=<20> Cyclomatic Complexity threshold.

0 commit comments

Comments
 (0)