Skip to content
This repository has been archived by the owner on Sep 24, 2024. It is now read-only.

Misc sprint fixes #121

Merged
merged 4 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions automation/makefile/operate.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ format:
@fvm dart fix --apply .
@fvm dart format -l 80 --fix .

create-flutter-runners:
@fvm flutter create --project-name $(PACKAGE) --org $(ORG) .

setup:
@echo "* Getting dependencies for setup tool *"
@fvm dart pub get --directory=./tool/setup_clone
@echo "* Setting up the project *"
@fvm dart ./tool/setup_clone/main.dart $(NAME)
@make prepare

clean:
@echo "* Cleaning the project *"
Expand Down
60 changes: 45 additions & 15 deletions documentation/makefile.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
This file is auto-generated
## Index

- [Build](#build)
- [Build android](#build-android)
- [Build ios](#build-ios)
- [Build web](#build-web)
- [Clean](#clean)
- [Coverage](#coverage)
- [Create flutter runners](#create-flutter-runners)
- [Dependency validator](#dependency-validator)
- [Doc](#doc)
- [Doctor](#doctor)
Expand Down Expand Up @@ -48,22 +50,38 @@ This file is auto-generated

## Targets

### Build
### Build android

#### Name

`build`
`build-android`

#### Perquisites

- `pub-get`
- `clean`

#### Recipe

```Makefile
@echo "Building Android APK"
@make clean
@fvm flutter build apk --release --tree-shake-icons --no-shrink
@fvm flutter build apk --no-pub --no-shrink
```

### Build ios

#### Name

`build-ios`

#### Perquisites

- `clean`

#### Recipe

```Makefile
@echo "Building iOS IPA"
@fvm flutter build ipa --no-pub
```

### Build web
Expand All @@ -74,14 +92,13 @@ This file is auto-generated

#### Perquisites

- `pub-get`
- `clean`

#### Recipe

```Makefile
@echo "Building Web app"
@make clean
@fvm flutter build web --release --dart-define=FLUTTER_WEB_USE_SKIA=true --no-source-maps --pwa-strategy offline-first
@fvm flutter build web --dart-define=FLUTTER_WEB_USE_SKIA=true --no-pub --no-source-maps --pwa-strategy offline-first
```

### Clean
Expand All @@ -92,15 +109,16 @@ This file is auto-generated

#### Used by

- [Build](#build)
- [Build android](#build-android)
- [Build ios](#build-ios)
- [Build web](#build-web)

#### Recipe

```Makefile
@echo "* Cleaning the project *"
@rm -rf build .flutter-plugins .flutter-plugins-dependencies coverage .dart_tool .packages pubspec.lock
@fvm flutter clean
@grind delete-flutter-artifacts
@grind clean
@git clean -d
@make pub-get
```
Expand Down Expand Up @@ -128,6 +146,18 @@ Run tests and generate coverage report
@genhtml -o coverage coverage/lcov.info
```

### Create flutter runners

#### Name

`create-flutter-runners`

#### Recipe

```Makefile
@fvm flutter create --project-name $(PACKAGE) --org $(ORG) .
```

### Dependency validator

#### Name
Expand Down Expand Up @@ -461,6 +491,7 @@ Prepares the application for the first run. Fetches latest dependencies, and ge
#### Used by

- [First run](#first-run)
- [Setup](#setup)

#### Perquisites

Expand All @@ -484,8 +515,6 @@ Fetches latest dependencies using Flutter Version Manager.

#### Used by

- [Build](#build)
- [Build web](#build-web)
- [Clean](#clean)
- [Gen build](#gen-build)
- [Gen build delete](#gen-build-delete)
Expand Down Expand Up @@ -617,6 +646,7 @@ Staging/Stage/Model/Pre-production
@fvm dart pub get --directory=./tool/setup_clone
@echo "* Setting up the project *"
@fvm dart ./tool/setup_clone/main.dart $(NAME)
@make prepare
```

### Simulator
Expand Down Expand Up @@ -680,7 +710,7 @@ Run tests
#### Recipe

```Makefile
@time flutter test --concurrency=6 --dart-define=environment=testing --coverage test/
@grind run-tests
```

### Version
Expand Down
10 changes: 10 additions & 0 deletions lib/src/core/extension/src/stream.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:purple_starter/src/core/logic/exhaust_map_stream_transformer.dart';

extension StreamX<A> on Stream<A> {
Stream<B> exhaustMap<B>(ExhaustMapStreamTransformerMapper<A, B> mapper) =>
transform(
ExhaustMapStreamTransformer(
mapper: mapper,
),
);
}
82 changes: 82 additions & 0 deletions lib/src/core/logic/exhaust_map_stream_transformer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// ignore_for_file: cancel_subscriptions

import 'dart:async';

import 'package:meta/meta.dart';
import 'package:pure/pure.dart';

typedef ExhaustMapStreamTransformerMapper<A, B> = Stream<B> Function(A event);

@immutable
class ExhaustMapStreamTransformer<A, B> extends StreamTransformerBase<A, B> {
final ExhaustMapStreamTransformerMapper<A, B> _mapper;

const ExhaustMapStreamTransformer({
required ExhaustMapStreamTransformerMapper<A, B> mapper,
}) : _mapper = mapper;

@override
Stream<B> bind(Stream<A> stream) {
StreamSubscription<B>? mappedSubscription;
StreamSubscription<A>? sourceSubscription;

Future<void> manipulateSubscriptions(
FutureOr<void> Function(StreamSubscription<Object?> subscription) action,
) async {
final perform = action.nullable;
await perform(mappedSubscription);
await perform(sourceSubscription);
}

void pauseSubscriptions() {
manipulateSubscriptions((subscription) => subscription.pause());
}

void resumeSubscriptions() {
manipulateSubscriptions((subscription) => subscription.resume());
}

final controller = stream.isBroadcast
? StreamController<B>.broadcast(sync: true)
: StreamController<B>(
onPause: pauseSubscriptions,
onResume: resumeSubscriptions,
sync: true,
);

Future<void> cancelSubscriptions() => manipulateSubscriptions(
(subscription) => subscription.cancel(),
);

void forgetMappedSubscription() {
mappedSubscription?.cancel();
mappedSubscription = null;
}

void wrapUp() {
cancelSubscriptions().whenComplete(controller.close);
}

void startListening() {
final addError = controller.addError;

sourceSubscription = stream.listen(
(event) {
mappedSubscription ??= _mapper(event).listen(
controller.add,
onError: addError,
onDone: forgetMappedSubscription,
);
},
onError: addError,
onDone: wrapUp,
);
}

controller
..onListen = startListening
..onCancel = cancelSubscriptions;

return controller.stream;
}
}
8 changes: 8 additions & 0 deletions lib/src/feature/app/bloc/initialization_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:pure/pure.dart';
import 'package:purple_starter/src/core/extension/extensions.dart';
import 'package:purple_starter/src/core/extension/src/stream.dart';
import 'package:purple_starter/src/core/model/environment_storage.dart';
import 'package:select_annotation/select_annotation.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Expand Down Expand Up @@ -143,4 +144,11 @@ class InitializationBloc
event.when(
initialize: _initialize,
);

@override
Stream<Transition<InitializationEvent, InitializationState>> transformEvents(
Stream<InitializationEvent> events,
TransitionFunction<InitializationEvent, InitializationState> transitionFn,
) =>
events.exhaustMap(transitionFn);
}
49 changes: 20 additions & 29 deletions tool/setup_clone/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import 'dart:async';

import 'dart:io';

Future<void> main(List<String> args) => Environment.run(
environment: createEnvironment(args),
body: performSetup,
);
Future<void> main(List<String> args) => Process.run(
'make',
['help'],
).then((value) => print(value.stdout));
// => Environment.run(
// environment: createEnvironment(args),
// body: performSetup,
// );

String capitalized(String source) =>
source[0].toUpperCase() + source.substring(1);
Expand Down Expand Up @@ -194,38 +198,25 @@ Future<void> createEmptyReadme() async {
await sink.close();
}

Future<bool> runProcessConcealing(
String command,
List<String> arguments,
) async {
try {
await Process.run(command, arguments);

return true;
} on Object {
return false;
}
}

Future<void> runFlutter(List<String> commands) => Process.run(
'fvm',
['flutter', ...commands],
Future<void> runMake(
String name, [
List<String> arguments = const [],
]) =>
Process.run(
'make',
[name, ...arguments],
);

Future<void> createFlutterRunners() {
final packageName = Environment.current().newName.packageName;

return runFlutter([
'create',
'--project-name',
packageName,
'--org',
'com.$packageName',
'.',
]);
return runMake(
'create-flutter-runners',
['PACKAGE=$packageName', 'ORG=com.$packageName'],
);
}

Future<void> format() => runFlutter(const ['format']);
Future<void> format() => runMake('format');

String assembleMessage(String newName, int replaced, Duration duration) =>
'Setup complete! '
Expand Down