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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.23.1

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

## 0.23.0

**Breaking changes:**
Expand Down
41 changes: 35 additions & 6 deletions lib/src/analysis_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,18 @@ Future<http.Response> _httpGetWithRetry(Uri uri) async {

const _analyzerErrorKeys = <String>['uri_has_not_been_generated'];

/// Update the well-known [custom] `analysis_options.yaml` content with
/// pass-through options from the package-provided [original] content.
/// Such options are:
/// - the `include:` predicate,
/// - the `formatter:` options (without any filtering),
/// - the `analyzer: / errors:` keys passing through keys
/// from [_analyzerErrorKeys],
/// - the `linter: / rules:` section, passing `true`/`false`
/// values if their key is not present in [custom].
String updatePassthroughOptions({
required String? original,
required String custom,
bool keepInclude = false,
}) {
Map? origMap;
if (original != null) {
Expand Down Expand Up @@ -115,18 +123,39 @@ String updatePassthroughOptions({
}
}

if (origMap case {'linter': {'rules': Map origRules}}) {
final customLinter = customMap.putIfAbsent(
'linter',
() => <String, Object?>{},
);
var customRules = customLinter.putIfAbsent(
'rules',
() => <String, Object?>{},
);
if (customRules is List) {
customRules = Map.fromEntries(customRules.map((e) => MapEntry(e, true)));
customLinter['rules'] = customRules;
}
if (customRules is Map) {
for (var e in origRules.entries) {
if (customRules.containsKey(e.key)) {
continue;
}
customRules[e.key] = e.value;
}
}
}

final origFormatter = origMap['formatter'];
if (origFormatter is Map) {
final customFormatter =
customMap.putIfAbsent('formatter', () => <String, dynamic>{}) as Map;
customFormatter.addAll(origFormatter.cast<String, dynamic>());
}

if (keepInclude) {
final newInclude = customMap['include'] ?? origMap['include'];
if (newInclude != null) {
customMap['include'] = newInclude;
}
final newInclude = customMap['include'] ?? origMap['include'];
if (newInclude != null) {
customMap['include'] = newInclude;
}

return json.encode(customMap);
Expand Down
1 change: 0 additions & 1 deletion lib/src/sdk_env.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ class ToolEnvironment {
final customOptionsContent = updatePassthroughOptions(
original: originalOptions,
custom: rawOptionsContent,
keepInclude: true,
);
try {
await analysisOptionsFile.writeAsString(customOptionsContent);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: pana
description: PAckage aNAlyzer - produce a report summarizing the health and quality of a Dart package.
version: 0.23.0
version: 0.23.1-dev
repository: https://github.com/dart-lang/pana
topics:
- tool
Expand Down
46 changes: 28 additions & 18 deletions test/analysis_options_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,41 @@ formatter:
});
});

test('ignore include in original', () {
test('passthrough linter rules', () {
final content = updatePassthroughOptions(
original: 'include: package:lints/other.yaml',
custom: '',
original: '''
linter:
rules:
avoid_relative_lib_imports: true
prefer_relative_imports: false
public_member_api_docs: false
''',
custom: '''
linter:
rules:
- prefer_relative_imports
''',
);
expect(json.decode(content), <String, Object?>{});
expect(json.decode(content), {
'linter': {
'rules': {
'avoid_relative_lib_imports': true,
'prefer_relative_imports': true,
'public_member_api_docs': false,
},
},
});
});

test('include only in custom: keepInclude=false', () {
test('update include from original', () {
final content = updatePassthroughOptions(
original: '',
custom: 'include: package:lints/other.yaml',
original: 'include: package:lints/other.yaml',
custom: '',
);
expect(json.decode(content), <String, Object?>{
'include': 'package:lints/other.yaml',
});
expect(json.decode(content), {'include': 'package:lints/other.yaml'});
});

test('include only in custom: keepInclude=true', () {
test('include only in custom', () {
final content = updatePassthroughOptions(
original: '',
custom: 'include: package:lints/other.yaml',
Expand All @@ -87,7 +103,6 @@ formatter:
final content = updatePassthroughOptions(
original: 'include: package:lints/other.yaml',
custom: '',
keepInclude: true,
);
expect(json.decode(content), <String, Object?>{
'include': 'package:lints/other.yaml',
Expand All @@ -98,19 +113,14 @@ formatter:
final content = updatePassthroughOptions(
original: 'include: package:lints/other.yaml',
custom: 'include: package:lints/core.yaml',
keepInclude: true,
);
expect(json.decode(content), <String, Object?>{
'include': 'package:lints/core.yaml',
});
});

test('keep include without include value', () {
final content = updatePassthroughOptions(
original: '',
custom: '',
keepInclude: true,
);
final content = updatePassthroughOptions(original: '', custom: '');
expect(json.decode(content), <String, Object?>{});
});
}
Loading