wyatt-bricks/tools/brick_generator/bin/brick_generator.dart
2022-08-07 23:31:22 +01:00

142 lines
4.2 KiB
Dart

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<void> main(List<String> 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<File>()
.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()}');
}
}