From 07d0d023c2e7bf677a97f4968d864740c15a1f70 Mon Sep 17 00:00:00 2001 From: Over_Brave <47111280+OverBrave@users.noreply.github.com> Date: Sat, 16 Aug 2025 11:44:21 +0300 Subject: [PATCH 1/4] feat: Add support for dynamic Flutter build arguments Refactors the Flutter build process to allow any argument from the `flutter build windows` command to be passed through the CLI. This change introduces a more flexible and scalable architecture by: - Modifying `FlutterBuilder` to accept a dynamic map of arguments. - Adding a predefined list of passthrough options in `inno_build.dart` to easily manage and extend supported arguments. - Updating `ArgParser` in the main executable to include new options like `--obfuscate`, `--split-debug-info`, and `--dart-define`. This enables crucial features like code obfuscation and compile-time variable definitions, making the tool suitable for more professional and secure production builds. --- bin/inno_build.dart | 31 ++--- lib/inno_build.dart | 200 +++++++----------------------- lib/services/flutter_builder.dart | 83 ++++++++----- 3 files changed, 112 insertions(+), 202 deletions(-) diff --git a/bin/inno_build.dart b/bin/inno_build.dart index 4860574..6fecde3 100644 --- a/bin/inno_build.dart +++ b/bin/inno_build.dart @@ -4,13 +4,11 @@ import 'dart:io'; // Package imports: import 'package:args/args.dart'; import 'package:cli_spin/cli_spin.dart'; - // Project imports: import 'package:inno_build/inno_build.dart'; import 'package:inno_build/models/build_mode.dart'; import 'package:inno_build/services/app_id_service.dart'; import 'package:inno_build/services/dependency_manager.dart'; -import 'package:inno_build/services/flutter_builder.dart'; import 'package:inno_build/services/inno_setup_manager.dart'; import 'package:inno_build/utils/constants.dart'; import 'package:inno_build/utils/pubspec_manager.dart'; @@ -25,22 +23,28 @@ Future main(List arguments) async { ..addFlag('install-inno', abbr: 'i', help: 'Install Inno Setup if not present.') ..addFlag('skip-flutter-build', help: 'Skip the Flutter build step.') - ..addFlag('verbose', abbr: 'v', help: 'Enable verbose output.') - ..addFlag('quiet', abbr: 'q', help: 'Suppress output (quiet mode).') ..addFlag('help', abbr: 'h', help: 'Show this help message.') - ..addFlag('version', help: 'Show version information.'); + ..addFlag('version', help: 'Show version information.') + + ..addFlag('obfuscate', help: 'Obfuscate the Dart code during the build.') + ..addOption('split-debug-info', help: 'Path to store split debug info files.') + ..addMultiOption('dart-define', help: 'Pass additional key-value pairs to the Dart compiler.') + ..addOption('target', abbr: 't', help: 'The main entry-point file of the application.') + + ..addFlag('verbose', abbr: 'v', help: 'Enable verbose output.') + ..addFlag('quiet', abbr: 'q', help: 'Suppress output (quiet mode).'); final argResults = parser.parse(arguments); stdout.writeln(welcomeMessage); if (argResults['help']) { - print(helpMessage); + print(parser.usage); return; } if (argResults['version']) { - print('Inno Build CLI v1.0.0'); + print('inno_build v1.0.0'); return; } @@ -54,12 +58,12 @@ Future main(List arguments) async { final buildMode = _determineBuildMode(argResults); + // Servislerin oluşturulması final pubspecManager = PubspecManager(); final appIdService = AppIdService(pubspecManager); final dependencyManager = DependencyManager(verbose: verbose); - final flutterBuilder = FlutterBuilder(buildMode, verbose: verbose); final innoSetupManager = - InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); + InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); final spinner = CliSpin(isSilent: quiet); final appLogic = InnoBuild( @@ -67,7 +71,6 @@ Future main(List arguments) async { pubspecManager: pubspecManager, appIdService: appIdService, dependencyManager: dependencyManager, - flutterBuilder: flutterBuilder, innoSetupManager: innoSetupManager, spinner: spinner, buildMode: buildMode, @@ -76,8 +79,8 @@ Future main(List arguments) async { try { await appLogic.run(); } catch (e) { - print(e); - exit(64); // Exit code for usage error + print('An error occurred: $e'); + exit(1); } } @@ -85,9 +88,9 @@ BuildMode _determineBuildMode(ArgResults argResults) { if (argResults['debug']) { if (argResults['release']) { print('Error: --release and --debug cannot be used together.'); - exit(64); // Exit code for usage error + exit(64); } return BuildMode.debug; } return BuildMode.release; -} +} \ No newline at end of file diff --git a/lib/inno_build.dart b/lib/inno_build.dart index a950d22..39fb6ed 100644 --- a/lib/inno_build.dart +++ b/lib/inno_build.dart @@ -15,107 +15,41 @@ import 'package:inno_build/utils/config.dart'; import 'package:inno_build/utils/constants.dart'; import 'package:inno_build/utils/pubspec_manager.dart'; +/// A list of command-line options that should be passed through to the +/// `flutter build` command. To add support for a new flutter build argument, +/// add it to this list and also to the ArgParser in your main executable file. +const List _flutterBuildOptions = [ + 'obfuscate', + 'split-debug-info', + 'dart-define', + 'target', + 'verbose', + 'quiet', + // Future Flutter build arguments can be added here. + // e.g., 'tree-shake-icons', 'build-name', 'build-number' +]; + /// This class is the main entry point of the `inno_build` command-line tool. -/// -/// It takes the parsed command-line arguments, and uses them to determine what -/// actions to take. The actions are: -/// 1. Generate a new App ID if the user specified the `--app-id` flag. -/// 2. Check if Inno Setup is installed, and download and install it if not. -/// 3. Check if the Visual C++ 2015-2022 Redistributable is downloaded, and -/// download it if not. -/// 4. Build the Flutter Windows application using the `flutter build` command. -/// 5. Build the Inno Setup script using the `inno_setup_manager` service. -/// 6. Compile the Inno Setup script using the `inno_setup_manager` service. class InnoBuild { - /// The parsed command-line arguments. - /// - /// This is used to determine the actions to take when running the `inno_build` - /// command-line tool. final ArgResults argResults; - - /// An instance of the `PubspecManager` class. - /// - /// This is used to read and write the `pubspec.yaml` file. final PubspecManager pubspecManager; - - /// An instance of the `AppIdService` class. - /// - /// This is used to generate a new App ID if the user specified the - /// `--app-id` flag. final AppIdService appIdService; - - /// An instance of the `DependencyManager` class. - /// - /// This is used to download and install Inno Setup if it is not already - /// installed, and to download the Visual C++ 2015-2022 Redistributable if - /// it is not already downloaded. final DependencyManager dependencyManager; - - /// An instance of the `FlutterBuilder` class. - /// - /// This is used to build the Flutter Windows application using the - /// `flutter build` command. - final FlutterBuilder flutterBuilder; - - /// An instance of the `InnoSetupManager` class. - /// - /// This is used to build the Inno Setup script and compile it using the - /// `inno_setup_manager` service. final InnoSetupManager innoSetupManager; - - /// An instance of the `CliSpin` class. - /// - /// This is used to display a spinner while the `inno_build` command-line tool - /// is running. final CliSpin spinner; - - /// The build mode specified by the user. - /// - /// This is either `BuildMode.debug` or `BuildMode.release`. final BuildMode buildMode; - /// Creates an instance of the `inno_build` command-line tool. - /// - /// The [argResults] parameter is the parsed command-line arguments. - /// - /// The [pubspecManager] parameter is an instance of the `PubspecManager` - /// class, which is used to read and write the `pubspec.yaml` file. - /// - /// The [appIdService] parameter is an instance of the `AppIdService` class, - /// which is used to generate a new App ID if the user specified the - /// `--app-id` flag. - /// - /// The [dependencyManager] parameter is an instance of the - /// `DependencyManager` class, which is used to check if Inno Setup is - /// installed, and download and install it if not. - /// - /// The [flutterBuilder] parameter is an instance of the `FlutterBuilder` - /// class, which is used to build the Flutter Windows application using - /// the `flutter build` command. - /// - /// The [innoSetupManager] parameter is an instance of the `InnoSetupManager` - /// class, which is used to build the Inno Setup script and compile it. - /// - /// The [spinner] parameter is an instance of the `CliSpin` class, which is - /// used to display a spinner on the console. - /// - /// The [buildMode] parameter is the build mode that the user specified using - /// the `--debug` or `--release` flag. InnoBuild({ required this.argResults, required this.pubspecManager, required this.appIdService, required this.dependencyManager, - required this.flutterBuilder, required this.innoSetupManager, required this.spinner, required this.buildMode, }); /// Runs the `inno_build` command-line tool. - /// - /// This method takes no arguments and returns a `Future` that completes when - /// the tool has finished running. Future run() async { _validateFlags(); if (argResults['install-inno']) { @@ -123,8 +57,6 @@ class InnoBuild { exit(0); } await _handleAppId(); - // await _checkAndInstallInnoSetup(); - // await _checkAndDownloadVccRedist(); if (!argResults['skip-flutter-build']) { await _buildFlutterApp(); } @@ -133,9 +65,6 @@ class InnoBuild { } /// Validates the command-line flags. - /// - /// This method is called by the `run` method and checks that the user has not - /// provided any invalid combinations of flags. void _validateFlags() { if (argResults['debug'] && argResults['release'] && @@ -144,15 +73,22 @@ class InnoBuild { 'Error: --release, --debug, and --install-inno cannot be used together.'); } if (argResults['verbose'] && argResults['quiet']) { - throw ArgumentError('Error: --verbose --quiet cannot be used together.'); + throw ArgumentError('Error: --verbose and --quiet cannot be used together.'); + } + } + + /// Collects all relevant arguments from argResults to be passed to Flutter. + Map _getFlutterBuildArgs() { + final args = {}; + for (final option in _flutterBuildOptions) { + if (argResults.wasParsed(option)) { + args[option] = argResults[option]; + } } + return args; } /// Handles generating a new App ID if the user specified the `--app-id` flag. - /// - /// This method is called by the `run` method and checks if the user has - /// specified the `--app-id` flag. If so, it generates a new App ID and updates - /// the `pubspec.yaml` file with it. Future _handleAppId() async { if (argResults['app-id'] != null) { spinner.start('Generating new App ID...'); @@ -175,48 +111,28 @@ class InnoBuild { } } - /// Checks if Inno Setup is installed, and downloads and installs it if not. - /// - /// This method is called by the `run` method and checks if Inno Setup is - /// installed. If not, it downloads and installs it. - // Future _checkAndInstallInnoSetup() async { - // spinner.start('Checking Inno Setup...'); - // if (File(innoCompilerPath).existsSync()) { - // spinner.success('Inno Setup is already installed.'); - // } else { - // await _installInnoSetup(); - // } - // } + /// Builds the Flutter Windows application using the `flutter build` command. + Future _buildFlutterApp() async { + spinner.start('Building Flutter Windows application...'); + + // Create a FlutterBuilder instance with the dynamic arguments. + final flutterBuilder = FlutterBuilder( + buildMode: buildMode, + flutterBuildArgs: _getFlutterBuildArgs(), + ); + + if (argResults['verbose']) spinner.stopAndPersist(); + + final exitCode = await flutterBuilder.buildApp(); - /// Checks if the Visual C++ 2015-2022 Redistributable is downloaded, and - /// downloads it if not. - /// - /// This method is called by the `run` method and checks if the Visual C++ - /// 2015-2022 Redistributable is downloaded. If not, it downloads it. - // Future _checkAndDownloadVccRedist() async { - // spinner.start('Checking Visual C++ 2015-2022 Redistributable...'); - // if (File(vcRedistPath).existsSync()) { - // spinner.success( - // 'Visual C++ 2015-2022 Redistributable is already donwloaded.'); - // } else { - // spinner.start('Downloading Visual C++ 2015-2022 Redistributable...'); - // if (argResults['verbose']) { - // spinner.stopAndPersist(); - // } - // final download = await dependencyManager.ensureVcredistDownloaded(); - // if (download == 0) { - // spinner.success( - // 'Downloaded Visual C++ 2015-2022 Redistributable successfully.'); - // } else { - // spinner.fail('Failed to download Visual C++ 2015-2022 Redistributable'); - // } - // } - // } + if (exitCode == 0) { + spinner.success('Built ${buildMode.buildPath}\\${Config.execName}.'); + } else { + spinner.fail('Failed to build Flutter application. Check the logs above for details.'); + } + } /// Downloads Inno Setup if it is not already installed. - /// - /// This method is called by the `run` method and downloads Inno Setup if it is - /// not already installed. Future _downloadInnoSetup() async { spinner.start('Downloading Inno Setup...'); final download = await dependencyManager.ensureInnoSetupDownloaded(); @@ -228,25 +144,7 @@ class InnoBuild { } } - /// Builds the Flutter Windows application using the `flutter build` command. - /// - /// This method is called by the `run` method and builds the Flutter Windows - /// application using the `flutter build` command. - Future _buildFlutterApp() async { - spinner.start('Building Flutter Windows application...'); - if (argResults['verbose']) spinner.stopAndPersist(); - final exitCode = await flutterBuilder.buildApp(); - if (exitCode == 0) { - spinner.success('Built ${buildMode.buildPath}\\${Config.execName}.'); - } else { - spinner.fail('Failed to build Flutter application'); - } - } - /// Installs Inno Setup if it is not already installed. - /// - /// This method is called by the `run` method and installs Inno Setup if it is - /// not already installed. Future _installInnoSetup() async { if (File(innoSetupInstallerPath).existsSync()) { spinner.start('Installing Inno Setup...'); @@ -269,9 +167,6 @@ class InnoBuild { } /// Builds the Inno Setup script using the `inno_setup_manager` service. - /// - /// This method is called by the `run` method and builds the Inno Setup script - /// using the `inno_setup_manager` service. Future _buildInnoSetupScript() async { spinner.start('Building Inno Setup script...'); try { @@ -284,9 +179,6 @@ class InnoBuild { } /// Compiles the Inno Setup script using the `inno_setup_manager` service. - /// - /// This method is called by the `run` method and compiles the Inno Setup script - /// using the `inno_setup_manager` service. Future _compileInnoSetupScript() async { spinner.start('Compiling Inno Setup script...'); if (argResults['verbose']) { @@ -299,4 +191,4 @@ class InnoBuild { spinner.fail('Failed to compile Inno Setup script'); } } -} +} \ No newline at end of file diff --git a/lib/services/flutter_builder.dart b/lib/services/flutter_builder.dart index a7c57e7..f179424 100644 --- a/lib/services/flutter_builder.dart +++ b/lib/services/flutter_builder.dart @@ -1,5 +1,3 @@ -// lib/services/flutter_builder.dart - // Dart imports: import 'dart:io'; @@ -9,53 +7,70 @@ import 'package:inno_build/models/build_mode.dart'; /// Class that builds a Flutter application. /// /// This class abstracts the process of building a Flutter application -/// using the `flutter build` command. The application is built in the -/// mode specified by [buildMode]. -/// -/// The [verbose] parameter allows to control the verbosity of the -/// command. If `true`, the `flutter build` command will be executed with -/// the `--verbose` flag and the output will be printed to the console. -/// If `false`, the command will be executed with the `--quiet` flag and -/// the output will be silent. +/// using the `flutter build` command. It dynamically constructs the command +/// based on the provided build mode and additional Flutter arguments. class FlutterBuilder { - /// Whether the `flutter build` command should be executed with the - /// `--verbose` flag. - /// - /// If `true`, the output will be printed to the console. If `false`, the - /// output will be silent. - final bool verbose; - /// The build mode to use when building the Flutter application. - /// - /// The build mode determines where the application will be built. - /// The possible values are: - /// - [BuildMode.debug]: The application will be built in debug mode. - /// - [BuildMode.release]: The application will be built in release mode. final BuildMode buildMode; + /// A map of additional arguments to pass to the 'flutter build' command. + /// Keys are the argument names (e.g., 'obfuscate', 'split-debug-info') + /// and values are the argument values. + /// For flags, the value should be `true`. For options with values, + /// it should be the string value. For multi-options, it can be a list. + final Map flutterBuildArgs; + /// Creates a new instance of [FlutterBuilder]. /// - /// The [verbose] parameter allows to control the verbosity of the - /// command. If `true`, the `flutter build` command will be executed with - /// the `--verbose` flag and the output will be printed to the console. - /// If `false`, the command will be executed with the `--quiet` flag and - /// the output will be silent. - FlutterBuilder(this.buildMode, {this.verbose = false}); + /// [buildMode] determines the build configuration (e.g., debug, release). + /// [flutterBuildArgs] contains all additional parameters to be passed + /// to the flutter build command. + FlutterBuilder({ + required this.buildMode, + this.flutterBuildArgs = const {}, + }); /// Builds the Flutter application. /// /// This method executes the `flutter build` command with the options - /// specified by [buildMode] and [verbose]. + /// specified by [buildMode] and [flutterBuildArgs]. /// The method returns the exit code of the `flutter build` command. Future buildApp() async { final mode = buildMode.name; - List args = ['/c', 'flutter', 'build', 'windows', '--$mode']; - if (verbose) args.add('--verbose'); + final List args = ['/c', 'flutter', 'build', 'windows', '--$mode']; + + // Dynamically add arguments from the map + flutterBuildArgs.forEach((key, value) { + // For flags like --obfuscate or --verbose where value is true + if (value is bool && value == true) { + args.add('--$key'); + } + // For options with values like --split-debug-info=... + else if (value is String && value.isNotEmpty) { + args.add('--$key=$value'); + } + // For list values like --dart-define=KEY=VALUE + else if (value is List) { + for (final item in value) { + if (item is String) { + args.add('--$key=$item'); + } + } + } + }); + + final bool isVerbose = flutterBuildArgs['verbose'] == true; + + // For debugging purposes, print the command that will be executed. + if (isVerbose) { + print('Executing command: cmd.exe ${args.join(' ')}'); + } + final process = await Process.start( 'cmd', args, - mode: verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal, + mode: isVerbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal, ); - return process.exitCode; + return await process.exitCode; } -} +} \ No newline at end of file From df0934ef0d232231ce9dd808cfb28b57b5b1b9a6 Mon Sep 17 00:00:00 2001 From: myavuzokumus <47111280+myavuzokumus@users.noreply.github.com> Date: Sat, 16 Aug 2025 08:50:43 +0000 Subject: [PATCH 2/4] [pre-commit] Update pre-commit changes --- bin/inno_build.dart | 16 +++++++++------- example/pubspec.lock | 24 ++++++++++++------------ lib/inno_build.dart | 8 +++++--- lib/services/flutter_builder.dart | 2 +- pubspec.lock | 23 +++++------------------ 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/bin/inno_build.dart b/bin/inno_build.dart index 6fecde3..b5e2078 100644 --- a/bin/inno_build.dart +++ b/bin/inno_build.dart @@ -4,6 +4,7 @@ import 'dart:io'; // Package imports: import 'package:args/args.dart'; import 'package:cli_spin/cli_spin.dart'; + // Project imports: import 'package:inno_build/inno_build.dart'; import 'package:inno_build/models/build_mode.dart'; @@ -25,12 +26,13 @@ Future main(List arguments) async { ..addFlag('skip-flutter-build', help: 'Skip the Flutter build step.') ..addFlag('help', abbr: 'h', help: 'Show this help message.') ..addFlag('version', help: 'Show version information.') - ..addFlag('obfuscate', help: 'Obfuscate the Dart code during the build.') - ..addOption('split-debug-info', help: 'Path to store split debug info files.') - ..addMultiOption('dart-define', help: 'Pass additional key-value pairs to the Dart compiler.') - ..addOption('target', abbr: 't', help: 'The main entry-point file of the application.') - + ..addOption('split-debug-info', + help: 'Path to store split debug info files.') + ..addMultiOption('dart-define', + help: 'Pass additional key-value pairs to the Dart compiler.') + ..addOption('target', + abbr: 't', help: 'The main entry-point file of the application.') ..addFlag('verbose', abbr: 'v', help: 'Enable verbose output.') ..addFlag('quiet', abbr: 'q', help: 'Suppress output (quiet mode).'); @@ -63,7 +65,7 @@ Future main(List arguments) async { final appIdService = AppIdService(pubspecManager); final dependencyManager = DependencyManager(verbose: verbose); final innoSetupManager = - InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); + InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); final spinner = CliSpin(isSilent: quiet); final appLogic = InnoBuild( @@ -93,4 +95,4 @@ BuildMode _determineBuildMode(ArgResults argResults) { return BuildMode.debug; } return BuildMode.release; -} \ No newline at end of file +} diff --git a/example/pubspec.lock b/example/pubspec.lock index 1708d83..95847ff 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -145,31 +145,31 @@ packages: path: ".." relative: true source: path - version: "0.3.0" + version: "0.4.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -275,10 +275,10 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.6" typed_data: dependency: transitive description: @@ -299,10 +299,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -328,5 +328,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.7.0-0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/inno_build.dart b/lib/inno_build.dart index 39fb6ed..a847b26 100644 --- a/lib/inno_build.dart +++ b/lib/inno_build.dart @@ -73,7 +73,8 @@ class InnoBuild { 'Error: --release, --debug, and --install-inno cannot be used together.'); } if (argResults['verbose'] && argResults['quiet']) { - throw ArgumentError('Error: --verbose and --quiet cannot be used together.'); + throw ArgumentError( + 'Error: --verbose and --quiet cannot be used together.'); } } @@ -128,7 +129,8 @@ class InnoBuild { if (exitCode == 0) { spinner.success('Built ${buildMode.buildPath}\\${Config.execName}.'); } else { - spinner.fail('Failed to build Flutter application. Check the logs above for details.'); + spinner.fail( + 'Failed to build Flutter application. Check the logs above for details.'); } } @@ -191,4 +193,4 @@ class InnoBuild { spinner.fail('Failed to compile Inno Setup script'); } } -} \ No newline at end of file +} diff --git a/lib/services/flutter_builder.dart b/lib/services/flutter_builder.dart index f179424..3934803 100644 --- a/lib/services/flutter_builder.dart +++ b/lib/services/flutter_builder.dart @@ -73,4 +73,4 @@ class FlutterBuilder { ); return await process.exitCode; } -} \ No newline at end of file +} diff --git a/pubspec.lock b/pubspec.lock index 9569c31..1a14819 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted - version: "76.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.3" + version: "67.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "6.4.1" ansi_regex: dependency: transitive description: @@ -214,14 +209,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" - macros: - dependency: transitive - description: - name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" - url: "https://pub.dev" - source: hosted - version: "0.1.3-main.0" matcher: dependency: transitive description: @@ -503,4 +490,4 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.4.4 <4.0.0" From c1368c23bb46ce8df78caaaf2810b6680edc30ce Mon Sep 17 00:00:00 2001 From: Over_Brave <47111280+OverBrave@users.noreply.github.com> Date: Sat, 16 Aug 2025 15:58:34 +0300 Subject: [PATCH 3/4] Fix: Add missing docstrings for public methods --- bin/inno_build.dart | 13 +++++-- lib/inno_build.dart | 62 ++++++++++++++++++++++++++++++- lib/services/flutter_builder.dart | 2 + 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/bin/inno_build.dart b/bin/inno_build.dart index 6fecde3..7ab0451 100644 --- a/bin/inno_build.dart +++ b/bin/inno_build.dart @@ -1,3 +1,5 @@ +// bin/inno_build.dart + // Dart imports: import 'dart:io'; @@ -13,6 +15,7 @@ import 'package:inno_build/services/inno_setup_manager.dart'; import 'package:inno_build/utils/constants.dart'; import 'package:inno_build/utils/pubspec_manager.dart'; +/// The main entry point for the Inno Build CLI. Future main(List arguments) async { final parser = ArgParser() ..addOption('app-id', abbr: 'a', help: 'Generate a new InnoSetup AppID.') @@ -27,9 +30,12 @@ Future main(List arguments) async { ..addFlag('version', help: 'Show version information.') ..addFlag('obfuscate', help: 'Obfuscate the Dart code during the build.') - ..addOption('split-debug-info', help: 'Path to store split debug info files.') - ..addMultiOption('dart-define', help: 'Pass additional key-value pairs to the Dart compiler.') - ..addOption('target', abbr: 't', help: 'The main entry-point file of the application.') + ..addOption('split-debug-info', + help: 'Path to store split debug info files.') + ..addMultiOption('dart-define', + help: 'Pass additional key-value pairs to the Dart compiler.') + ..addOption('target', + abbr: 't', help: 'The main entry-point file of the application.') ..addFlag('verbose', abbr: 'v', help: 'Enable verbose output.') ..addFlag('quiet', abbr: 'q', help: 'Suppress output (quiet mode).'); @@ -84,6 +90,7 @@ Future main(List arguments) async { } } +/// Determines the [BuildMode] based on the provided command-line arguments. BuildMode _determineBuildMode(ArgResults argResults) { if (argResults['debug']) { if (argResults['release']) { diff --git a/lib/inno_build.dart b/lib/inno_build.dart index 39fb6ed..3a7fde1 100644 --- a/lib/inno_build.dart +++ b/lib/inno_build.dart @@ -1,3 +1,5 @@ +// lib/inno_build.dart + // Dart imports: import 'dart:io'; @@ -30,15 +32,44 @@ const List _flutterBuildOptions = [ ]; /// This class is the main entry point of the `inno_build` command-line tool. +/// +/// It takes the parsed command-line arguments, and uses them to determine what +/// actions to take. The actions are: +/// 1. Generate a new App ID if the user specified the `--app-id` flag. +/// 2. Build the Flutter Windows application using the `flutter build` command. +/// 3. Build the Inno Setup script using the `inno_setup_manager` service. +/// 4. Compile the Inno Setup script using the `inno_setup_manager` service. class InnoBuild { + /// The parsed command-line arguments. final ArgResults argResults; + + /// An instance of the `PubspecManager` class. final PubspecManager pubspecManager; + + /// An instance of the `AppIdService` class. final AppIdService appIdService; + + /// An instance of the `DependencyManager` class. final DependencyManager dependencyManager; + + /// An instance of the `InnoSetupManager` class. final InnoSetupManager innoSetupManager; + + /// An instance of the `CliSpin` class. final CliSpin spinner; + + /// The build mode specified by the user. final BuildMode buildMode; + /// Creates an instance of the `inno_build` command-line tool. + /// + /// The [argResults] parameter is the parsed command-line arguments. + /// The [pubspecManager] parameter is an instance of the `PubspecManager`. + /// The [appIdService] parameter is an instance of the `AppIdService`. + /// The [dependencyManager] parameter is an instance of the `DependencyManager`. + /// The [innoSetupManager] parameter is an instance of the `InnoSetupManager`. + /// The [spinner] parameter is an instance of the `CliSpin` class. + /// The [buildMode] parameter is the build mode that the user specified. InnoBuild({ required this.argResults, required this.pubspecManager, @@ -50,6 +81,9 @@ class InnoBuild { }); /// Runs the `inno_build` command-line tool. + /// + /// This method takes no arguments and returns a `Future` that completes when + /// the tool has finished running. Future run() async { _validateFlags(); if (argResults['install-inno']) { @@ -65,6 +99,9 @@ class InnoBuild { } /// Validates the command-line flags. + /// + /// This method is called by the `run` method and checks that the user has not + /// provided any invalid combinations of flags. void _validateFlags() { if (argResults['debug'] && argResults['release'] && @@ -73,7 +110,8 @@ class InnoBuild { 'Error: --release, --debug, and --install-inno cannot be used together.'); } if (argResults['verbose'] && argResults['quiet']) { - throw ArgumentError('Error: --verbose and --quiet cannot be used together.'); + throw ArgumentError( + 'Error: --verbose and --quiet cannot be used together.'); } } @@ -89,6 +127,10 @@ class InnoBuild { } /// Handles generating a new App ID if the user specified the `--app-id` flag. + /// + /// This method is called by the `run` method and checks if the user has + /// specified the `--app-id` flag. If so, it generates a new App ID and updates + /// the `pubspec.yaml` file with it. Future _handleAppId() async { if (argResults['app-id'] != null) { spinner.start('Generating new App ID...'); @@ -112,6 +154,9 @@ class InnoBuild { } /// Builds the Flutter Windows application using the `flutter build` command. + /// + /// This method is called by the `run` method and builds the Flutter Windows + /// application using the `flutter build` command. Future _buildFlutterApp() async { spinner.start('Building Flutter Windows application...'); @@ -128,11 +173,15 @@ class InnoBuild { if (exitCode == 0) { spinner.success('Built ${buildMode.buildPath}\\${Config.execName}.'); } else { - spinner.fail('Failed to build Flutter application. Check the logs above for details.'); + spinner.fail( + 'Failed to build Flutter application. Check the logs above for details.'); } } /// Downloads Inno Setup if it is not already installed. + /// + /// This method is called by the `run` method and downloads Inno Setup if it is + /// not already installed. Future _downloadInnoSetup() async { spinner.start('Downloading Inno Setup...'); final download = await dependencyManager.ensureInnoSetupDownloaded(); @@ -145,6 +194,9 @@ class InnoBuild { } /// Installs Inno Setup if it is not already installed. + /// + /// This method is called by the `run` method and installs Inno Setup if it is + /// not already installed. Future _installInnoSetup() async { if (File(innoSetupInstallerPath).existsSync()) { spinner.start('Installing Inno Setup...'); @@ -167,6 +219,9 @@ class InnoBuild { } /// Builds the Inno Setup script using the `inno_setup_manager` service. + /// + /// This method is called by the `run` method and builds the Inno Setup script + /// using the `inno_setup_manager` service. Future _buildInnoSetupScript() async { spinner.start('Building Inno Setup script...'); try { @@ -179,6 +234,9 @@ class InnoBuild { } /// Compiles the Inno Setup script using the `inno_setup_manager` service. + /// + /// This method is called by the `run` method and compiles the Inno Setup script + /// using the `inno_setup_manager` service. Future _compileInnoSetupScript() async { spinner.start('Compiling Inno Setup script...'); if (argResults['verbose']) { diff --git a/lib/services/flutter_builder.dart b/lib/services/flutter_builder.dart index f179424..7d1467a 100644 --- a/lib/services/flutter_builder.dart +++ b/lib/services/flutter_builder.dart @@ -1,3 +1,5 @@ +// lib/services/flutter_builder.dart + // Dart imports: import 'dart:io'; From 78bc1adfa6905537911577a8449801d08e3624c7 Mon Sep 17 00:00:00 2001 From: myavuzokumus <47111280+myavuzokumus@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:04:32 +0000 Subject: [PATCH 4/4] [pre-commit] Update pre-commit changes --- bin/inno_build.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bin/inno_build.dart b/bin/inno_build.dart index 7ab0451..9f979d3 100644 --- a/bin/inno_build.dart +++ b/bin/inno_build.dart @@ -6,6 +6,7 @@ import 'dart:io'; // Package imports: import 'package:args/args.dart'; import 'package:cli_spin/cli_spin.dart'; + // Project imports: import 'package:inno_build/inno_build.dart'; import 'package:inno_build/models/build_mode.dart'; @@ -28,7 +29,6 @@ Future main(List arguments) async { ..addFlag('skip-flutter-build', help: 'Skip the Flutter build step.') ..addFlag('help', abbr: 'h', help: 'Show this help message.') ..addFlag('version', help: 'Show version information.') - ..addFlag('obfuscate', help: 'Obfuscate the Dart code during the build.') ..addOption('split-debug-info', help: 'Path to store split debug info files.') @@ -36,7 +36,6 @@ Future main(List arguments) async { help: 'Pass additional key-value pairs to the Dart compiler.') ..addOption('target', abbr: 't', help: 'The main entry-point file of the application.') - ..addFlag('verbose', abbr: 'v', help: 'Enable verbose output.') ..addFlag('quiet', abbr: 'q', help: 'Suppress output (quiet mode).'); @@ -69,7 +68,7 @@ Future main(List arguments) async { final appIdService = AppIdService(pubspecManager); final dependencyManager = DependencyManager(verbose: verbose); final innoSetupManager = - InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); + InnoSetupManager(buildMode, verbose: verbose, quiet: quiet); final spinner = CliSpin(isSilent: quiet); final appLogic = InnoBuild( @@ -100,4 +99,4 @@ BuildMode _determineBuildMode(ArgResults argResults) { return BuildMode.debug; } return BuildMode.release; -} \ No newline at end of file +}