Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 0.23.1

- Support passthrough of unrelated linter rules in analysis option customization.
- Support passthrough of unrelated analyzer errors in analysis option customization.

## 0.23.0

Expand Down
38 changes: 27 additions & 11 deletions lib/src/analysis_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ const _analyzerErrorKeys = <String>['uri_has_not_been_generated'];
/// Such options are:
/// - the `include:` predicate,
/// - the `formatter:` options (without any filtering),
/// - the `analyzer: / errors:` keys passing through keys
/// from [_analyzerErrorKeys],
/// - the `analyzer: / errors:` keys passing the values if
/// their key is not present in [custom] or are in [_analyzerErrorKeys],
/// - the `linter: / rules:` section, passing `true`/`false`
/// values if their key is not present in [custom].
String updatePassthroughOptions({
Expand All @@ -93,21 +93,23 @@ String updatePassthroughOptions({
origMap ??= {};

final customMap =
json.decode(json.encode(yaml.loadYaml(custom))) ?? <String, dynamic>{};
(json.decode(json.encode(yaml.loadYaml(custom))) as Map?) ??
<String, dynamic>{};

final origAnalyzer = origMap['analyzer'];
if (origAnalyzer is Map) {
final origErrors = origAnalyzer['errors'];
if (origErrors is Map) {
final appliedCustomRules = _extractAppliedRules(customMap);

if (origMap case {'analyzer': Map origAnalyzer}) {
if (origAnalyzer case {'errors': Map origErrors}) {
final customAnalyzer =
customMap.putIfAbsent('analyzer', () => <String, Object?>{}) as Map;
final customErrors =
customAnalyzer.putIfAbsent('errors', () => <String, Object?>{})
as Map;

for (var key in _analyzerErrorKeys) {
if (origErrors.containsKey(key)) {
customErrors[key] = origErrors[key];
for (var entry in origErrors.entries) {
if (_analyzerErrorKeys.contains(entry.key) ||
!appliedCustomRules.contains(entry.key)) {
customErrors[entry.key] = entry.value;
}
}
}
Expand Down Expand Up @@ -138,7 +140,7 @@ String updatePassthroughOptions({
}
if (customRules is Map) {
for (var e in origRules.entries) {
if (customRules.containsKey(e.key)) {
if (appliedCustomRules.contains(e.key)) {
continue;
}
customRules[e.key] = e.value;
Expand All @@ -160,3 +162,17 @@ String updatePassthroughOptions({

return json.encode(customMap);
}

Set<String> _extractAppliedRules(Map map) {
final appliedRules = <String>{};
if (map case {'linter': {'rules': List rules}}) {
appliedRules.addAll(rules.map((e) => e.toString()));
}
if (map case {'linter': {'rules': Map rules}}) {
appliedRules.addAll(rules.keys.map((e) => e.toString()));
}
if (map case {'analyzer': {'errors': Map errors}}) {
appliedRules.addAll(errors.keys.map((e) => e.toString()));
}
return appliedRules;
}
33 changes: 30 additions & 3 deletions test/analysis_options_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void main() {
expect(json.decode(content), <String, Object?>{});
});

test('passthrough for some options', () {
test('passthrough for most options', () {
final content = updatePassthroughOptions(
original: '''
analyzer:
Expand All @@ -44,7 +44,7 @@ formatter:
);
expect(json.decode(content), {
'analyzer': {
'errors': {'uri_has_not_been_generated': 'ignore'},
'errors': {'todo': 'ignore', 'uri_has_not_been_generated': 'ignore'},
'enable-experiment': ['macros'],
},
'formatter': {
Expand All @@ -55,7 +55,34 @@ formatter:
});
});

test('passthrough linter rules', () {
test('passthrough analysis errors except one', () {
final content = updatePassthroughOptions(
original: '''
analyzer:
errors:
todo: ignore
another-todo: ignore
uri_has_not_been_generated: ignore
''',
custom: '''
linter:
rules:
- todo
- uri_has_not_been_generated
''',
);
expect(json.decode(content), {
'analyzer': {
'errors': {
'another-todo': 'ignore',
'uri_has_not_been_generated': 'ignore',
},
},
'linter': isNotEmpty,
});
});

test('passthrough linter rules except one', () {
final content = updatePassthroughOptions(
original: '''
linter:
Expand Down