injectCleanArchitecture function

Future<void> injectCleanArchitecture(
  1. String projectName,
  2. String state
)

Implementation

Future<void> injectCleanArchitecture(String projectName,String state,) async {
  final libPath = Directory(p.join(projectName, 'lib'));

  if (libPath.existsSync()) {
    libPath.deleteSync(recursive: true);
  }

  // ✅ DELETE DEFAULT FLUTTER TEST FILE (ADD HERE)
  final defaultTestFile =
  File(p.join(projectName, 'test', 'widget_test.dart'));

  if (defaultTestFile.existsSync()) {
    defaultTestFile.deleteSync();
  }

  final folders = [
    'core/config',
    'core/network',
    'core/services',
    'core/constants',
    'core/utils',
    'data/models',
    'data/repositories',
    'data/sources',
    'domain/entities',
    'domain/usecases',
    'presentation/pages',
    'presentation/widgets',
    'routes',
    'app', // ✅ New app layer
  ];

  for (var folder in folders) {
    Directory(p.join(projectName, 'lib', folder))
        .createSync(recursive: true);
  }

  await installStateManagement(projectName, state);

  // ==============================
  // app/bootstrap.dart
  // ==============================

  final bootstrapContent = state == 'riverpod'
      ? '''
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'app.dart';

Future<void> bootstrap({required String flavor}) async {

  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    ProviderScope(
      child: MyApp(flavor: flavor),
    ),
  );

}
'''
      : '''
import 'package:flutter/material.dart';
import 'app.dart';

Future<void> bootstrap({required String flavor}) async {

  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp(flavor: flavor));

}
''';

  File(p.join(projectName, 'lib', 'app', 'bootstrap.dart'))
      .writeAsStringSync(bootstrapContent);

  // ==============================
  // app/app.dart
  // ==============================

  File(p.join(projectName, 'lib', 'app', 'app.dart'))
      .writeAsStringSync('''
import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  final String flavor;

  const MyApp({super.key, required this.flavor});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Text(
            flavor.toUpperCase(),
            style: const TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }
}
''');

  Directory(p.join(projectName, 'test')).createSync(recursive: true);

  File(p.join(projectName, 'test', 'app_test.dart'))
      .writeAsStringSync('''
import 'package:flutter_test/flutter_test.dart';
import 'package:$projectName/app/app.dart';

void main() {
  testWidgets('App renders flavor', (tester) async {
    await tester.pumpWidget(
      const MyApp(flavor: 'dev'),
    );

    expect(find.text('DEV'), findsOneWidget);
  });
}
''');

  // ==============================
  // main_dev.dart
  // ==============================

  File(p.join(projectName, 'lib', 'main_dev.dart'))
      .writeAsStringSync('''
import 'app/bootstrap.dart';

void main() {
  bootstrap(flavor: 'dev');
}
''');

  // ==============================
  // main_prod.dart
  // ==============================

  File(p.join(projectName, 'lib', 'main_prod.dart'))
      .writeAsStringSync('''
import 'app/bootstrap.dart';

void main() {
  bootstrap(flavor: 'prod');
}
''');

  print('✅ Clean architecture injected (enterprise pattern).');
}