pipeline update

This commit is contained in:
leedongmyung[desktop] 2023-11-19 21:04:34 +09:00
parent 9b48d80392
commit b4fac1a8fb
5 changed files with 163 additions and 50 deletions

View file

@ -6,17 +6,17 @@ pipeline:
id: main
workflow:
#동기식 실행, 해당 수행이 끝나야만 다음 스텝실행, command일경우 해당 id 기입
- exe: createAppData#1
- async: appData
#비동기식 실행, 해당 수행이 완료됨과 관계없이 실행하고 다음 스텝을 실행한다
- async: dartCompile#1
- exe: buildDart
#일반적인 if문과 동일
- if:
#property의 내용은 기본 dynamic(Object)형으로써, 비교시 정확한 캐스팅 필요, 적지 않을시 기본 string
condition-int: <property:test> == <property:result>
on-false:
- exe: <command:buildDartCompile#1>
- exe: zip
commands:
### Version 쓰기

View file

@ -2,11 +2,13 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dart_framework/platform/process.dart';
import 'package:dart_framework/subtitle/parser_base.dart';
import 'package:dart_framework/utils/system_util.dart';
import 'package:oto_cli/cli/cli.dart';
import 'package:oto_cli/oto/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
import 'package:oto_cli/oto/data/jenkins_data.dart';
import 'package:oto_cli/oto/data/pipeline_data.dart';
import 'package:oto_cli/oto/defined_data.dart';
import 'package:yaml/yaml.dart';
@ -23,8 +25,8 @@ class Application {
BuildType.file: () => DataComposerFile()
};
final Map<String, PipelineExecutor Function()> taskMap = {
'exe': () => PipelineExec(),
final Map<String, PipelineExecutor Function()> exeMap = {
'exe': () => PipelineExe(),
'async': () => PipelineAsync(),
'if': () => PipelineIf(),
/*'while': () => PipelineWhile(),
@ -32,14 +34,29 @@ class Application {
'switch': () => PipelineSwitch(),*/
};
DataJenkins? jenkinsData;
Map<String, dynamic>? property;
Map<String, DataCommand> dataCommandMap = {};
late Pipeline pipeline;
DataJenkins? jenkinsData;
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;
}
bool pipelineInitialize(List<dynamic> list) {
for (Map<String, dynamic> item in list) {}
return false;
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 {
@ -72,7 +89,7 @@ class Application {
if (dataCommandMap.containsKey(command.id)) {
var ex = ExceptionData();
ex.phase = 'Validate command list';
ex.message = 'Duplicate command id exists: ${command.id}';
ex.message = 'Duplicate command id exists: "${command.id}"';
throw Exception(ex);
} else {
dataCommandMap[command.id] = command;
@ -80,9 +97,15 @@ class Application {
}
//Parse pipeline & validate
var pipeline = build.pipeline;
List<dynamic> list = pipeline!.workflow;
bool validateResult = pipelineInitialize(list);
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!;
await pipeline.execute();
}
} on Exception catch (e, stacktace) {
await CLI.printString(e.toString(), color: Color.redStrong);
@ -123,43 +146,131 @@ class Application {
}
}
//####################### Pipeline #######################//
class Pipeline {
List<PipelineExecutor> _exeList;
Pipeline(this._exeList);
Future execute() async {
for (var exe in _exeList) {
await exe.execute();
}
return simpleFuture;
}
}
class PipelineValidateResult {
late String? message;
late bool enable = true;
late List<PipelineExecutor> exeList = [];
Pipeline? get pipeline {
if (exeList.isNotEmpty) {
return Pipeline(exeList);
} else {
return null;
}
}
}
abstract class PipelineExecutor {
bool initialize(Map<String, dynamic> set);
//set & validate data
PipelineValidateResult initialize(Map<String, dynamic> set);
Future execute();
PipelineValidateResult validateTasks(List<dynamic>? list) {
var result = PipelineValidateResult();
if (list != null) {
return Application.instance.pipelineInitialize(list);
}
return result;
}
}
class PipelineExec implements PipelineExecutor {
class PipelineExe extends PipelineExecutor {
late String targetCommandID;
@override
bool initialize(Map<String, dynamic> set) {
return false;
PipelineValidateResult initialize(Map<String, dynamic> set) {
var result = PipelineValidateResult();
targetCommandID = set.values.first as String;
if (!Application.instance.dataCommandMap.containsKey(targetCommandID)) {
result.enable = false;
result.message =
'The "$targetCommandID" command does not exist in the command list.';
}
return result;
}
Future<DataCommand> get commandData async {
var commandData = Application.instance.dataCommandMap[targetCommandID]!;
await Application.instance
.printBuildStep('Phase Start: ${commandData.name}', Color.green);
return dataFutrue(commandData);
}
@override
Future execute() async {
var now = DateTime.now();
var time =
'${now.minute.toString().padLeft(2)}:${now.second.toString().padLeft(2)}:${now.millisecond.toString().padLeft(2)}';
print('==================> [$time] Execute: $targetCommandID');
var data = await commandData;
await Command.byType(data.command).execute(data);
return simpleFuture;
}
}
class PipelineAsync implements PipelineExecutor {
@override
bool initialize(Map<String, dynamic> set) {
return false;
}
class PipelineAsync extends PipelineExe {
@override
Future execute() async {
var now = DateTime.now();
var time =
'${now.minute.toString().padLeft(2)}:${now.second.toString().padLeft(2)}:${now.millisecond.toString().padLeft(2)}';
print('==================> [$time] Async Execute: $targetCommandID');
executeAsync(await commandData);
return simpleFuture;
}
void executeAsync(DataCommand data) async {
await Command.byType(data.command).execute(data);
}
}
class PipelineIf implements PipelineExecutor {
class PipelineIf extends PipelineExecutor {
late DataIf _data;
late Pipeline? _pipelineTrue;
late Pipeline? _pipelineFalse;
@override
bool initialize(Map<String, dynamic> set) {
return false;
PipelineValidateResult initialize(Map<String, dynamic> set) {
var result = PipelineValidateResult();
_data = DataIf.fromJson(set.values.first);
var dataValidateResult = _data.validate();
if (!dataValidateResult.enable) {
return dataValidateResult;
}
//set true task
var validateResult = validateTasks(_data.on_true);
if (!validateResult.enable) {
return validateResult;
}
_pipelineTrue = validateResult.pipeline;
//set false task
validateResult = validateTasks(_data.on_false);
if (!validateResult.enable) {
return validateResult;
}
_pipelineFalse = validateResult.pipeline;
return result;
}
@override
Future execute() async {
//To-do: check true or false
await _pipelineTrue?.execute();
await _pipelineFalse?.execute();
return simpleFuture;
}
}

View file

@ -8,22 +8,28 @@ part of 'command_data.dart';
DataBuild _$DataBuildFromJson(Map<String, dynamic> json) => DataBuild()
..property = json['property'] as Map<String, dynamic>
..pipeline = json['pipeline'] == null
? null
: DataPipeline.fromJson(json['pipeline'] as Map<String, dynamic>)
..commands = (json['commands'] as List<dynamic>)
.map((e) => DataCommand.fromJson(e as Map<String, dynamic>))
.toList();
Map<String, dynamic> _$DataBuildToJson(DataBuild instance) => <String, dynamic>{
'property': instance.property,
'pipeline': instance.pipeline,
'commands': instance.commands,
};
DataCommand _$DataCommandFromJson(Map<String, dynamic> json) => DataCommand()
..command = $enumDecode(_$CommandTypeEnumMap, json['command'])
..id = json['id'] as String
..param = json['param'];
Map<String, dynamic> _$DataCommandToJson(DataCommand instance) =>
<String, dynamic>{
'command': _$CommandTypeEnumMap[instance.command]!,
'id': instance.id,
'param': instance.param,
};

View file

@ -1,16 +1,12 @@
// ignore_for_file: non_constant_identifier_names
import 'package:json_annotation/json_annotation.dart';
import 'package:oto_cli/oto/application.dart';
part 'pipeline_data.g.dart';
/// ***************************** Base Data ****************************///
abstract class DataValidator {
DataValidateResult validate();
}
class DataValidateResult {
late String? message;
bool result = true;
PipelineValidateResult validate();
}
@JsonSerializable()
@ -45,20 +41,20 @@ class DataIf implements DataValidator {
DataIf();
@override
DataValidateResult validate() {
var result = DataValidateResult();
PipelineValidateResult validate() {
var result = PipelineValidateResult();
if (condition_int == null &&
condition_float == null &&
condition_string == null &&
condition_version == null &&
condition_bool == null) {
result.message = 'If syntax requires a condition.';
result.result = false;
result.enable = false;
return result;
}
if (on_true == null && on_false == null) {
result.message = 'If syntax requires on-true or on-false.';
result.result = false;
result.enable = false;
return result;
}
return result;

View file

@ -17,20 +17,20 @@ Map<String, dynamic> _$DataPipelineToJson(DataPipeline instance) =>
};
DataIf _$DataIfFromJson(Map<String, dynamic> json) => DataIf()
..condition_int = json['condition_int'] as String?
..condition_float = json['condition_float'] as String?
..condition_string = json['condition_string'] as String?
..condition_version = json['condition_version'] as String?
..condition_bool = json['condition_bool'] as String?
..on_true = json['on_true'] as List<dynamic>?
..on_false = json['on_false'] as List<dynamic>?;
..condition_int = json['condition-int'] as String?
..condition_float = json['condition-float'] as String?
..condition_string = json['condition-string'] as String?
..condition_version = json['condition-version'] as String?
..condition_bool = json['condition-bool'] as String?
..on_true = json['on-true'] as List<dynamic>?
..on_false = json['on-false'] as List<dynamic>?;
Map<String, dynamic> _$DataIfToJson(DataIf instance) => <String, dynamic>{
'condition_int': instance.condition_int,
'condition_float': instance.condition_float,
'condition_string': instance.condition_string,
'condition_version': instance.condition_version,
'condition_bool': instance.condition_bool,
'on_true': instance.on_true,
'on_false': instance.on_false,
'condition-int': instance.condition_int,
'condition-float': instance.condition_float,
'condition-string': instance.condition_string,
'condition-version': instance.condition_version,
'condition-bool': instance.condition_bool,
'on-true': instance.on_true,
'on-false': instance.on_false,
};