-
Notifications
You must be signed in to change notification settings - Fork 6k
Allow engine variants other than "host_debug" to be clang-tidy linted #29668
Changes from all commits
15a6f9e
78845fd
1bb1424
b04ab6b
6e33389
23d6a03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,15 @@ | ||
| # clang_tidy | ||
|
|
||
| This is a Dart program/library that runs clang_tidy over modified files. It | ||
| takes two mandatory arguments that point at a compile_commands.json command | ||
| and the root of the Flutter engine repo: | ||
| This is a Dart program/library that runs clang_tidy over modified files in the Flutter engine repo. | ||
|
|
||
| By default the linter runs on the repo files changed contained in `src/out/host_debug/compile_commands.json` command. | ||
| To check files other than in `host_debug` use `--target-variant android_debug_unopt`, | ||
| `--target-variant ios_debug_sim_unopt`, etc. | ||
|
|
||
| Alternatively, use `--compile-commands` to specify a path to a `compile_commands.json` file. | ||
|
|
||
| ``` | ||
| $ bin/main.dart --compile-commands <compile_commands.json-path> --repo <path-to-repo> | ||
| $ bin/main.dart --target-variant <engine-variant> | ||
| $ bin/main.dart --compile-commands <compile_commands.json-path> | ||
| $ bin/main.dart --help | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,14 +5,17 @@ | |
| import 'dart:io' as io show Directory, File, Platform, stderr; | ||
|
|
||
| import 'package:args/args.dart'; | ||
| import 'package:path/path.dart' as path; | ||
|
|
||
| // Path to root of the flutter/engine repository containing this script. | ||
| final String _engineRoot = path.dirname(path.dirname(path.dirname(path.dirname(path.fromUri(io.Platform.script))))); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're computing this here, maybe we don't need the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was there any case where
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This pattern is probably safe here since we're always running the script from source, but it would break if the script were compiled to a snapshot and then the snapshot moved somewhere else before being run. We can keep this and get rid of the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If you do that and it doesn't work: Give The Script A Break 🙂
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed |
||
|
|
||
| /// A class for organizing the options to the Engine linter, and the files | ||
| /// that it operates on. | ||
| class Options { | ||
| /// Builds an instance of [Options] from the arguments. | ||
| Options({ | ||
| required this.buildCommandsPath, | ||
| required this.repoPath, | ||
| this.help = false, | ||
| this.verbose = false, | ||
| this.checksArg = '', | ||
|
|
@@ -30,7 +33,6 @@ class Options { | |
| return Options( | ||
| errorMessage: message, | ||
| buildCommandsPath: io.File('none'), | ||
| repoPath: io.Directory('none'), | ||
| errSink: errSink, | ||
| ); | ||
| } | ||
|
|
@@ -41,21 +43,20 @@ class Options { | |
| return Options( | ||
| help: true, | ||
| buildCommandsPath: io.File('none'), | ||
| repoPath: io.Directory('none'), | ||
| errSink: errSink, | ||
| ); | ||
| } | ||
|
|
||
| /// Builds an [Options] instance with an [ArgResults] instance. | ||
| factory Options._fromArgResults( | ||
| ArgResults options, { | ||
| required io.File buildCommandsPath, | ||
| StringSink? errSink, | ||
| }) { | ||
| return Options( | ||
| help: options['help'] as bool, | ||
| verbose: options['verbose'] as bool, | ||
| buildCommandsPath: io.File(options['compile-commands'] as String), | ||
| repoPath: io.Directory(options['repo'] as String), | ||
| buildCommandsPath: buildCommandsPath, | ||
| checksArg: options.wasParsed('checks') ? options['checks'] as String : '', | ||
| lintAll: io.Platform.environment['FLUTTER_LINT_ALL'] != null || | ||
| options['lint-all'] as bool, | ||
|
|
@@ -70,7 +71,17 @@ class Options { | |
| StringSink? errSink, | ||
| }) { | ||
| final ArgResults argResults = _argParser.parse(arguments); | ||
| final String? message = _checkArguments(argResults); | ||
|
|
||
| String? buildCommandsPath = argResults['compile-commands'] as String?; | ||
| // path/to/engine/src/out/variant/compile_commands.json | ||
jmagman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| buildCommandsPath ??= path.join( | ||
| argResults['src-dir'] as String, | ||
| 'out', | ||
| argResults['target-variant'] as String, | ||
| 'compile_commands.json', | ||
| ); | ||
| final io.File buildCommands = io.File(buildCommandsPath); | ||
| final String? message = _checkArguments(argResults, buildCommands); | ||
| if (message != null) { | ||
| return Options._error(message, errSink: errSink); | ||
| } | ||
|
|
@@ -79,14 +90,17 @@ class Options { | |
| } | ||
| return Options._fromArgResults( | ||
| argResults, | ||
| buildCommandsPath: buildCommands, | ||
| errSink: errSink, | ||
| ); | ||
| } | ||
|
|
||
| static final ArgParser _argParser = ArgParser() | ||
| ..addFlag( | ||
| 'help', | ||
| abbr: 'h', | ||
| help: 'Print help.', | ||
| negatable: false, | ||
| ) | ||
| ..addFlag( | ||
| 'lint-all', | ||
|
|
@@ -103,14 +117,25 @@ class Options { | |
| help: 'Print verbose output.', | ||
| defaultsTo: false, | ||
| ) | ||
| ..addOption( | ||
| 'repo', | ||
| help: 'Use the given path as the repo path', | ||
| ) | ||
| ..addOption( | ||
| 'compile-commands', | ||
| help: 'Use the given path as the source of compile_commands.json. This ' | ||
| 'file is created by running tools/gn', | ||
| 'file is created by running "tools/gn". Cannot be used with --target-variant ' | ||
| 'or --src-dir.', | ||
| ) | ||
| ..addOption( | ||
| 'target-variant', | ||
| aliases: <String>['variant'], | ||
| help: 'The engine variant directory containing compile_commands.json ' | ||
| 'created by running "tools/gn". Cannot be used with --compile-commands.', | ||
| valueHelp: 'host_debug|android_debug_unopt|ios_debug|ios_debug_sim_unopt', | ||
| defaultsTo: 'host_debug', | ||
| ) | ||
| ..addOption( | ||
| 'src-dir', | ||
| help: 'Path to the engine src directory. Cannot be used with --compile-commands.', | ||
| valueHelp: 'path/to/engine/src', | ||
| defaultsTo: path.dirname(_engineRoot), | ||
| ) | ||
| ..addOption( | ||
| 'checks', | ||
|
|
@@ -129,7 +154,7 @@ class Options { | |
| final io.File buildCommandsPath; | ||
|
|
||
| /// The root of the flutter/engine repository. | ||
| final io.Directory repoPath; | ||
| final io.Directory repoPath = io.Directory(_engineRoot); | ||
|
|
||
| /// Arguments to plumb through to clang-tidy formatted as a command line | ||
| /// argument. | ||
|
|
@@ -156,35 +181,30 @@ class Options { | |
| _errSink.writeln(message); | ||
| } | ||
| _errSink.writeln( | ||
| 'Usage: bin/main.dart [--help] [--lint-all] [--fix] [--verbose] [--diff-branch]', | ||
| 'Usage: bin/main.dart [--help] [--lint-all] [--fix] [--verbose] [--diff-branch] [--target-variant variant] [--src-dir path/to/engine/src]', | ||
| ); | ||
| _errSink.writeln(_argParser.usage); | ||
| } | ||
|
|
||
| /// Command line argument validation. | ||
| static String? _checkArguments(ArgResults argResults) { | ||
| static String? _checkArguments(ArgResults argResults, io.File buildCommandsPath) { | ||
| if (argResults.wasParsed('help')) { | ||
| return null; | ||
| } | ||
|
|
||
| if (!argResults.wasParsed('compile-commands')) { | ||
| return 'ERROR: The --compile-commands argument is required.'; | ||
| final bool compileCommandsParsed = argResults.wasParsed('compile-commands'); | ||
| if (compileCommandsParsed && argResults.wasParsed('target-variant')) { | ||
| return 'ERROR: --compile-commands option cannot be used with --target-variant.'; | ||
| } | ||
|
|
||
| if (!argResults.wasParsed('repo')) { | ||
| return 'ERROR: The --repo argument is required.'; | ||
| if (compileCommandsParsed && argResults.wasParsed('src-dir')) { | ||
| return 'ERROR: --compile-commands option cannot be used with --src-dir.'; | ||
| } | ||
|
|
||
| final io.File buildCommandsPath = io.File(argResults['compile-commands'] as String); | ||
| if (!buildCommandsPath.existsSync()) { | ||
| return "ERROR: Build commands path ${buildCommandsPath.absolute.path} doesn't exist."; | ||
| } | ||
|
|
||
| final io.Directory repoPath = io.Directory(argResults['repo'] as String); | ||
| if (!repoPath.existsSync()) { | ||
| return "ERROR: Repo path ${repoPath.absolute.path} doesn't exist."; | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to remove this block. It was only showing the first file linter errors because a linter failure makes the process fail, which populates the
job.exception, andbreaks so doesn't show the other job failures.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch