7320da0d19
Work towards https://github.com/dart-lang/sdk/issues/53578 Change-Id: Ia07d999abc2fcf4b8195c9f7688799bc099a1d88 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341385 Reviewed-by: Phil Quitslund <pquitslund@google.com> Reviewed-by: Alexander Thomas <athom@google.com> Reviewed-by: Jonas Termansen <sortie@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
144 lines
4.2 KiB
Dart
144 lines
4.2 KiB
Dart
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:analyzer/src/lint/registry.dart';
|
|
import 'package:analyzer/src/lint/state.dart';
|
|
import 'package:args/args.dart';
|
|
import 'package:linter/src/analyzer.dart';
|
|
import 'package:linter/src/rules.dart';
|
|
import 'package:linter/src/utils.dart';
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
import '../tool/util/path_utils.dart';
|
|
import 'since.dart';
|
|
import 'util/score_utils.dart' as score_utils;
|
|
|
|
/// Generates a list of lint rules in machine format suitable for consumption by
|
|
/// other tools.
|
|
void main(List<String> args) async {
|
|
var parser = ArgParser()
|
|
..addFlag('write', abbr: 'w', help: 'Write `rules.json` file.')
|
|
..addFlag('pretty',
|
|
abbr: 'p', help: 'Pretty-print output.', defaultsTo: true)
|
|
..addFlag('sets', abbr: 's', help: 'Include rule sets', defaultsTo: true);
|
|
var options = parser.parse(args);
|
|
|
|
var json = await generateRulesJson(
|
|
pretty: options['pretty'] == true,
|
|
includeSetInfo: options['sets'] == true);
|
|
|
|
if (options['write'] == true) {
|
|
var outFile = machineJsonFile();
|
|
printToConsole('Writing to ${outFile.path}');
|
|
outFile.writeAsStringSync(json);
|
|
} else {
|
|
printToConsole(json);
|
|
}
|
|
}
|
|
|
|
Future<String> generateRulesJson({
|
|
bool pretty = true,
|
|
bool includeSetInfo = true,
|
|
}) async {
|
|
registerLintRules();
|
|
var fixStatusMap = readFixStatusMap();
|
|
return await getMachineListing(Registry.ruleRegistry,
|
|
fixStatusMap: fixStatusMap, sinceInfo: sinceMap, pretty: pretty);
|
|
}
|
|
|
|
Future<String> getMachineListing(
|
|
Iterable<LintRule> ruleRegistry, {
|
|
Map<String, String>? fixStatusMap,
|
|
bool pretty = true,
|
|
bool includeSetInfo = true,
|
|
Map<String, SinceInfo>? sinceInfo,
|
|
}) async {
|
|
var rules = List<LintRule>.of(ruleRegistry, growable: false)..sort();
|
|
var encoder = pretty ? JsonEncoder.withIndent(' ') : JsonEncoder();
|
|
fixStatusMap ??= {};
|
|
|
|
var (
|
|
coreRules: coreRules,
|
|
recommendedRules: recommendedRules,
|
|
flutterRules: flutterRules
|
|
) = await _fetchSetRules(fetch: includeSetInfo);
|
|
|
|
var json = encoder.convert([
|
|
for (var rule in rules.where((rule) => !rule.state.isInternal))
|
|
{
|
|
'name': rule.name,
|
|
'description': rule.description,
|
|
'group': rule.group.name,
|
|
'state': rule.state.label,
|
|
'incompatible': rule.incompatibleRules,
|
|
'sets': [
|
|
if (coreRules.contains(rule.name)) 'core',
|
|
if (recommendedRules.contains(rule.name)) 'recommended',
|
|
if (flutterRules.contains(rule.name)) 'flutter',
|
|
],
|
|
'fixStatus': fixStatusMap[rule.name] ?? 'unregistered',
|
|
'details': rule.details,
|
|
if (sinceInfo != null)
|
|
'sinceDartSdk': sinceInfo[rule.name]?.sinceDartSdk ?? 'Unreleased',
|
|
}
|
|
]);
|
|
return json;
|
|
}
|
|
|
|
File machineJsonFile() {
|
|
var outPath = pathRelativeToPackageRoot(['tool', 'machine', 'rules.json']);
|
|
return File(outPath);
|
|
}
|
|
|
|
Map<String, String> readFixStatusMap() {
|
|
var statusFilePath = pathRelativeToPkgDir([
|
|
'analysis_server',
|
|
'lib',
|
|
'src',
|
|
'services',
|
|
'correction',
|
|
'error_fix_status.yaml'
|
|
]);
|
|
var contents = File(statusFilePath).readAsStringSync();
|
|
|
|
var yaml = loadYamlNode(contents) as YamlMap;
|
|
var fixStatusMap = <String, String>{};
|
|
for (var entry in yaml.entries) {
|
|
var code = entry.key as String;
|
|
if (code.startsWith('LintCode.')) {
|
|
fixStatusMap[code.substring(9)] =
|
|
(entry.value as YamlMap)['status'] as String;
|
|
}
|
|
}
|
|
return fixStatusMap;
|
|
}
|
|
|
|
Future<
|
|
({
|
|
Set<String> coreRules,
|
|
Set<String> recommendedRules,
|
|
Set<String> flutterRules,
|
|
})> _fetchSetRules({bool fetch = true}) async {
|
|
if (!fetch) {
|
|
return const (
|
|
coreRules: <String>{},
|
|
recommendedRules: <String>{},
|
|
flutterRules: <String>{},
|
|
);
|
|
}
|
|
|
|
var coreRules = {...await score_utils.coreRules};
|
|
var recommendedRules = {...coreRules, ...await score_utils.recommendedRules};
|
|
var flutterRules = {...recommendedRules, ...await score_utils.flutterRules};
|
|
|
|
return (
|
|
coreRules: coreRules,
|
|
recommendedRules: recommendedRules,
|
|
flutterRules: flutterRules,
|
|
);
|
|
}
|