-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow checking for deprecated rules (#131)
* feat: define LinterRule model * feat: define inspect script * docs: update all linter rule doc * feat: allow version argument * feat: specify "Dart" in log * docs: document the inspect script * docs: use "run" over "inspect" * refactor: barrel file * dos: update see also * ci: update Dart version
- Loading branch information
Showing
10 changed files
with
3,785 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
/// Very Good Dart analyzer settings and best practices | ||
/// used internally at [Very Good Ventures](https://verygood.ventures). | ||
library very_good_analysis; | ||
library; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:http/http.dart'; | ||
import 'package:linter_rules/linter_rules.dart'; | ||
|
||
/// The [Uri] to fetch all linter rules from. | ||
final _allLinterRulesUri = Uri.parse( | ||
'https://raw.githubusercontent.com/dart-lang/site-www/refs/heads/main/src/_data/linter_rules.json', | ||
); | ||
|
||
/// Compares Very Good Analysis with the all available Dart linter rules. | ||
/// | ||
/// Should be run from the root of the `linter_rules` package (tool/linter_rules), | ||
/// with the version of the Very Good Analysis to inspect. | ||
/// | ||
/// The version argument should be in the format of `x.y.z`. For example, | ||
/// `5.1.0`. | ||
/// | ||
/// To use the tool run (from tool/linter_rules): | ||
/// ```sh | ||
/// dart bin/inspect.dart $version | ||
/// ``` | ||
/// | ||
/// Where `$version` is the version of the Very Good Analysis to log the table | ||
/// for. For example: | ||
/// | ||
/// ```sh | ||
/// dart bin/inspect.dart 5.1.0 | ||
/// ``` | ||
/// | ||
/// It will log information about: | ||
/// - The number of Dart linter rules fetched. | ||
/// - The number of rules being declared in the given Very Good Analysis | ||
/// with the given version. | ||
/// - The number of deprecated rules Dart rules being used in Very Good | ||
/// Analysis with the given version. | ||
Future<void> main( | ||
List<String> args, { | ||
void Function(String) log = print, | ||
}) async { | ||
final version = args[0]; | ||
|
||
final response = await get(_allLinterRulesUri); | ||
final json = jsonDecode(response.body) as List<dynamic>; | ||
|
||
final dartRules = json | ||
.map( | ||
(rule) => LinterRule.fromJson(rule as Map<String, dynamic>), | ||
) | ||
.toList(); | ||
log('Fetched ${dartRules.length} Dart linter rules'); | ||
|
||
final vgaRules = await allVeryGoodAnalysisRules(version: version); | ||
log('Fetched ${vgaRules.length} Very Good Analysis rules'); | ||
log(''); | ||
|
||
final deprecatedDartRules = dartRules | ||
.where((rule) => rule.state == LinterRuleState.deprecated) | ||
.map((rule) => rule.name) | ||
.toSet(); | ||
final deprecatedVgaRules = | ||
vgaRules.where(deprecatedDartRules.contains).toList(); | ||
final deprecationMessage = StringBuffer( | ||
'''Found ${deprecatedVgaRules.length} deprecated Dart rules (out of ${deprecatedDartRules.length} deprecated Dart rules) in Very Good Analysis ($version)${deprecatedVgaRules.isEmpty ? '.' : ':'}''', | ||
); | ||
for (final rule in deprecatedVgaRules) { | ||
deprecationMessage.write('\n - $rule'); | ||
} | ||
log(deprecationMessage.toString()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import 'package:meta/meta.dart'; | ||
|
||
/// {@template LinterRuleState} | ||
/// The state of a [LinterRule] describing its present state within the Dart | ||
/// language. | ||
/// {@endtemplate} | ||
enum LinterRuleState { | ||
/// The rule is stable. | ||
stable, | ||
|
||
/// The rule has been removed from the Dart language. | ||
removed, | ||
|
||
/// The rule is currently experimental within the Dart language. | ||
experimental, | ||
|
||
/// The rule is deprecated and should not be used. | ||
deprecated; | ||
|
||
/// Converts a [String] value to a [LinterRuleState]. | ||
static LinterRuleState _fromJson(String value) { | ||
switch (value) { | ||
case 'stable': | ||
return LinterRuleState.stable; | ||
case 'removed': | ||
return LinterRuleState.removed; | ||
case 'experimental': | ||
return LinterRuleState.experimental; | ||
case 'deprecated': | ||
return LinterRuleState.deprecated; | ||
default: | ||
throw ArgumentError('Invalid value for LinterRuleState: $value'); | ||
} | ||
} | ||
} | ||
|
||
/// {@template FixStatus} | ||
/// Wether there is an automated fix available for the rule. | ||
/// {@endtemplate} | ||
enum FixStatus { | ||
/// The rule has an automated fix available. | ||
hasFix, | ||
|
||
/// The rule has no automated fix available. | ||
noFix, | ||
|
||
/// The rule can have an automated fix available, but is yet to be | ||
/// implemented. | ||
needsFix, | ||
|
||
/// The automated fix for the rule needs evaluation. | ||
needsEvaluation; | ||
|
||
/// Converts a [String] value to a [FixStatus]. | ||
static FixStatus _fromJson(String value) { | ||
switch (value) { | ||
case 'hasFix': | ||
return FixStatus.hasFix; | ||
case 'noFix': | ||
return FixStatus.noFix; | ||
case 'needsFix': | ||
return FixStatus.needsFix; | ||
case 'needsEvaluation': | ||
return FixStatus.needsEvaluation; | ||
default: | ||
throw ArgumentError('Invalid value for FixStatus: $value'); | ||
} | ||
} | ||
} | ||
|
||
/// {@template LinterRule} | ||
/// A linter rule within the Dart language. | ||
/// | ||
/// See also: | ||
/// | ||
/// * [Available linter rules](https://raw.githubusercontent.com/dart-lang/sdk/main/pkg/linter/tool/machine/rules.json) | ||
/// * [All linter rules](https://github.com/dart-lang/site-www/blob/main/src/_data/linter_rules.json) | ||
/// {@endtemplate} | ||
@immutable | ||
class LinterRule { | ||
/// {@macro LinterRule} | ||
const LinterRule({ | ||
required this.name, | ||
required this.description, | ||
required this.details, | ||
required this.categories, | ||
required this.state, | ||
required this.incompatible, | ||
required this.sets, | ||
required this.fixStatus, | ||
required this.sinceDartSdk, | ||
}); | ||
|
||
/// Converts JSON to a [LinterRule]. | ||
factory LinterRule.fromJson(Map<String, dynamic> json) { | ||
return LinterRule( | ||
name: json['name'] as String, | ||
description: json['description'] as String, | ||
details: json['details'] as String, | ||
categories: (json['categories'] as List).cast<String>(), | ||
state: LinterRuleState._fromJson(json['state'] as String), | ||
incompatible: (json['incompatible'] as List).cast<String>(), | ||
sets: (json['sets'] as List).cast<String>(), | ||
fixStatus: FixStatus._fromJson(json['fixStatus'] as String), | ||
sinceDartSdk: json['sinceDartSdk'] as String, | ||
); | ||
} | ||
|
||
/// The unique name of the linter rule. | ||
final String name; | ||
|
||
/// A brief description of the linter rule explaining what it does. | ||
final String description; | ||
|
||
/// A detailed explanation of the linter rule. | ||
final String details; | ||
|
||
/// Categories that the rule falls into. | ||
/// | ||
/// Examples include `style`, `errorProne`, `flutter`. | ||
final List<String> categories; | ||
|
||
/// {@macro LinterRuleState} | ||
final LinterRuleState state; | ||
|
||
/// Rules that are incompatible with this rule. | ||
final List<String> incompatible; | ||
|
||
/// The sets this rule belongs to. | ||
/// | ||
/// Examples include `core`, `recommended`, `flutter`. | ||
final List<String> sets; | ||
|
||
/// {@macro FixStatus} | ||
final FixStatus fixStatus; | ||
|
||
/// The Dart SDK version when the rule was introduced. | ||
final String sinceDartSdk; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export 'linter_rule.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.