From 4916969e482d41dadc832e315121ff94caa75acc Mon Sep 17 00:00:00 2001 From: fluttermiddlepodcast Date: Wed, 18 Jun 2025 20:10:09 +0300 Subject: [PATCH 1/2] added custom_lint example --- analysis_options.yaml | 30 +--- lib/features/users/widgets/users_list.dart | 18 +- pubspec.lock | 181 +++++++++++++++++---- pubspec.yaml | 10 +- 4 files changed, 169 insertions(+), 70 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 61b6c4d..fe99978 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,29 +1,5 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +analyzer: + plugins: + - custom_lint diff --git a/lib/features/users/widgets/users_list.dart b/lib/features/users/widgets/users_list.dart index ee86e3f..538ee7c 100644 --- a/lib/features/users/widgets/users_list.dart +++ b/lib/features/users/widgets/users_list.dart @@ -35,13 +35,17 @@ class _UsersListState extends State { @override Widget build(BuildContext context) { return BlocBuilder( - buildWhen: (prev, curr) { - if (prev is UsersBlocStateLoaded && curr is UsersBlocStateLoaded) { - return !const DeepCollectionEquality().equals(prev.users, curr.users); - } - - return true; - }, + // + // Чтобы убрать ошибку - добавьте `buildWhen` из комментария ниже. + // Вообще, можно вставить свою реализацию. Ошибка отсутствия `buildWhen` пропадет после его добавления. + // + // buildWhen: (prev, curr) { + // if (prev is UsersBlocStateLoaded && curr is UsersBlocStateLoaded) { + // return !const DeepCollectionEquality().equals(prev.users, curr.users); + // } + // + // return true; + // }, builder: (context, state) { return switch (state) { UsersBlocStateLoading _ => const UsersListShimmer(), diff --git a/pubspec.lock b/pubspec.lock index 9eb5695..4eeab11 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57 + sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f url: "https://pub.dev" source: hosted - version: "80.0.0" + version: "82.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e" + sha256: "904ae5bb474d32c38fb9482e2d925d5454cda04ddd0e55d2e6826bc72f6ba8c0" url: "https://pub.dev" source: hosted - version: "7.3.0" + version: "7.4.5" + analyzer_plugin: + dependency: transitive + description: + name: analyzer_plugin + sha256: ee188b6df6c85f1441497c7171c84f1392affadc0384f71089cb10a3bc508cef + url: "https://pub.dev" + source: hosted + version: "0.13.1" args: dependency: transitive description: @@ -41,6 +49,15 @@ packages: url: "https://pub.dev" source: hosted version: "9.0.0" + bloc_builder_build_when_lint_rule: + dependency: "direct dev" + description: + path: "." + ref: master + resolved-ref: a3113d6855454a72c647f8ba64a33c11f7f00a99 + url: "https://github.com/fluttermiddlepodcast/bloc_builder_build_when_lint_rule.git" + source: git + version: "1.0.0" bloc_concurrency: dependency: "direct main" description: @@ -61,10 +78,10 @@ packages: dependency: transitive description: name: build - sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 + sha256: "7cf79af8eb6023bee797a77b067fb6e63ac5650f3789546e023958098feb776e" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.5.2" build_config: dependency: transitive description: @@ -85,26 +102,26 @@ packages: dependency: transitive description: name: build_resolvers - sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0 + sha256: "7a507e6026abe52074836d51a945bfad456daa7493eb7a6cac565e490e7d5b54" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.5.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99" + sha256: "1ce1e5063b564f26c27bda54c82a3d38339df69ec58f90e0017f447de77e4839" url: "https://pub.dev" source: hosted - version: "2.4.15" + version: "2.5.2" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" + sha256: "564230f3fd9363df7870058fef11ec5502ee620aec3b1ee8106b943be5c63a76" url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "9.1.0" built_collection: dependency: transitive description: @@ -117,10 +134,10 @@ packages: dependency: transitive description: name: built_value - sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4 + sha256: "082001b5c3dc495d4a42f1d5789990505df20d8547d42507c29050af6933ee27" url: "https://pub.dev" source: hosted - version: "8.9.5" + version: "8.10.1" characters: dependency: transitive description: @@ -137,6 +154,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" + ci: + dependency: transitive + description: + name: ci + sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" clock: dependency: transitive description: @@ -177,14 +210,46 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" + custom_lint: + dependency: "direct dev" + description: + name: custom_lint + sha256: "409c485fd14f544af1da965d5a0d160ee57cd58b63eeaa7280a4f28cf5bda7f1" + url: "https://pub.dev" + source: hosted + version: "0.7.5" + custom_lint_builder: + dependency: transitive + description: + name: custom_lint_builder + sha256: "107e0a43606138015777590ee8ce32f26ba7415c25b722ff0908a6f5d7a4c228" + url: "https://pub.dev" + source: hosted + version: "0.7.5" + custom_lint_core: + dependency: transitive + description: + name: custom_lint_core + sha256: "31110af3dde9d29fb10828ca33f1dce24d2798477b167675543ce3d208dee8be" + url: "https://pub.dev" + source: hosted + version: "0.7.5" + custom_lint_visitor: + dependency: transitive + description: + name: custom_lint_visitor + sha256: cba5b6d7a6217312472bf4468cdf68c949488aed7ffb0eab792cd0b6c435054d + url: "https://pub.dev" + source: hosted + version: "1.0.0+7.4.5" dart_style: dependency: transitive description: name: dart_style - sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac" + sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.0" dio: dependency: "direct main" description: @@ -242,10 +307,10 @@ packages: dependency: "direct main" description: name: flutter_bloc - sha256: "1046d719fbdf230330d3443187cc33cc11963d15c9089f6cc56faa42a4c5f0cc" + sha256: cf51747952201a455a1c840f8171d273be009b932c75093020f9af64f2123e38 url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.1" flutter_lints: dependency: "direct dev" description: @@ -259,6 +324,14 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + url: "https://pub.dev" + source: hosted + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -295,18 +368,26 @@ packages: dependency: transitive description: name: hive_ce - sha256: ac66daee46ad46486a1ed12cf91e9d7479c875fb46889be8d2c96b557406647f + sha256: "708bb39050998707c5d422752159f91944d3c81ab42d80e1bd0ee37d8e130658" + url: "https://pub.dev" + source: hosted + version: "2.11.3" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b url: "https://pub.dev" source: hosted - version: "2.10.1" + version: "4.3.0" http: dependency: transitive description: name: http - sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" http_multi_server: dependency: transitive description: @@ -339,6 +420,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + isolate_channel: + dependency: transitive + description: + name: isolate_channel + sha256: f3d36f783b301e6b312c3450eeb2656b0e7d1db81331af2a151d9083a3f6b18d + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" js: dependency: transitive description: @@ -359,10 +448,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: "81f04dee10969f89f604e1249382d46b97a1ccad53872875369622b5bfc9e58a" + sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c url: "https://pub.dev" source: hosted - version: "6.9.4" + version: "6.9.5" leak_tracker: dependency: transitive description: @@ -471,10 +560,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.dev" source: hosted - version: "2.2.16" + version: "2.2.17" path_provider_foundation: dependency: transitive description: @@ -535,10 +624,10 @@ packages: dependency: transitive description: name: provider - sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.5" pub_semver: dependency: transitive description: @@ -555,6 +644,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" shelf: dependency: transitive description: @@ -608,6 +705,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -680,6 +785,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_math: dependency: transitive description: @@ -700,10 +813,10 @@ packages: dependency: transitive description: name: watcher - sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" web: dependency: transitive description: @@ -716,18 +829,18 @@ packages: dependency: transitive description: name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" url: "https://pub.dev" source: hosted - version: "0.1.6" + version: "1.0.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c476990..5e24398 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,9 +25,15 @@ dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^5.0.0 - build_runner: ^2.4.15 + flutter_lints: + build_runner: json_serializable: ^6.7.1 + custom_lint: + bloc_builder_build_when_lint_rule: + git: + url: https://github.com/fluttermiddlepodcast/bloc_builder_build_when_lint_rule.git + ref: master + flutter: uses-material-design: true From e0d9fd0370b2b563e222c7fbe36e325069cf2fe8 Mon Sep 17 00:00:00 2001 From: fluttermiddlepodcast Date: Wed, 18 Jun 2025 21:29:58 +0300 Subject: [PATCH 2/2] added custom_lint to CI --- .github/workflows/flutter.yaml | 17 +++++++++++++++++ lib/features/users/widgets/users_list.dart | 1 - 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/flutter.yaml b/.github/workflows/flutter.yaml index 1433bc8..35a2d2e 100644 --- a/.github/workflows/flutter.yaml +++ b/.github/workflows/flutter.yaml @@ -38,6 +38,23 @@ jobs: - name: Analyze code run: flutter analyze ${{ needs.changes.outputs.all_changed_files }} + custom_lint: + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.any_changed == 'true' + steps: + - uses: actions/checkout@v4 + - uses: kuhnroyal/flutter-fvm-config-action@v2 + id: fvm-config-action + - uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} + channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} + - name: Get dependencies + run: flutter pub get + - name: Analyze code + run: flutter pub run custom_lint ${{ needs.changes.outputs.all_changed_files }} + formatter: runs-on: ubuntu-latest needs: changes diff --git a/lib/features/users/widgets/users_list.dart b/lib/features/users/widgets/users_list.dart index 538ee7c..a9922ea 100644 --- a/lib/features/users/widgets/users_list.dart +++ b/lib/features/users/widgets/users_list.dart @@ -2,7 +2,6 @@ import 'package:bloc_example/features/users/bloc/users_bloc.dart'; import 'package:bloc_example/features/users/bloc/users_bloc_event.dart'; import 'package:bloc_example/features/users/bloc/users_bloc_state.dart'; import 'package:bloc_example/features/users/widgets/user_info_row.dart'; -import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart';