run method

  1. @override
Future<void> run()
override

Runs this command.

The return value is wrapped in a Future if necessary and returned by CommandRunner.runCommand.

Implementation

@override
Future<void> run() async {
  final configPath = argResults?['config'] ?? 'flavor_tools.yaml';
  final pathXcProject = argResults?['pathXcProject'];
  final teamId = argResults?['teamId'] ?? '""';
  final iconsLauncher = (argResults?['iconsLauncher'] ?? 'false') == 'true';

  final file = File(configPath);
  if (!await file.exists()) {
    print('Config file not found: $configPath');
    exit(1);
  }

  final content = await file.readAsString();
  final yaml = loadYaml(content);

  if (yaml is! YamlMap || yaml['flavors'] is! YamlMap) {
    print('Invalid config format. Expected "flavors" section.');
    exit(1);
  }

  final flavors = yaml['flavors'] as YamlMap;
  print('Found ${flavors.length} flavor(s) in config.\n');

  for (final entry in flavors.entries) {
    final flavorName = entry.key as String;
    if (entry.value is! YamlMap) {
      print('Skipping "$flavorName": invalid format, expected a map of properties.');
      continue;
    }
    final props = entry.value as YamlMap;

    final packageName = props['package_name'] as String?;
    final packageNameIos = props['package_name_ios'] as String? ?? packageName;
    final packageNameAndroid = props['package_name_android'] as String? ?? packageName;
    final displayName = props['display_name'] as String?;
    final dimension = props['dimension'] as String? ?? 'default';

    if (packageNameIos == null || packageNameAndroid == null || displayName == null) {
      print('Skipping "$flavorName": missing required fields (package_name, display_name).');
      continue;
    }

    // Check if flavor already exists and needs updating
    final existing = await readExistingFlavorValues(flavorName);
    if (existing.exists) {
      final needsIosPackage = packageNameIos != existing.iosPackageName ? packageNameIos : null;
      final needsIosDisplay = displayName != existing.iosDisplayName ? displayName : null;
      final needsAndroidPackage = packageNameAndroid != existing.androidPackageName ? packageNameAndroid : null;
      final needsAndroidDisplay = displayName != existing.androidDisplayName ? displayName : null;

      if (needsIosPackage != null || needsIosDisplay != null || needsAndroidPackage != null || needsAndroidDisplay != null) {
        print('--- Updating flavor: $flavorName ---');
        await updateFlavor(
          flavorName: flavorName,
          packageNameIos: needsIosPackage,
          packageNameAndroid: needsAndroidPackage,
          displayNameIos: needsIosDisplay,
          displayNameAndroid: needsAndroidDisplay,
        );
      } else {
        print('--- Flavor "$flavorName" is up to date ---');
      }
      print('');
      continue;
    }

    print('--- Creating flavor: $flavorName ---');
    final config = FlavorConfig(
      xcPath: pathXcProject ?? 'ios/Runner.xcodeproj/project.pbxproj',
      iosPackageName: packageNameIos,
      androidPackageName: packageNameAndroid,
      displayName: displayName,
      flavorName: flavorName,
      iosTeamId: props['team_id'] as String? ?? teamId,
      dimension: dimension,
      isEnabledIconsLauncher: props['icons_launcher'] as bool? ?? iconsLauncher,
    );

    await createFlavor(config);
    print('');
  }

  print('All flavors processed.');
}