oto/lib/oto/application.dart
leedongmyung[desktop] a9c051bd04 Code refactoring
2023-11-25 12:12:55 +09:00

149 lines
5 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dart_framework/platform/process.dart';
import 'package:dart_framework/utils/system_util.dart';
import 'package:oto_cli/cli/cli.dart';
import 'package:oto_cli/oto/commands/command.dart';
import 'package:oto_cli/oto/pipeline/pipeline.dart';
import 'package:oto_cli/oto/data/command_data.dart';
import 'package:oto_cli/oto/data/jenkins_data.dart';
import 'package:oto_cli/oto/core/data_composer.dart';
import 'package:yaml/yaml.dart';
enum BuildType { jenkins, test, file }
class Application {
Application._privateConstructor();
static final Application _instance = Application._privateConstructor();
static Application get instance => _instance;
final Map<BuildType, DataComposer Function()> _mapComposer = {
BuildType.test: () => DataComposerTest(),
BuildType.jenkins: () => DataComposerJenkins(),
BuildType.file: () => DataComposerFile()
};
final Map<String, PipelineExecutor Function()> exeMap = {
'exe': () => PipelineExe(),
'async': () => PipelineAsync(),
'if': () => PipelineIf(),
/*'while': () => PipelineWhile(),
'wait-until': () => PipelineWaitUntil(),
'switch': () => PipelineSwitch(),*/
};
DataJenkins? jenkinsData;
Map<String, dynamic> property = {};
Map<String, DataCommand> dataCommandMap = {};
late Pipeline pipeline;
//pipeline validate & initialize
PipelineValidateResult pipelineInitialize(List<dynamic> list) {
var result = PipelineValidateResult();
for (Map<String, dynamic> item in list) {
var key = item.keys.first;
if (!exeMap.containsKey(key)) {
result.enable = false;
result.message = 'Validate Error - "$key" is not a supported task';
return result;
}
var exe = exeMap[key]!();
var childResult = exe.initialize(item);
if (!childResult.enable) {
return childResult;
}
result.exeList.add(exe);
}
return result;
}
Future<void> build(BuildType buildType, {String? yamlContent}) async {
setUTF8();
// var envArgs = envArguments(arguments);
// bool isTest = envArgs.containsKey('isTest'); //for Unit Test
try {
var composer = _mapComposer[buildType]!();
await composer.compose(yamlContent, printBuildStep);
jenkinsData = composer.jenkinsData;
DataBuild? build =
DataBuild.fromJson(getMapFromYamlA(composer.buildYaml)!);
await CLI.println(
'********************************* Build Data *************************************',
color: Color.magenta);
print(composer.buildYaml);
property = build.property;
if (build.pipeline == null) {
//이후 pipeline 안정이후, command로만 빌드는 삭제, pipeline 필수로 넣도록 구성
for (var command in build.commands) {
await printBuildStep('Phase Start: ${command.name}', Color.green);
await Command.byType(command.command).execute(command);
}
} else {
//set command in dic, 중복 커맨드 id 필터
for (var command in build.commands) {
if (dataCommandMap.containsKey(command.id)) {
var ex = ExceptionData();
ex.phase = 'Validate command list';
ex.message = 'Duplicate command id exists: "${command.id}"';
throw Exception(ex);
} else {
dataCommandMap[command.id] = command;
}
}
//Parse pipeline & validate
var validateResult = pipelineInitialize(build.pipeline!.workflow);
if (!validateResult.enable) {
var ex = ExceptionData();
ex.phase = 'Validate Pipeline';
ex.message = validateResult.message;
throw Exception(ex);
}
pipeline = validateResult.pipeline!;
//start build
await pipeline.execute();
}
} on Exception catch (e, stacktace) {
await CLI.printString(e.toString(), color: Color.redStrong);
await CLI.printString(stacktace.toString(), color: Color.yellowStrong);
await printBuildStep('Build Failed', Color.redStrong);
exit(10);
}
await printBuildStep('Build Successfully Complete', Color.cyan);
exit(0);
}
Future setUTF8() async {
if (Platform.isWindows) {
var data = await ProcessExecutor.start(StringBuffer('chcp 65001'));
var exitCode = await data.process.exitCode;
print('Set Korean: ${exitCode == 0}');
}
return simpleFuture;
}
Map<String, dynamic>? getMapFromYamlA(String yamlStr) {
Map<String, dynamic>? map;
if (yamlStr.length > 5) {
YamlMap data = loadYaml(yamlStr);
map = jsonDecode(jsonEncode(data));
}
return map;
}
Future printBuildStep(String name, Color? color) async {
var message =
'''************************************************************************************
* $name
************************************************************************************''';
await CLI.printString(message, color: color ?? Color.green);
return simpleFuture;
}
}