Skip to content

Commit

Permalink
feat: Set up custom lint (#27)
Browse files Browse the repository at this point in the history
* chore: Add pubspec.lock to .gitignore

* feat: Add `avoid_hardcoded_japanese` rule

* chore: Update dependencies and add code check workflow

* chore: Add doc comment
  • Loading branch information
naipaka authored Jul 29, 2024
1 parent 93c6dc2 commit f695826
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 775 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/code-check.yml
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
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(),
];
}
64 changes: 64 additions & 0 deletions packages/altive_lints/lib/src/lints/avoid_hardcoded_japanese.dart
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
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

0 comments on commit f695826

Please sign in to comment.