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

functional_ref fix corrupts files #3804

Closed
lishaduck opened this issue Oct 23, 2024 · 2 comments · Fixed by #3814
Closed

functional_ref fix corrupts files #3804

lishaduck opened this issue Oct 23, 2024 · 2 comments · Fixed by #3814
Assignees
Labels
bug Something isn't working

Comments

@lishaduck
Copy link
Contributor

lishaduck commented Oct 23, 2024

Describe the bug
I'm using the functional_ref lint as a codemod to Rivepod v2.6.0, but it only works sometimes.

It often corrupts large files (the repro below), but also the message is wrong,1 and it always imports "package:riverpod" (once per fix when fix-all-ing!) even if only "package:hooks_riverpod" is in my dependencies.
It doesn't corrupt it using fix-all in the editor, but the other issues still trigger.

To Reproduce

(I picked a smallish file, I tried to minimize it a bit but it seems to be size-dependent)

Before

/// This library contains the authentication feature's business logic.
library;

import "dart:typed_data";

import "package:riverpod_annotation/riverpod_annotation.dart";

import "../data/auth_repository.dart";
import "../domain/account_type.dart";
import "../domain/pirate_auth_model.dart";
import "../domain/pirate_user_entity.dart";

part "auth_service.g.dart";

/// Get the current user.
@Riverpod(keepAlive: true)
base class PirateAuthService extends _$PirateAuthService {
  @override
  FutureOr<PirateAuthModel> build() async {
    return _createSession(anonymous: true);
  }

  /// Authenticate the current user.
  Future<void> authenticate() async {
    state = await AsyncValue.guard(_createSession);
  }

  Future<PirateAuthModel> _createSession({bool anonymous = false}) async {
    final auth = ref.read(authProvider);
    final account = await auth.authenticate(anonymous: anonymous);

    return PirateAuthModel(
      user: account,
    );
  }

  /// Create a new anonymous session for the user.
  Future<void> anonymous() async {
    state = await AsyncValue.guard(() => _createSession(anonymous: true));
  }
}

/// Get the current user with minimal fuss.
///
/// Use [pirateAuthServiceProvider] for more granular output.
@Riverpod(keepAlive: true)
Future<PirateUserEntity> user(UserRef ref) async => await ref.watch(
      pirateAuthServiceProvider.selectAsync((value) => value.user),
    );

/// Get the current user's name.
///
/// Named as such to prevent a naming conflict with riverpod.
@riverpod
Future<String> username(UsernameRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.name));

/// Get the current user's email address.
@riverpod
Future<String> email(EmailRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.email));

/// Get the current user's avatar.
@riverpod
Future<Uint8List> avatar(AvatarRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.avatar));

/// Get the current user's account type.
@riverpod
Future<AccountType> accountType(AccountTypeRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.accountType));

/// Get the current user's ID.
@riverpod
Future<int> id(IdRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.id));

After

/// This library contains the authentication feature's business logic.
library;

import "dart:typed_data";

import "package:riverpod/riverpod.dart";
import "package:riverpod/riverpod.dart";
import "package:riverpod/riverpod.dart";
import "package:riverpod/riverpod.dart";
import "package:riverpod/riverpod.dart";
import "package:riverpod/riverpod.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";

import "../data/auth_repository.dart";
import "../domain/account_type.dart";
import "../domain/pirate_auth_model.dart";
import "../domain/pirate_user_entity.dart";

part "auth_service.g.dart";

/// Get the current user.
@Riverpod(keepAlive: true)
base class PirateAuthService extends _$PirateAuthService {
  @override
  FutureOr<PirateAuthModel> build() async {
    return _createSession(anonymous: true);
  }

  /// Authenticate the current user.
  Future<void> authenticate() async {
    state = await AsyncValue.guard(_createSession);
  }

  Future<PirateAuthModel> _createSession({bool anonymous = false}) async {
    final auth = ref.read(authProvider);
    final account = await auth.authenticate(anonymous: anonymous);

    return PirateAuthModel(
      user: account,
    );
  }

  /// Create a new anonymous session for the user.
  Future<void> anonymous() async {
    state = await AsyncValue.guard(() => _crRef ion(anonymous: true));
  }
}

