import 'dart:io'; import 'package:brick_generator/shell.dart'; import 'package:brick_generator/yaml_reader.dart'; import 'package:path/path.dart' as path; import 'package:yaml/yaml.dart'; // Keys enum Syntax { camelCase('camel_case', 'camelCase'), constantCase('constant_case', 'constantCase'), dotCase('dot_case', 'dotCase'), headerCase('header_case', 'headerCase'), lowerCase('lower_case', 'lowerCase'), pascalCase('pascal_case', 'pascalCase'), paramCase('param_case', 'paramCase'), sentenceCase('sentence_case', 'sentenceCase'), snakeCase('snake_case', 'snakeCase'), titleCase('title_case', 'titleCase'), upperCase('upper_case', 'upperCase'); final String mapKey; final String id; const Syntax(this.mapKey, this.id); } // Other Keys const _projectNameKey = 'project_name'; const _brickNameKey = 'brick_name'; const _pathToBrickifyKey = 'path_to_brickify'; const _syntaxKey = 'syntax'; // Constants const _bricks = 'bricks'; const _brickFolderLabel = '__brick__'; const _yamlFileName = 'brick_config.yaml'; Future main(List arguments) async { try { if (arguments.length != 1) { throw ArgumentError('Please entry exemple project path'); } final projectPath = arguments[0]; // Store options from yaml file final option = YamlReader.readYamlFile(path.join(projectPath, _yamlFileName)); final syntaxMap = option[_syntaxKey] as YamlMap; stdout.writeln('🍺 get options $syntaxMap'); for (final syntax in Syntax.values) { if (syntaxMap[syntax.mapKey] == null) { throw ArgumentError( 'Yaml file is not conform : ${syntax.toString()} is missing', ); } } final projectName = option[_projectNameKey] as String; final brickName = option[_brickNameKey] as String; // Define paths final sourcePath = path.join(projectPath, option[_pathToBrickifyKey] as String); final targetPath = path.join(_bricks, brickName, _brickFolderLabel); stdout.writeln('🍺 path defined'); // Remove previously generated files final targetDir = Directory(targetPath); if (targetDir.existsSync()) { await targetDir.delete(recursive: true); } // create target folder await Shell.mkdir(targetPath); // Copy project files await Shell.cp(sourcePath, targetPath); stdout.writeln('🍺 files copied'); // Convert values to variables await Future.wait( Directory(targetPath) .listSync(recursive: true) .whereType() .map((_) async { var file = _; try { var contents = await file.readAsString(); // Transform all values in variables for (final syntax in Syntax.values) { contents = contents.replaceAll( syntaxMap[syntax.mapKey] as String, '{{#${syntax.id}}}{{$projectName}}{{/${syntax.id}}}', ); } file = await file.writeAsString(contents); // Rename file if needed final filePath = file.path; if (filePath.contains(syntaxMap[Syntax.snakeCase.mapKey] as String)) { try { var pathList = filePath.split(Platform.pathSeparator).sublist(3); pathList = pathList .map( (segment) => segment.replaceAll( syntaxMap[Syntax.snakeCase.mapKey] as String, '{{$projectName.snakeCase()}}', ), ) .toList(); final newPath = path.join( filePath .split(Platform.pathSeparator) .sublist(0, 3) .join(Platform.pathSeparator), pathList.join(Platform.pathSeparator), ); File(newPath).createSync(recursive: true); file.renameSync(newPath); Directory(file.parent.path).deleteSync(recursive: true); } catch (_) { stdout.writeln('❌ ${_.toString()}'); } } } catch (_) { stdout.writeln('❌ ${_.toString()}'); } }), ); } catch (_) { stdout.writeln('❌ ${_.toString()}'); } }