This guide explains the hooks used in CleanForge bricks and their functionality. Hooks are special scripts that run before (pre_gen.dart
) and after (post_gen.dart
) the brick generation process.
← Back to Main Documentation | Feature Guide → |
pre_gen.dart
)The pre-generation hook for the main CleanForge brick performs several setup validations and preparations:
// Primary responsibilities of pre_gen.dart
void run(HookContext context) {
// 1. Validate project name
// 2. Set up directory structure
// 3. Configure dependencies
// 4. Initialize Git repository if needed
// 5. Prepare environment files
}
Key functions:
post_gen.dart
)The post-generation hook handles final setup and configuration:
// Primary responsibilities of post_gen.dart
void run(HookContext context) {
// 1. Update pubspec.yaml
// 2. Run pub get
// 3. Initialize GetX structure
// 4. Set up theme configuration
// 5. Configure routing
}
Key functions:
pre_gen.dart
)The feature brick’s pre-generation hook handles feature-specific validations:
// Primary responsibilities of pre_gen.dart
void run(HookContext context) {
// 1. Validate feature name
// 2. Check for conflicts
// 3. Prepare feature structure
// 4. Validate dependencies
}
Key functions:
post_gen.dart
)The feature brick’s post-generation hook handles feature integration:
// Primary responsibilities of post_gen.dart
void run(HookContext context) {
// 1. Update route configuration
// 2. Register bindings
// 3. Set up feature dependencies
// 4. Configure feature module
}
Key functions:
// Example of auto-generated binding registration
void registerBindings(String featureName) {
final bindingPath = 'lib/features/$featureName/presentation/bindings/${featureName}_binding.dart';
final binding = File(bindingPath);
// Update app_binding.dart to include new feature binding
final appBinding = File('lib/app/app_binding.dart');
// Add new binding to dependencies
}
Both bricks include common utility functions in their hooks:
// Convert feature name to different cases
String toSnakeCase(String name) => name.replaceAllMapped(
RegExp(r'[A-Z]'),
(Match m) => '_${m[0]?.toLowerCase()}',
).toLowerCase();
String toPascalCase(String name) => name
.split('_')
.map((word) => word[0].toUpperCase() + word.substring(1))
.join();
// Add content to existing files
void appendToFile(String path, String content) {
final file = File(path);
if (file.existsSync()) {
file.writeAsStringSync(content, mode: FileMode.append);
}
}
// Update specific sections in files
void updateSection(String path, String marker, String content) {
final file = File(path);
if (file.existsSync()) {
var text = file.readAsStringSync();
text = text.replaceAll(RegExp(r'// $marker\n.*// End $marker', dotAll: true),
'// $marker\n$content\n // End $marker');
file.writeAsStringSync(text);
}
}
bool isValidPackageName(String name) {
final regex = RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$');
return regex.hasMatch(name);
}
bool isValidFeatureName(String name) {
final regex = RegExp(r'^[a-zA-Z][a-zA-Z0-9_]*$');
return regex.hasMatch(name);
}
void handleErrors(void Function() operation) {
try {
operation();
} catch (e) {
print('Error during hook execution: $e');
rethrow;
}
}
void ensureWritePermission(String path) {
final directory = Directory(path);
if (!directory.existsSync()) {
directory.createSync(recursive: true);
}
}
void checkDependencyConflicts(String path) {
final pubspec = File('$path/pubspec.yaml');
// Check for version conflicts
}
String normalizePath(String path) {
return path.replaceAll(RegExp(r'\\'), '/');
}
To test hooks during development:
# Test main brick
mason make cleanforge --project_name test_project
# Test feature brick
mason make cleanforge_feature --feat test_feature