run method

void run(
  1. List<String> arguments, {
  2. String? workingDirectory,
})

Implementation

void run(List<String> arguments, {String? workingDirectory}) async {
  final parser = ArgParser()
    ..addOption('package',
        abbr: 'p', help: 'Package name', defaultsTo: 'twafok')
    ..addFlag('help', abbr: 'h', help: 'Show help', negatable: false);

  try {
    final results = parser.parse(arguments);

    if (results['help'] == true) {
      _printHelp(parser);
      return;
    }

    final args = results.rest;
    final workDir = workingDirectory ?? Directory.current.path;

    // Remove 'add_usecase' from args if it's the first argument
    List<String> cleanArgs = List.from(args);
    if (cleanArgs.isNotEmpty && cleanArgs[0] == 'add_usecase') {
      cleanArgs.removeAt(0);
    }

    String featurePath;
    String usecaseAction;
    final packageName = results['package'] as String;

    // Case 1: User provided both feature path and action
    if (cleanArgs.length >= 2) {
      featurePath = cleanArgs[0];
      usecaseAction = cleanArgs[1];
    }
    // Case 2: User provided only action (try to auto-detect feature path)
    else if (cleanArgs.length == 1) {
      usecaseAction = cleanArgs[0];
      final autoPath = await _findFeaturePath(workDir);
      if (autoPath != null) {
        featurePath = autoPath;
        print('');
        print('📍 Auto-detected feature path: $featurePath');
      } else {
        print('❌ Could not auto-detect feature path');
        print('💡 Please run this command from inside a feature folder');
        print(
            '   Or provide the full path: twafok add_usecase lib/features/FeatureName action_name');
        exit(1);
      }
    }
    // Case 3: No arguments
    else {
      print('❌ Missing usecase action');
      print('');
      print('Usage:');
      print('  twafok add_usecase <feature_path> <usecase_action>');
      print(
          '  twafok add_usecase <usecase_action> (from inside feature folder)');
      exit(1);
    }

    // Build absolute path
    final absoluteFeaturePath = path.isAbsolute(featurePath)
        ? featurePath
        : path.join(workDir, featurePath);

    print('');
    print('📂 Working directory: $workDir');
    print('📁 Feature path: $absoluteFeaturePath');
    print('🎯 UseCase action: $usecaseAction');

    // Validate paths
    final featureDir = Directory(absoluteFeaturePath);
    if (!await featureDir.exists()) {
      print('❌ Feature path does not exist: $absoluteFeaturePath');
      print('');
      print('💡 Make sure:');
      print(
          '   1. You are running this command from inside a feature folder');
      print(
          '   2. Or provide the full path: twafok add_usecase lib/features/buffet action_name');
      exit(1);
    }

    final rawFeature = path.basename(absoluteFeaturePath);
    final naming = NamingUtils(rawFeature, usecaseAction);

    print('');
    print('🚀 Twafok CLI - Adding UseCase');
    print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
    print('   UseCase     : ${naming.usecaseClass}');
    print('   Feature     : ${naming.featureCap}');
    print('   Path        : $absoluteFeaturePath');
    print('   Package     : $packageName');
    print('');

    // 1. Generate UseCase file
    print('📝 Generating files...');
    final usecaseGen = UsecaseGenerator(absoluteFeaturePath, naming);
    await usecaseGen.generate();

    // 2. Update BaseRepository
    final repoGen = RepositoryGenerator(absoluteFeaturePath, naming);
    await repoGen.updateBaseRepository();

    // 3. Update Repository impl
    await repoGen.updateRepositoryImpl();

    // 4. Update DataSource
    final dsGen = DataSourceGenerator(absoluteFeaturePath, naming);
    await dsGen.updateDataSource();

    // 5. Update Cubit
    final cubitGen = CubitGenerator(absoluteFeaturePath, naming);
    await cubitGen.updateCubit();

    // 6 & 7. Regenerate DI and barrel files (optional)
    print('');
    print('🔄 Running additional scripts...');
    // Generate DI
    final diCommand = GenerateDiCommand();
    diCommand.run([absoluteFeaturePath], workingDirectory: workDir);

    // Generate Paths/Barrel
    final pathsCommand = GeneratePathsCommand();
    pathsCommand.run([absoluteFeaturePath], workingDirectory: workDir);

    // 8. Format the project
    await _formatProject(workDir);

    print('');
    print('✨ Success!');
    print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
    print(
        '✅ UseCase \'${naming.usecaseClass}\' added to \'${naming.featureCap}\' feature');
    print('');
    print('📝 Next steps:');
    print('   1. Update ${naming.requestClass} fields to match your API');
    print('   2. Update the endpoint in RemoteDataSource');
    print('   3. Call ${naming.actionCamel}${naming.featureCap}() from UI');
  } catch (e, stackTrace) {
    print('❌ Error: $e');
    if (e is! ArgumentError) {
      print('Stack trace: $stackTrace');
    }
    exit(1);
  }
}