diff --git a/tools/clang_tidy/lib/clang_tidy.dart b/tools/clang_tidy/lib/clang_tidy.dart index 67599166046b9..1c9a517733ee5 100644 --- a/tools/clang_tidy/lib/clang_tidy.dart +++ b/tools/clang_tidy/lib/clang_tidy.dart @@ -48,6 +48,7 @@ class ClangTidy { required io.Directory repoPath, String checksArg = '', bool lintAll = false, + bool fix = false, StringSink? outSink, StringSink? errSink, }) : @@ -56,6 +57,7 @@ class ClangTidy { repoPath: repoPath, checksArg: checksArg, lintAll: lintAll, + fix: fix, errSink: errSink, ), _outSink = outSink ?? io.stdout, @@ -207,7 +209,7 @@ class ClangTidy { break; case LintAction.lint: _outSink.writeln('🔶 linting $relativePath'); - jobs.add(command.createLintJob(checks)); + jobs.add(command.createLintJob(checks, options.fix)); break; case LintAction.skipThirdParty: _outSink.writeln('🔷 ignoring $relativePath (third_party)'); diff --git a/tools/clang_tidy/lib/src/command.dart b/tools/clang_tidy/lib/src/command.dart index d2566ee769754..7a1d6df8fc234 100644 --- a/tools/clang_tidy/lib/src/command.dart +++ b/tools/clang_tidy/lib/src/command.dart @@ -129,11 +129,13 @@ class Command { } /// The job for the process runner for the lint needed for this command. - WorkerJob createLintJob(String? checks) { + WorkerJob createLintJob(String? checks, bool fix) { final List args = [ filePath, if (checks != null) checks, + if (fix) + '--fix', '--', ]; args.addAll(tidyArgs.split(' ')); diff --git a/tools/clang_tidy/lib/src/options.dart b/tools/clang_tidy/lib/src/options.dart index 9efa28da3703d..35862849431a0 100644 --- a/tools/clang_tidy/lib/src/options.dart +++ b/tools/clang_tidy/lib/src/options.dart @@ -17,6 +17,7 @@ class Options { this.verbose = false, this.checksArg = '', this.lintAll = false, + this.fix = false, this.errorMessage, StringSink? errSink, }) : checks = checksArg.isNotEmpty ? '--checks=$checksArg' : null, @@ -58,6 +59,7 @@ class Options { checksArg: options.wasParsed('checks') ? options['checks'] as String : '', lintAll: io.Platform.environment['FLUTTER_LINT_ALL'] != null || options['lint-all'] as bool, + fix: options['fix'] as bool, errSink: errSink, ); } @@ -91,6 +93,11 @@ class Options { help: 'lint all of the sources, regardless of FLUTTER_NOLINT.', defaultsTo: false, ) + ..addFlag( + 'fix', + help: 'Apply suggested fixes.', + defaultsTo: false, + ) ..addFlag( 'verbose', help: 'Print verbose output.', @@ -134,6 +141,9 @@ class Options { /// Whether all files should be linted. final bool lintAll; + /// Whether checks should apply available fix-ups to the working copy. + final bool fix; + /// If there was a problem with the command line arguments, this string /// contains the error message. final String? errorMessage; @@ -146,7 +156,7 @@ class Options { _errSink.writeln(message); } _errSink.writeln( - 'Usage: bin/main.dart [--help] [--lint-all] [--verbose] [--diff-branch]', + 'Usage: bin/main.dart [--help] [--lint-all] [--fix] [--verbose] [--diff-branch]', ); _errSink.writeln(_argParser.usage); } diff --git a/tools/clang_tidy/test/clang_tidy_test.dart b/tools/clang_tidy/test/clang_tidy_test.dart index 4656f33926e98..cfde20873660f 100644 --- a/tools/clang_tidy/test/clang_tidy_test.dart +++ b/tools/clang_tidy/test/clang_tidy_test.dart @@ -204,14 +204,24 @@ Future main(List args) async { expect(commands, isNotEmpty); final Command command = commands.first; expect(command.tidyPath, contains('clang/bin/clang-tidy')); - final WorkerJob job = command.createLintJob(null); - expect(job.command, [ + final WorkerJob jobNoFix = command.createLintJob(null, false); + expect(jobNoFix.command, [ '../../buildtools/mac-x64/clang/bin/clang-tidy', filePath, '--', '', filePath, ]); + + final WorkerJob jobWithFix = command.createLintJob(null, true); + expect(jobWithFix.command, [ + '../../buildtools/mac-x64/clang/bin/clang-tidy', + filePath, + '--fix', + '--', + '', + filePath, + ]); }); test('Command getLintAction flags third_party files', () async {