177 lines
5.7 KiB
Dart
177 lines
5.7 KiB
Dart
// ignore_for_file: depend_on_referenced_packages
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:dart_framework/log/log.dart';
|
|
import 'package:dart_framework/platform/process.dart';
|
|
import 'package:dart_framework/utils/string_util.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/core/defined_data.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';
|
|
import 'package:path/path.dart' as pathlib;
|
|
|
|
enum BuildType { jenkins, test, file, scheduler }
|
|
|
|
enum CommandState { ready, progress, complete }
|
|
|
|
class Application {
|
|
Application._privateConstructor();
|
|
static final Application _instance = Application._privateConstructor();
|
|
static Application get instance => _instance;
|
|
static String get current {
|
|
if(Application.instance.buildType == BuildType.jenkins)
|
|
{
|
|
return Platform.environment['WORKSPACE']!;
|
|
}
|
|
else
|
|
{
|
|
return pathlib.current;
|
|
}
|
|
}
|
|
|
|
static File? _logFile;
|
|
static bool _logEnable = true;
|
|
static String get enter {
|
|
return _logFile == null ? '' : '\n';
|
|
}
|
|
|
|
final Map<BuildType, DataComposer Function()> _mapComposer = {
|
|
BuildType.test: () => DataComposerTest(),
|
|
BuildType.jenkins: () => DataComposerJenkins(),
|
|
BuildType.file: () => DataComposerFile()
|
|
};
|
|
|
|
DataCommon? commonData;
|
|
Map<String, dynamic> property = {};
|
|
Map<String, CommandState> commandStates = {};
|
|
Map<String, DataCommand> dataCommandMap = {};
|
|
late Pipeline pipeline;
|
|
late BuildType _buildType;
|
|
|
|
get buildType {
|
|
return _buildType;
|
|
}
|
|
|
|
Future build( BuildType buildType, {String? yamlContent,
|
|
DataBuild? buildData, bool logEnable = true, String? logPath}) async {
|
|
_buildType = buildType;
|
|
_logEnable = logEnable;
|
|
setUTF8();
|
|
|
|
DataBuild build;
|
|
DataComposer? composer;
|
|
// var envArgs = envArguments(arguments);
|
|
// bool isTest = envArgs.containsKey('isTest'); //for Unit Test
|
|
try {
|
|
if(_buildType == BuildType.scheduler) {
|
|
commonData = DataCommon.fromJson(FileData.jenkinsMap!);
|
|
build = buildData!;
|
|
_logFile = File(logPath!);
|
|
CLI.logFunc = log;
|
|
} else {
|
|
composer = _mapComposer[buildType]!();
|
|
await composer.compose(yamlContent, printBuildStep);
|
|
commonData = composer.commonData;
|
|
build = DataBuild.fromJson(getMapFromYamlA(composer.buildYaml)!);
|
|
}
|
|
if(_logEnable) {
|
|
await CLI.printString('$enter********************************* Build Data *************************************', color: Color.magenta);
|
|
if(composer != null) log(composer.buildYaml);
|
|
}
|
|
|
|
property = build.property ?? {};
|
|
if(!property.containsKey('workspace')) {
|
|
property['workspace'] = current;
|
|
}
|
|
property = Command.replaceAllTagsMap(property, replace: true);
|
|
|
|
//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 =
|
|
Pipeline.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);
|
|
}
|
|
|
|
if(logEnable) await printBuildStep('Build Successfully Complete', Color.cyan);
|
|
if(buildType != BuildType.scheduler) {
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
Future setUTF8() async {
|
|
if (Platform.isWindows) {
|
|
var data = await ProcessExecutor.start(StringBuffer('chcp 65001'), logHandler: logWithType);
|
|
var exitCode = await data.process.exitCode;
|
|
log('Set Korean: ${exitCode == 0}');
|
|
}
|
|
return simpleFuture;
|
|
}
|
|
|
|
static void logWithType(String message, LogType logType) {
|
|
log(message, logType: logType);
|
|
}
|
|
|
|
static void log(String message, {LogType logType = LogType.verbose}) {
|
|
if(_logFile == null) {
|
|
print(message);
|
|
} else {
|
|
if(_logEnable || logType == LogType.error) {
|
|
_logFile?.writeAsStringSync('[${getDates()}] $message\n', mode: FileMode.append, flush: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Map<String, dynamic>? getMapFromYamlA(String yamlStr) {
|
|
Map<String, dynamic>? map;
|
|
if (yamlStr.length > 5) {
|
|
YamlMap data = loadYaml(yamlStr);
|
|
map = jsonDecode(jsonEncode(data));
|
|
}
|
|
return map;
|
|
}
|
|
|
|
void updateCommandState(String target, CommandState state) {
|
|
commandStates[target] = state;
|
|
}
|
|
|
|
Future printBuildStep(String name, Color? color) async {
|
|
var message =
|
|
'''$enter************************************************************************************
|
|
* $name
|
|
************************************************************************************''';
|
|
await CLI.printString(message, color: color ?? Color.green);
|
|
return simpleFuture;
|
|
}
|
|
}
|