Committed by
GitHub
Merge pull request #579 from Grohden/chore/pipeline-analyzer
chore: add analyzer to PR check pipeline
Showing
15 changed files
with
121 additions
and
32 deletions
| @@ -20,8 +20,7 @@ jobs: | @@ -20,8 +20,7 @@ jobs: | ||
| 20 | flutter-version: '1.20.2' | 20 | flutter-version: '1.20.2' |
| 21 | channel: 'stable' | 21 | channel: 'stable' |
| 22 | - run: flutter pub get | 22 | - run: flutter pub get |
| 23 | - # run static analys code | ||
| 24 | - #- run: flutter analyze | 23 | + - run: flutter analyze |
| 25 | # run flutter widgets tests and unit tests | 24 | # run flutter widgets tests and unit tests |
| 26 | - run: flutter test --coverage | 25 | - run: flutter test --coverage |
| 27 | # Upload coverage reports to Codecov | 26 | # Upload coverage reports to Codecov |
| 1 | -include: package:effective_dart/analysis_options.yaml | 1 | +# Include option is buggy: |
| 2 | +# https://github.com/flutter/flutter/issues/62591 | ||
| 3 | +# In case the include issue gets fixed, lines below INCLUDE_FIX | ||
| 4 | +# can be removed | ||
| 5 | + | ||
| 6 | +# include: package:effective_dart/analysis_options.1.2.0.yaml | ||
| 2 | analyzer: | 7 | analyzer: |
| 3 | strong-mode: | 8 | strong-mode: |
| 4 | implicit-casts: false | 9 | implicit-casts: false |
| @@ -10,3 +15,71 @@ linter: | @@ -10,3 +15,71 @@ linter: | ||
| 10 | # Desirable, but would be breaking changes: | 15 | # Desirable, but would be breaking changes: |
| 11 | avoid_positional_boolean_parameters: false | 16 | avoid_positional_boolean_parameters: false |
| 12 | constant_identifier_names: false | 17 | constant_identifier_names: false |
| 18 | + include_file_not_found: false | ||
| 19 | + | ||
| 20 | + # INCLUDE_FIX (copy of effective dart 1.2.0) | ||
| 21 | + # STYLE | ||
| 22 | + camel_case_types: true | ||
| 23 | + camel_case_extensions: true | ||
| 24 | + library_names: true | ||
| 25 | + file_names: true | ||
| 26 | + library_prefixes: true | ||
| 27 | + non_constant_identifier_names: true | ||
| 28 | + directives_ordering: true | ||
| 29 | + lines_longer_than_80_chars: true # avoid | ||
| 30 | + curly_braces_in_flow_control_structures: true | ||
| 31 | + | ||
| 32 | + # DOCUMENTATION | ||
| 33 | + slash_for_doc_comments: true | ||
| 34 | + package_api_docs: true # prefer | ||
| 35 | + #- comment_references # Unused because https://github.com/dart-lang/sdk/issues/36974 | ||
| 36 | + | ||
| 37 | + # USAGE | ||
| 38 | + implementation_imports: true | ||
| 39 | + avoid_relative_lib_imports: true # prefer | ||
| 40 | + prefer_relative_imports: true # prefer | ||
| 41 | + prefer_adjacent_string_concatenation: true | ||
| 42 | + prefer_interpolation_to_compose_strings: true # prefer | ||
| 43 | + unnecessary_brace_in_string_interps: true # avoid | ||
| 44 | + prefer_collection_literals: true | ||
| 45 | + avoid_function_literals_in_foreach_calls: true # avoid | ||
| 46 | + prefer_iterable_whereType: true | ||
| 47 | + prefer_function_declarations_over_variables: true | ||
| 48 | + unnecessary_lambdas: true | ||
| 49 | + prefer_equal_for_default_values: true | ||
| 50 | + avoid_init_to_null: true | ||
| 51 | + unnecessary_getters_setters: true | ||
| 52 | + #- unnecessary_getters # prefer # Disabled pending fix: https://github.com/dart-lang/linter/issues/23 | ||
| 53 | + #- prefer_expression_function_bodies # consider | ||
| 54 | + unnecessary_this: true | ||
| 55 | + prefer_initializing_formals: true | ||
| 56 | + type_init_formals: true | ||
| 57 | + empty_constructor_bodies: true | ||
| 58 | + unnecessary_new: true | ||
| 59 | + unnecessary_const: true | ||
| 60 | + avoid_catches_without_on_clauses: true # avoid | ||
| 61 | + avoid_catching_errors: true | ||
| 62 | + use_rethrow_when_possible: true | ||
| 63 | + | ||
| 64 | + # DESIGN | ||
| 65 | + use_to_and_as_if_applicable: true # prefer | ||
| 66 | + one_member_abstracts: true # avoid | ||
| 67 | + avoid_classes_with_only_static_members: true # avoid | ||
| 68 | + prefer_mixin: true | ||
| 69 | + prefer_final_fields: true # prefer | ||
| 70 | + use_setters_to_change_properties: true | ||
| 71 | + avoid_setters_without_getters: true | ||
| 72 | + avoid_returning_null: true # avoid | ||
| 73 | + avoid_returning_this: true # avoid | ||
| 74 | + type_annotate_public_apis: true # prefer | ||
| 75 | + #- prefer_typing_uninitialized_variables # consider | ||
| 76 | + omit_local_variable_types: true # avoid | ||
| 77 | + avoid_types_on_closure_parameters: true # avoid | ||
| 78 | + avoid_return_types_on_setters: true # avoid | ||
| 79 | + prefer_generic_function_type_aliases: true | ||
| 80 | + avoid_private_typedef_functions: true # prefer | ||
| 81 | + #- use_function_type_syntax_for_parameters # consider | ||
| 82 | + hash_and_equals: true | ||
| 83 | + avoid_equals_and_hash_code_on_mutable_classes: true # avoid | ||
| 84 | + avoid_null_checks_in_equality_operators: true | ||
| 85 | + |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:get/get.dart'; | 2 | import 'package:get/get.dart'; |
| 3 | -import 'package:get_demo/routes/app_pages.dart'; | 3 | + |
| 4 | +import 'routes/app_pages.dart'; | ||
| 4 | import 'shared/logger/logger_utils.dart'; | 5 | import 'shared/logger/logger_utils.dart'; |
| 5 | 6 | ||
| 6 | void main() { | 7 | void main() { |
| 1 | import 'package:dio/dio.dart'; | 1 | import 'package:dio/dio.dart'; |
| 2 | import 'package:get/get.dart'; | 2 | import 'package:get/get.dart'; |
| 3 | -import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart'; | ||
| 4 | -import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart'; | 3 | + |
| 5 | import '../data/home_repository.dart'; | 4 | import '../data/home_repository.dart'; |
| 5 | +import '../domain/adapters/repository_adapter.dart'; | ||
| 6 | +import '../presentation/controllers/home_controller.dart'; | ||
| 6 | 7 | ||
| 7 | class HomeBinding extends Bindings { | 8 | class HomeBinding extends Bindings { |
| 8 | @override | 9 | @override |
| 1 | import 'package:dio/dio.dart'; | 1 | import 'package:dio/dio.dart'; |
| 2 | -import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart'; | ||
| 3 | -import 'package:get_demo/pages/home/domain/entity/cases_model.dart'; | 2 | + |
| 3 | +import '../domain/adapters/repository_adapter.dart'; | ||
| 4 | +import '../domain/entity/cases_model.dart'; | ||
| 4 | 5 | ||
| 5 | class HomeRepository implements IHomeRepository { | 6 | class HomeRepository implements IHomeRepository { |
| 6 | HomeRepository({this.dio}); | 7 | HomeRepository({this.dio}); |
| @@ -13,7 +14,7 @@ class HomeRepository implements IHomeRepository { | @@ -13,7 +14,7 @@ class HomeRepository implements IHomeRepository { | ||
| 13 | final response = await dio.get("https://api.covid19api.com/summary"); | 14 | final response = await dio.get("https://api.covid19api.com/summary"); |
| 14 | 15 | ||
| 15 | return CasesModel.fromJson(response.data as Map<String, dynamic>); | 16 | return CasesModel.fromJson(response.data as Map<String, dynamic>); |
| 16 | - } catch (e) { | 17 | + } on Exception catch (e) { |
| 17 | print(e.toString()); | 18 | print(e.toString()); |
| 18 | return Future.error(e.toString()); | 19 | return Future.error(e.toString()); |
| 19 | } | 20 | } |
| 1 | import 'package:get/get.dart'; | 1 | import 'package:get/get.dart'; |
| 2 | -import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart'; | ||
| 3 | -import 'package:get_demo/pages/home/domain/entity/cases_model.dart'; | 2 | + |
| 3 | +import '../../domain/adapters/repository_adapter.dart'; | ||
| 4 | +import '../../domain/entity/cases_model.dart'; | ||
| 4 | 5 | ||
| 5 | enum Status { loading, success, error } | 6 | enum Status { loading, success, error } |
| 6 | 7 | ||
| @@ -22,14 +23,16 @@ class HomeController extends GetxController { | @@ -22,14 +23,16 @@ class HomeController extends GetxController { | ||
| 22 | 23 | ||
| 23 | /// fetch cases from Api | 24 | /// fetch cases from Api |
| 24 | Future<void> fetchDataFromApi() async { | 25 | Future<void> fetchDataFromApi() async { |
| 25 | - /// When the repository returns the value, change the status to success, and fill in "cases" | 26 | + /// When the repository returns the value, change the status to success, |
| 27 | + /// and fill in "cases" | ||
| 26 | return homeRepository.getCases().then( | 28 | return homeRepository.getCases().then( |
| 27 | (data) { | 29 | (data) { |
| 28 | cases(data); | 30 | cases(data); |
| 29 | status(Status.success); | 31 | status(Status.success); |
| 30 | }, | 32 | }, |
| 31 | 33 | ||
| 32 | - /// In case of error, print the error and change the status to Status.error | 34 | + /// In case of error, print the error and change the status |
| 35 | + /// to Status.error | ||
| 33 | onError: (err) { | 36 | onError: (err) { |
| 34 | print("$err"); | 37 | print("$err"); |
| 35 | return status(Status.error); | 38 | return status(Status.error); |
| 1 | import 'dart:ui'; | 1 | import 'dart:ui'; |
| 2 | + | ||
| 2 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 3 | import 'package:get/get.dart'; | 4 | import 'package:get/get.dart'; |
| 4 | -import 'package:get_demo/pages/home/domain/entity/cases_model.dart'; | 5 | + |
| 5 | import '../controllers/home_controller.dart'; | 6 | import '../controllers/home_controller.dart'; |
| 6 | 7 | ||
| 7 | class CountryView extends GetWidget<HomeController> { | 8 | class CountryView extends GetWidget<HomeController> { |
| @@ -30,7 +31,7 @@ class CountryView extends GetWidget<HomeController> { | @@ -30,7 +31,7 @@ class CountryView extends GetWidget<HomeController> { | ||
| 30 | child: ListView.builder( | 31 | child: ListView.builder( |
| 31 | itemCount: controller.cases.value.countries.length, | 32 | itemCount: controller.cases.value.countries.length, |
| 32 | itemBuilder: (context, index) { | 33 | itemBuilder: (context, index) { |
| 33 | - Country country = controller.cases.value.countries[index]; | 34 | + final country = controller.cases.value.countries[index]; |
| 34 | return ListTile( | 35 | return ListTile( |
| 35 | onTap: () { | 36 | onTap: () { |
| 36 | Get.toNamed('/details', arguments: country); | 37 | Get.toNamed('/details', arguments: country); |
| @@ -2,12 +2,13 @@ import 'dart:ui'; | @@ -2,12 +2,13 @@ import 'dart:ui'; | ||
| 2 | 2 | ||
| 3 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 4 | import 'package:get/get.dart'; | 4 | import 'package:get/get.dart'; |
| 5 | -import 'package:get_demo/pages/home/domain/entity/cases_model.dart'; | 5 | + |
| 6 | +import '../../domain/entity/cases_model.dart'; | ||
| 6 | 7 | ||
| 7 | class DetailsView extends StatelessWidget { | 8 | class DetailsView extends StatelessWidget { |
| 8 | @override | 9 | @override |
| 9 | Widget build(BuildContext context) { | 10 | Widget build(BuildContext context) { |
| 10 | - Country country = Get.arguments as Country; | 11 | + final country = Get.arguments as Country; |
| 11 | return Container( | 12 | return Container( |
| 12 | decoration: BoxDecoration( | 13 | decoration: BoxDecoration( |
| 13 | image: DecorationImage( | 14 | image: DecorationImage( |
| @@ -2,7 +2,8 @@ import 'dart:ui'; | @@ -2,7 +2,8 @@ import 'dart:ui'; | ||
| 2 | 2 | ||
| 3 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 4 | import 'package:get/get.dart'; | 4 | import 'package:get/get.dart'; |
| 5 | -import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart'; | 5 | + |
| 6 | +import '../controllers/home_controller.dart'; | ||
| 6 | 7 | ||
| 7 | class HomeView extends GetView<HomeController> { | 8 | class HomeView extends GetView<HomeController> { |
| 8 | @override | 9 | @override |
| @@ -28,7 +29,7 @@ class HomeView extends GetView<HomeController> { | @@ -28,7 +29,7 @@ class HomeView extends GetView<HomeController> { | ||
| 28 | body: Center( | 29 | body: Center( |
| 29 | child: Obx( | 30 | child: Obx( |
| 30 | () { | 31 | () { |
| 31 | - Status status = controller.status.value; | 32 | + final status = controller.status.value; |
| 32 | if (status == Status.loading) return CircularProgressIndicator(); | 33 | if (status == Status.loading) return CircularProgressIndicator(); |
| 33 | if (status == Status.error) return Text('Error on connection :('); | 34 | if (status == Status.error) return Text('Error on connection :('); |
| 34 | return Column( | 35 | return Column( |
| 1 | import 'package:get/get.dart'; | 1 | import 'package:get/get.dart'; |
| 2 | -import 'package:get_demo/pages/home/bindings/home_binding.dart'; | ||
| 3 | -import 'package:get_demo/pages/home/presentation/views/country_view.dart'; | ||
| 4 | -import 'package:get_demo/pages/home/presentation/views/details_view.dart'; | ||
| 5 | -import 'package:get_demo/pages/home/presentation/views/home_view.dart'; | 2 | + |
| 3 | +import '../pages/home/bindings/home_binding.dart'; | ||
| 4 | +import '../pages/home/presentation/views/country_view.dart'; | ||
| 5 | +import '../pages/home/presentation/views/details_view.dart'; | ||
| 6 | +import '../pages/home/presentation/views/home_view.dart'; | ||
| 6 | 7 | ||
| 7 | part 'app_routes.dart'; | 8 | part 'app_routes.dart'; |
| 8 | 9 | ||
| 10 | +// ignore: avoid_classes_with_only_static_members | ||
| 9 | class AppPages { | 11 | class AppPages { |
| 10 | static const INITIAL = Routes.HOME; | 12 | static const INITIAL = Routes.HOME; |
| 11 | 13 |
| 1 | class Logger { | 1 | class Logger { |
| 2 | // Sample of abstract logging function | 2 | // Sample of abstract logging function |
| 3 | static void write(String text, {bool isError = false}) { | 3 | static void write(String text, {bool isError = false}) { |
| 4 | - print('** ' + text + ' [' + isError.toString() + ']'); | 4 | + print('** $text [$isError]'); |
| 5 | } | 5 | } |
| 6 | } | 6 | } |
| @@ -49,7 +49,7 @@ void main() { | @@ -49,7 +49,7 @@ void main() { | ||
| 49 | binding.builder(); | 49 | binding.builder(); |
| 50 | 50 | ||
| 51 | /// recover your controller | 51 | /// recover your controller |
| 52 | - HomeController controller = Get.find(); | 52 | + final controller = Get.find<HomeController>(); |
| 53 | 53 | ||
| 54 | /// check if onInit was called | 54 | /// check if onInit was called |
| 55 | expect(controller.initialized, true); | 55 | expect(controller.initialized, true); |
| @@ -4,7 +4,8 @@ import 'dart:collection'; | @@ -4,7 +4,8 @@ import 'dart:collection'; | ||
| 4 | import '../rx_core/rx_interface.dart'; | 4 | import '../rx_core/rx_interface.dart'; |
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | -/// global object that registers against `GetX` and `Obx`, and allows the reactivity | 7 | +/// global object that registers against `GetX` and `Obx`, and allows the |
| 8 | +/// reactivity | ||
| 8 | /// of those `Widgets` and Rx values. | 9 | /// of those `Widgets` and Rx values. |
| 9 | RxInterface getObs; | 10 | RxInterface getObs; |
| 10 | 11 | ||
| @@ -207,6 +208,9 @@ class RxBool extends _RxImpl<bool> { | @@ -207,6 +208,9 @@ class RxBool extends _RxImpl<bool> { | ||
| 207 | 208 | ||
| 208 | /// Toggles the bool [value] between false and true. | 209 | /// Toggles the bool [value] between false and true. |
| 209 | /// A shortcut for `flag.value = !flag.value;` | 210 | /// A shortcut for `flag.value = !flag.value;` |
| 211 | + /// FIXME: why return this? fluent interface is not | ||
| 212 | + /// not really a dart thing since we have '..' operator | ||
| 213 | + // ignore: avoid_returning_this | ||
| 210 | RxBool toggle() { | 214 | RxBool toggle() { |
| 211 | subject.add(_value = !_value); | 215 | subject.add(_value = !_value); |
| 212 | return this; | 216 | return this; |
| @@ -295,7 +299,8 @@ class RxInt extends _BaseRxNum<int> { | @@ -295,7 +299,8 @@ class RxInt extends _BaseRxNum<int> { | ||
| 295 | } | 299 | } |
| 296 | 300 | ||
| 297 | 301 | ||
| 298 | -/// Foundation class used for custom `Types` outside the common native Dart types. | 302 | +/// Foundation class used for custom `Types` outside the common native Dart |
| 303 | +/// types. | ||
| 299 | /// For example, any custom "Model" class, like User().obs will use `Rx` as | 304 | /// For example, any custom "Model" class, like User().obs will use `Rx` as |
| 300 | /// wrapper. | 305 | /// wrapper. |
| 301 | class Rx<T> extends _RxImpl<T> { | 306 | class Rx<T> extends _RxImpl<T> { |
| @@ -27,6 +27,7 @@ typedef GetStateUpdate = bool Function(); | @@ -27,6 +27,7 @@ typedef GetStateUpdate = bool Function(); | ||
| 27 | // TODO: check performance HIT for the extra method call. | 27 | // TODO: check performance HIT for the extra method call. |
| 28 | mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { | 28 | mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { |
| 29 | // To avoid the creation of an anonym function to be GC later. | 29 | // To avoid the creation of an anonym function to be GC later. |
| 30 | + // ignore: prefer_function_declarations_over_variables | ||
| 30 | static final VoidCallback _stateCallback = () {}; | 31 | static final VoidCallback _stateCallback = () {}; |
| 31 | 32 | ||
| 32 | /// Experimental method to replace setState((){}); | 33 | /// Experimental method to replace setState((){}); |
| @@ -68,12 +69,11 @@ class GetxController extends DisposableInterface { | @@ -68,12 +69,11 @@ class GetxController extends DisposableInterface { | ||
| 68 | // for (final rs in _updatersGroupIds[id]) rs(); | 69 | // for (final rs in _updatersGroupIds[id]) rs(); |
| 69 | // } | 70 | // } |
| 70 | 71 | ||
| 71 | - ids.forEach((id) { | ||
| 72 | -// _updatersIds[id]?.call(() {}); //<old> | ||
| 73 | -// _updatersGroupIds[id]?.forEach((rs) => rs(() {})); //<old> | 72 | + for (final id in ids) { |
| 74 | _updatersIds[id]?.call(); | 73 | _updatersIds[id]?.call(); |
| 74 | + // ignore: avoid_function_literals_in_foreach_calls | ||
| 75 | _updatersGroupIds[id]?.forEach((rs) => rs()); | 75 | _updatersGroupIds[id]?.forEach((rs) => rs()); |
| 76 | - }); | 76 | + } |
| 77 | } | 77 | } |
| 78 | } | 78 | } |
| 79 | 79 |
-
Please register or login to post a comment