/// Get the current user with minimal fuss.
///
/// Use [pirateAuthServiceProvider] for more granular output.
@Riverpod(keepAlive: true)
Future<PirateUserEntity> user(UserRef ref) async => await ref.watch(
      pirateAuthServiceProvider.selectAsync((Ref lue.user),
    );

/// Get the current user's name.
///
/// Named as such to prevent a naming conflict with riverpod.
@riverpod
Future<String> username(UsernameRef ref) async =>
    await ref.watch(uRef er.selectAsync((value) => value.name));

/// Get the current user's email address.
@riverpod
Future<String> email(EmailRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => valuRef 

/// Get the current user's avatar.
@riverpod
Future<Uint8List> avatar(AvatarRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.avatar));

/// Get the current user's account type.
@Ref <AccountType> accountType(AccountTypeRef ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.accountType));

/// Get the current user's ID.
@riverpod
Future<int> id(Ref ref) async =>
    await ref.watch(userProvider.selectAsync((value) => value.id));

Diff

diff --git a/lib/features/auth/application/auth_service.dart b/lib/features/auth/application/auth_service.dart
index 6f8355d..f3a934a 100644
--- a/lib/features/auth/application/auth_service.dart
+++ b/lib/features/auth/application/auth_service.dart
@@ -3,6 +3,12 @@ library;
 
 import "dart:typed_data";
 
+import "package:riverpod/riverpod.dart";
+import "package:riverpod/riverpod.dart";
+import "package:riverpod/riverpod.dart";
+import "package:riverpod/riverpod.dart";
+import "package:riverpod/riverpod.dart";
+import "package:riverpod/riverpod.dart";
 import "package:riverpod_annotation/riverpod_annotation.dart";
 
 import "../data/auth_repository.dart";
@@ -36,7 +42,7 @@ base class PirateAuthService extends _$PirateAuthService {
 
   /// Create a new anonymous session for the user.
   Future<void> anonymous() async {
-    state = await AsyncValue.guard(() => _createSession(anonymous: true));
+    state = await AsyncValue.guard(() => _crRef ion(anonymous: true));
   }
 }
 
@@ -45,7 +51,7 @@ base class PirateAuthService extends _$PirateAuthService {
 /// Use [pirateAuthServiceProvider] for more granular output.
 @Riverpod(keepAlive: true)
 Future<PirateUserEntity> user(UserRef ref) async => await ref.watch(
-      pirateAuthServiceProvider.selectAsync((value) => value.user),
+      pirateAuthServiceProvider.selectAsync((Ref lue.user),
     );
 
 /// Get the current user's name.
@@ -53,12 +59,12 @@ Future<PirateUserEntity> user(UserRef ref) async => await ref.watch(
 /// Named as such to prevent a naming conflict with riverpod.
 @riverpod
 Future<String> username(UsernameRef ref) async =>
-    await ref.watch(userProvider.selectAsync((value) => value.name));
+    await ref.watch(uRef er.selectAsync((value) => value.name));
 
 /// Get the current user's email address.
 @riverpod
 Future<String> email(EmailRef ref) async =>
-    await ref.watch(userProvider.selectAsync((value) => value.email));
+    await ref.watch(userProvider.selectAsync((value) => valuRef 
 
 /// Get the current user's avatar.
 @riverpod
@@ -66,11 +72,10 @@ Future<Uint8List> avatar(AvatarRef ref) async =>
     await ref.watch(userProvider.selectAsync((value) => value.avatar));
 
 /// Get the current user's account type.
-@riverpod
-Future<AccountType> accountType(AccountTypeRef ref) async =>
+@Ref <AccountType> accountType(AccountTypeRef ref) async =>
     await ref.watch(userProvider.selectAsync((value) => value.accountType));
 
 /// Get the current user's ID.
 @riverpod
-Future<int> id(IdRef ref) async =>
+Future<int> id(Ref ref) async =>
     await ref.watch(userProvider.selectAsync((value) => value.id));

Expected behavior
It'd work fine.

Footnotes

  1. "Functional providers must receive a ref matching the provider name as their first positional parameter." (Not anymore)

@lishaduck lishaduck added bug Something isn't working needs triage labels Oct 23, 2024
@rrousselGit
Copy link
Owner

I'm already working on it :)

@rrousselGit
Copy link
Owner

Should be fixed with the newer releases.
Make sure to run dart pub upgrade

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants