diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1aa47ee2..40f2db1a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,6 +42,7 @@ jobs: # TODO(rrousselGit) update riverpod_cli test setup to be supported by the CI # - packages/riverpod_cli - packages/riverpod_generator + - packages/riverpod_generator/integration/build_yaml # TODO(rrousselGit) update riverpod_graph test setup to be supported by the CI # - packages/riverpod_graph - packages/riverpod_lint @@ -62,6 +63,11 @@ jobs: run: echo "PUB_CACHE="$HOME/.pub-cache"" >> $GITHUB_ENV - name: Install dependencies run: flutter pub get + - name: Install dependencies (integration/buid.yaml) + run: | + if test -d "integration/build_yaml"; then + flutter pub get integration/build_yaml + fi - name: Check format run: flutter format --set-exit-if-changed . diff --git a/codecov.yml b/codecov.yml index 66c249eb5..fb6e9d11f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,5 @@ codecov: - require_ci_to_pass: yes + require_ci_to_pass: true coverage: precision: 2 @@ -21,8 +21,10 @@ ignore: - "**/*.g.dart" - "**/*.freezed.dart" - "packages/riverpod_cli" + - "packages/riverpod_generator" + - "packages/riverpod_lint" comment: layout: "reach,diff,flags,tree" behavior: default - require_changes: no + require_changes: false diff --git a/packages/riverpod_generator/README.md b/packages/riverpod_generator/README.md index 5bfd7db20..d7c135d94 100644 --- a/packages/riverpod_generator/README.md +++ b/packages/riverpod_generator/README.md @@ -156,6 +156,21 @@ class Home extends ConsumerWidget { } ``` +## Global configuration + +You can change provider name suffix in the build.yaml file: + +```yaml +targets: + $default: + builders: + riverpod_generator: + options: + # Could be changed to "Pod", such that riverpod_generator + # would generate "countPod" instead of "countProvider" + provider_name_suffix: "Provider" # (default) +``` + [family]: https://riverpod.dev/docs/concepts/modifiers/family [provider]: https://github.com/rrousselGit/provider [riverpod]: https://github.com/rrousselGit/riverpod diff --git a/packages/riverpod_generator/integration/build_yaml/.gitignore b/packages/riverpod_generator/integration/build_yaml/.gitignore new file mode 100644 index 000000000..3c8a15727 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/packages/riverpod_generator/integration/build_yaml/README.md b/packages/riverpod_generator/integration/build_yaml/README.md new file mode 100644 index 000000000..ab311a327 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/README.md @@ -0,0 +1,23 @@ +# Pub + +Install needed global packages + +```bash +cd riverpod +dart pub global activate melos +``` + +Build the riverpod packages + +```bash +fluttter pub get +``` + +## Start the tests + +```bash +cd examples/build_yaml +flutter pub run build_runner build + +flutter test +``` diff --git a/packages/riverpod_generator/integration/build_yaml/build.yaml b/packages/riverpod_generator/integration/build_yaml/build.yaml new file mode 100644 index 000000000..7337d42a9 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/build.yaml @@ -0,0 +1,6 @@ +targets: + $default: + builders: + riverpod_generator: + options: + provider_name_suffix: 'Pod' \ No newline at end of file diff --git a/packages/riverpod_generator/integration/build_yaml/lib/main.dart b/packages/riverpod_generator/integration/build_yaml/lib/main.dart new file mode 100644 index 000000000..9ece9457b --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/lib/main.dart @@ -0,0 +1,29 @@ +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'main.g.dart'; + +@riverpod +int count(CountRef ref) { + return 1; +} + +@riverpod +FutureOr countFuture(CountFutureRef ref) { + return 1; +} + +@riverpod +class CountNotifier extends _$CountNotifier { + @override + int build() { + return 1; + } +} + +@riverpod +class CountAsyncNotifier extends _$CountAsyncNotifier { + @override + FutureOr build() { + return 1; + } +} diff --git a/packages/riverpod_generator/integration/build_yaml/lib/main.g.dart b/packages/riverpod_generator/integration/build_yaml/lib/main.g.dart new file mode 100644 index 000000000..77a918cf3 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/lib/main.g.dart @@ -0,0 +1,87 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'main.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +// ignore_for_file: avoid_private_typedef_functions, non_constant_identifier_names, subtype_of_sealed_class, invalid_use_of_internal_member, unused_element, constant_identifier_names, unnecessary_raw_strings, library_private_types_in_public_api + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +String _$CountNotifierHash() => r'a8dd7a66ee0002b8af657245c4affaa206fd99ec'; + +/// See also [CountNotifier]. +final countNotifierPod = AutoDisposeNotifierProvider( + CountNotifier.new, + name: r'countNotifierPod', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$CountNotifierHash, +); +typedef CountNotifierRef = AutoDisposeNotifierProviderRef; + +abstract class _$CountNotifier extends AutoDisposeNotifier { + @override + int build(); +} + +String _$CountAsyncNotifierHash() => + r'2a7049d864bf396e44a5937b4001efb4774a5f29'; + +/// See also [CountAsyncNotifier]. +final countAsyncNotifierPod = + AutoDisposeAsyncNotifierProvider( + CountAsyncNotifier.new, + name: r'countAsyncNotifierPod', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$CountAsyncNotifierHash, +); +typedef CountAsyncNotifierRef = AutoDisposeAsyncNotifierProviderRef; + +abstract class _$CountAsyncNotifier extends AutoDisposeAsyncNotifier { + @override + FutureOr build(); +} + +String _$countHash() => r'4c7e72b275767a60ece5e8662ab1e28f73cf7e44'; + +/// See also [count]. +final countPod = AutoDisposeProvider( + count, + name: r'countPod', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$countHash, +); +typedef CountRef = AutoDisposeProviderRef; +String _$countFutureHash() => r'ec7cc31ce1c1a10607f1dcb35dd217acd2877729'; + +/// See also [countFuture]. +final countFuturePod = AutoDisposeFutureProvider( + countFuture, + name: r'countFuturePod', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$countFutureHash, +); +typedef CountFutureRef = AutoDisposeFutureProviderRef; diff --git a/packages/riverpod_generator/integration/build_yaml/pubspec.yaml b/packages/riverpod_generator/integration/build_yaml/pubspec.yaml new file mode 100644 index 000000000..13c70da21 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/pubspec.yaml @@ -0,0 +1,16 @@ +name: build_yaml +description: A sample command-line application. +version: 1.0.0 + +environment: + sdk: ">=2.18.4 <3.0.0" + +dependencies: + riverpod: + riverpod_annotation: + +dev_dependencies: + build_runner: ^2.3.2 + build_verify: ^3.0.0 + riverpod_generator: + test: ^1.16.0 diff --git a/packages/riverpod_generator/integration/build_yaml/pubspec_overrides.yaml b/packages/riverpod_generator/integration/build_yaml/pubspec_overrides.yaml new file mode 100644 index 000000000..e323b7f0b --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/pubspec_overrides.yaml @@ -0,0 +1,8 @@ +# melos_managed_dependency_overrides: riverpod,riverpod_annotation,riverpod_generator +dependency_overrides: + riverpod: + path: ../../../riverpod + riverpod_annotation: + path: ../../../riverpod_annotation + riverpod_generator: + path: ../.. diff --git a/packages/riverpod_generator/integration/build_yaml/test/build_yaml_test.dart b/packages/riverpod_generator/integration/build_yaml/test/build_yaml_test.dart new file mode 100644 index 000000000..f30c4eef4 --- /dev/null +++ b/packages/riverpod_generator/integration/build_yaml/test/build_yaml_test.dart @@ -0,0 +1,21 @@ +import 'package:build_verify/build_verify.dart'; +import 'package:build_yaml/main.dart'; +import 'package:test/test.dart'; + +void main() { + test( + 'ensure_build', + () => expectBuildClean( + packageRelativeDirectory: + 'packages/riverpod_generator/integration/build_yaml', + ), + timeout: const Timeout(Duration(minutes: 1)), + ); + + test('provider names', () { + expect(countPod.name, 'countPod'); + expect(countFuturePod.name, 'countFuturePod'); + expect(countNotifierPod.name, 'countNotifierPod'); + expect(countAsyncNotifierPod.name, 'countAsyncNotifierPod'); + }); +} diff --git a/packages/riverpod_generator/lib/src/models.dart b/packages/riverpod_generator/lib/src/models.dart index bf718c81c..545c63213 100644 --- a/packages/riverpod_generator/lib/src/models.dart +++ b/packages/riverpod_generator/lib/src/models.dart @@ -16,6 +16,8 @@ enum ProviderType { asyncNotifier, } +const _defaultProviderNameSuffix = 'Provider'; + class Data { Data.function({ required this.rawName, @@ -29,6 +31,7 @@ class Data { required this.providerDoc, required this.createElement, required this.createAst, + required this.buildYamlOptions, }) : notifierName = null; Data.notifier({ @@ -43,6 +46,7 @@ class Data { required this.providerDoc, required this.createElement, required this.createAst, + required this.buildYamlOptions, }) : functionName = null; final ExecutableElement createElement; @@ -57,6 +61,7 @@ class Data { final List parameters; final bool keepAlive; final String providerDoc; + final BuildYamlOptions buildYamlOptions; String get hashFunctionName => '_\$${rawName}Hash'; @@ -68,13 +73,13 @@ class Data { /// foo -> fooProvider /// Foo -> fooProvider String get providerName { - return '${rawName.lowerFirst}Provider'; + return '${rawName.lowerFirst}$_nameSuffix'; } /// foo -> FooProvider /// Foo -> FooProvider String get providerTypeNameImpl { - return '${rawName.titled}Provider'; + return '${rawName.titled}$_nameSuffix'; } /// foo -> FooFamily @@ -105,6 +110,9 @@ class Data { bool get isNotifier => functionName == null; + String get _nameSuffix => + buildYamlOptions.providerNameSuffix ?? _defaultProviderNameSuffix; + String notifierType({bool generics = true}) { final trailing = generics ? '<$valueDisplayType>' : ''; final leading = keepAlive ? '' : 'AutoDispose'; @@ -253,6 +261,20 @@ class GlobalData { final ElementHash hash = ElementHash(); } +class BuildYamlOptions { + BuildYamlOptions({ + this.providerNameSuffix, + }); + + factory BuildYamlOptions.fromMap(Map map) { + return BuildYamlOptions( + providerNameSuffix: map['provider_name_suffix'] as String?, + ); + } + + final String? providerNameSuffix; +} + extension on String { String get titled { return replaceFirstMapped( diff --git a/packages/riverpod_generator/lib/src/riverpod_generator.dart b/packages/riverpod_generator/lib/src/riverpod_generator.dart index b6b4c7eec..912300f34 100644 --- a/packages/riverpod_generator/lib/src/riverpod_generator.dart +++ b/packages/riverpod_generator/lib/src/riverpod_generator.dart @@ -22,9 +22,10 @@ const riverpodTypeChecker = TypeChecker.fromRuntime(Riverpod); @immutable // ignore: invalid_use_of_internal_member class RiverpodGenerator extends ParserGenerator { - RiverpodGenerator(this.configs); + RiverpodGenerator(Map mapConfig) + : config = BuildYamlOptions.fromMap(mapConfig); - final Map configs; + final BuildYamlOptions config; @override GlobalData parseGlobalData(LibraryElement library) { @@ -78,6 +79,7 @@ class RiverpodGenerator extends ParserGenerator { parameters: element.parameters.skip(1).toList(), valueDisplayType: _getUserModelType(element).getDisplayString(withNullability: true), + buildYamlOptions: config, ); } @@ -129,6 +131,7 @@ class RiverpodGenerator extends ParserGenerator { parameters: buildMethod.parameters, valueDisplayType: _getUserModelType(buildMethod) .getDisplayString(withNullability: true), + buildYamlOptions: config, ); } diff --git a/packages/riverpod_generator/test/build_yaml_config_test.dart b/packages/riverpod_generator/test/build_yaml_config_test.dart new file mode 100644 index 000000000..df4665de4 --- /dev/null +++ b/packages/riverpod_generator/test/build_yaml_config_test.dart @@ -0,0 +1,10 @@ +import 'package:riverpod_generator/src/models.dart'; +import 'package:test/test.dart'; + +void main() { + test('custom suffix', () async { + const map = {'provider_name_suffix': 'Pod'}; + final options = BuildYamlOptions.fromMap(map); + expect(options.providerNameSuffix, 'Pod'); + }); +}