Skip to content

Commit

Permalink
Add flavors and generated code on top of base flutter app
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidDWiser committed Jan 16, 2024
1 parent 2c57475 commit f7b62a8
Show file tree
Hide file tree
Showing 117 changed files with 403 additions and 4,075 deletions.
3 changes: 3 additions & 0 deletions packages/rx_bloc_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [3.4.0]
* Add changes here

## [3.3.1]
* Update the build_custom fastlane task so that if the required environment variables do not exist the user will be prompted to enter their values
* Convert the expected fastlane environment variables to uppercase
Expand Down
5 changes: 5 additions & 0 deletions packages/rx_bloc_cli/bin/compile_bundles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ dart run mason_cli:mason bundle \
-o lib/src/templates/ \
mason_templates/bricks/rx_bloc_base

dart run mason_cli:mason bundle \
-t dart \
-o lib/src/templates/ \
mason_templates/bricks/rx_bloc_flavor_config

dart run mason_cli:mason bundle \
-t dart \
-o lib/src/templates/ \
Expand Down
2 changes: 2 additions & 0 deletions packages/rx_bloc_cli/bin/compile_win.bat
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dart run mason_cli:mason bundle -t dart mason_templates/bricks/rx_bloc_base ^
dart run mason_cli:mason bundle -t dart mason_templates/bricks/rx_bloc_flavor_config ^
& dart run mason_cli:mason bundle -t dart mason_templates/bricks/feature_counter ^
& dart run mason_cli:mason bundle -t dart mason_templates/bricks/feature_deeplink ^
& dart run mason_cli:mason bundle -t dart mason_templates/bricks/feature_widget_toolkit ^
Expand All @@ -17,6 +18,7 @@ dart run mason_cli:mason bundle -t dart mason_templates/bricks/rx_bloc_base ^
& dart run mason_cli:mason bundle -t dart mason_templates/bricks/lib_analytics ^
& dart run mason_cli:mason bundle -t dart mason_templates/bricks/lib_auth_matrix ^
& move /Y rx_bloc_base_bundle.dart lib\src\templates\ ^
& move /Y rx_bloc_flavor_config.dart lib\src\templates\ ^
& move /Y feature_counter_bundle.dart lib\src\templates\ ^
& move /Y feature_deeplink_bundle.dart lib\src\templates\ ^
& move /Y feature_widget_toolkit_bundle.dart lib\src\templates\ ^
Expand Down
4 changes: 2 additions & 2 deletions packages/rx_bloc_cli/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Before you start working on your app, make sure you familiarize yourself with th

| Path | Contains |
|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `lib/main.dart` | The production flavour of the app. |
| `lib/main_prod.dart` | The production flavour of the app. |
| `lib/main_dev.dart` | The development flavour of the app. |
| `lib/main_sit.dart` | The SIT flavour of the app. |
| `lib/main_uat.dart` | The UAT flavour of the app. |
Expand Down Expand Up @@ -307,7 +307,7 @@ Full translation key (feature name+separator+translation key): notifications___o

Before you start using analytics, you need to add platform specific configurations:
1. The `iOS` configuration files can be found at `ios/environments/[flavor]]/firebase/GoogleService-Info.plist`
2. For `Android` the configuration files are located at `android/app/src/[flavor]/google-services.json`
2. For `Android` the configuration files are located at `android/environments/[flavor]/google-services.json`
3. All `Web` analytics configurations can be found inside `lib/base/app/config/firebase_web_config.js`

Every flavor represents a separate Firebase project that will be used for app tracking. For each flavor, based on the targeted platforms you'll have to download the [configuration files][firebase_configs_lnk] and place them in the appropriate location mentioned above.
Expand Down
93 changes: 66 additions & 27 deletions packages/rx_bloc_cli/lib/src/commands/create_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:io';

