diff --git a/CHANGELOG.md b/CHANGELOG.md index 38225f2a..f8ff63a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.23.1 + +- Support passthrough of unrelated linter rules in analysis option customization. + ## 0.23.0 **Breaking changes:** diff --git a/lib/src/analysis_options.dart b/lib/src/analysis_options.dart index dbb5c7c6..d8c51d48 100644 --- a/lib/src/analysis_options.dart +++ b/lib/src/analysis_options.dart @@ -71,10 +71,18 @@ Future _httpGetWithRetry(Uri uri) async { const _analyzerErrorKeys = ['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) { @@ -115,6 +123,29 @@ String updatePassthroughOptions({ } } + if (origMap case {'linter': {'rules': Map origRules}}) { + final customLinter = customMap.putIfAbsent( + 'linter', + () => {}, + ); + var customRules = customLinter.putIfAbsent( + 'rules', + () => {}, + ); + 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 = @@ -122,11 +153,9 @@ String updatePassthroughOptions({ customFormatter.addAll(origFormatter.cast()); } - 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); diff --git a/lib/src/sdk_env.dart b/lib/src/sdk_env.dart index 8b705b47..eb22f83e 100644 --- a/lib/src/sdk_env.dart +++ b/lib/src/sdk_env.dart @@ -216,7 +216,6 @@ class ToolEnvironment { final customOptionsContent = updatePassthroughOptions( original: originalOptions, custom: rawOptionsContent, - keepInclude: true, ); try { await analysisOptionsFile.writeAsString(customOptionsContent); diff --git a/lib/src/version.dart b/lib/src/version.dart index e54650ea..6aac02f7 100644 --- a/lib/src/version.dart +++ b/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '0.23.0'; +const packageVersion = '0.23.1-dev'; diff --git a/pubspec.yaml b/pubspec.yaml index 3a9e947e..33f77045 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 diff --git a/test/analysis_options_test.dart b/test/analysis_options_test.dart index aaf768ee..292e80b0 100644 --- a/test/analysis_options_test.dart +++ b/test/analysis_options_test.dart @@ -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), {}); + 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), { - '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', @@ -87,7 +103,6 @@ formatter: final content = updatePassthroughOptions( original: 'include: package:lints/other.yaml', custom: '', - keepInclude: true, ); expect(json.decode(content), { 'include': 'package:lints/other.yaml', @@ -98,7 +113,6 @@ formatter: final content = updatePassthroughOptions( original: 'include: package:lints/other.yaml', custom: 'include: package:lints/core.yaml', - keepInclude: true, ); expect(json.decode(content), { 'include': 'package:lints/core.yaml', @@ -106,11 +120,7 @@ formatter: }); test('keep include without include value', () { - final content = updatePassthroughOptions( - original: '', - custom: '', - keepInclude: true, - ); + final content = updatePassthroughOptions(original: '', custom: ''); expect(json.decode(content), {}); }); }