-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[camera_android_camerax][tool] Integrate dart_code_linter for cyclomatic complexity checks #11999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
14be833
f206376
0299ea1
30757fa
fc676e2
e82d111
5e798fe
8b336a2
2f96c6b
84abbf0
eb76af7
d93d538
dd58a0d
214f051
71559a9
24d9e8a
ea9770a
e9bdaeb
342eab8
64a8a90
db7e807
f745d82
d14f6e1
002182d
c1247d4
b934bf8
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 |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| include: ../../../analysis_options.yaml | ||
|
|
||
| analyzer: | ||
| exclude: | ||
| - build/** | ||
| - android/** | ||
| - ios/** | ||
| - web/** | ||
| - windows/** | ||
| - macos/** | ||
| - linux/** | ||
|
|
||
| dart_code_linter: | ||
| metrics: | ||
| cyclomatic-complexity: 15 | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| import 'dart:io' as io; | ||
|
|
||
| import 'package:file/file.dart'; | ||
| import 'package:yaml/yaml.dart'; | ||
|
|
||
| import 'common/core.dart'; | ||
| import 'common/file_filters.dart'; | ||
|
|
@@ -330,10 +331,75 @@ class AnalyzeCommand extends PackageLoopingCommand { | |
| ...skillsErrors, | ||
| ]; | ||
|
|
||
| if (errors.isNotEmpty) { | ||
| return PackageResult.fail(errors); | ||
| final customCheckRunners = <_CustomLinter>[ | ||
|
Contributor
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. Don't think we need this since we're only adding one linter at the moment
Contributor
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. I am expecting we will expand this list. I would like to keep the functionality for now. |
||
| _CustomLinter(dependencyName: 'dart_code_linter', run: _runDartCodeLinterForPackage), | ||
| ]; | ||
|
|
||
| // Skip custom linters during downgrade as metrics are redundant and vulnerable to dependency issues. | ||
| if (!getBoolArg(_downgradeFlag)) { | ||
| final Pubspec pubspec = package.parsePubspec(); | ||
| for (final runner in customCheckRunners) { | ||
| final bool hasDependency = pubspec.devDependencies.containsKey(runner.dependencyName); | ||
| if (hasDependency) { | ||
| errors.addAll(await runner.run(package)); | ||
| } | ||
| } | ||
| } | ||
| return PackageResult.success(); | ||
|
|
||
| return errors.isEmpty ? PackageResult.success() : PackageResult.fail(errors); | ||
| } | ||
|
|
||
| /// Retrieves the configured cyclomatic complexity threshold from the local | ||
| /// `analysis_options.yaml` if it exists and is configured. | ||
| int? _getLinterThreshold(RepositoryPackage package) { | ||
| final File optionsFile = package.directory.childFile('analysis_options.yaml'); | ||
| if (!optionsFile.existsSync()) { | ||
| return null; | ||
| } | ||
| try { | ||
| final Object? yaml = loadYaml(optionsFile.readAsStringSync()); | ||
| if (yaml is YamlMap) { | ||
| final Object? linter = yaml['dart_code_linter']; | ||
| if (linter is YamlMap) { | ||
| final Object? metrics = linter['metrics']; | ||
| if (metrics is YamlMap) { | ||
| final Object? complexity = metrics['cyclomatic-complexity']; | ||
| if (complexity is int) { | ||
| return complexity; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } catch (_) { | ||
| // Ignore errors parsing invalid/incomplete files. | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /// Runs the `dart_code_linter` metrics analyzer on the package. | ||
| /// | ||
| /// Assumes `dart_code_linter` is present in `dev_dependencies`. | ||
| Future<List<String>> _runDartCodeLinterForPackage(RepositoryPackage package) async { | ||
| if (!package.libDirectory.existsSync()) { | ||
| return <String>[]; | ||
| } | ||
| print('Running dart_code_linter:metrics analysis...'); | ||
| final int linterExitCode = await processRunner.runAndStream(_dartBinaryPath, <String>[ | ||
| 'run', | ||
| 'dart_code_linter:metrics', | ||
| 'analyze', | ||
| 'lib', | ||
| '--set-exit-on-violation-level=warning', | ||
| ], workingDir: package.directory); | ||
| if (linterExitCode != 0) { | ||
| final int? threshold = _getLinterThreshold(package); | ||
| final thresholdMessage = threshold != null ? ' (configured threshold: $threshold)' : ''; | ||
| return <String>[ | ||
| 'Metrics violations found$thresholdMessage. See the package\'s local "analysis_options.yaml" for configured thresholds.', | ||
| ]; | ||
| } | ||
|
|
||
| return <String>[]; | ||
| } | ||
|
|
||
| /// Validates that `.agents/skills` contains Dart code if configured for skills analysis. | ||
|
|
@@ -485,3 +551,17 @@ class AnalyzeCommand extends PackageLoopingCommand { | |
| return errors.isEmpty ? PackageResult.success() : PackageResult.fail(errors); | ||
| } | ||
| } | ||
|
|
||
| /// Represents a custom linter check that is executed during package analysis. | ||
| class _CustomLinter { | ||
| const _CustomLinter({required this.dependencyName, required this.run}); | ||
|
|
||
| /// The name of the package dependency that triggers this custom check. | ||
| /// | ||
| /// The check is only executed if this dependency is listed in the package's | ||
| /// `dev_dependencies`. | ||
| final String dependencyName; | ||
|
|
||
| /// The runner function that executes the custom check. | ||
| final Future<List<String>> Function(RepositoryPackage) run; | ||
| } | ||
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.
You've audited this as safe to run in our CI and locally?
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.
SHA1 (dart_code_linter-4.1.5.tar.gz) = 86fa1bd240a88c98a4c45f0beb43b4e7adb32735
For auditability this this is the artifact I inspected.
Looking at the code I didn't see anything suspicious.
Some things I found but I do not think are blocking:
It uses https://pub.dev/packages/pub_updater to see if there is a newer version. It works without internet access.
There is a python script to make cursor skills. It is for contributors but I found that interesting.
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.
As concrete examples of suspicious things I looked for. Code that tried to spawn other process, code that tried to install other things, network calls, code that read env variables that looked like secrets.