createFeature function

Future<void> createFeature(
  1. String featureName, {
  2. String? stateArg,
})

Implementation

Future<void> createFeature(String featureName, {String? stateArg}) async {
  // 🧭 Step 1: Detect Flutter project root
  final projectRoot = _findProjectRoot();

  if (projectRoot == null) {
    print(
      'āŒ Could not find pubspec.yaml — please run this inside a Flutter project.',
    );
    exit(1);
  }

  print('šŸš€ Creating feature "$featureName"...\n');

  // 🧱 Step 2: Load or ask for state management choice
  final stateManagement = _getOrAskStateManagement(projectRoot);

  // 🧩 Step 3: Build folder paths
  final base = p.join(projectRoot.path, 'lib', 'features', featureName);

  final dirs = [
    'data/models',
    'data/datasources',
    'domain/entities',
    'domain/repositories',
    'domain/usecases',
    'presentation/screens',
    'presentation/widgets',
  ];

  // Add state-management specific folders
  switch (stateManagement) {
    case 'bloc':
      dirs.add('presentation/bloc');
      break;
    case 'riverpod':
      dirs.add('presentation/providers');
      break;
    case 'provider':
      dirs.add('presentation/providers');
      break;
    case 'getx':
      dirs.add('presentation/controllers');
      break;
  }

  for (var dir in dirs) {
    createDir(p.join(base, dir));
  }

  // 🧩 Step 4: Generate common files
  createFile(p.join(base, 'data/models/${featureName}_model.dart'), '''
class ${_pascal(featureName)}Model {
  // TODO: Define model fields
}
''');

  createFile(p.join(base, 'domain/entities/${featureName}_entity.dart'), '''
class ${_pascal(featureName)}Entity {
  // TODO: Define entity fields
}
''');

  createFile(
    p.join(base, 'domain/repositories/${featureName}_repository.dart'),
    '''
abstract class ${_pascal(featureName)}Repository {
  // TODO: Define abstract methods
}
''',
  );

  createFile(
    p.join(base, 'presentation/screens/${featureName}_screen.dart'),
    '''
import 'package:flutter/material.dart';

class ${_pascal(featureName)}Screen extends StatelessWidget {
  const ${_pascal(featureName)}Screen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('${_pascal(featureName)} Screen')),
      body: const Center(child: Text('Welcome to ${_pascal(featureName)} feature!')),
    );
  }
}
''',
  );

  // 🧠 Step 5: Generate state management boilerplate
  _generateStateManagement(stateManagement, featureName, base);

  print(
    '\nāœ… Feature "$featureName" with "$stateManagement" state management generated successfully!',
  );
}