Skip to content

Commit

Permalink
feat: include bot to update when exclusion table needs changes (#132)
Browse files Browse the repository at this point in the history
* feat: include bot to update when exclusion table needs changes

* revert: exclusion reasons

* revert: format on save
  • Loading branch information
alestiago authored Jan 2, 2025
1 parent 2a80995 commit 7c9292c
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 12 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/bot_update_exclusions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: bot_update_exclusions

on:
# This should ideally trigger whenever there is a commit to the [Dart Linter rules](https://raw.githubusercontent.com/dart-lang/sdk/main/pkg/linter/tool/machine/rules.json).
# However, this is not yet possible see: https://github.com/orgs/community/discussions/26323
schedule:
# At 08:06 on every day-of-week from Monday through Friday.
- cron: "6 8 * * 1-5"
workflow_dispatch:

jobs:
build:
defaults:
run:
working-directory: tool/linter_rules

runs-on: ubuntu-latest

steps:
- name: 📚 Git Checkout
uses: actions/checkout@v4

- name: 🎯 Setup Dart
uses: dart-lang/setup-dart@v1

- name: 📦 Install Dependencies
run: dart pub get

- name: 🔍 Check for changes
id: make
run: if dart lib/exclusion_reason_table.dart --set-exit-if-changed; then echo "did_change=false"; else echo "did_change=true"; fi >> $GITHUB_ENV

- name: 🔑 Config Git User
if: ${{ env.did_change == 'true' }}
run: |
git config user.name VGV Bot
git config user.email [email protected]
- name: ✍️ Make changes
if: ${{ env.did_change == 'true' }}
run: dart lib/exclusion_reason_table.dart

- name: 📝 Create Pull Request
if: ${{ env.did_change == 'true' }}
uses: peter-evans/[email protected]
with:
base: main
branch: chore/update-spdx-license
commit-message: "docs: update exclusion table"
title: "docs: update exclusion table"
body: |
There are rules that require an update to their exclusion reasons.
labels: bot
author: VGV Bot <[email protected]>
assignees: vgvbot
committer: VGV Bot <[email protected]>
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,4 @@ Below is a list of rules that are not enabled by default together with the reaso
[pub_badge_link]: https://pub.dartlang.org/packages/very_good_analysis
[very_good_ventures_link]: https://verygood.ventures
[very_good_ventures_link_dark]: https://verygood.ventures#gh-dark-mode-only
[very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only
[very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only
14 changes: 12 additions & 2 deletions tool/linter_rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,23 @@ The reasons are defined in the [`exclusion_reasons.json`](exclusion_reasons.json
To generate the exclusion reason table, run the following command (from `tool/linter_rules`, and don't forget to `dart pub get`):

```sh
dart lib/exclusion_reason_table.dart $version
dart lib/exclusion_reason_table.dart
```

This command will update the README table for the rules that are not enabled by default in the specified `$version` of Very Good Analysis. The `$version` is a user specified argument and it should be in the format `x.y.z`. In addition, no longer excluded rules will be removed from the `exclusion_reasons.json` file. The command does not format the output, so it is recommended to format both files with your preferred formatter after running the command.
This command will update the README table for the rules that are not enabled by default in the specified `$version` of Very Good Analysis.

In addition, no longer excluded rules will be removed from the `exclusion_reasons.json` file. The command does not format the output, so it is recommended to format both files with your preferred formatter after running the command.

Rules that are missing a reason in the `exclusion_reasons.json` file will be given the reason `Not specified`.

### Options

| Option | Description | Default |
| ------------------- | --------------------------------------------------------------------- | --------------------------------------- |
| version | The Very Good Analysis version to use. | latest (from lib/analysis_options.yaml) |
| set-exit-if-changed | Set the exit code to 2 if there are changes to the exclusion reasons. | false |


## Inspection 🔍

If you're looking to update Very Good Analysis you might want to inspect the health of the latest rule set. You can use the script at `bin/inspect.dart` to do exactly that.
Expand Down
50 changes: 41 additions & 9 deletions tool/linter_rules/lib/exclusion_reason_table.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import 'dart:io';

import 'package:args/args.dart';
import 'package:collection/collection.dart';
import 'package:linter_rules/linter_rules.dart';

/// The reason to fallback to if no reason is found in the exclusion reasons
Expand Down Expand Up @@ -35,25 +39,41 @@ String _linterRuleLink(String rule) {
/// with the version of the Very Good Analysis to update the documentation for
/// as the first argument.
///
/// The version argument should be in the format of `x.y.z`. For example,
/// `5.1.0`.
/// The new table will be written to the README.md file. However, it might not
/// follow the same formatting as the rest of the file, so it is recommended to
/// manually format it after running the tool.
///
/// ## Usage
///
/// To use the tool run (from tool/linter_rules):
/// ```sh
/// dart lib/exclusion_reason_table.dart $version
/// dart lib/exclusion_reason_table.dart
/// ```
///
/// Where `$version` is the version of the Very Good Analysis to log the table
/// for.
/// ## Options
///
/// The new table will be written to the README.md file. However, it might not
/// follow the same formatting as the rest of the file, so it is recommended to
/// manually format it after running the tool.
/// * `--version`: The version of the Very Good Analysis to update the table
/// for, defaults to the latest version found in the lib analysis options file.
/// * `--set-exit-if-changed`: Set the exit code to 2 if there are changes to
/// the exclusion reasons.
Future<void> main(
List<String> args, {
void Function(String) log = print,
}) async {
final version = args[0];
final argsParser = ArgParser()
..addOption(
'version',
help: 'The version of the Very Good Analysis to update the table for.',
)
..addFlag(
'set-exit-if-changed',
help:
'''Set the exit code to 2 if there are changes to the exclusion reasons.''',
);
final parsedArgs = argsParser.parse(args);

final version = parsedArgs['version'] as String? ?? latestVgaVersion();
final setExitIfChanged = parsedArgs['set-exit-if-changed'] as bool;

final linterRules = (await allLinterRules()).toSet();
log('Found ${linterRules.length} available linter rules');
Expand All @@ -71,6 +91,14 @@ Future<void> main(
for (final rule in excludedRules)
rule: previousExclusionReasons[rule] ?? _noReasonFallback,
};

final hasChanged = !const DeepCollectionEquality()
.equals(previousExclusionReasons, exclusionReasons);
if (!hasChanged) {
log('No changes to the exclusion reasons');
return;
}

await writeExclusionReasons(exclusionReasons);

final markdownTable = generateMarkdownTable(
Expand All @@ -86,4 +114,8 @@ Future<void> main(
await Readme().updateTagContent(_excludedRulesTableTag, '\n$markdownTable');

log('''Updated the README.md file with the excluded rules table.''');

if (hasChanged && setExitIfChanged) {
exit(2);
}
}
1 change: 1 addition & 0 deletions tool/linter_rules/lib/linter_rules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library;

export 'src/all_linter_rules.dart';
export 'src/all_vga_rules.dart';
export 'src/latest_vga_version.dart';
export 'src/linter_rules_reasons.dart';
export 'src/markdown_table_generator.dart';
export 'src/models/models.dart';
Expand Down
36 changes: 36 additions & 0 deletions tool/linter_rules/lib/src/latest_vga_version.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'dart:io';

import 'package:path/path.dart' as path;

/// The file path containing the latest Very Good Analysis options version.
///
/// It assumes that the current directory is the root of the `linter_rules`
/// package (tool/linter_rules).
final _latestVeryGoodAnalaysisFilePath = path.joinAll(
['..', '..', 'lib', 'analysis_options.yaml'],
);

/// Returns the latest Very Good Analysis version from the analysis options
/// file.
String latestVgaVersion() {
final analysisOptionsFile = File(_latestVeryGoodAnalaysisFilePath);

if (!analysisOptionsFile.existsSync()) {
throw ArgumentError(
'''Could not find analysis options file at ${analysisOptionsFile.path}''',
);
}

final yaml = analysisOptionsFile.readAsStringSync();

final versionRegex = RegExp(r'analysis_options\.(\d+\.\d+\.\d+)\.yaml');
final match = versionRegex.firstMatch(yaml);

if (match == null) {
throw ArgumentError(
'''Could not find Very Good Analysis version in ${analysisOptionsFile.path}''',
);
}

return match.group(1)!;
}
2 changes: 2 additions & 0 deletions tool/linter_rules/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ environment:
sdk: ^3.4.0

dependencies:
args: ^2.6.0
collection: ^1.19.1
http: ^1.2.1
meta: ^1.16.0
path: ^1.9.0
Expand Down

0 comments on commit 7c9292c

Please sign in to comment.