import 'package:args/command_runner.dart';
import 'package:mason/mason.dart';
import 'package:rx_bloc_cli/src/templates/rx_bloc_flavor_config_bundle.dart';

import '../extensions/arg_parser_extensions.dart';
import '../extensions/arg_results_extensions.dart';
Expand All @@ -12,6 +13,7 @@ import '../models/generator_arguments_provider.dart';
import '../models/readers/interactive_arguments_reader.dart';
import '../models/readers/non_interactive_arguments_reader.dart';
import '../templates/rx_bloc_base_bundle.dart';
import '../utils/flavor_generator.dart';
import '../utils/git_ignore_creator.dart';

/// CreateCommand is a custom command that helps you create a new project.
Expand All @@ -24,15 +26,18 @@ class CreateCommand extends Command<int> {
Logger? logger,
MasonBundle? bundle,
Future<MasonGenerator> Function(MasonBundle)? generator,
Map<String, dynamic>? vars,
}) : _logger = logger ?? Logger(),
_bundleGenerator = BundleGenerator(bundle ?? rxBlocBaseBundle),
_vars = vars,
_generator = generator ?? MasonGenerator.fromBundle {
argParser.addCommandArguments(CommandArguments.values);
}

final Logger _logger;
final BundleGenerator _bundleGenerator;
final Future<MasonGenerator> Function(MasonBundle) _generator;
final Map<String, dynamic>? _vars;

