feat: rewrite generator
This commit is contained in:
parent
1646dbd919
commit
18aeef9e35
30
tools/brick_generator/bin/brick.yaml
Normal file
30
tools/brick_generator/bin/brick.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: <brick_name>
|
||||||
|
description: <brick_description>
|
||||||
|
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
vars:
|
||||||
|
display_name:
|
||||||
|
type: string
|
||||||
|
description: The display name
|
||||||
|
default: Display Name
|
||||||
|
prompt: What is the display name?
|
||||||
|
|
||||||
|
project_name:
|
||||||
|
type: string
|
||||||
|
description: The project name
|
||||||
|
default: wyatt_app
|
||||||
|
prompt: What is the project name?
|
||||||
|
|
||||||
|
bundle_id:
|
||||||
|
type: string
|
||||||
|
description: The bundle id used in Android and iOS
|
||||||
|
default: io.wyattapp.new
|
||||||
|
prompt: What is the bundle id?
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
type: boolean
|
||||||
|
description: If this app is a Flutter or Dart project.
|
||||||
|
default: false
|
||||||
|
prompt: Is it Flutter app ?
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:brick_generator/core/logger.dart';
|
||||||
|
import 'package:brick_generator/core/shell.dart';
|
||||||
import 'package:brick_generator/file_system_utils.dart';
|
import 'package:brick_generator/file_system_utils.dart';
|
||||||
import 'package:brick_generator/logger.dart';
|
|
||||||
import 'package:brick_generator/models/brick_config.dart';
|
import 'package:brick_generator/models/brick_config.dart';
|
||||||
import 'package:brick_generator/shell.dart';
|
|
||||||
import 'package:brick_generator/yaml_reader.dart';
|
import 'package:brick_generator/yaml_reader.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
182
tools/brick_generator/bin/brickgen.dart
Normal file
182
tools/brick_generator/bin/brickgen.dart
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:args/args.dart';
|
||||||
|
import 'package:brick_generator/core/file_system.dart';
|
||||||
|
import 'package:brick_generator/core/logger.dart';
|
||||||
|
import 'package:brick_generator/models/brick_config.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
|
const _configurationFileName = 'brickgen.yaml';
|
||||||
|
const _masonConfigurationFileName = 'brick.yaml';
|
||||||
|
const _brickFolderName = '__brick__';
|
||||||
|
|
||||||
|
const _helpOption = 'help';
|
||||||
|
const _verboseOption = 'verbose';
|
||||||
|
const _removeEmptyOption = 'remove-empty';
|
||||||
|
|
||||||
|
class Brickgen {
|
||||||
|
final String brickPath;
|
||||||
|
final String outputPath;
|
||||||
|
final bool deleteEmptyFolders;
|
||||||
|
|
||||||
|
late String configPath;
|
||||||
|
|
||||||
|
String? toBrickifyPath;
|
||||||
|
String? masonConfigPath;
|
||||||
|
String? targetPath;
|
||||||
|
|
||||||
|
Brickgen({
|
||||||
|
required this.brickPath,
|
||||||
|
required this.outputPath,
|
||||||
|
required this.deleteEmptyFolders,
|
||||||
|
}) {
|
||||||
|
configPath = join(brickPath, _configurationFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> run() async {
|
||||||
|
// Load config
|
||||||
|
final config = BrickConfig.fromFile(configPath);
|
||||||
|
Logger.debug('Read config: \n${config.toMason()}');
|
||||||
|
Logger.info('Config retrieved.');
|
||||||
|
|
||||||
|
// Define paths
|
||||||
|
toBrickifyPath = FileSystem.joinExists(
|
||||||
|
brickPath,
|
||||||
|
config.brickgenConfig.pathToBrickify,
|
||||||
|
);
|
||||||
|
Logger.debug('Define `toBrickifyPath`: $toBrickifyPath');
|
||||||
|
|
||||||
|
masonConfigPath = FileSystem.joinTouch(
|
||||||
|
outputPath,
|
||||||
|
config.name,
|
||||||
|
_masonConfigurationFileName,
|
||||||
|
);
|
||||||
|
Logger.debug('Define `masonConfigPath`: $masonConfigPath');
|
||||||
|
|
||||||
|
targetPath = FileSystem.joinRecreate(
|
||||||
|
outputPath,
|
||||||
|
config.name,
|
||||||
|
_brickFolderName,
|
||||||
|
);
|
||||||
|
Logger.debug('Define `targetPath`: $targetPath');
|
||||||
|
|
||||||
|
// Check paths
|
||||||
|
if (toBrickifyPath == null || targetPath == null) {
|
||||||
|
throw Exception('An error occures during path definition.');
|
||||||
|
}
|
||||||
|
Logger.info('Paths defined.');
|
||||||
|
|
||||||
|
// Copy (and exclude from copy) project files
|
||||||
|
await FileSystem.copyFolder(
|
||||||
|
toBrickifyPath!,
|
||||||
|
targetPath!,
|
||||||
|
ignoreList: config.brickgenConfig.ignore,
|
||||||
|
);
|
||||||
|
Logger.info('Project copied.');
|
||||||
|
|
||||||
|
// Convert compilable values -> variables (in files)
|
||||||
|
FileSystem.convertCompilableVariablesInFolder(config, targetPath!);
|
||||||
|
Logger.info('Files content converted with variables.');
|
||||||
|
|
||||||
|
// Create `.gitkeep` in empty folders (to keep them in brick generation)
|
||||||
|
// Or remove them (depending of --remove option)
|
||||||
|
if (deleteEmptyFolders) {
|
||||||
|
FileSystem.removeEmptyFolders(targetPath!);
|
||||||
|
Logger.info('Empty folders removed.');
|
||||||
|
} else {
|
||||||
|
FileSystem.createGitKeepInEmptyFolders(targetPath!);
|
||||||
|
Logger.info('Empty folders marked as to keep.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert compilable values -> variables (files/folder names)
|
||||||
|
FileSystem.renameCompilableFilesInFolder(config, targetPath!);
|
||||||
|
Logger.info('Files renamed with variables.');
|
||||||
|
|
||||||
|
// Take care of boolean mapping and boolean fs
|
||||||
|
|
||||||
|
// Create Mason config
|
||||||
|
FileSystem.writeFile(masonConfigPath!, config.toMason());
|
||||||
|
Logger.info('Mason `brick.yaml` generated.');
|
||||||
|
|
||||||
|
// Create gitkeep hook
|
||||||
|
|
||||||
|
// Copy custom hooks
|
||||||
|
|
||||||
|
// Success!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> main(List<String> args) async {
|
||||||
|
int exitCode = 0;
|
||||||
|
|
||||||
|
final parser = ArgParser()
|
||||||
|
..addFlag(
|
||||||
|
_helpOption,
|
||||||
|
negatable: false,
|
||||||
|
abbr: 'h',
|
||||||
|
help: 'Show this help dialog',
|
||||||
|
)
|
||||||
|
..addFlag(
|
||||||
|
_verboseOption,
|
||||||
|
negatable: false,
|
||||||
|
abbr: 'v',
|
||||||
|
help: 'Show additional diagnostic info',
|
||||||
|
)
|
||||||
|
..addFlag(
|
||||||
|
_removeEmptyOption,
|
||||||
|
negatable: false,
|
||||||
|
abbr: 'r',
|
||||||
|
help: 'Remove empty folders (if not it creates '
|
||||||
|
'.gitkeep in each empty folders)',
|
||||||
|
);
|
||||||
|
|
||||||
|
final argResults = parser.parse(args);
|
||||||
|
|
||||||
|
if (argResults[_helpOption] as bool? ?? false) {
|
||||||
|
Logger.info('Brickgen\n${parser.usage}');
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argResults[_verboseOption] as bool? ?? false) {
|
||||||
|
Logger.setVerbose();
|
||||||
|
}
|
||||||
|
|
||||||
|
final paths = argResults.rest;
|
||||||
|
|
||||||
|
if (paths.length < 2) {
|
||||||
|
Logger.error('Please provide input and output paths.');
|
||||||
|
if (!(argResults[_helpOption] as bool? ?? false)) {
|
||||||
|
Logger.info('Brickgen\n${parser.usage}');
|
||||||
|
}
|
||||||
|
exitCode = 1;
|
||||||
|
exit(exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
final brickPath = paths[0];
|
||||||
|
final outputPath = paths[1];
|
||||||
|
|
||||||
|
await Brickgen(
|
||||||
|
brickPath: brickPath,
|
||||||
|
outputPath: outputPath,
|
||||||
|
deleteEmptyFolders: argResults[_removeEmptyOption] as bool? ?? false,
|
||||||
|
).run();
|
||||||
|
|
||||||
|
exit(exitCode);
|
||||||
|
}
|
357
tools/brick_generator/lib/core/file_system.dart
Normal file
357
tools/brick_generator/lib/core/file_system.dart
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:brick_generator/core/logger.dart';
|
||||||
|
import 'package:brick_generator/core/shell.dart';
|
||||||
|
import 'package:brick_generator/models/brick_config.dart';
|
||||||
|
import 'package:brick_generator/models/brick_variable_string.dart';
|
||||||
|
import 'package:brick_generator/models/ignore_list.dart';
|
||||||
|
import 'package:brick_generator/models/variable_string_syntax.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
|
abstract class FileSystem {
|
||||||
|
static void writeFile(String path, Object? content, {bool binary = false}) {
|
||||||
|
final file = File(join(path))..createSync(recursive: true);
|
||||||
|
|
||||||
|
if (content == null) {
|
||||||
|
// Just create an empty file
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (binary) {
|
||||||
|
file.writeAsBytesSync(content as List<int>);
|
||||||
|
} else {
|
||||||
|
file.writeAsStringSync(content as String);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Logger.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> copyFolder(
|
||||||
|
String from,
|
||||||
|
String to, {
|
||||||
|
IgnoreList? ignoreList,
|
||||||
|
}) async {
|
||||||
|
if (!FileSystemEntity.isDirectorySync(from)) {
|
||||||
|
throw ArgumentError('Path must be a directory', 'from');
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> copiedFolders = [];
|
||||||
|
|
||||||
|
// Copy folders
|
||||||
|
await Future.wait<void>(
|
||||||
|
Directory(from)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<Directory>()
|
||||||
|
.map((directory) async {
|
||||||
|
final absolutPath = directory.path;
|
||||||
|
final name = absolutPath.split('/').last;
|
||||||
|
|
||||||
|
if (ignoreList != null && ignoreList.contains(from, absolutPath)) {
|
||||||
|
Logger.debug('Ignoring $absolutPath');
|
||||||
|
} else {
|
||||||
|
Logger.debug('cp -Rf $absolutPath $to/$name');
|
||||||
|
copiedFolders.add(absolutPath);
|
||||||
|
await Shell.cp(absolutPath, '$to/$name');
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy files
|
||||||
|
await Future.wait<void>(
|
||||||
|
Directory(from)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<File>()
|
||||||
|
.map((file) async {
|
||||||
|
final absolutPath = file.path;
|
||||||
|
final name = absolutPath.split('/').last;
|
||||||
|
|
||||||
|
if (ignoreList != null && ignoreList.contains(from, absolutPath)) {
|
||||||
|
Logger.debug('Ignoring $absolutPath');
|
||||||
|
} else {
|
||||||
|
if (copiedFolders.any(absolutPath.startsWith)) {
|
||||||
|
Logger.debug('$absolutPath already copied!');
|
||||||
|
} else {
|
||||||
|
Logger.debug('cp -Rf $absolutPath $to/$name');
|
||||||
|
await Shell.cp(absolutPath, '$to/$name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeDirectory(String path) {
|
||||||
|
final dir = Directory(path);
|
||||||
|
if (dir.existsSync()) {
|
||||||
|
dir.deleteSync(recursive: true);
|
||||||
|
}
|
||||||
|
dir.createSync(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join and verify if the joined path exists.
|
||||||
|
static String joinExists(
|
||||||
|
String part1, [
|
||||||
|
String? part2,
|
||||||
|
String? part3,
|
||||||
|
String? part4,
|
||||||
|
String? part5,
|
||||||
|
String? part6,
|
||||||
|
String? part7,
|
||||||
|
String? part8,
|
||||||
|
]) {
|
||||||
|
final path = join(part1, part2, part3, part4, part5, part6, part7, part8);
|
||||||
|
|
||||||
|
if (FileSystemEntity.isDirectorySync(path)) {
|
||||||
|
Logger.debug('$path is a directory, and it exists.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileSystemEntity.isFileSync(path)) {
|
||||||
|
Logger.debug('$path is a file, and it exists.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ArgumentError('Joined path is not existing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join and verify if the joined path exists. If not, create it.
|
||||||
|
static String joinCreate(
|
||||||
|
String part1, [
|
||||||
|
String? part2,
|
||||||
|
String? part3,
|
||||||
|
String? part4,
|
||||||
|
String? part5,
|
||||||
|
String? part6,
|
||||||
|
String? part7,
|
||||||
|
String? part8,
|
||||||
|
]) {
|
||||||
|
final path = join(part1, part2, part3, part4, part5, part6, part7, part8);
|
||||||
|
|
||||||
|
if (FileSystemEntity.isDirectorySync(path)) {
|
||||||
|
Logger.debug('$path is a directory, and it exists.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileSystemEntity.isFileSync(path)) {
|
||||||
|
Logger.debug('$path is a file, and it exists.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeDirectory(path);
|
||||||
|
Logger.debug('$path directory was created.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join and verify if the joined path exists. If yes, recreate it.
|
||||||
|
static String joinRecreate(
|
||||||
|
String part1, [
|
||||||
|
String? part2,
|
||||||
|
String? part3,
|
||||||
|
String? part4,
|
||||||
|
String? part5,
|
||||||
|
String? part6,
|
||||||
|
String? part7,
|
||||||
|
String? part8,
|
||||||
|
]) {
|
||||||
|
final path = join(part1, part2, part3, part4, part5, part6, part7, part8);
|
||||||
|
|
||||||
|
if (FileSystemEntity.isDirectorySync(path)) {
|
||||||
|
makeDirectory(path);
|
||||||
|
Logger.debug('$path directory was recreated.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileSystemEntity.isFileSync(path)) {
|
||||||
|
Logger.debug('$path is a file ! No recreate it!');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeDirectory(path);
|
||||||
|
Logger.debug('$path directory was created.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join and verify if the joined path exists. If yes, touch it. If not
|
||||||
|
/// create an empty file.
|
||||||
|
static String joinTouch(
|
||||||
|
String part1, [
|
||||||
|
String? part2,
|
||||||
|
String? part3,
|
||||||
|
String? part4,
|
||||||
|
String? part5,
|
||||||
|
String? part6,
|
||||||
|
String? part7,
|
||||||
|
String? part8,
|
||||||
|
]) {
|
||||||
|
final path = join(part1, part2, part3, part4, part5, part6, part7, part8);
|
||||||
|
|
||||||
|
if (FileSystemEntity.isDirectorySync(path)) {
|
||||||
|
Logger.debug('$path is a directory ! No recreate it!');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileSystemEntity.isFileSync(path)) {
|
||||||
|
writeFile(path, null);
|
||||||
|
Logger.debug('$path files was touched!');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFile(path, null);
|
||||||
|
Logger.debug('$path file was created.');
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transforms compilable variables:
|
||||||
|
/// For each String `vars` in config, search for compilable in code, then
|
||||||
|
/// convert it to his mustache format.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```yaml
|
||||||
|
/// bundle_id:
|
||||||
|
/// compilable: io.wyattapp.new
|
||||||
|
/// type: string
|
||||||
|
/// description: The bundle id used in Android and iOS
|
||||||
|
/// default: io.wyattapp.new
|
||||||
|
/// prompt: "What is the bundle id?"
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Search for `io.wyattapp.new` then converts
|
||||||
|
/// it to `{{#dotCase}}{{bundle_id}}{{/dotCase}}`
|
||||||
|
static void convertCompilableVariablesInFolder(
|
||||||
|
BrickConfig config,
|
||||||
|
String targetPath,
|
||||||
|
) {
|
||||||
|
if (!FileSystemEntity.isDirectorySync(targetPath)) {
|
||||||
|
throw ArgumentError('Target must be a directory', 'targetPath');
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory(targetPath)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<File>()
|
||||||
|
.forEach((file) {
|
||||||
|
String? contents;
|
||||||
|
|
||||||
|
try {
|
||||||
|
contents = file.readAsStringSync();
|
||||||
|
} catch (e) {
|
||||||
|
Logger.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.variables.whereType<BrickVariableString>().forEach((variable) {
|
||||||
|
// Replace all string variables
|
||||||
|
for (final syntax in VariableStringSyntax.values) {
|
||||||
|
final toReplace = variable.syntax?[syntax.mapKey];
|
||||||
|
if (toReplace != null) {
|
||||||
|
contents = contents!.replaceAll(
|
||||||
|
toReplace,
|
||||||
|
'{{#${syntax.id}}}{{${variable.name}}}{{/${syntax.id}}}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger.debug('Variable `${variable.name}` replaced in ${file.path}');
|
||||||
|
});
|
||||||
|
|
||||||
|
file.writeAsStringSync(contents!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createGitKeepInEmptyFolders(String targetPath) {
|
||||||
|
if (!FileSystemEntity.isDirectorySync(targetPath)) {
|
||||||
|
throw ArgumentError('Target must be a directory', 'targetPath');
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory(targetPath)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<Directory>()
|
||||||
|
.forEach((directory) {
|
||||||
|
if (directory.existsSync() &&
|
||||||
|
directory.listSync(recursive: true).isEmpty) {
|
||||||
|
joinTouch(directory.path, '.gitkeep');
|
||||||
|
Logger.debug('${directory.path} (empty) marked as to keep.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeEmptyFolders(String targetPath) {
|
||||||
|
if (!FileSystemEntity.isDirectorySync(targetPath)) {
|
||||||
|
throw ArgumentError('Target must be a directory', 'targetPath');
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory(targetPath)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<Directory>()
|
||||||
|
.forEach((directory) {
|
||||||
|
if (directory.existsSync() &&
|
||||||
|
directory.listSync(recursive: true).isEmpty) {
|
||||||
|
directory.deleteSync(recursive: true);
|
||||||
|
Logger.debug('${directory.path} (empty) deleted.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transforms compilable file/folder names:
|
||||||
|
/// For each String `vars` in config, search for compilable in code, then
|
||||||
|
/// convert it to his mustache format.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```yaml
|
||||||
|
/// project_name:
|
||||||
|
/// compilable: wyatt_app_template
|
||||||
|
/// type: string
|
||||||
|
/// description: The project name
|
||||||
|
/// default: wyatt_app
|
||||||
|
/// prompt: "What is the project name?"
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Search for `wyatt_app_template` files and folders then converts
|
||||||
|
/// it to `{{project_name.snakeCase()}}`
|
||||||
|
static void renameCompilableFilesInFolder(
|
||||||
|
BrickConfig config,
|
||||||
|
String targetPath,
|
||||||
|
) {
|
||||||
|
if (!FileSystemEntity.isDirectorySync(targetPath)) {
|
||||||
|
throw ArgumentError('Target must be a directory', 'targetPath');
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory(targetPath)
|
||||||
|
.listSync(recursive: true)
|
||||||
|
.whereType<File>()
|
||||||
|
.forEach((file) {
|
||||||
|
config.variables.whereType<BrickVariableString>().forEach((variable) {
|
||||||
|
// Replace all string variables
|
||||||
|
for (final syntax in VariableStringSyntax.values) {
|
||||||
|
final toReplace = variable.syntax?[syntax.mapKey];
|
||||||
|
if (toReplace != null && file.path.contains(toReplace)) {
|
||||||
|
final newPath = file.path.replaceAll(
|
||||||
|
toReplace,
|
||||||
|
'{{${variable.name}.${syntax.id}}}',
|
||||||
|
);
|
||||||
|
|
||||||
|
File(newPath).createSync(recursive: true);
|
||||||
|
file.renameSync(newPath);
|
||||||
|
Logger.debug(
|
||||||
|
'${file.path} renamed with variable `${variable.name}`',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -19,13 +19,19 @@ import 'dart:io';
|
|||||||
import 'package:brick_generator/models/log_level.dart';
|
import 'package:brick_generator/models/log_level.dart';
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
|
static bool verbose = false;
|
||||||
|
|
||||||
|
static void setVerbose() => verbose = true;
|
||||||
|
|
||||||
static void log(Object? message, {LogLevel level = LogLevel.info}) {
|
static void log(Object? message, {LogLevel level = LogLevel.info}) {
|
||||||
stdout.writeln('${level.prefix} ${message.toString()}');
|
stdout.writeln('${level.prefix} ${message.toString()}');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug(Object? message) {
|
static void debug(Object? message) {
|
||||||
|
if (verbose) {
|
||||||
log(message, level: LogLevel.debug);
|
log(message, level: LogLevel.debug);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void info(Object? message) {
|
static void info(Object? message) {
|
||||||
log(message);
|
log(message);
|
@ -16,23 +16,20 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:brick_generator/logger.dart';
|
import 'package:brick_generator/core/logger.dart';
|
||||||
|
|
||||||
class Shell {
|
abstract class Shell {
|
||||||
static Future<void> cp(String source, String destination) {
|
static Future<void> cp(String source, String destination) =>
|
||||||
return _Cmd.run('cp', ['-Rf', source, destination]);
|
_Cmd.run('cp', ['-Rf', source, destination]);
|
||||||
}
|
|
||||||
|
|
||||||
static Future<void> mkdir(String destination) {
|
static Future<void> mkdir(String destination) =>
|
||||||
return _Cmd.run('mkdir', ['-p', destination]);
|
_Cmd.run('mkdir', ['-p', destination]);
|
||||||
}
|
|
||||||
|
|
||||||
static Future<void> rm(String target, {bool recursive = false}) {
|
static Future<void> rm(String target, {bool recursive = false}) =>
|
||||||
return _Cmd.run('rm', ['-f${recursive ? "r" : ""}', target]);
|
_Cmd.run('rm', ['-f${recursive ? "r" : ""}', target]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Cmd {
|
abstract class _Cmd {
|
||||||
static Future<ProcessResult> run(
|
static Future<ProcessResult> run(
|
||||||
String cmd,
|
String cmd,
|
||||||
List<String> args, {
|
List<String> args, {
|
@ -291,27 +291,21 @@ extension StringExtension on String {
|
|||||||
/// print('Hello World'.sentence()) // Hello world
|
/// print('Hello World'.sentence()) // Hello world
|
||||||
/// print('helloWorld'.sentence()) // Hello world
|
/// print('helloWorld'.sentence()) // Hello world
|
||||||
/// ```
|
/// ```
|
||||||
String sentence() {
|
String sentence() => lower().capitalize();
|
||||||
return lower().capitalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// print('Hello World'.title()) // Hello World
|
/// print('Hello World'.title()) // Hello World
|
||||||
/// print('helloWorld'.title()) // Hello World
|
/// print('helloWorld'.title()) // Hello World
|
||||||
/// ```
|
/// ```
|
||||||
String title() {
|
String title() => header().splitMapJoin(
|
||||||
return header().splitMapJoin(
|
|
||||||
_defaultMatcher,
|
_defaultMatcher,
|
||||||
onMatch: (m) => ' ',
|
onMatch: (m) => ' ',
|
||||||
onNonMatch: (n) => n,
|
onNonMatch: (n) => n,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// print('Hello World'.mustache()) // {{ Hello World }}
|
/// print('Hello World'.mustache()) // {{ Hello World }}
|
||||||
/// print('helloWorld'.mustache()) // {{ Hello World }}
|
/// print('helloWorld'.mustache()) // {{ Hello World }}
|
||||||
/// ```
|
/// ```
|
||||||
String mustache() {
|
String mustache() => '{{ ${title()} }}';
|
||||||
return '{{ ${title()} }}';
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:brick_generator/logger.dart';
|
import 'package:brick_generator/core/logger.dart';
|
||||||
|
import 'package:brick_generator/core/shell.dart';
|
||||||
import 'package:brick_generator/models/brick_config.dart';
|
import 'package:brick_generator/models/brick_config.dart';
|
||||||
import 'package:brick_generator/models/variable_string_syntax.dart';
|
import 'package:brick_generator/models/variable_string_syntax.dart';
|
||||||
import 'package:brick_generator/models/variable_type.dart';
|
import 'package:brick_generator/models/variable_type.dart';
|
||||||
import 'package:brick_generator/shell.dart';
|
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
class FileSystemUtils {
|
class FileSystemUtils {
|
||||||
@ -88,7 +88,7 @@ class FileSystemUtils {
|
|||||||
final snake =
|
final snake =
|
||||||
variable!.syntax![VariableStringSyntax.snakeCase.mapKey];
|
variable!.syntax![VariableStringSyntax.snakeCase.mapKey];
|
||||||
if (snake == null) {
|
if (snake == null) {
|
||||||
final err = 'Invalid snake_case syntax';
|
const err = 'Invalid snake_case syntax';
|
||||||
Logger.throwError(ArgumentError(err), err);
|
Logger.throwError(ArgumentError(err), err);
|
||||||
}
|
}
|
||||||
final newPath = file.path.replaceAll(
|
final newPath = file.path.replaceAll(
|
||||||
@ -123,7 +123,7 @@ class FileSystemUtils {
|
|||||||
BrickConfig brickConfig,
|
BrickConfig brickConfig,
|
||||||
String brickPath,
|
String brickPath,
|
||||||
) async {
|
) async {
|
||||||
for (final String ignore in brickConfig.brickIgnore ?? []) {
|
for (final String ignore in brickConfig.brickgenConfig.ignore.ignored) {
|
||||||
final String toDelete = join(brickPath, ignore);
|
final String toDelete = join(brickPath, ignore);
|
||||||
if (FileSystemEntity.isDirectorySync(toDelete)) {
|
if (FileSystemEntity.isDirectorySync(toDelete)) {
|
||||||
await Shell.rm(toDelete, recursive: true);
|
await Shell.rm(toDelete, recursive: true);
|
||||||
|
69
tools/brick_generator/lib/models/boolean_file_system.dart
Normal file
69
tools/brick_generator/lib/models/boolean_file_system.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/boolean_file_system_variable.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _foldersKey = 'folders';
|
||||||
|
const _filesKey = 'files';
|
||||||
|
|
||||||
|
class BooleanFileSystem {
|
||||||
|
BooleanFileSystem({
|
||||||
|
required this.booleanName,
|
||||||
|
required this.folders,
|
||||||
|
required this.files,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BooleanFileSystem.fromYaml(String key, YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
final variableName = key;
|
||||||
|
final folders = BooleanFileSystemVariable.fromYaml(
|
||||||
|
source.nodes[_foldersKey] as YamlMap?,
|
||||||
|
);
|
||||||
|
final files = BooleanFileSystemVariable.fromYaml(
|
||||||
|
source.nodes[_filesKey] as YamlMap?,
|
||||||
|
);
|
||||||
|
|
||||||
|
return BooleanFileSystem(
|
||||||
|
booleanName: variableName,
|
||||||
|
folders: folders,
|
||||||
|
files: files,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String booleanName;
|
||||||
|
BooleanFileSystemVariable folders;
|
||||||
|
BooleanFileSystemVariable files;
|
||||||
|
|
||||||
|
BooleanFileSystem copyWith({
|
||||||
|
String? booleanName,
|
||||||
|
BooleanFileSystemVariable? folders,
|
||||||
|
BooleanFileSystemVariable? files,
|
||||||
|
}) =>
|
||||||
|
BooleanFileSystem(
|
||||||
|
booleanName: booleanName ?? this.booleanName,
|
||||||
|
folders: folders ?? this.folders,
|
||||||
|
files: files ?? this.files,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BooleanFileSystem(booleanName: $booleanName, '
|
||||||
|
'folders: $folders, files: $files)';
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _onTrueKey = 'on_true';
|
||||||
|
const _onFalseKey = 'on_false';
|
||||||
|
|
||||||
|
class BooleanFileSystemVariable {
|
||||||
|
BooleanFileSystemVariable({
|
||||||
|
required this.onTrueNames,
|
||||||
|
required this.onFalseNames,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BooleanFileSystemVariable.fromYaml(YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
final onTrueNames = (source[_onTrueKey] as YamlList?)
|
||||||
|
?.map((element) => element as String)
|
||||||
|
.toList();
|
||||||
|
final onFalseNames = (source[_onFalseKey] as YamlList?)
|
||||||
|
?.map((element) => element as String)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return BooleanFileSystemVariable(
|
||||||
|
onTrueNames: onTrueNames ?? [],
|
||||||
|
onFalseNames: onFalseNames ?? [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> onTrueNames;
|
||||||
|
final List<String> onFalseNames;
|
||||||
|
|
||||||
|
BooleanFileSystemVariable copyWith({
|
||||||
|
List<String>? onTrueNames,
|
||||||
|
List<String>? onFalseNames,
|
||||||
|
}) =>
|
||||||
|
BooleanFileSystemVariable(
|
||||||
|
onTrueNames: onTrueNames ?? this.onTrueNames,
|
||||||
|
onFalseNames: onFalseNames ?? this.onFalseNames,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BooleanFileSystemVariable(onTrueNames: $onTrueNames, '
|
||||||
|
'onFalseNames: $onFalseNames)';
|
||||||
|
}
|
77
tools/brick_generator/lib/models/boolean_mapping.dart
Normal file
77
tools/brick_generator/lib/models/boolean_mapping.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/boolean_name_single_mapping.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _foldersKey = 'folders';
|
||||||
|
const _filesKey = 'files';
|
||||||
|
|
||||||
|
class BooleanMapping {
|
||||||
|
BooleanMapping({
|
||||||
|
required this.booleanName,
|
||||||
|
required this.folders,
|
||||||
|
required this.files,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BooleanMapping.fromYaml(String key, YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
final variableName = key;
|
||||||
|
final folders = (source.nodes[_foldersKey] as YamlList?)
|
||||||
|
?.map(
|
||||||
|
(element) =>
|
||||||
|
BooleanNameSingleMapping.fromYaml(element as YamlMap?),
|
||||||
|
)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final files = (source.nodes[_filesKey] as YamlList?)
|
||||||
|
?.map(
|
||||||
|
(element) =>
|
||||||
|
BooleanNameSingleMapping.fromYaml(element as YamlMap?),
|
||||||
|
)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
|
||||||
|
return BooleanMapping(
|
||||||
|
booleanName: variableName,
|
||||||
|
folders: folders,
|
||||||
|
files: files,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String booleanName;
|
||||||
|
List<BooleanNameSingleMapping> folders;
|
||||||
|
List<BooleanNameSingleMapping> files;
|
||||||
|
|
||||||
|
BooleanMapping copyWith({
|
||||||
|
String? booleanName,
|
||||||
|
List<BooleanNameSingleMapping>? folders,
|
||||||
|
List<BooleanNameSingleMapping>? files,
|
||||||
|
}) =>
|
||||||
|
BooleanMapping(
|
||||||
|
booleanName: booleanName ?? this.booleanName,
|
||||||
|
folders: folders ?? this.folders,
|
||||||
|
files: files ?? this.files,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BooleanMapping(booleanName: $booleanName, '
|
||||||
|
'folders: $folders, files: $files)';
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/boolean_name_mapping.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _onTrueKey = 'on_true';
|
||||||
|
const _onFalseKey = 'on_false';
|
||||||
|
|
||||||
|
class BooleanNameListMapping extends BooleanNameMapping {
|
||||||
|
BooleanNameListMapping({
|
||||||
|
required this.fileSystemEntityName,
|
||||||
|
required this.onTrueNames,
|
||||||
|
required this.onFalseNames,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BooleanNameListMapping.fromYaml(YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
final fsEntityName = source.keys.first as String;
|
||||||
|
final onTrueNames =
|
||||||
|
((source.values.first as YamlMap?)?[_onTrueKey] as YamlList?)
|
||||||
|
?.map((element) => element as String)
|
||||||
|
.toList();
|
||||||
|
final onFalseNames =
|
||||||
|
((source.values.first as YamlMap?)?[_onFalseKey] as YamlList?)
|
||||||
|
?.map((element) => element as String)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return BooleanNameListMapping(
|
||||||
|
fileSystemEntityName: fsEntityName,
|
||||||
|
onTrueNames: onTrueNames ?? [],
|
||||||
|
onFalseNames: onFalseNames ?? [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String fileSystemEntityName;
|
||||||
|
final List<String> onTrueNames;
|
||||||
|
final List<String> onFalseNames;
|
||||||
|
|
||||||
|
BooleanNameListMapping copyWith({
|
||||||
|
String? fileSystemEntityName,
|
||||||
|
List<String>? onTrueNames,
|
||||||
|
List<String>? onFalseNames,
|
||||||
|
}) =>
|
||||||
|
BooleanNameListMapping(
|
||||||
|
fileSystemEntityName: fileSystemEntityName ?? this.fileSystemEntityName,
|
||||||
|
onTrueNames: onTrueNames ?? this.onTrueNames,
|
||||||
|
onFalseNames: onFalseNames ?? this.onFalseNames,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get onFalseName => onFalseNames.first;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get onTrueName => onTrueNames.first;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'BooleanNameListMapping(fileSystemEntityName: $fileSystemEntityName, '
|
||||||
|
'onTrueNames: $onTrueNames, onFalseNames: $onFalseNames)';
|
||||||
|
}
|
21
tools/brick_generator/lib/models/boolean_name_mapping.dart
Normal file
21
tools/brick_generator/lib/models/boolean_name_mapping.dart
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
abstract class BooleanNameMapping {
|
||||||
|
String get fileSystemEntityName;
|
||||||
|
String get onTrueName;
|
||||||
|
String get onFalseName;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/boolean_name_mapping.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _onTrueKey = 'on_true';
|
||||||
|
const _onFalseKey = 'on_false';
|
||||||
|
|
||||||
|
class BooleanNameSingleMapping extends BooleanNameMapping {
|
||||||
|
BooleanNameSingleMapping({
|
||||||
|
required this.fileSystemEntityName,
|
||||||
|
required this.onTrueName,
|
||||||
|
required this.onFalseName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BooleanNameSingleMapping.fromYaml(YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
final fsEntityName = source.keys.first as String;
|
||||||
|
final onTrueName =
|
||||||
|
(source.values.first as YamlMap?)?[_onTrueKey] as String?;
|
||||||
|
final onFalseName =
|
||||||
|
(source.values.first as YamlMap?)?[_onFalseKey] as String?;
|
||||||
|
|
||||||
|
return BooleanNameSingleMapping(
|
||||||
|
fileSystemEntityName: fsEntityName,
|
||||||
|
onTrueName: onTrueName ?? fsEntityName,
|
||||||
|
onFalseName: onFalseName ?? fsEntityName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String fileSystemEntityName;
|
||||||
|
@override
|
||||||
|
final String onTrueName;
|
||||||
|
@override
|
||||||
|
final String onFalseName;
|
||||||
|
|
||||||
|
BooleanNameSingleMapping copyWith({
|
||||||
|
String? fileSystemEntityName,
|
||||||
|
String? onTrueName,
|
||||||
|
String? onFalseName,
|
||||||
|
}) =>
|
||||||
|
BooleanNameSingleMapping(
|
||||||
|
fileSystemEntityName: fileSystemEntityName ?? this.fileSystemEntityName,
|
||||||
|
onTrueName: onTrueName ?? this.onTrueName,
|
||||||
|
onFalseName: onFalseName ?? this.onFalseName,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'BooleanNameSingleMapping(fileSystemEntityName: $fileSystemEntityName, '
|
||||||
|
'onTrueName: $onTrueName, onFalseName: $onFalseName)';
|
||||||
|
}
|
@ -14,96 +14,86 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import 'package:brick_generator/logger.dart';
|
|
||||||
import 'package:brick_generator/models/brick_variable.dart';
|
import 'package:brick_generator/models/brick_variable.dart';
|
||||||
|
import 'package:brick_generator/models/brickgen_config.dart';
|
||||||
|
import 'package:brick_generator/yaml_reader.dart';
|
||||||
import 'package:yaml/yaml.dart';
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
const _nameKey = 'name';
|
const _nameKey = 'name';
|
||||||
const _descriptionKey = 'description';
|
const _descriptionKey = 'description';
|
||||||
const _versionKey = 'version';
|
const _versionKey = 'version';
|
||||||
const _pathToBrickifyKey = 'path_to_brickify';
|
|
||||||
const _brickIgnoreKey = 'brick_ignore';
|
|
||||||
const _varsKey = 'vars';
|
const _varsKey = 'vars';
|
||||||
|
const _brickgenKey = 'brickgen';
|
||||||
|
|
||||||
class BrickConfig {
|
class BrickConfig {
|
||||||
String? name;
|
|
||||||
String? description;
|
|
||||||
String? version;
|
|
||||||
String? pathToBrickify;
|
|
||||||
List<String>? brickIgnore;
|
|
||||||
List<BrickVariable?>? variables;
|
|
||||||
|
|
||||||
BrickConfig({
|
BrickConfig({
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.version,
|
required this.version,
|
||||||
required this.pathToBrickify,
|
|
||||||
required this.brickIgnore,
|
|
||||||
required this.variables,
|
required this.variables,
|
||||||
|
required this.brickgenConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
BrickConfig._();
|
factory BrickConfig.parse(YamlMap? data) {
|
||||||
factory BrickConfig.parser() => BrickConfig._();
|
if (data == null) {
|
||||||
|
throw ArgumentError.notNull('data');
|
||||||
|
}
|
||||||
|
|
||||||
static BrickConfig? from(YamlMap? data) => data != null
|
final variables = (data[_varsKey] as YamlMap?)
|
||||||
? BrickConfig(
|
?.entries
|
||||||
name: data[_nameKey] as String?,
|
.map(
|
||||||
description: data[_descriptionKey] as String?,
|
(e) => BrickVariable.fromYaml(e.key as String, e.value as YamlMap?),
|
||||||
version: data[_versionKey] as String?,
|
|
||||||
pathToBrickify: data[_pathToBrickifyKey] as String?,
|
|
||||||
brickIgnore: (data[_brickIgnoreKey] as YamlList?)
|
|
||||||
?.map((dynamic element) => element as String)
|
|
||||||
.toList(),
|
|
||||||
variables: (data[_varsKey] as YamlMap?)
|
|
||||||
?.map<dynamic, BrickVariable?>(
|
|
||||||
(dynamic key, dynamic value) =>
|
|
||||||
MapEntry<dynamic, BrickVariable?>(
|
|
||||||
key,
|
|
||||||
BrickVariable.from(value as YamlMap?),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.values
|
.toList();
|
||||||
.toList(),
|
|
||||||
)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
void checkFormat() {
|
final config = BrickConfig(
|
||||||
if (name == null || description == null || pathToBrickify == null) {
|
name: data[_nameKey] as String? ?? '',
|
||||||
final err = 'Yaml file is not conform';
|
description: data[_descriptionKey] as String? ?? '',
|
||||||
Logger.throwError(ArgumentError(err), err);
|
version: data[_versionKey] as String? ?? '',
|
||||||
}
|
variables: variables ?? [],
|
||||||
if (variables != null) {
|
brickgenConfig: BrickgenConfig.parse(data[_brickgenKey] as YamlMap?),
|
||||||
for (final variable in variables!) {
|
);
|
||||||
variable?.checkFormat();
|
|
||||||
}
|
return config;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String toBrickYaml() {
|
factory BrickConfig.fromFile(String? path) {
|
||||||
String content = '''
|
if (path == null) {
|
||||||
|
throw ArgumentError.notNull('path');
|
||||||
|
}
|
||||||
|
|
||||||
|
final config = YamlReader.readYamlFile(path);
|
||||||
|
|
||||||
|
return BrickConfig.parse(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String description;
|
||||||
|
String version;
|
||||||
|
List<BrickVariable<dynamic>> variables;
|
||||||
|
BrickgenConfig brickgenConfig;
|
||||||
|
|
||||||
|
String toMason() {
|
||||||
|
final content = StringBuffer('''
|
||||||
name: $name
|
name: $name
|
||||||
description: $description
|
description: $description
|
||||||
|
|
||||||
version: $version
|
version: $version
|
||||||
|
|
||||||
''';
|
''');
|
||||||
|
|
||||||
if (variables?.isNotEmpty ?? false) {
|
if (variables.isNotEmpty) {
|
||||||
content += 'vars:\n';
|
content.writeln('vars:');
|
||||||
for (final BrickVariable? v in variables!) {
|
for (final variable in variables) {
|
||||||
if (v != null) {
|
content.writeln(variable.toMason());
|
||||||
final vString = '''
|
|
||||||
${v.name}:
|
|
||||||
type: ${v.type.toString()}
|
|
||||||
description: ${v.description}
|
|
||||||
default: ${v.defaultValue}
|
|
||||||
prompt: ${v.prompt}
|
|
||||||
''';
|
|
||||||
content += vString;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return content;
|
return content.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BrickConfig(name: $name, '
|
||||||
|
'description: $description, version: $version, variables: $variables, '
|
||||||
|
'brickgenConfig: $brickgenConfig)';
|
||||||
}
|
}
|
||||||
|
@ -14,53 +14,46 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import 'package:brick_generator/logger.dart';
|
import 'package:brick_generator/models/brick_variable_boolean.dart';
|
||||||
|
import 'package:brick_generator/models/brick_variable_string.dart';
|
||||||
import 'package:brick_generator/models/variable_type.dart';
|
import 'package:brick_generator/models/variable_type.dart';
|
||||||
import 'package:brick_generator/string_extension.dart';
|
|
||||||
import 'package:yaml/yaml.dart';
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
const _typeKey = 'type';
|
const _typeKey = 'type';
|
||||||
const _nameKey = 'name';
|
|
||||||
const _descriptionKey = 'description';
|
|
||||||
const _defaultKey = 'default';
|
|
||||||
const _promptKey = 'prompt';
|
|
||||||
|
|
||||||
class BrickVariable {
|
|
||||||
VariableType? type;
|
|
||||||
String? name;
|
|
||||||
String? description;
|
|
||||||
String? defaultValue;
|
|
||||||
String? prompt;
|
|
||||||
Map<String, String>? syntax;
|
|
||||||
|
|
||||||
|
abstract class BrickVariable<T> {
|
||||||
BrickVariable({
|
BrickVariable({
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.defaultValue,
|
required this.defaultValue,
|
||||||
required this.prompt,
|
required this.prompt,
|
||||||
required this.syntax,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
BrickVariable._();
|
String name;
|
||||||
|
VariableType type;
|
||||||
|
String description;
|
||||||
|
T defaultValue;
|
||||||
|
String prompt;
|
||||||
|
|
||||||
factory BrickVariable.parser() => BrickVariable._();
|
static BrickVariable<dynamic> fromYaml(String key, YamlMap? source) {
|
||||||
|
final type = VariableType.fromString(source?[_typeKey] as String?);
|
||||||
static BrickVariable? from(YamlMap? data) => data != null
|
switch (type) {
|
||||||
? BrickVariable(
|
case VariableType.string:
|
||||||
type: VariableType.fromString(data[_typeKey] as String?),
|
return BrickVariableString.fromYaml(key, source);
|
||||||
name: data[_nameKey] as String?,
|
case VariableType.boolean:
|
||||||
description: data[_descriptionKey] as String?,
|
return BrickVariableBoolean.fromYaml(key, source);
|
||||||
defaultValue: data[_defaultKey] as String?,
|
case VariableType.none:
|
||||||
prompt: data[_promptKey] as String?,
|
throw ArgumentError('Invalid variable type', 'type');
|
||||||
syntax: (data[_nameKey] as String? ?? '').syntaxes,
|
|
||||||
)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
void checkFormat() {
|
|
||||||
if (name == null || description == null || type == null) {
|
|
||||||
final err = 'Yaml file is not conform';
|
|
||||||
Logger.throwError(ArgumentError(err), err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(wyatt): use `yaml_writer` to dumps YAML properly.
|
||||||
|
String toMason() => '''
|
||||||
|
$name:
|
||||||
|
type: $type
|
||||||
|
description: $description
|
||||||
|
default: $defaultValue
|
||||||
|
prompt: $prompt
|
||||||
|
''';
|
||||||
}
|
}
|
||||||
|
53
tools/brick_generator/lib/models/brick_variable_boolean.dart
Normal file
53
tools/brick_generator/lib/models/brick_variable_boolean.dart
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/brick_variable.dart';
|
||||||
|
import 'package:brick_generator/models/variable_type.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _typeKey = 'type';
|
||||||
|
const _descriptionKey = 'description';
|
||||||
|
const _defaultKey = 'default';
|
||||||
|
const _promptKey = 'prompt';
|
||||||
|
|
||||||
|
class BrickVariableBoolean extends BrickVariable<bool> {
|
||||||
|
BrickVariableBoolean({
|
||||||
|
required super.type,
|
||||||
|
required super.name,
|
||||||
|
required super.description,
|
||||||
|
required super.defaultValue,
|
||||||
|
required super.prompt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BrickVariableBoolean.fromYaml(String key, YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrickVariableBoolean(
|
||||||
|
type: VariableType.fromString(source[_typeKey] as String?),
|
||||||
|
name: key,
|
||||||
|
description: source[_descriptionKey] as String? ?? '',
|
||||||
|
defaultValue: source[_defaultKey] as bool? ?? false,
|
||||||
|
prompt: source[_promptKey] as String? ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BrickVariableBoolean(name: $name, '
|
||||||
|
'description: $description, defaultValue: $defaultValue, '
|
||||||
|
'prompt: $prompt,)';
|
||||||
|
}
|
62
tools/brick_generator/lib/models/brick_variable_string.dart
Normal file
62
tools/brick_generator/lib/models/brick_variable_string.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/core/string_extension.dart';
|
||||||
|
import 'package:brick_generator/models/brick_variable.dart';
|
||||||
|
import 'package:brick_generator/models/variable_type.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _compilableKey = 'compilable';
|
||||||
|
const _typeKey = 'type';
|
||||||
|
const _descriptionKey = 'description';
|
||||||
|
const _defaultKey = 'default';
|
||||||
|
const _promptKey = 'prompt';
|
||||||
|
|
||||||
|
class BrickVariableString extends BrickVariable<String> {
|
||||||
|
BrickVariableString({
|
||||||
|
required this.compilable,
|
||||||
|
required this.syntax,
|
||||||
|
required super.type,
|
||||||
|
required super.name,
|
||||||
|
required super.description,
|
||||||
|
required super.defaultValue,
|
||||||
|
required super.prompt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BrickVariableString.fromYaml(String key, YamlMap? source) {
|
||||||
|
if (source == null) {
|
||||||
|
throw ArgumentError.notNull('source');
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrickVariableString(
|
||||||
|
compilable: source[_compilableKey] as String? ?? '',
|
||||||
|
type: VariableType.fromString(source[_typeKey] as String?),
|
||||||
|
name: key,
|
||||||
|
description: source[_descriptionKey] as String? ?? '',
|
||||||
|
defaultValue: source[_defaultKey] as String? ?? '',
|
||||||
|
prompt: source[_promptKey] as String? ?? '',
|
||||||
|
syntax: (source[_compilableKey] as String? ?? '').syntaxes,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String compilable;
|
||||||
|
Map<String, String>? syntax;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BrickVariableString(name: $name, '
|
||||||
|
'description: $description, compilable: $compilable, '
|
||||||
|
'defaultValue: $defaultValue, prompt: $prompt,)';
|
||||||
|
}
|
84
tools/brick_generator/lib/models/brickgen_config.dart
Normal file
84
tools/brick_generator/lib/models/brickgen_config.dart
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'package:brick_generator/models/boolean_file_system.dart';
|
||||||
|
import 'package:brick_generator/models/boolean_mapping.dart';
|
||||||
|
import 'package:brick_generator/models/ignore_list.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
const _pathToBrickifyKey = 'path_to_brickify';
|
||||||
|
const _ignoreKey = 'ignore';
|
||||||
|
const _hooksKey = 'hooks';
|
||||||
|
const _booleanMappingKey = 'boolean_mapping';
|
||||||
|
const _booleanFileSystemKey = 'boolean_file_system';
|
||||||
|
|
||||||
|
class BrickgenConfig {
|
||||||
|
final String pathToBrickify;
|
||||||
|
final IgnoreList ignore;
|
||||||
|
final bool hooks;
|
||||||
|
final List<BooleanMapping> booleanMapping;
|
||||||
|
final List<BooleanFileSystem> booleanFileSystem;
|
||||||
|
|
||||||
|
BrickgenConfig({
|
||||||
|
required this.pathToBrickify,
|
||||||
|
required this.ignore,
|
||||||
|
required this.hooks,
|
||||||
|
required this.booleanMapping,
|
||||||
|
required this.booleanFileSystem,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BrickgenConfig.parse(YamlMap? data) {
|
||||||
|
if (data == null) {
|
||||||
|
throw ArgumentError.notNull('data');
|
||||||
|
}
|
||||||
|
|
||||||
|
final booleanMapping = (data[_booleanMappingKey] as YamlMap?)
|
||||||
|
?.entries
|
||||||
|
.map(
|
||||||
|
(e) =>
|
||||||
|
BooleanMapping.fromYaml(e.key as String, e.value as YamlMap?),
|
||||||
|
)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
|
||||||
|
final booleanFileSystem = (data[_booleanFileSystemKey] as YamlMap?)
|
||||||
|
?.entries
|
||||||
|
.map(
|
||||||
|
(e) => BooleanFileSystem.fromYaml(
|
||||||
|
e.key as String,
|
||||||
|
e.value as YamlMap?,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
|
||||||
|
final config = BrickgenConfig(
|
||||||
|
pathToBrickify: data[_pathToBrickifyKey] as String? ?? '',
|
||||||
|
ignore: IgnoreList.fromConfig(data[_ignoreKey] as YamlList?),
|
||||||
|
hooks: data[_hooksKey] as bool? ?? false,
|
||||||
|
booleanMapping: booleanMapping,
|
||||||
|
booleanFileSystem: booleanFileSystem,
|
||||||
|
);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BrickgenConfig(pathToBrickify: $pathToBrickify, '
|
||||||
|
'ignore: $ignore, hooks: $hooks, booleanMapping: $booleanMapping, '
|
||||||
|
'booleanFileSystem: $booleanFileSystem)';
|
||||||
|
}
|
108
tools/brick_generator/lib/models/ignore_list.dart
Normal file
108
tools/brick_generator/lib/models/ignore_list.dart
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright (C) 2023 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
class IgnoreList {
|
||||||
|
final List<String> ignoredFiles;
|
||||||
|
final List<String> ignoredFolders;
|
||||||
|
|
||||||
|
IgnoreList({
|
||||||
|
required this.ignoredFiles,
|
||||||
|
required this.ignoredFolders,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Only parse files an folders (no glob)
|
||||||
|
/// - file <- file
|
||||||
|
/// - folder/ <- folder, ends with "/"
|
||||||
|
/// - infolder/file <- file
|
||||||
|
/// - sub/folder/ <- folder, ends with "/"
|
||||||
|
factory IgnoreList.fromConfig(YamlList? list) {
|
||||||
|
final List<String> ignoredFiles = [];
|
||||||
|
final List<String> ignoredFolders = [];
|
||||||
|
|
||||||
|
final ignored =
|
||||||
|
list?.map<String>((element) => element as String).toList() ?? [];
|
||||||
|
|
||||||
|
for (final element in ignored) {
|
||||||
|
if (element.endsWith('/')) {
|
||||||
|
// This is a folder
|
||||||
|
ignoredFolders.add(element.substring(0, element.length - 1));
|
||||||
|
} else {
|
||||||
|
// This is a file
|
||||||
|
ignoredFiles.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IgnoreList(
|
||||||
|
ignoredFiles: ignoredFiles,
|
||||||
|
ignoredFolders: ignoredFolders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory IgnoreList.fromBrickIgnoreFile() {
|
||||||
|
throw UnimplementedError('.brickignore is not yet supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(String root, String path) {
|
||||||
|
final FileSystemEntityType type = FileSystemEntity.typeSync(path);
|
||||||
|
|
||||||
|
// Check if file/folder is an ignored folder (or any subtree of it)
|
||||||
|
for (final element in ignoredFolders) {
|
||||||
|
final ignoredPath = join(root, element);
|
||||||
|
if (path.startsWith(ignoredPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case FileSystemEntityType.file:
|
||||||
|
for (final element in ignoredFiles) {
|
||||||
|
final ignoredPath = join(root, element);
|
||||||
|
if (ignoredPath == path) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case FileSystemEntityType.directory:
|
||||||
|
for (final element in ignoredFolders) {
|
||||||
|
final ignoredPath = join(root, element);
|
||||||
|
if (ignoredPath == path) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case FileSystemEntityType.link:
|
||||||
|
case FileSystemEntityType.notFound:
|
||||||
|
case FileSystemEntityType.pipe:
|
||||||
|
case FileSystemEntityType.unixDomainSock:
|
||||||
|
throw ArgumentError(
|
||||||
|
'This file system entity type is not supported',
|
||||||
|
'from',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'IgnoreList(ignoredFiles: $ignoredFiles, '
|
||||||
|
'ignoredFolders: $ignoredFolders)';
|
||||||
|
}
|
@ -20,7 +20,7 @@ enum LogLevel {
|
|||||||
success('✅'),
|
success('✅'),
|
||||||
error('❌');
|
error('❌');
|
||||||
|
|
||||||
final String prefix;
|
|
||||||
|
|
||||||
const LogLevel(this.prefix);
|
const LogLevel(this.prefix);
|
||||||
|
|
||||||
|
final String prefix;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ enum VariableStringSyntax {
|
|||||||
pathCase('path_case', 'pathCase'),
|
pathCase('path_case', 'pathCase'),
|
||||||
mustacheCase('mustache_case', 'mustacheCase');
|
mustacheCase('mustache_case', 'mustacheCase');
|
||||||
|
|
||||||
|
const VariableStringSyntax(this.mapKey, this.id);
|
||||||
|
|
||||||
final String mapKey;
|
final String mapKey;
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
const VariableStringSyntax(this.mapKey, this.id);
|
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,19 @@
|
|||||||
enum VariableType {
|
enum VariableType {
|
||||||
none,
|
none,
|
||||||
string,
|
string,
|
||||||
bool;
|
boolean;
|
||||||
|
|
||||||
static VariableType fromString(String? type) {
|
static VariableType fromString(String? type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'string':
|
case 'string':
|
||||||
return string;
|
return string;
|
||||||
case 'bool':
|
case 'boolean':
|
||||||
return bool;
|
return boolean;
|
||||||
default:
|
default:
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() => name;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,14 @@ environment:
|
|||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
args: ^2.3.2
|
||||||
path: ^1.8.2
|
path: ^1.8.2
|
||||||
yaml: ^3.1.1
|
yaml: ^3.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test: ^1.22.2
|
test: ^1.22.2
|
||||||
wyatt_analysis:
|
wyatt_analysis:
|
||||||
git:
|
hosted:
|
||||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
ref: wyatt_analysis-v2.1.0
|
name: wyatt_analysis
|
||||||
path: packages/wyatt_analysis
|
version: 2.3.0
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import 'package:brick_generator/string_extension.dart';
|
import 'package:brick_generator/core/string_extension.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -32,22 +32,22 @@ void main() {
|
|||||||
'snake_case': 'feature_name',
|
'snake_case': 'feature_name',
|
||||||
};
|
};
|
||||||
test('transforms `feature_name`', () {
|
test('transforms `feature_name`', () {
|
||||||
final name = 'feature_name';
|
const name = 'feature_name';
|
||||||
expect(name.syntaxes, equals(expected));
|
expect(name.syntaxes, equals(expected));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('transforms `featureName`', () {
|
test('transforms `featureName`', () {
|
||||||
final name = 'feature_name';
|
const name = 'feature_name';
|
||||||
expect(name.syntaxes, equals(expected));
|
expect(name.syntaxes, equals(expected));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('transforms `feature-Name`', () {
|
test('transforms `feature-Name`', () {
|
||||||
final name = 'feature_name';
|
const name = 'feature_name';
|
||||||
expect(name.syntaxes, equals(expected));
|
expect(name.syntaxes, equals(expected));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('transforms `Feature Name`', () {
|
test('transforms `Feature Name`', () {
|
||||||
final name = 'feature_name';
|
const name = 'feature_name';
|
||||||
expect(name.syntaxes, equals(expected));
|
expect(name.syntaxes, equals(expected));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user