work on brick generator dart script
This commit is contained in:
parent
4f86d6dbbd
commit
fbe7abcc4f
@ -1,6 +1,38 @@
|
|||||||
A sample command-line application with an entrypoint in `bin/`, library code
|
A sample command-line application to generate which allows to generate the template of a brick from a project which compiles. with an entrypoint in `bin/`, library code
|
||||||
in `lib/`.
|
in `lib/`.
|
||||||
|
|
||||||
```sh
|
# How to use
|
||||||
dart /bin/brick_generator.dart wyatt_clean_code wyatt_clean_code wyatt-clean-code "Wyatt Demo" app.wyatt.io
|
|
||||||
|
- Add your app in `apps`.
|
||||||
|
- Add `brick_config.yaml` in you app folder and add this fields :
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
brick_name: wyatt_feature_brick
|
||||||
|
project_name: projet_name
|
||||||
|
|
||||||
|
path_to_brickify: lib/feature_brick_test_folder
|
||||||
|
|
||||||
|
syntax:
|
||||||
|
camel_case: featureBrick
|
||||||
|
constant_case: FEATURE_BRICK
|
||||||
|
dot_case: feature.brick
|
||||||
|
header_case: Feature-Brick
|
||||||
|
lower_case: feature brick
|
||||||
|
pascal_case: FeatureBrick
|
||||||
|
param_case: feature-brick
|
||||||
|
sentence_case: Feature brick
|
||||||
|
snake_case: feature_brick
|
||||||
|
title_case: Feature Brick
|
||||||
|
upper_case: FEATURE BRICK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
then run command with project path
|
||||||
|
|
||||||
|
```sh
|
||||||
|
dart tools/brick_generator/bin/brick_generator.dart ./apps/wyatt_feature_brick
|
||||||
|
```
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
- Work on bool variables
|
||||||
|
- Add several variables (here only one is possible)
|
@ -1,30 +1 @@
|
|||||||
# This file configures the static analysis results for your project (errors,
|
include: package:wyatt_analysis/analysis_options.yaml
|
||||||
# warnings, and lints).
|
|
||||||
#
|
|
||||||
# This enables the 'recommended' set of lints from `package:lints`.
|
|
||||||
# This set helps identify many issues that may lead to problems when running
|
|
||||||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
|
||||||
# style and format.
|
|
||||||
#
|
|
||||||
# If you want a smaller set of lints you can change this to specify
|
|
||||||
# 'package:lints/core.yaml'. These are just the most critical lints
|
|
||||||
# (the recommended set includes the core lints).
|
|
||||||
# The core lints are also what is used by pub.dev for scoring packages.
|
|
||||||
|
|
||||||
include: package:lints/recommended.yaml
|
|
||||||
|
|
||||||
# Uncomment the following section to specify additional rules.
|
|
||||||
|
|
||||||
# linter:
|
|
||||||
# rules:
|
|
||||||
# - camel_case_types
|
|
||||||
|
|
||||||
# analyzer:
|
|
||||||
# exclude:
|
|
||||||
# - path/to/excluded/files/**
|
|
||||||
|
|
||||||
# For more information about the core and recommended set of lints, see
|
|
||||||
# https://dart.dev/go/core-lints
|
|
||||||
|
|
||||||
# For additional information about configuring this file, see
|
|
||||||
# https://dart.dev/guides/language/analysis-options
|
|
||||||
|
@ -1,102 +1,141 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:brick_generator/shell.dart';
|
import 'package:brick_generator/shell.dart';
|
||||||
|
import 'package:brick_generator/yaml_reader.dart';
|
||||||
import 'package:path/path.dart' as path;
|
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
|
// Constants
|
||||||
final _apps = 'apps';
|
const _bricks = 'bricks';
|
||||||
final _bricks = 'bricks';
|
const _brickFolderLabel = '__brick__';
|
||||||
final _staticDir = path.join('tools', 'brick_generator', 'assets');
|
const _yamlFileName = 'brick_config.yaml';
|
||||||
|
|
||||||
Future<void> main(List<String> arguments) async {
|
Future<void> main(List<String> arguments) async {
|
||||||
final _appName = arguments[0];
|
try {
|
||||||
|
if (arguments.length != 1) {
|
||||||
|
throw ArgumentError('Please entry exemple project path');
|
||||||
|
}
|
||||||
|
|
||||||
final _projectSnakeName = arguments[1];
|
final projectPath = arguments[0];
|
||||||
final _projectParamName = arguments[2];
|
|
||||||
final _projectTitleName = arguments[3];
|
|
||||||
final _orgName = arguments[4];
|
|
||||||
|
|
||||||
final _sourcePath = path.join(_apps, _appName);
|
// Store options from yaml file
|
||||||
final _targetPath = path.join(_bricks, _appName, '__brick__');
|
final option =
|
||||||
|
YamlReader.readYamlFile(path.join(projectPath, _yamlFileName));
|
||||||
|
final syntaxMap = option[_syntaxKey] as YamlMap;
|
||||||
|
stdout.writeln('🍺 get options $syntaxMap');
|
||||||
|
|
||||||
final _androidPath = path.join(_targetPath, 'android');
|
for (final syntax in Syntax.values) {
|
||||||
final _androidKotlinPath =
|
if (syntaxMap[syntax.mapKey] == null) {
|
||||||
path.join(_androidPath, 'app', 'src', 'main', 'kotlin');
|
throw ArgumentError(
|
||||||
final _orgPath = path.join(_androidKotlinPath, 'com');
|
'Yaml file is not conform : ${syntax.toString()} is missing',
|
||||||
|
|
||||||
// Remove Previously Generated Files
|
|
||||||
final targetDir = Directory(_targetPath);
|
|
||||||
if (targetDir.existsSync()) {
|
|
||||||
await targetDir.delete(recursive: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy Project Files
|
|
||||||
await Shell.cp(_sourcePath, _targetPath);
|
|
||||||
|
|
||||||
// Delete Android's Organization Folder Hierarchy
|
|
||||||
Directory(_orgPath).deleteSync(recursive: true);
|
|
||||||
|
|
||||||
// Convert Values to Variables
|
|
||||||
await Future.wait(
|
|
||||||
Directory(_targetPath)
|
|
||||||
.listSync(recursive: true)
|
|
||||||
.whereType<File>()
|
|
||||||
.map((_) async {
|
|
||||||
var file = _;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (path.extension(file.path) == '.dart') {
|
|
||||||
final contents = await file.readAsString();
|
|
||||||
file = await file.writeAsString(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
final contents = await file.readAsString();
|
|
||||||
file = await file.writeAsString(
|
|
||||||
contents
|
|
||||||
.replaceAll(
|
|
||||||
_projectSnakeName,
|
|
||||||
'{{#snakeCase}}{{project_name}}{{/snakeCase}}',
|
|
||||||
)
|
|
||||||
.replaceAll(
|
|
||||||
_projectParamName,
|
|
||||||
'{{#paramCase}}{{project_name}}{{/paramCase}}',
|
|
||||||
)
|
|
||||||
.replaceAll('A new Flutter project.', '{{{description}}}')
|
|
||||||
.replaceAll(
|
|
||||||
_projectTitleName,
|
|
||||||
'{{#titleCase}}{{project_name}}{{/titleCase}}',
|
|
||||||
)
|
|
||||||
.replaceAll(
|
|
||||||
_orgName,
|
|
||||||
path.isWithin(_androidPath, file.path)
|
|
||||||
? '{{#dotCase}}{{org_name}}{{/dotCase}}.{{#snakeCase}}{{project_name}}{{/snakeCase}}'
|
|
||||||
: '{{#dotCase}}{{org_name}}{{/dotCase}}.{{#paramCase}}{{project_name}}{{/paramCase}}',
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
final fileSegments = file.path.split('/').sublist(2);
|
}
|
||||||
if (fileSegments.contains(_projectSnakeName)) {
|
}
|
||||||
final newPathSegment = fileSegments.join('/').replaceAll(
|
|
||||||
_projectSnakeName,
|
final projectName = option[_projectNameKey] as String;
|
||||||
'{{#snakeCase}}{{project_name}}{{/snakeCase}}',
|
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),
|
||||||
);
|
);
|
||||||
final newPath = path.join(_targetPath, newPathSegment);
|
|
||||||
File(newPath).createSync(recursive: true);
|
File(newPath).createSync(recursive: true);
|
||||||
file.renameSync(newPath);
|
file.renameSync(newPath);
|
||||||
Directory(file.parent.path).deleteSync(recursive: true);
|
Directory(file.parent.path).deleteSync(recursive: true);
|
||||||
|
} catch (_) {
|
||||||
|
stdout.writeln('❌ ${_.toString()}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
stdout.writeln('❌ ${_.toString()}');
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
}),
|
||||||
}),
|
);
|
||||||
);
|
} catch (_) {
|
||||||
|
stdout.writeln('❌ ${_.toString()}');
|
||||||
final mainActivityKt = File(
|
}
|
||||||
path.join(
|
|
||||||
_androidKotlinPath,
|
|
||||||
'{{#pathCase}}{{org_name}}{{/pathCase}}',
|
|
||||||
'MainActivity.kt',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await Shell.mkdir(mainActivityKt.parent.path);
|
|
||||||
await Shell.cp(path.join(_staticDir, 'MainActivity.kt'), mainActivityKt.path);
|
|
||||||
}
|
}
|
||||||
|
7
tools/brick_generator/lib/yaml_reader.dart
Normal file
7
tools/brick_generator/lib/yaml_reader.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
class YamlReader {
|
||||||
|
static YamlMap readYamlFile(String path) =>
|
||||||
|
loadYaml(File(path).readAsStringSync()) as YamlMap;
|
||||||
|
}
|
@ -5,7 +5,15 @@ version: 1.0.0
|
|||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.17.0 <3.0.0'
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
path: ^1.8.2
|
path: ^1.8.2
|
||||||
|
yaml: ^3.1.1
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
wyatt_analysis:
|
||||||
|
git:
|
||||||
|
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||||
|
ref: wyatt_analysis-v2.1.0
|
||||||
|
path: packages/wyatt_analysis
|
||||||
|
Loading…
x
Reference in New Issue
Block a user