/// region Command requirements
Expand All @@ -45,6 +50,7 @@ class CreateCommand extends Command<int> {
@override
Future<int> run() async {
final arguments = _readGeneratorArguments();
await _preGen(arguments);
await _generateViaMasonBundle(arguments);
await _postGen(arguments.outputDirectory);
return ExitCode.success.code;
Expand All @@ -54,6 +60,19 @@ class CreateCommand extends Command<int> {
/// region Code generation
/// Generates the basic flutter project
Future<void> _preGen(GeneratorArguments args) async {
final createFlutterProject = await Process.run(
'flutter',
[
'create',
args.outputDirectory.path,
],
);

await FlavorGenerator.addFlavors(_generator, args);
}

GeneratorArguments _readGeneratorArguments() {
final parsedArgumentResults = argResults!;
final outputDirectory = parsedArgumentResults.outputDirectory;
Expand All @@ -71,6 +90,7 @@ class CreateCommand extends Command<int> {
}
}

/// Generates necessary project files from mason template
Future<void> _generateViaMasonBundle(GeneratorArguments arguments) async {
final bundle = _bundleGenerator.generate(arguments);

Expand All @@ -79,29 +99,30 @@ class CreateCommand extends Command<int> {
final generator = await _generator(bundle);
var generatedFiles = await generator.generate(
DirectoryGeneratorTarget(arguments.outputDirectory),
vars: {
'project_name': arguments.projectName,
'domain_name': arguments.organisationDomain,
'organization_name': arguments.organisationName,
'uses_firebase': arguments.usesFirebase,
'analytics': arguments.analyticsEnabled,
'push_notifications': arguments.pushNotificationsEnabled,
'enable_feature_counter': arguments.counterEnabled,
'enable_feature_deeplinks': arguments.deepLinkEnabled,
'enable_feature_widget_toolkit': arguments.widgetToolkitEnabled,
'enable_login': arguments.loginEnabled,
'enable_social_logins': arguments.socialLoginsEnabled,
'enable_change_language': arguments.changeLanguageEnabled,
'enable_dev_menu': arguments.devMenuEnabled,
'enable_feature_otp': arguments.otpEnabled,
'enable_patrol': arguments.patrolTestsEnabled,
'has_authentication': arguments.authenticationEnabled,
'realtime_communication': arguments.realtimeCommunicationEnabled,
'enable_pin_code': arguments.pinCodeEnabled,
'cicd': arguments.cicdEnabled,
'cicd_github': arguments.cicdGithubEnabled,
'enable_auth_matrix': arguments.authMatrixEnabled,
},
vars: _vars ??
{
'project_name': arguments.projectName,
'domain_name': arguments.organisationDomain,
'organization_name': arguments.organisationName,
'uses_firebase': arguments.usesFirebase,
'analytics': arguments.analyticsEnabled,
'push_notifications': arguments.pushNotificationsEnabled,
'enable_feature_counter': arguments.counterEnabled,
'enable_feature_deeplinks': arguments.deepLinkEnabled,
'enable_feature_widget_toolkit': arguments.widgetToolkitEnabled,
'enable_login': arguments.loginEnabled,
'enable_social_logins': arguments.socialLoginsEnabled,
'enable_change_language': arguments.changeLanguageEnabled,
'enable_dev_menu': arguments.devMenuEnabled,
'enable_feature_otp': arguments.otpEnabled,
'enable_patrol': arguments.patrolTestsEnabled,
'has_authentication': arguments.authenticationEnabled,
'realtime_communication': arguments.realtimeCommunicationEnabled,
'enable_pin_code': arguments.pinCodeEnabled,
'cicd': arguments.cicdEnabled,
'cicd_github': arguments.cicdGithubEnabled,
'enable_auth_matrix': arguments.authMatrixEnabled,
},
);

// Manually create project gitignore
Expand All @@ -123,6 +144,7 @@ class CreateCommand extends Command<int> {
await _writeOutputLog(fileCount, arguments);
}

/// Runs any dart/flutter specific post-gen commands
Future<void> _postGen(Directory outputDirectory) async {
var progress = _logger.progress('dart pub get');

Expand Down Expand Up @@ -161,8 +183,29 @@ class CreateCommand extends Command<int> {
);

_progressFinish(format, progress);

await _fileCleanup(outputDirectory);
}

/// Remove any generated files that are not needed (files created through the
/// `flutter create` command or when adding flavors)
Future<void> _fileCleanup(Directory outputDirectory) async {
const filesToRemove = [
'test/widget_test.dart',
'lib/main.dart',
];

for (var path in filesToRemove) {
try {
await File('${outputDirectory.absolute.path}/$path').delete();
} catch (_) {}
}
}

/// endregion
/// region Output logging
void _progressFinish(ProcessResult result, Progress progress) {
if (result.stderr.toString().trim().isNotEmpty) {
progress.fail(result.stderr.toString());
Expand All @@ -171,10 +214,6 @@ class CreateCommand extends Command<int> {
}
}

/// endregion
/// region Output logging
/// Writes an output log with the status of the file generation
Future<void> _writeOutputLog(
int fileCount, GeneratorArguments arguments) async {
Expand Down
2 changes: 1 addition & 1 deletion packages/rx_bloc_cli/lib/src/rx_bloc_cli_constants.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/// Indicates the version of the package
const rxBlocCliPackageVersion = '3.3.1';
const rxBlocCliPackageVersion = '3.4.0';
63 changes: 63 additions & 0 deletions packages/rx_bloc_cli/lib/src/utils/flavor_generator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'dart:io';

import 'package:mason/mason.dart';

import '../models/generator_arguments.dart';
import '../templates/rx_bloc_flavor_config_bundle.dart';

/// Utility class containing logic for flavor generation
class FlavorGenerator {
/// Generates flavor config and uses it to add flavors to project
static Future<void> addFlavors(
Future<MasonGenerator> Function(MasonBundle) generator,
GeneratorArguments args,
) async {
await _generateFlavorConfig(generator, args);

final addFlavorizr = await Process.run(
'flutter',
[
'pub',
'add',
'flutter_flavorizr',
],
workingDirectory: args.outputDirectory.path,
);

final dartGet = await Process.run(
'dart',
['pub', 'get'],
workingDirectory: args.outputDirectory.path,
);

final runFlavorizr = await Process.run(
'flutter',
[
'pub',
'run',
'flutter_flavorizr',
],
workingDirectory: args.outputDirectory.path,
);
}

///region Helper functions
/// Generates config file used to define flavors
static Future<void> _generateFlavorConfig(
Future<MasonGenerator> Function(MasonBundle) generator,
GeneratorArguments arguments,
) async {
final _bundle = await generator(rxBlocFlavorConfigBundle);
var generatedFiles = await _bundle.generate(
DirectoryGeneratorTarget(arguments.outputDirectory),
vars: {
'project_name': arguments.projectName,
'domain_name': arguments.organisationDomain,
'organization_name': arguments.organisationName,
},
);
}

/// endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
import 'package:{{project_name}}/main.dart' as app;
import 'package:{{project_name}}/main_prod.dart' as app;
import 'package:{{project_name}}/main_dev.dart' as app_dev;
import 'package:{{project_name}}/main_sit.dart' as app_sit;
import 'package:{{project_name}}/main_uat.dart' as app_uat;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Development" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="additionalArgs" value="--dart-define=&quot;ENABLE_DEV_MENU=true&quot;" />
<option name="buildFlavor" value="development" />
<option name="buildFlavor" value="dev" />
<option name="filePath" value="$PROJECT_DIR$/lib/main_dev.dart" />
<method v="2" />
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Production" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="buildFlavor" value="production" />
<option name="filePath" value="$PROJECT_DIR$/lib/main.dart" />
<option name="buildFlavor" value="prod" />
<option name="filePath" value="$PROJECT_DIR$/lib/main_prod.dart" />
<method v="2" />
</configuration>
</component>
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,28 @@
"request": "launch",
"type": "dart",
"program": "lib/main_dev.dart",
"args": [ "--flavor", "development", "--target", "lib/main_dev.dart" ]
"args": [ "--flavor", "dev", "--target", "lib/main_dev.dart" ]
},
{
"name": "stag",
"name": "sit",
"request": "launch",
"type": "dart",
"program": "lib/main_staging.dart",
"args": ["--flavor", "staging", "--target", "lib/main_staging.dart"]
"program": "lib/main_sit.dart",
"args": ["--flavor", "sit", "--target", "lib/main_sit.dart"]
},
{
"name": "uat",
"request": "launch",
"type": "dart",
"program": "lib/main_uat.dart",
"args": ["--flavor", "uat", "--target", "lib/main_uat.dart"]
},
{
"name": "prod",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"args": ["--flavor", "production", "--target", "lib/main.dart"]
"program": "lib/main_prod.dart",
"args": ["--flavor", "prod", "--target", "lib/main_prod.dart"]
},
{
"name": "Generate goldens",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Before you start working on your app, make sure you familiarize yourself with th

| Path | Contains |
|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `lib/main.dart` | The production flavour of the app. |
| `lib/main_prod.dart` | The production flavour of the app. |
| `lib/main_dev.dart` | The development flavour of the app. |
| `lib/main_sit.dart` | The SIT flavour of the app. |
| `lib/main_uat.dart` | The UAT flavour of the app. |
Expand Down Expand Up @@ -307,7 +307,7 @@ Full translation key (feature name+separator+translation key): notifications___o

Before you start using analytics, you need to add platform specific configurations:
1. The `iOS` configuration files can be found at `ios/environments/[flavor]]/firebase/GoogleService-Info.plist`
2. For `Android` the configuration files are located at `android/app/src/[flavor]/google-services.json`
2. For `Android` the configuration files are located at `android/environments/[flavor]/google-services.json`
3. All `Web` analytics configurations can be found inside `lib/base/app/config/firebase_web_config.js`

Every flavor represents a separate Firebase project that will be used for app tracking. For each flavor, based on the targeted platforms you'll have to download the [configuration files][firebase_configs_lnk] and place them in the appropriate location mentioned above.
Expand Down

This file was deleted.

Loading

0 comments on commit f7b62a8

Please sign in to comment.