run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<int> run() async {
if (argResults!.rest.isEmpty) {
logger.err('Feature name is required.');
return ExitCode.usage.code;
}
final featureName = argResults!.rest.first;
final routerType = argResults!['router'] as String;
final rc = ReCase(featureName);
logger.info('Creating feature: ${rc.snakeCase} with router: $routerType');
final featurePath = 'lib/features/${rc.snakeCase}';
// 1. Create directories
// Data Layer
FileUtils.createDirectory('$featurePath/data/datasources', logger: logger);
FileUtils.createDirectory('$featurePath/data/models', logger: logger);
FileUtils.createDirectory('$featurePath/data/repositories', logger: logger);
// Domain Layer
FileUtils.createDirectory('$featurePath/domain/entities', logger: logger);
FileUtils.createDirectory(
'$featurePath/domain/repositories',
logger: logger,
);
FileUtils.createDirectory('$featurePath/domain/usecases', logger: logger);
// Presentation Layer
FileUtils.createDirectory(
'$featurePath/presentation/controllers',
logger: logger,
);
FileUtils.createDirectory(
'$featurePath/presentation/pages',
logger: logger,
);
FileUtils.createDirectory(
'$featurePath/presentation/widgets',
logger: logger,
);
// Bindings
FileUtils.createDirectory('$featurePath/bindings', logger: logger);
// 2. Get Package Name (prefix)
final packageName = _getPackageName();
// 3. Create Files and Sub-Barrels
// Bindings
FileUtils.createFile(
'$featurePath/bindings/${rc.snakeCase}_binding.dart',
Templates.binding(featureName, packageName),
logger: logger,
);
FileUtils.createFile(
'$featurePath/bindings/bindings.dart',
Templates.subBarrel(['${rc.snakeCase}_binding.dart']),
logger: logger,
);
// Controllers
FileUtils.createFile(
'$featurePath/presentation/controllers/${rc.snakeCase}_controller.dart',
Templates.controller(featureName),
logger: logger,
);
FileUtils.createFile(
'$featurePath/presentation/controllers/controllers.dart',
Templates.subBarrel(['${rc.snakeCase}_controller.dart']),
logger: logger,
);
// Pages
FileUtils.createFile(
'$featurePath/presentation/pages/${rc.snakeCase}_page.dart',
Templates.page(featureName, packageName),
logger: logger,
);
FileUtils.createFile(
'$featurePath/presentation/pages/pages.dart',
Templates.subBarrel(['${rc.snakeCase}_page.dart']),
logger: logger,
);
// Other folders (Empty barrels)
FileUtils.createFile(
'$featurePath/data/datasources/datasources.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/domain/entities/entities.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/domain/repositories/repositories.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/domain/usecases/usecases.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/data/repositories/repositories.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/data/models/models.dart',
Templates.subBarrel(),
logger: logger,
);
FileUtils.createFile(
'$featurePath/presentation/widgets/widgets.dart',
Templates.subBarrel(),
logger: logger,
);
// Main Feature Barrel
FileUtils.createFile(
'$featurePath/${rc.snakeCase}.dart',
Templates.barrel(featureName),
logger: logger,
);
// 4. Auto-register in DI (This is simplified, parsing Dart files is complex without `analyzer`)
// _updateDI(rc, packageName);
// 5. Auto-register in Router
// 5. Auto-register in Router
_updateRouter(rc, routerType, packageName);
// 6. Update Features Barrel
_updateFeaturesBarrel(rc);
logger.success('Feature $featureName created successfully!');
return ExitCode.success.code;
}