From a9c051bd04223b202006d07de3bd363552017251 Mon Sep 17 00:00:00 2001 From: "leedongmyung[desktop]" Date: Sat, 25 Nov 2023 12:12:55 +0900 Subject: [PATCH] Code refactoring --- assets/pipeline-test.yaml | 46 ++-- bin/main.dart | 9 - lib/oto/application.dart | 249 +----------------- .../build/app_data_creator.dart | 8 +- lib/oto/{ => commands}/build/build_dart.dart | 10 +- .../build/build_dart_compile.dart | 21 +- .../{ => commands}/build/build_dot_net.dart | 8 +- .../{ => commands}/build/build_flutter.dart | 7 +- lib/oto/{ => commands}/build/build_ios.dart | 23 +- lib/oto/{ => commands}/command.dart | 83 +++--- lib/oto/{ => commands}/file/copy.dart | 11 +- lib/oto/{ => commands}/file/delete.dart | 8 +- lib/oto/{ => commands}/file/rename.dart | 11 +- lib/oto/{ => commands}/git/git.dart | 8 +- lib/oto/{ => commands}/shell/shell.dart | 6 +- lib/oto/{ => commands}/uploader/ftp.dart | 11 +- lib/oto/{ => commands}/uploader/uploader.dart | 4 +- lib/oto/{ => commands}/util/execute_app.dart | 6 +- lib/oto/{ => commands}/util/publish_ios.dart | 20 +- lib/oto/{ => commands}/util/slack.dart | 10 +- lib/oto/{ => commands}/util/zip.dart | 9 +- lib/oto/core/data_composer.dart | 120 +++++++++ lib/oto/{ => core}/defined_data.dart | 2 +- lib/oto/data/command_data.dart | 52 ++-- lib/oto/data/command_data.g.dart | 71 +++-- lib/oto/data/pipeline_data.dart | 2 +- lib/oto/pipeline/pipeline.dart | 131 +++++++++ 27 files changed, 487 insertions(+), 459 deletions(-) rename lib/oto/{ => commands}/build/app_data_creator.dart (72%) rename lib/oto/{ => commands}/build/build_dart.dart (77%) rename lib/oto/{ => commands}/build/build_dart_compile.dart (65%) rename lib/oto/{ => commands}/build/build_dot_net.dart (78%) rename lib/oto/{ => commands}/build/build_flutter.dart (80%) rename lib/oto/{ => commands}/build/build_ios.dart (76%) rename lib/oto/{ => commands}/command.dart (69%) rename lib/oto/{ => commands}/file/copy.dart (87%) rename lib/oto/{ => commands}/file/delete.dart (78%) rename lib/oto/{ => commands}/file/rename.dart (71%) rename lib/oto/{ => commands}/git/git.dart (69%) rename lib/oto/{ => commands}/shell/shell.dart (85%) rename lib/oto/{ => commands}/uploader/ftp.dart (98%) rename lib/oto/{ => commands}/uploader/uploader.dart (95%) rename lib/oto/{ => commands}/util/execute_app.dart (81%) rename lib/oto/{ => commands}/util/publish_ios.dart (70%) rename lib/oto/{ => commands}/util/slack.dart (78%) rename lib/oto/{ => commands}/util/zip.dart (88%) create mode 100644 lib/oto/core/data_composer.dart rename lib/oto/{ => core}/defined_data.dart (99%) create mode 100644 lib/oto/pipeline/pipeline.dart diff --git a/assets/pipeline-test.yaml b/assets/pipeline-test.yaml index ae0c954..e64a974 100644 --- a/assets/pipeline-test.yaml +++ b/assets/pipeline-test.yaml @@ -19,31 +19,31 @@ pipeline: - exe: zip commands: -### 콜백이 필요없는 단순 깃 명령 호출 -- command: Git - id: git - param: - commands: - - restore . - - clean -f - - switch pipeline +# ### 콜백이 필요없는 단순 깃 명령 호출 +# - command: Git +# id: git +# param: +# commands: +# - restore . +# - clean -f +# - switch pipeline -### 깃 리비전 정보 저장 -- command: GitRev - id: git-rev - param: - result-value: +# ### 깃 리비전 정보 저장 +# - command: GitRev +# id: git-rev +# param: +# result-value: -### Json value read -- command: JsonValue - id: json-value - param: - - set: - from: gitHash - to: - - set: - from: version - to: +# ### Json value read +# - command: JsonValue +# id: json-value +# param: +# - set: +# from: gitHash +# to: +# - set: +# from: version +# to: ### Version 쓰기 - command: CreateAppData diff --git a/bin/main.dart b/bin/main.dart index eee3ffd..410973c 100644 --- a/bin/main.dart +++ b/bin/main.dart @@ -13,13 +13,4 @@ void main(List arguments) async { CommandStart(), CommandStop() ]); - -// String test = ''' -// Error on line 5, column 1: Expected ':'. -// ╷ -// 5 │ < commands: -// │ ^ -// ╵ -// '''; -// await CLI.printString(test, color: Color.red); } diff --git a/lib/oto/application.dart b/lib/oto/application.dart index 7c6206a..67ad3ac 100644 --- a/lib/oto/application.dart +++ b/lib/oto/application.dart @@ -4,11 +4,11 @@ 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/command.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/data/pipeline_data.dart'; -import 'package:oto_cli/oto/defined_data.dart'; +import 'package:oto_cli/oto/core/data_composer.dart'; import 'package:yaml/yaml.dart'; enum BuildType { jenkins, test, file } @@ -34,10 +34,11 @@ class Application { }; DataJenkins? jenkinsData; - Map? property; + Map property = {}; Map dataCommandMap = {}; late Pipeline pipeline; + //pipeline validate & initialize PipelineValidateResult pipelineInitialize(List list) { var result = PipelineValidateResult(); for (Map item in list) { @@ -104,6 +105,8 @@ class Application { throw Exception(ex); } pipeline = validateResult.pipeline!; + + //start build await pipeline.execute(); } } on Exception catch (e, stacktace) { @@ -144,241 +147,3 @@ class Application { return simpleFuture; } } - -//####################### Pipeline #######################// -class Pipeline { - List _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 exeList = []; - Pipeline? get pipeline { - if (exeList.isNotEmpty) { - return Pipeline(exeList); - } else { - return null; - } - } -} - -abstract class PipelineExecutor { - //set & validate data - PipelineValidateResult initialize(Map set); - Future execute(); - - PipelineValidateResult validateTasks(List? list) { - var result = PipelineValidateResult(); - if (list != null) { - return Application.instance.pipelineInitialize(list); - } - return result; - } -} - -class PipelineExe extends PipelineExecutor { - late String targetCommandID; - @override - PipelineValidateResult initialize(Map 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 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 extends PipelineExe { - @override - Future execute() async { - executeAsync(await commandData); - return simpleFuture; - } - - void executeAsync(DataCommand data) async { - await Command.byType(data.command).execute(data); - } -} - -class PipelineIf extends PipelineExecutor { - late DataIf _data; - late Pipeline? _pipelineTrue; - late Pipeline? _pipelineFalse; - - @override - PipelineValidateResult initialize(Map 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; - } -} - -//############################ DataComposer ##########################// -abstract class DataComposer { - DataJenkins? jenkinsData; - String buildYaml = ''; - - Future compose(String? yaml, Future Function(String, Color?) printer) async { - return simpleFuture; - } -} - -class DataComposerTest extends DataComposer { - @override - Future compose(String? yaml, Future Function(String, Color?) printer) async { - jenkinsData = DataJenkins.fromJson(TestData.jenkinsMap!); - buildYaml = TestData.buildYaml; - return simpleFuture; - } -} - -class DataComposerFile extends DataComposer { - @override - Future compose(String? yaml, Future Function(String, Color?) printer) async { - jenkinsData = DataJenkins.fromJson(FileData.jenkinsMap!); - buildYaml = yaml ?? '---'; - return simpleFuture; - } -} - -class DataComposerJenkins extends DataComposer { - @override - Future compose(String? yaml, Future Function(String, Color?) printer) async { - Map? jenkinsMap; - String os = Platform.operatingSystem; - var enable = true; - print('Current OS: $os'); - print('Start build...'); - String jsonStr = ''; - if (Platform.isMacOS || Platform.isLinux) { - await Process.run('zsh', [ - '${Directory.current.path}/assets/script/shell/jenkins_env_params.sh' - ]).then((ProcessResult result) => jsonStr = result.stdout); - jenkinsMap = getMapFromJson(jsonStr)!; - } else if (Platform.isWindows) { - await Process.run('cmd', [ - '/C', - '${Directory.current.path}/assets/script/batch/jenkins_env_params.bat' - ]).then((ProcessResult result) => jsonStr = result.stdout); - jsonStr = jsonStr.substring(jsonStr.indexOf('{')); - jsonStr = jsonStr.replaceAll('\\', '/'); - jenkinsMap = getMapFromJson(jsonStr); - } else { - enable = false; - printer( - 'is not Mac/Windows/Linux. build must be execute in Mac/Windows os system', - Color.redStrong); - } - if (enable) { - await printer('Jenkins Variables', Color.green); - print(jsonStr); - } - jenkinsData = DataJenkins.fromJson(jenkinsMap!); - buildYaml = await getBuildData(); - - return simpleFuture; - } - - Future getBuildData() async { - var c = Completer(); - var file = File('${jenkinsData!.workspace}/build_data.conf'); - var content = ''; - if (Platform.isWindows) { - content = file - .readAsStringSync(encoding: utf8) - .replaceAll('BuildData=', '') - .replaceAll('\\', '/'); - var regEx = RegExp(r'(%)([a-zA-Z0-9]+)(%)'); - var list = regEx.allMatches(content); - var params = []; - for (var match in list) { - var param = match.group(2); - if (!params.contains(param)) { - params.add(param!); - } - } - - var temp = File('${jenkinsData!.workspace}/param_temp.bat'); - var bat = ''; - for (var param in params) { - bat += '@echo %$param%\n'; - } - temp.writeAsStringSync(bat); - - var resultParam = ''; - await Process.run('cmd', ['/C', temp.path]) - .then((ProcessResult result) => resultParam = result.stdout); - var values = resultParam.split('\n'); - var length = params.length; - for (var i = 0; i < length; ++i) { - var value = values[i] - .toString() - .replaceAll('\\', '/') - .replaceAll(RegExp('\r|\n'), ''); - content = content.replaceAll('%${params[i]}%', value); - } - temp.deleteSync(); - } else { - content = await file.readAsString(); - } - c.complete(content); - return c.future; - } -} diff --git a/lib/oto/build/app_data_creator.dart b/lib/oto/commands/build/app_data_creator.dart similarity index 72% rename from lib/oto/build/app_data_creator.dart rename to lib/oto/commands/build/app_data_creator.dart index 1ca8cf1..356d4b9 100644 --- a/lib/oto/build/app_data_creator.dart +++ b/lib/oto/commands/build/app_data_creator.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'package:dart_framework/core/app_data_manager.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class CreateAppData extends Command { @@ -11,10 +10,9 @@ class CreateAppData extends Command { @override Future execute(DataCommand command) async { Completer c = Completer(); - var jenkins = Application.instance.jenkinsData!; var data = DataAppDataCreator.fromJson(command.param); - var workspace = data.workspace ?? jenkins.workspace; - workspace = workspace.replaceAll('\\', '/'); + var workspace = getWorkspace(data.workspace); + var appData = await AppDataManager.to .create(data.scm, workspace, data.relativeAssetPath, data.name); Command.setReturnValue(data.returnVersion, appData.version); diff --git a/lib/oto/build/build_dart.dart b/lib/oto/commands/build/build_dart.dart similarity index 77% rename from lib/oto/build/build_dart.dart rename to lib/oto/commands/build/build_dart.dart index 058df03..0e558e6 100644 --- a/lib/oto/build/build_dart.dart +++ b/lib/oto/commands/build/build_dart.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'package:dart_framework/platform/process.dart'; -import 'package:dart_framework/utils/path.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class BuildDart extends Command { @@ -19,12 +17,10 @@ class BuildDart extends Command { Future execute(DataCommand command) async { Completer c = Completer(); var data = DataBuildDart.fromJson(command.param); - var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var targetPath = - Path.getNormal(Command.replaceTag(data.targetPath ?? workspace)); + var workspace = getWorkspace(data.workspace); var shell = StringBuffer(); - shell.write('cd $targetPath'); + shell.write('cd $workspace'); shell.write(' && flutter clean'); shell.write(' && flutter pub upgrade --major-versions'); shell.write(' && flutter packages upgrade'); diff --git a/lib/oto/build/build_dart_compile.dart b/lib/oto/commands/build/build_dart_compile.dart similarity index 65% rename from lib/oto/build/build_dart_compile.dart rename to lib/oto/commands/build/build_dart_compile.dart index ba588a1..262e8fd 100644 --- a/lib/oto/build/build_dart_compile.dart +++ b/lib/oto/commands/build/build_dart_compile.dart @@ -1,14 +1,10 @@ import 'dart:async'; import 'dart:io'; -import 'package:oto_cli/oto/build/build_dart.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/build/build_dart.dart'; import 'package:oto_cli/oto/data/command_data.dart'; -import 'package:dart_framework/utils/path.dart'; // ignore: depend_on_referenced_packages import 'package:path/path.dart' as path; -import '../application.dart'; - class BuildDartCompile extends BuildDart { @override Future appendShell( @@ -16,10 +12,8 @@ class BuildDartCompile extends BuildDart { var c = Completer(); var data = DataBuildDartCompile.fromJson(command.param); var extension = getExeExtension(); - var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var targetPath = - Path.getNormal(Command.replaceTag(data.targetPath ?? workspace)); - var binPath = path.join(targetPath, 'bin'); + var workspace = getWorkspace(data.workspace); + var binPath = path.join(workspace, 'bin'); //find build target var targetDir = Directory(binPath); @@ -29,20 +23,19 @@ class BuildDartCompile extends BuildDart { findedDartFile = path.basename(file.path); break; } - findedDartFile = path.join(targetPath, 'bin', findedDartFile); - var targetDartFile = - Command.replaceTag(data.targetDartFile ?? findedDartFile); + findedDartFile = path.join(workspace, 'bin', findedDartFile); + var targetDartFile = replaceTag(data.targetDartFile ?? findedDartFile); //clear build path var buildFolderName = 'release'; - var buildPath = path.join(targetPath, buildFolderName); + var buildPath = path.join(workspace, buildFolderName); var buildDir = Directory(buildPath); var buildFileName = data.buildFileName ?? 'release'; if (!buildDir.existsSync()) { buildDir.createSync(); } buildPath = - path.join(targetPath, buildFolderName, '$buildFileName$extension'); + path.join(workspace, buildFolderName, '$buildFileName$extension'); var preBuildFile = File(buildPath); if (preBuildFile.existsSync()) { preBuildFile.deleteSync(); diff --git a/lib/oto/build/build_dot_net.dart b/lib/oto/commands/build/build_dot_net.dart similarity index 78% rename from lib/oto/build/build_dot_net.dart rename to lib/oto/commands/build/build_dot_net.dart index c19524f..6cfed45 100644 --- a/lib/oto/build/build_dot_net.dart +++ b/lib/oto/commands/build/build_dot_net.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:dart_framework/platform/process.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class BuildDotNet extends Command { @@ -9,13 +8,14 @@ class BuildDotNet extends Command { @override Future execute(DataCommand command) async { - Completer c = Completer(); var data = DataBuildDotNet.fromJson(command.param); - var workspace = Application.instance.jenkinsData!.workspace; + var workspace = getWorkspace(data.workspace); + var shell = StringBuffer(); shell.writeln('cd $workspace'); shell.writeln( 'MSBuild ${data.projectFile} /t:build /p:Configuration=Release;Platform=x86'); + var process = await ProcessExecutor.start(shell, workspace: workspace, printStderr: false); diff --git a/lib/oto/build/build_flutter.dart b/lib/oto/commands/build/build_flutter.dart similarity index 80% rename from lib/oto/build/build_flutter.dart rename to lib/oto/commands/build/build_flutter.dart index 73cdeeb..d94c816 100644 --- a/lib/oto/build/build_flutter.dart +++ b/lib/oto/commands/build/build_flutter.dart @@ -1,6 +1,7 @@ import 'dart:async'; -import 'package:oto_cli/oto/build/build_dart.dart'; +import 'package:dart_framework/utils/system_util.dart'; +import 'package:oto_cli/oto/commands/build/build_dart.dart'; import 'package:oto_cli/oto/data/command_data.dart'; // ignore: constant_identifier_names @@ -10,13 +11,11 @@ class BuildFlutter extends BuildDart { @override Future appendShell( StringBuffer shell, DataCommand command) async { - var c = Completer(); var data = DataBuildFlutter.fromJson(command.param); var platform = data.platform.toString().replaceAll('BuildPlatform.', '').toLowerCase(); var additional = data.additional == null ? '' : ' ${data.additional!}'; shell.write(' && flutter build $platform$additional'); - c.complete(shell); - return c.future; + return dataFutrue(shell); } } diff --git a/lib/oto/build/build_ios.dart b/lib/oto/commands/build/build_ios.dart similarity index 76% rename from lib/oto/build/build_ios.dart rename to lib/oto/commands/build/build_ios.dart index a931d8f..ba6334e 100644 --- a/lib/oto/build/build_ios.dart +++ b/lib/oto/commands/build/build_ios.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; import 'package:dart_framework/platform/process.dart'; import 'package:dart_framework/utils/path.dart'; @@ -13,8 +13,8 @@ class BuildiOS extends Command { Future execute(DataCommand command) async { Completer c = Completer(); var data = DataBuildiOS.fromJson(command.param); - var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var workspacePath = Path.getNormal(Command.replaceTag(data.workspacePath)); + var workspace = getWorkspace(data.workspace); + var xcworkspaceFilePath = getPathNormal(data.xcworkspaceFilePath); var destination = data.destination ?? 'generic/platform=iOS build'; var cleanPod = data.cleanPod ?? false; @@ -32,7 +32,7 @@ class BuildiOS extends Command { shell.write(' && pod install'); } shell.write( - ' && xcodebuild -workspace $workspacePath -scheme ${data.scheme} -destination $destination'); + ' && xcodebuild -workspace $xcworkspaceFilePath -scheme ${data.scheme} -destination $destination'); var processData = await ProcessExecutor.start(shell, workspace: workspace, printStderr: false); @@ -60,9 +60,9 @@ class ArchiveiOS extends Command { Future execute(DataCommand command) async { Completer c = Completer(); var data = DataArchiveiOS.fromJson(command.param); - var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var workspacePath = Path.getNormal(Command.replaceTag(data.workspacePath)); - var archivePath = Path.getNormal(Command.replaceTag(data.archivePath)); + var workspace = getWorkspace(data.workspace); + var workspacePath = getPathNormal(data.xcworkspaceFilePath); + var archivePath = getPathNormal(data.archivePath); var shell = StringBuffer(); shell.write( @@ -83,11 +83,10 @@ class ExportiOS extends Command { Future execute(DataCommand command) async { Completer c = Completer(); var data = DataExportiOS.fromJson(command.param); - var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var archivePath = Path.getNormal(Command.replaceTag(data.archivePath)); - var exportPath = Path.getNormal(Command.replaceTag(data.exportPath)); - var exportOptionPlistPath = - Path.getNormal(Command.replaceTag(data.exportOptionPlistPath)); + var workspace = getWorkspace(data.workspace); + var archivePath = getPathNormal(data.archivePath); + var exportPath = getPathNormal(data.exportPath); + var exportOptionPlistPath = getPathNormal(data.exportOptionPlistPath); var shell = StringBuffer(); shell.write( diff --git a/lib/oto/command.dart b/lib/oto/commands/command.dart similarity index 69% rename from lib/oto/command.dart rename to lib/oto/commands/command.dart index 8685fb3..9d36147 100644 --- a/lib/oto/command.dart +++ b/lib/oto/commands/command.dart @@ -1,24 +1,26 @@ // ignore_for_file: constant_identifier_names import 'dart:async'; +import 'package:dart_framework/utils/path.dart'; import 'package:dart_framework/utils/system_util.dart'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/build/app_data_creator.dart'; -import 'package:oto_cli/oto/build/build_dart.dart'; -import 'package:oto_cli/oto/build/build_dart_compile.dart'; -import 'package:oto_cli/oto/build/build_dot_net.dart'; -import 'package:oto_cli/oto/build/build_flutter.dart'; -import 'package:oto_cli/oto/build/build_ios.dart'; +import 'package:oto_cli/oto/commands/build/app_data_creator.dart'; +import 'package:oto_cli/oto/commands/build/build_dart.dart'; +import 'package:oto_cli/oto/commands/build/build_dart_compile.dart'; +import 'package:oto_cli/oto/commands/build/build_dot_net.dart'; +import 'package:oto_cli/oto/commands/build/build_flutter.dart'; +import 'package:oto_cli/oto/commands/build/build_ios.dart'; import 'package:oto_cli/oto/data/command_data.dart'; -import 'package:oto_cli/oto/file/delete.dart'; -import 'package:oto_cli/oto/file/rename.dart'; -import 'package:oto_cli/oto/shell/shell.dart'; -import 'package:oto_cli/oto/file/copy.dart'; -import 'package:oto_cli/oto/util/execute_app.dart'; -import 'package:oto_cli/oto/util/publish_ios.dart'; -import 'package:oto_cli/oto/util/slack.dart'; -import 'package:oto_cli/oto/util/zip.dart'; -import 'package:oto_cli/oto/uploader/uploader.dart'; +import 'package:oto_cli/oto/data/jenkins_data.dart'; +import 'package:oto_cli/oto/commands/file/delete.dart'; +import 'package:oto_cli/oto/commands/file/rename.dart'; +import 'package:oto_cli/oto/commands/shell/shell.dart'; +import 'package:oto_cli/oto/commands/file/copy.dart'; +import 'package:oto_cli/oto/commands/util/execute_app.dart'; +import 'package:oto_cli/oto/commands/util/publish_ios.dart'; +import 'package:oto_cli/oto/commands/util/slack.dart'; +import 'package:oto_cli/oto/commands/util/zip.dart'; +import 'package:oto_cli/oto/commands/uploader/uploader.dart'; enum CommandType { SimpleCommand, @@ -72,19 +74,6 @@ abstract class Command { Command(); static final Map _cache = {}; - static String replaceTag(String raw) { - var regEx = RegExp(r'()'); - var list = regEx.allMatches(raw); - for (var match in list) { - var param = match.group(2); - if (!_cache.containsKey(param)) { - _cache[param!] = _getTagValue(param); - } - var target = ''; - raw = raw.replaceAll(target, _cache[param]); - } - return raw; - } static void setReturnValue(String tag, dynamic value) { var regEx = RegExp(r'()'); @@ -92,7 +81,7 @@ abstract class Command { tag = match!.group(2)!; if (tag.startsWith('property')) { var key = tag.replaceFirst('property.', ''); - Application.instance.property![key] = value; + Application.instance.property[key] = value; } } @@ -102,7 +91,7 @@ abstract class Command { if (value.startsWith('property.')) { var map = Application.instance.property; var param = value.replaceFirst('property.', ''); - if (map!.containsKey(param)) { + if (map.containsKey(param)) { data = map[param]; setted = true; } else { @@ -119,6 +108,40 @@ abstract class Command { return data; } + static String replaceTagValue(String raw) { + var regEx = RegExp(r'()'); + var list = regEx.allMatches(raw); + for (var match in list) { + var param = match.group(2); + if (!_cache.containsKey(param)) { + _cache[param!] = _getTagValue(param); + } + var target = ''; + raw = raw.replaceAll(target, _cache[param]); + } + return raw; + } + + Map get property { + return Application.instance.property; + } + + DataJenkins? get jenkinsData { + return Application.instance.jenkinsData; + } + + String getWorkspace(String? dataWorkspace) { + return getPathNormal(dataWorkspace ?? jenkinsData!.workspace); + } + + String getPathNormal(String path) { + return replaceTag(Path.getNormal(path)); + } + + String replaceTag(String raw) { + return Command.replaceTagValue(raw); + } + Future execute(DataCommand command) async { return simpleFuture; } diff --git a/lib/oto/file/copy.dart b/lib/oto/commands/file/copy.dart similarity index 87% rename from lib/oto/file/copy.dart rename to lib/oto/commands/file/copy.dart index 7b8ed2d..5b45bd0 100644 --- a/lib/oto/file/copy.dart +++ b/lib/oto/commands/file/copy.dart @@ -2,24 +2,20 @@ import 'dart:async'; import 'dart:io'; import 'package:dart_framework/utils/path.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class Copy extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataCopy.fromJson(command.param); - var result = true; var isMove = data.isMove == null ? false : data.isMove!; var entries = data.copyMap.entries; try { var ignoredList = []; for (var entry in entries) { - var start = Path.getNormal(Command.replaceTag(entry.key)); - var dest = Path.getNormal(Command.replaceTag(entry.value)); + var start = getPathNormal(entry.key); + var dest = getPathNormal(entry.value); var destDir = Directory(dest); var name = Path.getName(start); if (name == "*") { @@ -72,7 +68,6 @@ class Copy extends Command { } } on Exception catch (e) { print('Copy General Exception: $e'); - result = false; } return complete(0, command); } diff --git a/lib/oto/file/delete.dart b/lib/oto/commands/file/delete.dart similarity index 78% rename from lib/oto/file/delete.dart rename to lib/oto/commands/file/delete.dart index 5677a96..99ccbab 100644 --- a/lib/oto/file/delete.dart +++ b/lib/oto/commands/file/delete.dart @@ -2,20 +2,17 @@ import 'dart:async'; import 'package:dart_framework/utils/path.dart'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class Delete extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataDelete.fromJson(command.param); - var result = true; try { var ignoredList = []; for (var item in data.list) { - var path = Path.getNormal(Command.replaceTag(item)); + var path = getPathNormal(item); var name = Path.getName(path); if (name == "*") { //Delete & recreate dest folder @@ -31,7 +28,6 @@ class Delete extends Command { } } on Exception catch (e) { print('Copy General Exception: $e'); - result = false; } return complete(0, command); } diff --git a/lib/oto/file/rename.dart b/lib/oto/commands/file/rename.dart similarity index 71% rename from lib/oto/file/rename.dart rename to lib/oto/commands/file/rename.dart index 9db976c..a51d0fd 100644 --- a/lib/oto/file/rename.dart +++ b/lib/oto/commands/file/rename.dart @@ -3,22 +3,18 @@ import 'dart:io'; import 'package:path/path.dart' as path; import 'package:dart_framework/utils/path.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class Rename extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataRename.fromJson(command.param); - var result = true; var entries = data.renameMap.entries; try { for (var entry in entries) { - var start = Path.getNormal(Command.replaceTag(entry.key)); - var targetName = Command.replaceTag(entry.value); + var start = getPathNormal(entry.key); + var targetName = replaceTag(entry.value); var type = Path.getType(start); var parentPath = Path.getParent(start)!; var newPath = path.join(parentPath, targetName); @@ -32,7 +28,6 @@ class Rename extends Command { } } on Exception catch (e) { print('Copy General Exception: $e'); - result = false; } return complete(0, command); } diff --git a/lib/oto/git/git.dart b/lib/oto/commands/git/git.dart similarity index 69% rename from lib/oto/git/git.dart rename to lib/oto/commands/git/git.dart index 5d5b795..50f7336 100644 --- a/lib/oto/git/git.dart +++ b/lib/oto/commands/git/git.dart @@ -1,19 +1,17 @@ import 'dart:async'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; import 'package:dart_framework/platform/process.dart'; class Git extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataExecuteApp.fromJson(command.param); - var exe = Command.replaceTag(data.executable); - var desktop = Command.replaceTag(data.desktopServicePath); + var exe = replaceTag(data.executable); + var desktop = replaceTag(data.desktopServicePath); print('Process Start: $exe'); var content = 'start "" "$exe" & exit'; diff --git a/lib/oto/shell/shell.dart b/lib/oto/commands/shell/shell.dart similarity index 85% rename from lib/oto/shell/shell.dart rename to lib/oto/commands/shell/shell.dart index 5f87207..0a4008d 100644 --- a/lib/oto/shell/shell.dart +++ b/lib/oto/commands/shell/shell.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:dart_framework/platform/process.dart'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class Shell extends Command { @@ -13,8 +13,8 @@ class Shell extends Command { var data = DataShell.fromJson(command.param); print(command.param); //Start here - var workspace = Command.replaceTag(data.workspace ?? jenkins.workspace); - var path = Command.replaceTag(data.path); + var workspace = getWorkspace(data.workspace); + var path = getPathNormal(data.path); var shell = StringBuffer(); if (Platform.isWindows) { shell.writeln('call $path'); diff --git a/lib/oto/uploader/ftp.dart b/lib/oto/commands/uploader/ftp.dart similarity index 98% rename from lib/oto/uploader/ftp.dart rename to lib/oto/commands/uploader/ftp.dart index c33de80..761d4df 100644 --- a/lib/oto/uploader/ftp.dart +++ b/lib/oto/commands/uploader/ftp.dart @@ -4,7 +4,7 @@ import 'package:ftpconnect/ftpconnect.dart'; // ignore: implementation_imports import 'package:ftpconnect/src/ftp_entry.dart'; import 'package:dart_framework/utils/path.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; class FTP { final String _host; @@ -84,8 +84,8 @@ class FTP { } Future _upload(String local, String remote) async { - local = Command.replaceTag(local); - remote = Command.replaceTag(remote); + local = Command.replaceTagValue(local); + remote = Command.replaceTagValue(remote); if (await Directory(local).exists()) { var name = Path.getName(local); var childRemoteFolder = '$remote/$name'; @@ -259,10 +259,7 @@ brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Librar class SFTP extends FTP { SFTP(super.host, - {super.port = 22, - super.user, - super.password, - super.timeout}); + {super.port = 22, super.user, super.password, super.timeout}); @override Future connect() async {} diff --git a/lib/oto/uploader/uploader.dart b/lib/oto/commands/uploader/uploader.dart similarity index 95% rename from lib/oto/uploader/uploader.dart rename to lib/oto/commands/uploader/uploader.dart index 032ddad..e2e2fc7 100644 --- a/lib/oto/uploader/uploader.dart +++ b/lib/oto/commands/uploader/uploader.dart @@ -3,9 +3,9 @@ import 'dart:core'; import 'dart:io'; import 'package:path/path.dart' as path; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; -import 'package:oto_cli/oto/uploader/ftp.dart'; +import 'package:oto_cli/oto/commands/uploader/ftp.dart'; import 'package:dart_framework/utils/path.dart'; class Uploader extends Command { diff --git a/lib/oto/util/execute_app.dart b/lib/oto/commands/util/execute_app.dart similarity index 81% rename from lib/oto/util/execute_app.dart rename to lib/oto/commands/util/execute_app.dart index 7c74143..a077193 100644 --- a/lib/oto/util/execute_app.dart +++ b/lib/oto/commands/util/execute_app.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; import 'package:dart_framework/platform/process.dart'; @@ -12,8 +12,8 @@ class ExecuteApp extends Command { var jenkins = Application.instance.jenkinsData; var data = DataExecuteApp.fromJson(command.param); - var exe = Command.replaceTag(data.executable); - var desktop = Command.replaceTag(data.desktopServicePath); + var exe = replaceTag(data.executable); + var desktop = replaceTag(data.desktopServicePath); print('Process Start: $exe'); var content = 'start "" "$exe" & exit'; diff --git a/lib/oto/util/publish_ios.dart b/lib/oto/commands/util/publish_ios.dart similarity index 70% rename from lib/oto/util/publish_ios.dart rename to lib/oto/commands/util/publish_ios.dart index 611ab19..8ded18f 100644 --- a/lib/oto/util/publish_ios.dart +++ b/lib/oto/commands/util/publish_ios.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; import 'package:dart_framework/utils/path.dart'; // ignore: depend_on_referenced_packages @@ -15,8 +15,8 @@ class PublishiOS extends Command { Future execute(DataCommand command) async { var data = DataPublishiOS.fromJson(command.param); var workspace = Path.getNormal(Application.instance.jenkinsData!.workspace); - var menifestURL = Command.replaceTag(data.menifestURL); - var destinationPath = Command.replaceTag(data.destinationPath); + var menifestURL = replaceTag(data.menifestURL); + var destinationPath = replaceTag(data.destinationPath); var templatePath = path.normalize( '${path.dirname(Platform.script.toFilePath())}/../assets/template'); @@ -35,14 +35,12 @@ class PublishiOS extends Command { var menifestContent = await File('$templatePath/manifest.plist').readAsString(); menifestContent = menifestContent - .replaceFirst('IPA_URL', Command.replaceTag(data.ipaURL)) - .replaceFirst('BUNDLE_ID', Command.replaceTag(data.bundleID)) - .replaceFirst('VERSION', Command.replaceTag(data.version)) - .replaceFirst('APP_NAME', Command.replaceTag(data.appName)) - .replaceFirst( - 'DISPLAY_IMAGE_URL', Command.replaceTag(data.displayImageURL)) - .replaceFirst( - 'FULL_SIZE_IMAGE_URL', Command.replaceTag(data.fullSizeImageURL)); + .replaceFirst('IPA_URL', replaceTag(data.ipaURL)) + .replaceFirst('BUNDLE_ID', replaceTag(data.bundleID)) + .replaceFirst('VERSION', replaceTag(data.version)) + .replaceFirst('APP_NAME', replaceTag(data.appName)) + .replaceFirst('DISPLAY_IMAGE_URL', replaceTag(data.displayImageURL)) + .replaceFirst('FULL_SIZE_IMAGE_URL', replaceTag(data.fullSizeImageURL)); var menifestFile = File('$destinationPath/manifest.plist'); await menifestFile.writeAsString(menifestContent); diff --git a/lib/oto/util/slack.dart b/lib/oto/commands/util/slack.dart similarity index 78% rename from lib/oto/util/slack.dart rename to lib/oto/commands/util/slack.dart index f98df61..b87ad47 100644 --- a/lib/oto/util/slack.dart +++ b/lib/oto/commands/util/slack.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:dart_framework/utils/system_util.dart'; import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; import 'package:color/color.dart'; import 'package:dart_framework/utils/slack/slack_sender.dart'; @@ -24,16 +24,14 @@ class Slack extends Command { class SlackBuild extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataSlackBuild.fromJson(command.param); - var result = true; - var version = Command.replaceTag(data.version); - var download = Command.replaceTag(data.downloadURL); + var version = replaceTag(data.version); + var download = replaceTag(data.downloadURL); var channel = data.channel ?? 'build'; var color = Color.hex(data.color); var sender = SlackSender(); + await sender.sendBuild(data.appName, data.type, color, version, download, channel: channel); diff --git a/lib/oto/util/zip.dart b/lib/oto/commands/util/zip.dart similarity index 88% rename from lib/oto/util/zip.dart rename to lib/oto/commands/util/zip.dart index faac463..db4cb10 100644 --- a/lib/oto/util/zip.dart +++ b/lib/oto/commands/util/zip.dart @@ -3,18 +3,15 @@ import 'dart:io'; import 'package:archive/archive_io.dart'; import 'package:dart_framework/utils/path.dart'; -import 'package:oto_cli/oto/application.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/command_data.dart'; class Zip extends Command { @override Future execute(DataCommand command) async { - var common = Application.instance.property; - var jenkins = Application.instance.jenkinsData; var data = DataZip.fromJson(command.param); try { - var zipFilePath = Path.getNormal(Command.replaceTag(data.zipFile)); + var zipFilePath = Path.getNormal(replaceTag(data.zipFile)); print('Start Compress...'); var parent = Directory(Path.getParent(zipFilePath)!); if (!parent.existsSync()) parent.createSync(recursive: true); @@ -26,7 +23,7 @@ class Zip extends Command { encoder.create(zipFilePath); var list = data.zipList; for (var path in list) { - path = Path.getNormal(Command.replaceTag(path)); + path = Path.getNormal(replaceTag(path)); var name = Path.getName(path); if (name == '*') { parent = Directory(Path.getParent(path)!); diff --git a/lib/oto/core/data_composer.dart b/lib/oto/core/data_composer.dart new file mode 100644 index 0000000..5ef9515 --- /dev/null +++ b/lib/oto/core/data_composer.dart @@ -0,0 +1,120 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:dart_framework/utils/system_util.dart'; +import 'package:oto_cli/cli/cli.dart'; +import 'package:oto_cli/oto/data/jenkins_data.dart'; +import 'package:oto_cli/oto/core/defined_data.dart'; + +abstract class DataComposer { + DataJenkins? jenkinsData; + String buildYaml = ''; + + Future compose(String? yaml, Future Function(String, Color?) printer) async { + return simpleFuture; + } +} + +class DataComposerTest extends DataComposer { + @override + Future compose(String? yaml, Future Function(String, Color?) printer) async { + jenkinsData = DataJenkins.fromJson(TestData.jenkinsMap!); + buildYaml = TestData.buildYaml; + return simpleFuture; + } +} + +class DataComposerFile extends DataComposer { + @override + Future compose(String? yaml, Future Function(String, Color?) printer) async { + jenkinsData = DataJenkins.fromJson(FileData.jenkinsMap!); + buildYaml = yaml ?? '---'; + return simpleFuture; + } +} + +class DataComposerJenkins extends DataComposer { + @override + Future compose(String? yaml, Future Function(String, Color?) printer) async { + Map? jenkinsMap; + String os = Platform.operatingSystem; + var enable = true; + print('Current OS: $os'); + print('Start build...'); + String jsonStr = ''; + if (Platform.isMacOS || Platform.isLinux) { + await Process.run('zsh', [ + '${Directory.current.path}/assets/script/shell/jenkins_env_params.sh' + ]).then((ProcessResult result) => jsonStr = result.stdout); + jenkinsMap = getMapFromJson(jsonStr)!; + } else if (Platform.isWindows) { + await Process.run('cmd', [ + '/C', + '${Directory.current.path}/assets/script/batch/jenkins_env_params.bat' + ]).then((ProcessResult result) => jsonStr = result.stdout); + jsonStr = jsonStr.substring(jsonStr.indexOf('{')); + jsonStr = jsonStr.replaceAll('\\', '/'); + jenkinsMap = getMapFromJson(jsonStr); + } else { + enable = false; + printer( + 'is not Mac/Windows/Linux. build must be execute in Mac/Windows os system', + Color.redStrong); + } + if (enable) { + await printer('Jenkins Variables', Color.green); + print(jsonStr); + } + jenkinsData = DataJenkins.fromJson(jenkinsMap!); + buildYaml = await getBuildData(); + + return simpleFuture; + } + + Future getBuildData() async { + var c = Completer(); + var file = File('${jenkinsData!.workspace}/build_data.conf'); + var content = ''; + if (Platform.isWindows) { + content = file + .readAsStringSync(encoding: utf8) + .replaceAll('BuildData=', '') + .replaceAll('\\', '/'); + var regEx = RegExp(r'(%)([a-zA-Z0-9]+)(%)'); + var list = regEx.allMatches(content); + var params = []; + for (var match in list) { + var param = match.group(2); + if (!params.contains(param)) { + params.add(param!); + } + } + + var temp = File('${jenkinsData!.workspace}/param_temp.bat'); + var bat = ''; + for (var param in params) { + bat += '@echo %$param%\n'; + } + temp.writeAsStringSync(bat); + + var resultParam = ''; + await Process.run('cmd', ['/C', temp.path]) + .then((ProcessResult result) => resultParam = result.stdout); + var values = resultParam.split('\n'); + var length = params.length; + for (var i = 0; i < length; ++i) { + var value = values[i] + .toString() + .replaceAll('\\', '/') + .replaceAll(RegExp('\r|\n'), ''); + content = content.replaceAll('%${params[i]}%', value); + } + temp.deleteSync(); + } else { + content = await file.readAsString(); + } + c.complete(content); + return c.future; + } +} diff --git a/lib/oto/defined_data.dart b/lib/oto/core/defined_data.dart similarity index 99% rename from lib/oto/defined_data.dart rename to lib/oto/core/defined_data.dart index e549550..dc3ebb4 100644 --- a/lib/oto/defined_data.dart +++ b/lib/oto/core/defined_data.dart @@ -3,7 +3,7 @@ import 'dart:io'; // ignore: depend_on_referenced_packages import 'package:yaml/yaml.dart' as yaml; -import 'package:oto_cli/oto/build/build_flutter.dart'; +import 'package:oto_cli/oto/commands/build/build_flutter.dart'; class FileData { static Map? get jenkinsMap { diff --git a/lib/oto/data/command_data.dart b/lib/oto/data/command_data.dart index 48b0372..b817114 100644 --- a/lib/oto/data/command_data.dart +++ b/lib/oto/data/command_data.dart @@ -3,7 +3,7 @@ import 'package:dart_framework/utils/slack/slack_sender.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:dart_framework/core/app_data_manager.dart'; -import 'package:oto_cli/oto/command.dart'; +import 'package:oto_cli/oto/commands/command.dart'; import 'package:oto_cli/oto/data/pipeline_data.dart'; part 'command_data.g.dart'; @@ -38,10 +38,17 @@ class DataCommand { Map toJson() => _$DataCommandToJson(this); } +@JsonSerializable() +class DataParam { + DataParam(); + + late String? workspace; +} + /// ***************************** Command List ****************************/// //SimpleCommand @JsonSerializable() -class DataSimpleCommand { +class DataSimpleCommand extends DataParam { DataSimpleCommand(); late String message; @@ -53,11 +60,10 @@ class DataSimpleCommand { //AppDataCreator @JsonSerializable() -class DataAppDataCreator { +class DataAppDataCreator extends DataParam { DataAppDataCreator(); late SCMType scm; - late String? workspace; late String relativeAssetPath; late String returnVersion; late String returnHash; @@ -70,10 +76,9 @@ class DataAppDataCreator { //BuildDart @JsonSerializable() -class DataBuildDart { +class DataBuildDart extends DataParam { DataBuildDart(); - late String? targetPath; late bool? executeBuildRunner; factory DataBuildDart.fromJson(Map json) => @@ -111,7 +116,7 @@ class DataBuildDartCompile extends DataBuildDart { //BuildDotNet @JsonSerializable() -class DataBuildDotNet { +class DataBuildDotNet extends DataParam { DataBuildDotNet(); late String projectFile; @@ -123,12 +128,12 @@ class DataBuildDotNet { //BuildiOS @JsonSerializable() -class DataBuildiOS { +class DataBuildiOS extends DataParam { DataBuildiOS(); - late String workspacePath; late String scheme; late String? destination; + late String xcworkspaceFilePath; late bool? cleanPod; factory DataBuildiOS.fromJson(Map json) => @@ -138,10 +143,10 @@ class DataBuildiOS { //ArchiveiOS @JsonSerializable() -class DataArchiveiOS { +class DataArchiveiOS extends DataParam { DataArchiveiOS(); - late String workspacePath; + late String xcworkspaceFilePath; late String scheme; late String archivePath; @@ -152,7 +157,7 @@ class DataArchiveiOS { //ExportiOS @JsonSerializable() -class DataExportiOS { +class DataExportiOS extends DataParam { DataExportiOS(); late String archivePath; @@ -166,7 +171,7 @@ class DataExportiOS { //PublishiOS @JsonSerializable() -class DataPublishiOS { +class DataPublishiOS extends DataParam { DataPublishiOS(); late String bundleID; @@ -185,7 +190,7 @@ class DataPublishiOS { //ExecuteApp @JsonSerializable() -class DataExecuteApp { +class DataExecuteApp extends DataParam { DataExecuteApp(); late String executable; @@ -198,7 +203,7 @@ class DataExecuteApp { //Uploader @JsonSerializable() -class DataUploader { +class DataUploader extends DataParam { DataUploader(); late bool sftp; @@ -213,7 +218,7 @@ class DataUploader { Map toJson() => _$DataUploaderToJson(this); } -class DataFile { +class DataFile extends DataParam { DataFile(); late List? ignorePattern; } @@ -257,7 +262,7 @@ class DataRename extends DataFile { //Slack @JsonSerializable() -class DataSlack { +class DataSlack extends DataParam { DataSlack(); factory DataSlack.fromJson(Map json) => @@ -267,7 +272,7 @@ class DataSlack { //Slack Build @JsonSerializable() -class DataSlackBuild { +class DataSlackBuild extends DataParam { DataSlackBuild(); late String appName; @@ -284,7 +289,7 @@ class DataSlackBuild { //Zip @JsonSerializable() -class DataZip { +class DataZip extends DataParam { DataZip(); late String zipFile; @@ -297,10 +302,9 @@ class DataZip { //Shell @JsonSerializable() -class DataShell { +class DataShell extends DataParam { DataShell(); - late String? workspace; late String path; factory DataShell.fromJson(Map json) => @@ -310,10 +314,9 @@ class DataShell { //Git @JsonSerializable() -class DataGit { +class DataGit extends DataParam { DataGit(); - late String? workspace; late List commands; factory DataGit.fromJson(Map json) => @@ -323,10 +326,9 @@ class DataGit { //Git @JsonSerializable() -class DataGitRev { +class DataGitRev extends DataParam { DataGitRev(); - late String? workspace; @JsonKey(name: 'result-value') late String result_value; diff --git a/lib/oto/data/command_data.g.dart b/lib/oto/data/command_data.g.dart index c6470ec..f06dae0 100644 --- a/lib/oto/data/command_data.g.dart +++ b/lib/oto/data/command_data.g.dart @@ -55,18 +55,28 @@ const _$CommandTypeEnumMap = { CommandType.Shell: 'Shell', }; +DataParam _$DataParamFromJson(Map json) => + DataParam()..workspace = json['workspace'] as String?; + +Map _$DataParamToJson(DataParam instance) => { + 'workspace': instance.workspace, + }; + DataSimpleCommand _$DataSimpleCommandFromJson(Map json) => - DataSimpleCommand()..message = json['message'] as String; + DataSimpleCommand() + ..workspace = json['workspace'] as String? + ..message = json['message'] as String; Map _$DataSimpleCommandToJson(DataSimpleCommand instance) => { + 'workspace': instance.workspace, 'message': instance.message, }; DataAppDataCreator _$DataAppDataCreatorFromJson(Map json) => DataAppDataCreator() - ..scm = $enumDecode(_$SCMTypeEnumMap, json['scm']) ..workspace = json['workspace'] as String? + ..scm = $enumDecode(_$SCMTypeEnumMap, json['scm']) ..relativeAssetPath = json['relativeAssetPath'] as String ..returnVersion = json['returnVersion'] as String ..returnHash = json['returnHash'] as String @@ -74,8 +84,8 @@ DataAppDataCreator _$DataAppDataCreatorFromJson(Map json) => Map _$DataAppDataCreatorToJson(DataAppDataCreator instance) => { - 'scm': _$SCMTypeEnumMap[instance.scm]!, 'workspace': instance.workspace, + 'scm': _$SCMTypeEnumMap[instance.scm]!, 'relativeAssetPath': instance.relativeAssetPath, 'returnVersion': instance.returnVersion, 'returnHash': instance.returnHash, @@ -89,25 +99,25 @@ const _$SCMTypeEnumMap = { DataBuildDart _$DataBuildDartFromJson(Map json) => DataBuildDart() - ..targetPath = json['targetPath'] as String? + ..workspace = json['workspace'] as String? ..executeBuildRunner = json['executeBuildRunner'] as bool?; Map _$DataBuildDartToJson(DataBuildDart instance) => { - 'targetPath': instance.targetPath, + 'workspace': instance.workspace, 'executeBuildRunner': instance.executeBuildRunner, }; DataBuildFlutter _$DataBuildFlutterFromJson(Map json) => DataBuildFlutter() - ..targetPath = json['targetPath'] as String? + ..workspace = json['workspace'] as String? ..executeBuildRunner = json['executeBuildRunner'] as bool? ..platform = json['platform'] as String ..additional = json['additional'] as String?; Map _$DataBuildFlutterToJson(DataBuildFlutter instance) => { - 'targetPath': instance.targetPath, + 'workspace': instance.workspace, 'executeBuildRunner': instance.executeBuildRunner, 'platform': instance.platform, 'additional': instance.additional, @@ -116,7 +126,7 @@ Map _$DataBuildFlutterToJson(DataBuildFlutter instance) => DataBuildDartCompile _$DataBuildDartCompileFromJson( Map json) => DataBuildDartCompile() - ..targetPath = json['targetPath'] as String? + ..workspace = json['workspace'] as String? ..executeBuildRunner = json['executeBuildRunner'] as bool? ..targetDartFile = json['targetDartFile'] as String? ..buildFileName = json['buildFileName'] as String?; @@ -124,55 +134,64 @@ DataBuildDartCompile _$DataBuildDartCompileFromJson( Map _$DataBuildDartCompileToJson( DataBuildDartCompile instance) => { - 'targetPath': instance.targetPath, + 'workspace': instance.workspace, 'executeBuildRunner': instance.executeBuildRunner, 'targetDartFile': instance.targetDartFile, 'buildFileName': instance.buildFileName, }; DataBuildDotNet _$DataBuildDotNetFromJson(Map json) => - DataBuildDotNet()..projectFile = json['projectFile'] as String; + DataBuildDotNet() + ..workspace = json['workspace'] as String? + ..projectFile = json['projectFile'] as String; Map _$DataBuildDotNetToJson(DataBuildDotNet instance) => { + 'workspace': instance.workspace, 'projectFile': instance.projectFile, }; DataBuildiOS _$DataBuildiOSFromJson(Map json) => DataBuildiOS() - ..workspacePath = json['workspacePath'] as String + ..workspace = json['workspace'] as String? ..scheme = json['scheme'] as String ..destination = json['destination'] as String? + ..xcworkspaceFilePath = json['xcworkspaceFilePath'] as String ..cleanPod = json['cleanPod'] as bool?; Map _$DataBuildiOSToJson(DataBuildiOS instance) => { - 'workspacePath': instance.workspacePath, + 'workspace': instance.workspace, 'scheme': instance.scheme, 'destination': instance.destination, + 'xcworkspaceFilePath': instance.xcworkspaceFilePath, 'cleanPod': instance.cleanPod, }; DataArchiveiOS _$DataArchiveiOSFromJson(Map json) => DataArchiveiOS() - ..workspacePath = json['workspacePath'] as String + ..workspace = json['workspace'] as String? + ..xcworkspaceFilePath = json['xcworkspaceFilePath'] as String ..scheme = json['scheme'] as String ..archivePath = json['archivePath'] as String; Map _$DataArchiveiOSToJson(DataArchiveiOS instance) => { - 'workspacePath': instance.workspacePath, + 'workspace': instance.workspace, + 'xcworkspaceFilePath': instance.xcworkspaceFilePath, 'scheme': instance.scheme, 'archivePath': instance.archivePath, }; DataExportiOS _$DataExportiOSFromJson(Map json) => DataExportiOS() + ..workspace = json['workspace'] as String? ..archivePath = json['archivePath'] as String ..exportOptionPlistPath = json['exportOptionPlistPath'] as String ..exportPath = json['exportPath'] as String; Map _$DataExportiOSToJson(DataExportiOS instance) => { + 'workspace': instance.workspace, 'archivePath': instance.archivePath, 'exportOptionPlistPath': instance.exportOptionPlistPath, 'exportPath': instance.exportPath, @@ -180,6 +199,7 @@ Map _$DataExportiOSToJson(DataExportiOS instance) => DataPublishiOS _$DataPublishiOSFromJson(Map json) => DataPublishiOS() + ..workspace = json['workspace'] as String? ..bundleID = json['bundleID'] as String ..version = json['version'] as String ..appName = json['appName'] as String @@ -191,6 +211,7 @@ DataPublishiOS _$DataPublishiOSFromJson(Map json) => Map _$DataPublishiOSToJson(DataPublishiOS instance) => { + 'workspace': instance.workspace, 'bundleID': instance.bundleID, 'version': instance.version, 'appName': instance.appName, @@ -203,16 +224,19 @@ Map _$DataPublishiOSToJson(DataPublishiOS instance) => DataExecuteApp _$DataExecuteAppFromJson(Map json) => DataExecuteApp() + ..workspace = json['workspace'] as String? ..executable = json['executable'] as String ..desktopServicePath = json['desktopServicePath'] as String; Map _$DataExecuteAppToJson(DataExecuteApp instance) => { + 'workspace': instance.workspace, 'executable': instance.executable, 'desktopServicePath': instance.desktopServicePath, }; DataUploader _$DataUploaderFromJson(Map json) => DataUploader() + ..workspace = json['workspace'] as String? ..sftp = json['sftp'] as bool ..port = json['port'] as int ..host = json['host'] as String @@ -222,6 +246,7 @@ DataUploader _$DataUploaderFromJson(Map json) => DataUploader() Map _$DataUploaderToJson(DataUploader instance) => { + 'workspace': instance.workspace, 'sftp': instance.sftp, 'port': instance.port, 'host': instance.host, @@ -231,6 +256,7 @@ Map _$DataUploaderToJson(DataUploader instance) => }; DataCopy _$DataCopyFromJson(Map json) => DataCopy() + ..workspace = json['workspace'] as String? ..ignorePattern = (json['ignorePattern'] as List?) ?.map((e) => e as String) .toList() @@ -238,12 +264,14 @@ DataCopy _$DataCopyFromJson(Map json) => DataCopy() ..copyMap = Map.from(json['copyMap'] as Map); Map _$DataCopyToJson(DataCopy instance) => { + 'workspace': instance.workspace, 'ignorePattern': instance.ignorePattern, 'isMove': instance.isMove, 'copyMap': instance.copyMap, }; DataDelete _$DataDeleteFromJson(Map json) => DataDelete() + ..workspace = json['workspace'] as String? ..ignorePattern = (json['ignorePattern'] as List?) ?.map((e) => e as String) .toList() @@ -251,11 +279,13 @@ DataDelete _$DataDeleteFromJson(Map json) => DataDelete() Map _$DataDeleteToJson(DataDelete instance) => { + 'workspace': instance.workspace, 'ignorePattern': instance.ignorePattern, 'list': instance.list, }; DataRename _$DataRenameFromJson(Map json) => DataRename() + ..workspace = json['workspace'] as String? ..ignorePattern = (json['ignorePattern'] as List?) ?.map((e) => e as String) .toList() @@ -263,17 +293,21 @@ DataRename _$DataRenameFromJson(Map json) => DataRename() Map _$DataRenameToJson(DataRename instance) => { + 'workspace': instance.workspace, 'ignorePattern': instance.ignorePattern, 'renameMap': instance.renameMap, }; -DataSlack _$DataSlackFromJson(Map json) => DataSlack(); +DataSlack _$DataSlackFromJson(Map json) => + DataSlack()..workspace = json['workspace'] as String?; -Map _$DataSlackToJson(DataSlack instance) => - {}; +Map _$DataSlackToJson(DataSlack instance) => { + 'workspace': instance.workspace, + }; DataSlackBuild _$DataSlackBuildFromJson(Map json) => DataSlackBuild() + ..workspace = json['workspace'] as String? ..appName = json['appName'] as String ..type = $enumDecode(_$SlackBuildTypeEnumMap, json['type']) ..color = json['color'] as String @@ -283,6 +317,7 @@ DataSlackBuild _$DataSlackBuildFromJson(Map json) => Map _$DataSlackBuildToJson(DataSlackBuild instance) => { + 'workspace': instance.workspace, 'appName': instance.appName, 'type': _$SlackBuildTypeEnumMap[instance.type]!, 'color': instance.color, @@ -300,11 +335,13 @@ const _$SlackBuildTypeEnumMap = { }; DataZip _$DataZipFromJson(Map json) => DataZip() + ..workspace = json['workspace'] as String? ..zipFile = json['zipFile'] as String ..zipList = (json['zipList'] as List).map((e) => e as String).toList(); Map _$DataZipToJson(DataZip instance) => { + 'workspace': instance.workspace, 'zipFile': instance.zipFile, 'zipList': instance.zipList, }; diff --git a/lib/oto/data/pipeline_data.dart b/lib/oto/data/pipeline_data.dart index a155a4e..e487a08 100644 --- a/lib/oto/data/pipeline_data.dart +++ b/lib/oto/data/pipeline_data.dart @@ -1,7 +1,7 @@ // ignore_for_file: non_constant_identifier_names import 'package:json_annotation/json_annotation.dart'; -import 'package:oto_cli/oto/application.dart'; +import 'package:oto_cli/oto/pipeline/pipeline.dart'; part 'pipeline_data.g.dart'; /// ***************************** Base Data ****************************/// diff --git a/lib/oto/pipeline/pipeline.dart b/lib/oto/pipeline/pipeline.dart new file mode 100644 index 0000000..9e717eb --- /dev/null +++ b/lib/oto/pipeline/pipeline.dart @@ -0,0 +1,131 @@ +//####################### Pipeline #######################// +import 'package:dart_framework/utils/system_util.dart'; +import 'package:oto_cli/cli/cli.dart'; +import 'package:oto_cli/oto/application.dart'; +import 'package:oto_cli/oto/commands/command.dart'; +import 'package:oto_cli/oto/data/command_data.dart'; +import 'package:oto_cli/oto/data/pipeline_data.dart'; + +class Pipeline { + List _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 exeList = []; + Pipeline? get pipeline { + if (exeList.isNotEmpty) { + return Pipeline(exeList); + } else { + return null; + } + } +} + +abstract class PipelineExecutor { + //set & validate data + PipelineValidateResult initialize(Map set); + Future execute(); + + PipelineValidateResult validateTasks(List? list) { + var result = PipelineValidateResult(); + if (list != null) { + return Application.instance.pipelineInitialize(list); + } + return result; + } +} + +class PipelineExe extends PipelineExecutor { + late String targetCommandID; + @override + PipelineValidateResult initialize(Map 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 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 extends PipelineExe { + @override + Future execute() async { + executeAsync(await commandData); + return simpleFuture; + } + + void executeAsync(DataCommand data) async { + await Command.byType(data.command).execute(data); + } +} + +class PipelineIf extends PipelineExecutor { + late DataIf _data; + late Pipeline? _pipelineTrue; + late Pipeline? _pipelineFalse; + + @override + PipelineValidateResult initialize(Map 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; + } +}