diff --git a/example/lib/auto_route/app_router.dart b/example/lib/auto_route/app_router.dart new file mode 100644 index 0000000..8838bb8 --- /dev/null +++ b/example/lib/auto_route/app_router.dart @@ -0,0 +1,13 @@ +import 'package:auto_route/auto_route.dart'; +import 'app_router.gr.dart'; + +@AutoRouterConfig() +class AppRouter extends RootStackRouter { + @override + RouteType get defaultRouteType => const RouteType.adaptive(); + + @override + List get routes => [ + AutoRoute(page: SplashRoute.page, path: '/', initial: true), + ]; +} diff --git a/example/lib/auto_route/app_router.gr.dart b/example/lib/auto_route/app_router.gr.dart new file mode 100644 index 0000000..c354f48 --- /dev/null +++ b/example/lib/auto_route/app_router.gr.dart @@ -0,0 +1,29 @@ +// dart format width=80 +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// AutoRouterGenerator +// ************************************************************************** + +// ignore_for_file: type=lint +// coverage:ignore-file + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:auto_route/auto_route.dart' as _i2; +import 'package:example/splash_route.dart' as _i1; + +/// generated route for +/// [_i1.SplashRoute] +class SplashRoute extends _i2.PageRouteInfo { + const SplashRoute({List<_i2.PageRouteInfo>? children}) + : super(SplashRoute.name, initialChildren: children); + + static const String name = 'SplashRoute'; + + static _i2.PageInfo page = _i2.PageInfo( + name, + builder: (data) { + return const _i1.SplashRoute(); + }, + ); +} diff --git a/example/lib/freezed/theme_bloc.dart b/example/lib/freezed/theme_bloc.dart new file mode 100644 index 0000000..e92ebd2 --- /dev/null +++ b/example/lib/freezed/theme_bloc.dart @@ -0,0 +1,30 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'theme_bloc.freezed.dart'; +part 'theme_event.dart'; +part 'theme_state.dart'; + +class ThemeBloc extends Bloc { + ThemeBloc() : super(_Light()) { + on<_Load>(_loadThemeEvent); + on<_Set>(_setThemeEvent); + } + + FutureOr _loadThemeEvent( + _Load event, + Emitter emit, + ) async { + emit(_Light()); + } + + FutureOr _setThemeEvent( + _Set event, + Emitter emit, + ) async { + emit(_Light()); + } +} diff --git a/example/lib/freezed/theme_bloc.freezed.dart b/example/lib/freezed/theme_bloc.freezed.dart new file mode 100644 index 0000000..24d6971 --- /dev/null +++ b/example/lib/freezed/theme_bloc.freezed.dart @@ -0,0 +1,477 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'theme_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +/// @nodoc +mixin _$ThemeEvent { + @optionalTypeArgs + TResult when({ + required TResult Function() load, + required TResult Function(ThemeMode themeMode) set, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? load, + TResult? Function(ThemeMode themeMode)? set, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? load, + TResult Function(ThemeMode themeMode)? set, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Load value) load, + required TResult Function(_Set value) set, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Load value)? load, + TResult? Function(_Set value)? set, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Load value)? load, + TResult Function(_Set value)? set, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ThemeEventCopyWith<$Res> { + factory $ThemeEventCopyWith( + ThemeEvent value, $Res Function(ThemeEvent) then) = + _$ThemeEventCopyWithImpl<$Res, ThemeEvent>; +} + +/// @nodoc +class _$ThemeEventCopyWithImpl<$Res, $Val extends ThemeEvent> + implements $ThemeEventCopyWith<$Res> { + _$ThemeEventCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ThemeEvent + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$LoadImplCopyWith<$Res> { + factory _$$LoadImplCopyWith( + _$LoadImpl value, $Res Function(_$LoadImpl) then) = + __$$LoadImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$LoadImplCopyWithImpl<$Res> + extends _$ThemeEventCopyWithImpl<$Res, _$LoadImpl> + implements _$$LoadImplCopyWith<$Res> { + __$$LoadImplCopyWithImpl(_$LoadImpl _value, $Res Function(_$LoadImpl) _then) + : super(_value, _then); + + /// Create a copy of ThemeEvent + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$LoadImpl implements _Load { + const _$LoadImpl(); + + @override + String toString() { + return 'ThemeEvent.load()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$LoadImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() load, + required TResult Function(ThemeMode themeMode) set, + }) { + return load(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? load, + TResult? Function(ThemeMode themeMode)? set, + }) { + return load?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? load, + TResult Function(ThemeMode themeMode)? set, + required TResult orElse(), + }) { + if (load != null) { + return load(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Load value) load, + required TResult Function(_Set value) set, + }) { + return load(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Load value)? load, + TResult? Function(_Set value)? set, + }) { + return load?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Load value)? load, + TResult Function(_Set value)? set, + required TResult orElse(), + }) { + if (load != null) { + return load(this); + } + return orElse(); + } +} + +abstract class _Load implements ThemeEvent { + const factory _Load() = _$LoadImpl; +} + +/// @nodoc +abstract class _$$SetImplCopyWith<$Res> { + factory _$$SetImplCopyWith(_$SetImpl value, $Res Function(_$SetImpl) then) = + __$$SetImplCopyWithImpl<$Res>; + @useResult + $Res call({ThemeMode themeMode}); +} + +/// @nodoc +class __$$SetImplCopyWithImpl<$Res> + extends _$ThemeEventCopyWithImpl<$Res, _$SetImpl> + implements _$$SetImplCopyWith<$Res> { + __$$SetImplCopyWithImpl(_$SetImpl _value, $Res Function(_$SetImpl) _then) + : super(_value, _then); + + /// Create a copy of ThemeEvent + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? themeMode = null, + }) { + return _then(_$SetImpl( + themeMode: null == themeMode + ? _value.themeMode + : themeMode // ignore: cast_nullable_to_non_nullable + as ThemeMode, + )); + } +} + +/// @nodoc + +class _$SetImpl implements _Set { + const _$SetImpl({required this.themeMode}); + + @override + final ThemeMode themeMode; + + @override + String toString() { + return 'ThemeEvent.set(themeMode: $themeMode)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SetImpl && + (identical(other.themeMode, themeMode) || + other.themeMode == themeMode)); + } + + @override + int get hashCode => Object.hash(runtimeType, themeMode); + + /// Create a copy of ThemeEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SetImplCopyWith<_$SetImpl> get copyWith => + __$$SetImplCopyWithImpl<_$SetImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() load, + required TResult Function(ThemeMode themeMode) set, + }) { + return set(themeMode); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? load, + TResult? Function(ThemeMode themeMode)? set, + }) { + return set?.call(themeMode); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? load, + TResult Function(ThemeMode themeMode)? set, + required TResult orElse(), + }) { + if (set != null) { + return set(themeMode); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Load value) load, + required TResult Function(_Set value) set, + }) { + return set(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Load value)? load, + TResult? Function(_Set value)? set, + }) { + return set?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Load value)? load, + TResult Function(_Set value)? set, + required TResult orElse(), + }) { + if (set != null) { + return set(this); + } + return orElse(); + } +} + +abstract class _Set implements ThemeEvent { + const factory _Set({required final ThemeMode themeMode}) = _$SetImpl; + + ThemeMode get themeMode; + + /// Create a copy of ThemeEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SetImplCopyWith<_$SetImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ThemeState { + @optionalTypeArgs + TResult when({ + required TResult Function() light, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? light, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? light, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Light value) light, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Light value)? light, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Light value)? light, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ThemeStateCopyWith<$Res> { + factory $ThemeStateCopyWith( + ThemeState value, $Res Function(ThemeState) then) = + _$ThemeStateCopyWithImpl<$Res, ThemeState>; +} + +/// @nodoc +class _$ThemeStateCopyWithImpl<$Res, $Val extends ThemeState> + implements $ThemeStateCopyWith<$Res> { + _$ThemeStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ThemeState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$LightImplCopyWith<$Res> { + factory _$$LightImplCopyWith( + _$LightImpl value, $Res Function(_$LightImpl) then) = + __$$LightImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$LightImplCopyWithImpl<$Res> + extends _$ThemeStateCopyWithImpl<$Res, _$LightImpl> + implements _$$LightImplCopyWith<$Res> { + __$$LightImplCopyWithImpl( + _$LightImpl _value, $Res Function(_$LightImpl) _then) + : super(_value, _then); + + /// Create a copy of ThemeState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$LightImpl implements _Light { + const _$LightImpl(); + + @override + String toString() { + return 'ThemeState.light()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$LightImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() light, + }) { + return light(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? light, + }) { + return light?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? light, + required TResult orElse(), + }) { + if (light != null) { + return light(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Light value) light, + }) { + return light(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Light value)? light, + }) { + return light?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Light value)? light, + required TResult orElse(), + }) { + if (light != null) { + return light(this); + } + return orElse(); + } +} + +abstract class _Light implements ThemeState { + const factory _Light() = _$LightImpl; +} diff --git a/example/lib/freezed/theme_event.dart b/example/lib/freezed/theme_event.dart new file mode 100644 index 0000000..d9b4fc3 --- /dev/null +++ b/example/lib/freezed/theme_event.dart @@ -0,0 +1,10 @@ +part of 'theme_bloc.dart'; + +@freezed +sealed class ThemeEvent with _$ThemeEvent { + const factory ThemeEvent.load() = _Load; + + const factory ThemeEvent.set({ + required ThemeMode themeMode, + }) = _Set; +} diff --git a/example/lib/freezed/theme_state.dart b/example/lib/freezed/theme_state.dart new file mode 100644 index 0000000..5c876c8 --- /dev/null +++ b/example/lib/freezed/theme_state.dart @@ -0,0 +1,6 @@ +part of 'theme_bloc.dart'; + +@freezed +sealed class ThemeState with _$ThemeState { + const factory ThemeState.light() = _Light; +} diff --git a/example/lib/models/freezed_union.freezed.dart b/example/lib/models/freezed_union.freezed.dart index 1fba332..a3d2014 100644 --- a/example/lib/models/freezed_union.freezed.dart +++ b/example/lib/models/freezed_union.freezed.dart @@ -12,7 +12,7 @@ part of 'freezed_union.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); /// @nodoc mixin _$FreezedUnion { @@ -72,6 +72,9 @@ class _$FreezedUnionCopyWithImpl<$Res, $Val extends FreezedUnion> final $Val _value; // ignore: unused_field final $Res Function($Val) _then; + + /// Create a copy of FreezedUnion + /// with the given fields replaced by the non-null parameter values. } /// @nodoc @@ -87,6 +90,9 @@ class __$$HomeImplCopyWithImpl<$Res> implements _$$HomeImplCopyWith<$Res> { __$$HomeImplCopyWithImpl(_$HomeImpl _value, $Res Function(_$HomeImpl) _then) : super(_value, _then); + + /// Create a copy of FreezedUnion + /// with the given fields replaced by the non-null parameter values. } /// @nodoc @@ -192,6 +198,8 @@ class __$$UserUnionImplCopyWithImpl<$Res> _$UserUnionImpl _value, $Res Function(_$UserUnionImpl) _then) : super(_value, _then); + /// Create a copy of FreezedUnion + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ @@ -230,7 +238,9 @@ class _$UserUnionImpl implements UserUnion { @override int get hashCode => Object.hash(runtimeType, user); - @JsonKey(ignore: true) + /// Create a copy of FreezedUnion + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') _$$UserUnionImplCopyWith<_$UserUnionImpl> get copyWith => @@ -303,7 +313,10 @@ abstract class UserUnion implements FreezedUnion { const factory UserUnion(final User user) = _$UserUnionImpl; User get user; - @JsonKey(ignore: true) + + /// Create a copy of FreezedUnion + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) _$$UserUnionImplCopyWith<_$UserUnionImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/example/lib/splash_route.dart b/example/lib/splash_route.dart new file mode 100644 index 0000000..0eff55c --- /dev/null +++ b/example/lib/splash_route.dart @@ -0,0 +1,15 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'splash_screen.dart'; + +@RoutePage() +class SplashRoute extends StatelessWidget { + const SplashRoute({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return SplashScreen(); + } +} diff --git a/example/lib/splash_screen.dart b/example/lib/splash_screen.dart new file mode 100644 index 0000000..c9b6621 --- /dev/null +++ b/example/lib/splash_screen.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class SplashScreen extends StatelessWidget { + const SplashScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/example/lib/user_mappr.auto_mappr.dart b/example/lib/user_mappr.auto_mappr.dart index 0dc7fd3..4bdc540 100644 --- a/example/lib/user_mappr.auto_mappr.dart +++ b/example/lib/user_mappr.auto_mappr.dart @@ -1,3 +1,4 @@ +// dart format width=80 // GENERATED CODE - DO NOT MODIFY BY HAND // ************************************************************************** @@ -64,16 +65,23 @@ class $UserMappr implements _i1.AutoMapprInterface { /// {@macro AutoMapprInterface:tryConvert} /// {@macro package:example/user_mappr.dart} @override - TARGET? tryConvert(SOURCE? model) { + TARGET? tryConvert( + SOURCE? model, { + void Function(Object error, StackTrace stackTrace, SOURCE? source)? + onMappingError, + }) { if (canConvert(recursive: false)) { - return _convert( + return _safeConvert( model, - canReturnNull: true, + onMappingError: onMappingError, ); } for (final mappr in _delegates) { if (mappr.canConvert()) { - return mappr.tryConvert(model); + return mappr.tryConvert( + model, + onMappingError: onMappingError, + ); } } @@ -103,13 +111,20 @@ class $UserMappr implements _i1.AutoMapprInterface { /// {@macro package:example/user_mappr.dart} @override Iterable tryConvertIterable( - Iterable model) { + Iterable model, { + void Function(Object error, StackTrace stackTrace, SOURCE? source)? + onMappingError, + }) { if (canConvert(recursive: false)) { - return model.map((item) => _convert(item, canReturnNull: true)); + return model.map( + (item) => _safeConvert(item, onMappingError: onMappingError)); } for (final mappr in _delegates) { if (mappr.canConvert()) { - return mappr.tryConvertIterable(model); + return mappr.tryConvertIterable( + model, + onMappingError: onMappingError, + ); } } @@ -138,13 +153,23 @@ class $UserMappr implements _i1.AutoMapprInterface { /// /// {@macro package:example/user_mappr.dart} @override - List tryConvertList(Iterable model) { + List tryConvertList( + Iterable model, { + void Function(Object error, StackTrace stackTrace, SOURCE? source)? + onMappingError, + }) { if (canConvert(recursive: false)) { - return tryConvertIterable(model).toList(); + return tryConvertIterable( + model, + onMappingError: onMappingError, + ).toList(); } for (final mappr in _delegates) { if (mappr.canConvert()) { - return mappr.tryConvertList(model); + return mappr.tryConvertList( + model, + onMappingError: onMappingError, + ); } } @@ -173,13 +198,23 @@ class $UserMappr implements _i1.AutoMapprInterface { /// /// {@macro package:example/user_mappr.dart} @override - Set tryConvertSet(Iterable model) { + Set tryConvertSet( + Iterable model, { + void Function(Object error, StackTrace stackTrace, SOURCE? source)? + onMappingError, + }) { if (canConvert(recursive: false)) { - return tryConvertIterable(model).toSet(); + return tryConvertIterable( + model, + onMappingError: onMappingError, + ).toSet(); } for (final mappr in _delegates) { if (mappr.canConvert()) { - return mappr.tryConvertSet(model); + return mappr.tryConvertSet( + model, + onMappingError: onMappingError, + ); } } @@ -204,6 +239,35 @@ class $UserMappr implements _i1.AutoMapprInterface { throw Exception('No ${model.runtimeType} -> $targetTypeOf mapping.'); } + TARGET? _safeConvert( + SOURCE? model, { + void Function(Object error, StackTrace stackTrace, SOURCE? source)? + onMappingError, + }) { + if (!useSafeMapping()) { + return _convert( + model, + canReturnNull: true, + ); + } + try { + return _convert( + model, + canReturnNull: true, + ); + } catch (e, s) { + onMappingError?.call(e, s, model); + return null; + } + } + + /// {@macro AutoMapprInterface:useSafeMapping} + /// {@macro package:example/user_mappr.dart} + @override + bool useSafeMapping() { + return false; + } + _i3.User _map__i2$UserDto_To__i3$User(_i2.UserDto? input) { final model = input; if (model == null) { diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ebc265c..8a29bd4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -6,22 +6,43 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.19.2 <3.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: - json_serializable: ^6.6.1 - json_annotation: ^4.8.1 - freezed_annotation: ^2.4.1 - auto_mappr_annotation: 2.1.0 + json_serializable: ^6.9.3 + json_annotation: ^4.9.0 + freezed_annotation: ^2.4.4 + auto_route: ^9.3.0 + # due to conflict with json_serializable that uses source_gen ^2.0.0 + auto_mappr_annotation: + git: + url: https://github.com/amrgetment/auto_mappr.git + ref: main + path: packages/auto_mappr_annotation + flutter_bloc: ^9.0.0 dev_dependencies: - build_runner: ^2.3.3 + build_runner: ^2.4.14 cached_build_runner: path: ../ - auto_mappr: 2.2.0 + # due to conflict with json_serializable that uses source_gen ^2.0.0 + auto_mappr: + git: + url: https://github.com/amrgetment/auto_mappr.git + ref: main + path: packages/auto_mappr - flutter_lints: ^2.0.0 - freezed: ^2.4.6 + flutter_lints: ^5.0.0 + freezed: ^2.5.7 + auto_route_generator: ^9.0.0 + +dependency_overrides: + # due to conflict with json_serializable that uses source_gen ^2.0.0 + auto_mappr_annotation: + git: + url: https://github.com/amrgetment/auto_mappr.git + ref: main + path: packages/auto_mappr_annotation flutter: uses-material-design: true diff --git a/lib/cached_build_runner.dart b/lib/cached_build_runner.dart index e15d35e..8cb8786 100644 --- a/lib/cached_build_runner.dart +++ b/lib/cached_build_runner.dart @@ -12,7 +12,7 @@ /// - `utils/log.dart` for logging messages to the console. /// - `utils/utils.dart` for utility functions. -library cached_build_runner; +library; import 'dart:async'; import 'dart:io'; @@ -112,7 +112,7 @@ class CachedBuildRunner implements Disposable { Logger.v(badFiles.map((e) => e.path).join('\n')); /// let's handle bad files - by generating the .g.dart / .mocks.dart files for them - final success = _buildRunnerWrapper.runBuild(badFiles); + final success = await _buildRunnerWrapper.runBuild(badFiles); if (!success) return; diff --git a/lib/core/build_runner_wrapper.dart b/lib/core/build_runner_wrapper.dart index ffd3085..8a43099 100644 --- a/lib/core/build_runner_wrapper.dart +++ b/lib/core/build_runner_wrapper.dart @@ -7,7 +7,7 @@ import 'package:cached_build_runner/utils/utils.dart'; class BuildRunnerWrapper { const BuildRunnerWrapper(); - bool runBuild(List files) { + Future runBuild(List files) async { if (files.isEmpty) return true; Logger.header( 'Generating Codes for non-cached files, found ${files.length} files', @@ -17,22 +17,52 @@ class BuildRunnerWrapper { final filterList = _getBuildFilterList(files); - Logger.d('Run: "flutter pub run build_runner build --build-filter $filterList"'); - final process = Process.runSync( + Logger.d( + 'Run: "flutter pub run build_runner build --build-filter $filterList"', + ); + final process = await Process.start( 'flutter', - ['pub', 'run', 'build_runner', 'build', '--delete-conflicting-outputs', '--build-filter', filterList], + [ + 'pub', + 'run', + 'build_runner', + 'build', + '--delete-conflicting-outputs', + '--build-filter', + filterList, + ], workingDirectory: Utils.projectDirectory, runInShell: true, ); - final stdOut = process.stdout?.toString() ?? ''; - final stdErrr = process.stderr?.toString() ?? ''; - Logger.v(stdOut.trim(), showPrefix: false); - if (stdErrr.trim().isNotEmpty) { - Logger.e(stdErrr.trim()); - } + /// Listen to the standard output (stdout) of the process. + /// - If the log is an elapsed-time `[INFO]` log (e.g., `[INFO] 2m 10s elapsed, 946/1016 actions completed.`), + /// it updates the same line instead of printing a new one. + /// - All other logs are printed normally. + process.stdout.transform(const SystemEncoding().decoder).listen((data) { + // Regex pattern to match only elapsed-time logs + final elapsedTimeLogPattern = + RegExp(r'\[INFO\] \d+m \d+s elapsed, \d+/\d+ actions completed\.'); + + if (elapsedTimeLogPattern.hasMatch(data)) { + stdout.write( + '\r$data', + ); // Overwrites the previous line with the latest progress + } else { + print(data); // Prints normally for other logs + } + }); + + process.stderr.transform(const SystemEncoding().decoder).listen((data) { + if (data.trim().isNotEmpty) { + Logger.e('Error: $data'); + } + }); + + final exitCode = await process.exitCode; + Logger.d('Process exited with code: $exitCode'); - return process.exitCode == 0; + return exitCode == 0; } /// Returns a comma-separated string of the file paths from the given list of [CodeFile]s diff --git a/lib/core/dependency_visitor.dart b/lib/core/dependency_visitor.dart index b0a3b89..1038fec 100644 --- a/lib/core/dependency_visitor.dart +++ b/lib/core/dependency_visitor.dart @@ -45,6 +45,8 @@ class DependencyVisitor { final relativeImportLines = importLines[_relativeImportsConst] ?? const []; final absoluteImportLines = importLines[_absoluteImportsConst] ?? const []; + final currentDirectory = path.dirname(filePath); + final paths = []; // absolute import lines @@ -54,7 +56,7 @@ class DependencyVisitor { // relative import lines for (final import in relativeImportLines) { - paths.add(path.normalize(path.join(_dirName, import))); + paths.add(path.normalize(path.join(currentDirectory, import))); } return paths; diff --git a/lib/model/code_file_generated_type.dart b/lib/model/code_file_generated_type.dart index e69de29..59d254d 100644 --- a/lib/model/code_file_generated_type.dart +++ b/lib/model/code_file_generated_type.dart @@ -0,0 +1,4 @@ +enum CodeFileGeneratedType { + import, + partFile, +} diff --git a/pubspec.yaml b/pubspec.yaml index 3cec055..ce2cd17 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,13 +12,13 @@ dependencies: args: ^2.4.0 barbecue: ^0.5.0 crypto: ^3.0.1 - get_it: ^7.6.7 + get_it: ^8.0.3 hive: ^2.2.3 - logger: ^1.1.0 + logger: ^2.5.0 meta: ^1.11.0 path: ^1.8.2 synchronized: ^3.0.1 text_table: ^4.0.3 dev_dependencies: - netglade_analysis: ^7.0.0 + netglade_analysis: ^15.0.0