Skip to content
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

feat: Set up custom lint #27

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/code-check.yml
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a workflow to run tests for analyze and custom_lint using GitHub Actions.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: code check

on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4

- uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true

- name: Install Melos
uses: bluefireteam/melos-action@v3

- name: Analyze packages
run: melos analyze

- name: Custom lint
run: melos custom_lint

- name: Check for the existence of unformatted files
# Cannot use `melos format` as it requires excluding files generated from the target file
run: melos run format:ci --no-select
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ flutter_*.png
linked_*.ds
unlinked.ds
unlinked_spec.ds
pubspec.lock

# Android related
**/android/**/gradle-wrapper.jar
Expand Down
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"dart.runPubGetOnPubspecChanges": "always",
"cSpell.words": [
"altive",
"bluefireteam",
"bools",
"combinators",
"diffscrape",
Expand All @@ -10,6 +11,7 @@
"ints",
"pubspec",
"redeclares",
"subosito",
"tearoffs",
"todos",
"unawaited",
Expand Down
17 changes: 17 additions & 0 deletions melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,20 @@ packages:
command:
version:
workspaceChangelog: false

scripts:
custom_lint:
exec: dart run custom_lint
description: Run custom_lint.
packageFilters:
dependsOn: "custom_lint"

# Issue on file exclusion feature: https://github.com/dart-lang/dart_style/issues/864
# NOTE: Using the `exec:` format causes processing to stop
format:ci:
run: |
melos exec -- \
dart format --set-exit-if-changed lib/
description: Run dart format for CI.
packageFilters:
dirExists: lib
8 changes: 8 additions & 0 deletions packages/altive_lints/example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# https://pub.dev/packages/altive_lints
include: package:altive_lints/altive_lints.yaml
analyzer:
plugins:
- custom_lint

custom_lint:
rules:
# Unnecessary if not localizing or not using Japanese.
# - avoid_hardcoded_japanese: false
Comment on lines +9 to +10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have provided an example of rule exclusion.

62 changes: 0 additions & 62 deletions packages/altive_lints/example/pubspec.lock

This file was deleted.

4 changes: 3 additions & 1 deletion packages/altive_lints/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ dependencies:
sdk: flutter

dev_dependencies:
altive_lints: ^1.10.0
altive_lints:
path: ../
custom_lint: ^0.6.4
12 changes: 12 additions & 0 deletions packages/altive_lints/lib/altive_lints.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:custom_lint_builder/custom_lint_builder.dart';

import 'src/lints/avoid_hardcoded_japanese.dart';

PluginBase createPlugin() => _AltivePlugin();

class _AltivePlugin extends PluginBase {
@override
List<LintRule> getLintRules(CustomLintConfigs configs) => [
const AvoidHardcodedJapanese(),
Comment on lines +9 to +10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an example, I have defined custom lint rules that have already been implemented in another repository.

];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';

/// An `avoid_hardcoded_japanese` rule which detects
/// and reports hardcoded Japanese text strings within the code.
///
/// This rule ensures that all user-facing text is
/// properly internationalized to support Japanese localization efforts.
///
/// ### Example
///
/// #### BAD:
///
/// ```dart
/// final message = 'ใ“ใ‚“ใซใกใฏ'; // LINT
/// print('ใ‚จใƒฉใƒผใŒ็™บ็”Ÿใ—ใพใ—ใŸ'); // LINT
/// ```
///
/// #### GOOD:
///
/// ```dart
/// final message = AppLocalizations.of(context).hello;
/// print(AppLocalizations.of(context).errorOccurred);
/// ```
///
class AvoidHardcodedJapanese extends DartLintRule {
const AvoidHardcodedJapanese() : super(code: _code);

static const _code = LintCode(
name: 'avoid_hardcoded_japanese',
problemMessage: 'This string appears to be untranslated to Japanese.\n'
'Ensure all user-facing text is properly internationalized for '
'Japanese localization.',
);

@override
void run(
CustomLintResolver resolver,
ErrorReporter reporter,
CustomLintContext context,
) {
context.registry.addSimpleStringLiteral((node) {
final stringValue = node.stringValue;
if (stringValue == null) {
return;
}
if (isJapanese(stringValue)) {
reporter.reportErrorForNode(_code, node);
}
});

context.registry.addStringInterpolation((node) {
final stringValue = node.toSource();
if (isJapanese(stringValue)) {
reporter.reportErrorForNode(_code, node);
}
});
}

/// Checks if the string contains Japanese characters
/// (Hiragana, Katakana, Kanji).
bool isJapanese(String value) =>
RegExp(r'[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FD0]').hasMatch(value);
}
5 changes: 5 additions & 0 deletions packages/altive_lints/lint_test/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# https://pub.dev/packages/altive_lints
include: package:altive_lints/altive_lints.yaml
analyzer:
plugins:
- custom_lint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the test does not start from the main function, the test code is placed in the lint_test directory instead of the test directory. I referred to other repositories that use custom_lint.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Check the `avoid_hardcoded_japanese` rule.

// expect_lint: avoid_hardcoded_japanese
const hiragana = 'ใ‚ใ„ใ†ใˆใŠ';

// expect_lint: avoid_hardcoded_japanese
const katakana = 'ใ‚ขใ‚คใ‚ฆใ‚จใ‚ช';

// expect_lint: avoid_hardcoded_japanese
const kanji = 'ๆผขๅญ—';

const notJapanese = 'abc';
11 changes: 11 additions & 0 deletions packages/altive_lints/lint_test/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: altive_lints_test
description: A starting point for Dart libraries or applications.
publish_to: none

environment:
sdk: ^3.0.0

dev_dependencies:
altive_lints:
path: ../
custom_lint: ^0.6.4
5 changes: 0 additions & 5 deletions packages/altive_lints/pubspec.lock

This file was deleted.

4 changes: 4 additions & 0 deletions packages/altive_lints/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ topics:

environment:
sdk: ^3.0.0

dependencies:
analyzer: ^6.4.1
custom_lint_builder: ^0.6.4
Loading