Skip to content
Open
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
8 changes: 8 additions & 0 deletions packages/unified_distributor/lib/src/cli/command_package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ class CommandPackage extends Command {
'You may add multiple \'--build-dart-define key=value\' pairs',
].join('\n'),
);

argParser.addOption(
'post-package-windows-cmd',
valueHelp: 'command',
help: 'Command to execute after Windows build but before packaging (e.g., "call ./sign-file.bat")',
);
}

final UnifiedDistributor distributor;
Expand All @@ -118,6 +124,7 @@ class CommandPackage extends Command {
final String? artifactName = argResults?['artifact-name'];
final String? flutterBuildArgs = argResults?['flutter-build-args'];
final bool isSkipClean = argResults?.wasParsed('skip-clean') ?? false;
final String? postPackageWindowsCmd = argResults?['post-package-windows-cmd'];
final Map<String, dynamic> buildArguments =
_generateBuildArgs(flutterBuildArgs);

Expand All @@ -139,6 +146,7 @@ class CommandPackage extends Command {
artifactName: artifactName,
cleanBeforeBuild: !isSkipClean,
buildArguments: buildArguments,
postPackageWindowsCmd: postPackageWindowsCmd,
);
}

Expand Down
69 changes: 68 additions & 1 deletion packages/unified_distributor/lib/src/unified_distributor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class UnifiedDistributor {
required bool cleanBeforeBuild,
required Map<String, dynamic> buildArguments,
Map<String, String>? variables,
String? postPackageWindowsCmd,
}) async {
List<MakeResult> makeResultList = [];

Expand All @@ -161,7 +162,7 @@ class UnifiedDistributor {
BuildResult? buildResult;

for (String target in targets) {
logger.info('Packaging ${pubspec.name} ${pubspec.version} as $target:');
logger.info('Packaging ${pubspec.name} ${pubspec.version} as $target for ${platform.toLowerCase()}:');
if (!isBuildOnlyOnce || (isBuildOnlyOnce && buildResult == null)) {
try {
buildResult = await _builder.build(
Expand All @@ -186,6 +187,72 @@ class UnifiedDistributor {
}

if (buildResult != null) {
// Execute custom Windows command if specified and platform is Windows
if (platform.toLowerCase() == 'windows' &&
postPackageWindowsCmd != null &&
postPackageWindowsCmd.isNotEmpty) {
logger.info('Executing post-package Windows command: $postPackageWindowsCmd');
try {
// Create a temporary batch file to execute the command
final tempDir = Directory.systemTemp;
final tempFile = File('${tempDir.path}\\fastforge_temp_cmd_${DateTime.now().millisecondsSinceEpoch}.bat');

try {
// Process the command to properly handle paths with spaces
String processedCmd = postPackageWindowsCmd;

// Find all quoted paths and ensure they're properly formatted
final pathRegex = RegExp(r'"([^"]+)"');
processedCmd = processedCmd.replaceAllMapped(pathRegex, (match) {
String path = match.group(1)!;
// Remove any existing escaping to prevent double escaping
path = path.replaceAll(r'\\', r'\');
// Ensure the path is properly formatted for Windows
path = path.replaceAll(r'/', r'\');
return '"$path"';
});

// Write the command to the batch file
tempFile.writeAsStringSync('@echo off\nsetlocal enabledelayedexpansion\n$processedCmd', flush: true);
logger.info('Created temporary batch file: ${tempFile.path}');
logger.info('Processed command: $processedCmd');

// Execute the temporary batch file
ProcessResult result = await Process.run(
tempFile.path,
[],
workingDirectory: Directory.current.path,
);

if (result.exitCode == 0) {
logger.info('Post-package command executed successfully'.brightGreen());
if (result.stdout.toString().isNotEmpty) {
print(result.stdout);
}
} else {
logger.severe('Post-package command failed with exit code ${result.exitCode}'.red());
if (result.stderr.toString().isNotEmpty) {
logger.severe(result.stderr.toString().red());
}
if (result.stdout.toString().isNotEmpty) {
logger.severe(result.stdout.toString().red());
}
throw Exception('Post-build command failed');
}
} finally {
// Clean up the temporary file
if (tempFile.existsSync()) {
tempFile.deleteSync();
logger.info('Cleaned up temporary batch file');
}
}
} catch (error) {
logger.severe('Failed to execute post-build command: $error'.red());
rethrow;
}
}


String buildMode =
buildArguments.containsKey('profile') ? 'profile' : 'release';
Map<String, dynamic>? arguments = {
Expand Down