스케쥴러 1차 완료

This commit is contained in:
Toki 2024-12-26 23:35:57 +09:00
parent 1a936f8059
commit 45a6cd748a
40 changed files with 285 additions and 155 deletions

9
.vscode/launch.json vendored
View file

@ -66,7 +66,14 @@
"type": "dart",
"program": "./bin/main.dart",
"args": ["exe", "-f", "./slack_test.yaml"]
},
},
{
"name": "exe scheduler test",
"request": "launch",
"type": "dart",
"program": "./bin/main.dart",
"args": ["exe", "-f", "./assets/scheduler.yaml"]
},
{
"name": "test",
"request": "launch",

View file

@ -2,20 +2,37 @@
scheduler:
alias: test
# cron: '* * * * *'
interval: 3000 # ms
interval: 60000 # ms
enableLog: true # (Optional) default: false
property:
workspace: .
workspace: /Users/toki/works/oto_cli
pipeline:
id: main
workflow:
- exe: print
- exe: diff
- if:
condition-bool: <!property.isDiff> == true
on-true:
- exe: shell
commands:
### Print
- command: Print
id: print
- command: FileDiffCheck
id: diff
param:
message: test
paths:
- /Users/toki/works/oto_cli/lib/oto/data/command_data.dart
- /Users/toki/works/oto_cli/lib/oto/data/jenkins_data.dart
- /Users/toki/works/oto_cli/lib/oto/data/jira_data.dart
- /Users/toki/works/oto_cli/lib/oto/data/pipeline_data.dart
setDiff: <@property.isDiff>
- command: Shell
id: shell
param:
commands:
- flutter pub run build_runner build

View file

@ -1,7 +1,7 @@
---
scheduler:
alias: test2
cron: '*/5 * * * *'
cron: '0 */2 * * *'
enableLog: true # (Optional) default: false
property:

View file

@ -101,6 +101,11 @@ class CLI {
}
}
static Function(String)? _logFunc;
static set logFunc(Function(String) value) {
_logFunc = value;
}
CLI._privateConstructor();
static final CLI _instance = CLI._privateConstructor();
static CLI get current => _instance;
@ -121,13 +126,17 @@ class CLI {
static Future print(List<String> printList,
{Color? color, Color? background}) async {
if (color != null || background != null) {
for (var i = 0; i < printList.length; ++i) {
printList[i] =
CLI.style(printList[i], color: color, background: background);
if(_logFunc == null) {
if (color != null || background != null) {
for (var i = 0; i < printList.length; ++i) {
printList[i] =
CLI.style(printList[i], color: color, background: background);
}
}
await printer.printCLI(printList);
} else {
_logFunc!(printList.join('\n'));
}
await printer.printCLI(printList);
return simpleFuture;
}

View file

@ -9,10 +9,12 @@ import 'package:oto_cli/cli/cli.dart';
import 'package:oto_cli/cli/commands/command_base.dart';
import 'package:dart_framework/utils/system_util.dart';
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/data/command_data.dart';
class CommandExe extends CommandBase {
late IsolateHandler _handler;
bool _complete = false;
bool _ready = false;
@override
Map<String, List<String>> get arguments => {
@ -51,11 +53,22 @@ class CommandExe extends CommandBase {
return simpleFuture;
}
Future executeScheduler(DataBuild build, bool logEnable, String logPath) async {
_handler = IsolateManager.create(IsolateExe.scheduler(build, logEnable, logPath));
await isComplete();
_handler.exit();
return simpleFuture;
}
Future isComplete() async {
_ready = false;
_complete = false;
_handler.addEventListener(IsolateEvent.ready, (data) => _ready = true);
_handler.addListener('complete', (data) => _complete = true);
while (!_complete) {
while (!(_complete && _ready)) {
await Future.delayed(const Duration(milliseconds: 200));
}
return simpleFuture;
}
Future startYaml(String target) async {
@ -80,15 +93,26 @@ class CommandExe extends CommandBase {
}
class IsolateExe extends IsolateBase {
final BuildType _buildType;
late BuildType _buildType;
bool _logEnable = true;
DataBuild? _build = null;
String? _yamleContent = null;
IsolateExe(this._buildType, {String? yamlContent}) {
String? _logPath = null;
IsolateExe(this._buildType, {String? yamlContent, DataBuild? build, bool logEnable = true, String? logPath}) {
_yamleContent = yamlContent;
_build = build;
_logEnable = logEnable;
_logPath = logPath;
}
factory IsolateExe.scheduler(DataBuild build, bool logEnable, String logPath) {
return IsolateExe(BuildType.scheduler, build: build, logEnable: logEnable, logPath: logPath);
}
@override
void onReady(Object? initData) async {
await Application.instance.build(_buildType, yamlContent: _yamleContent);
await Application.instance.build(_buildType, yamlContent: _yamleContent, buildData: _build, logEnable: _logEnable, logPath: _logPath);
send(IsoMessege('complete'));
}
}

View file

@ -7,8 +7,10 @@ import 'package:dart_framework/platform/isolate_manager.dart';
import 'package:dart_framework/utils/string_util.dart';
import 'package:dart_framework/utils/system_util.dart';
import 'package:file_hasher/file_hasher.dart';
import 'package:oto_cli/cli/commands/command_exe.dart';
import 'package:oto_cli/cli/commands/scheduler/scheduler_interval.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';
class IsolateScheduler extends IsolateBase {
@ -26,6 +28,7 @@ class IsolateScheduler extends IsolateBase {
String? cronExpress;
late DataBuild build;
SchedulerInterval? schedulerInterval;
CommandExe commandExe = CommandExe();
Cron? cron;
int nextStartTime = 0;
@ -54,7 +57,7 @@ class IsolateScheduler extends IsolateBase {
//============ Validate yaml format ============//
try {
build = DataBuild.fromJson(map!);
} on Exception catch(e, stacktace) {
} on Exception {
onError('Failed to parse yaml file.');
return;
}
@ -73,7 +76,7 @@ class IsolateScheduler extends IsolateBase {
try {
Schedule.parse(scheduler.cron!);
cronExpress = scheduler.cron!;
} on Error catch(e, stacktace) {
} on Error {
onError("Cron express '${build.scheduler!.cron}' is not a suitable format.");
return;
}
@ -82,6 +85,10 @@ class IsolateScheduler extends IsolateBase {
if(scheduler.interval != null) {
interval = scheduler.interval!;
}
logEnable = scheduler.enableLog == null ? false : scheduler.enableLog!;
schedulerInterval?.activate = false;
}
//============ execute cron/interval ============//
@ -101,9 +108,6 @@ class IsolateScheduler extends IsolateBase {
} else {
//Use interval
if(updated) {
if(schedulerInterval != null) {
schedulerInterval!.activate = false;
}
schedulerInterval = SchedulerInterval(interval!, build, execute);
}
}
@ -117,13 +121,15 @@ class IsolateScheduler extends IsolateBase {
}
Future execute(DataBuild data) async {
send(IsoMessege('log', data: "Scheduler '$alias' has started."));
notProgress = false;
logFile = File('$logsPath/${alias}_${getDate()}_${getTime().replaceAll(':', '')}_[$pid].txt');
if(data.scheduler!.enableLog ?? false) {
logFile = File('$logsPath/${alias}_${getDate()}_${getTime().replaceAll(':', '')}_[$pid].txt');
log('Start process on pid [$pid]');
}
await Future.delayed(Duration(seconds: 1)); //To-do: delete test, exe task
await commandExe.executeScheduler(data, logEnable, logFile.path);
notProgress = true;
send(IsoMessege('log', data: "Scheduler '$alias' is done."));
return simpleFuture;
}

View file

@ -284,9 +284,10 @@ class SchedulerManager {
for(var alias in _schedulers) {
var enable = settings.containsKey(alias) ? settings[alias]!.enable : true;
if(!_map.containsKey(alias) && enable) {
_log('Schduler started: $alias');
_log('Schduler found: $alias');
var handler = IsolateManager.create(IsolateScheduler({'alias': alias, 'root': _schedulerPath, 'logs': _logsPath}));
handler.addListener('terminated', _onTerminated );
handler.addListener('log', _onLog);
_map[alias] = handler;
}
if(_map.containsKey(alias) && !enable) {
@ -334,6 +335,10 @@ class SchedulerManager {
await _checkTerminate();
}
void _onLog(Object? data) {
_log(data as String);
}
void _log(String message) {
logFile.writeAsStringSync('[${getDates()}] $message\n', mode: FileMode.append, flush: true);
}

View file

@ -3,10 +3,13 @@
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';
@ -14,7 +17,7 @@ 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 }
enum BuildType { jenkins, test, file, scheduler }
enum CommandState { ready, progress, complete }
@ -33,6 +36,12 @@ class Application {
}
}
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(),
@ -45,31 +54,40 @@ class Application {
Map<String, DataCommand> dataCommandMap = {};
late Pipeline pipeline;
late BuildType _buildType;
get buildType
{
get buildType {
return _buildType;
}
Future<void> build(BuildType buildType, {String? yamlContent}) async {
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 {
var composer = _mapComposer[buildType]!();
await composer.compose(yamlContent, printBuildStep);
commonData = composer.commonData;
DataBuild? build =
DataBuild.fromJson(getMapFromYamlA(composer.buildYaml)!);
await CLI.println(
'********************************* Build Data *************************************',
color: Color.magenta);
print(composer.buildYaml);
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'))
{
if(!property.containsKey('workspace')) {
property['workspace'] = current;
}
property = Command.replaceAllTagsMap(property, replace: true);
@ -106,19 +124,35 @@ class Application {
exit(10);
}
await printBuildStep('Build Successfully Complete', Color.cyan);
exit(0);
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'));
var data = await ProcessExecutor.start(StringBuffer('chcp 65001'), logHandler: logWithType);
var exitCode = await data.process.exitCode;
print('Set Korean: ${exitCode == 0}');
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) {
@ -134,7 +168,7 @@ class Application {
Future printBuildStep(String name, Color? color) async {
var message =
'''************************************************************************************
'''$enter************************************************************************************
* $name
************************************************************************************''';
await CLI.printString(message, color: color ?? Color.green);

View file

@ -1,5 +1,6 @@
import 'package:dart_framework/platform/process.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';
@ -17,7 +18,7 @@ class AwsCli extends Command {
for (String arg in args) {
shell.write(' $arg');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:dart_framework/platform/process.dart';
import 'package:dart_framework/utils/system_util.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';
@ -27,7 +28,7 @@ class BuildDart extends Command {
}
var process = await ProcessExecutor.start(await appendShell(shell, command),
printStderr: false);
printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:dart_framework/platform/process.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';
@ -15,7 +16,7 @@ class BuildDotNet extends Command {
' && MSBuild ${data.projectFile} /t:build /p:Configuration=Release;Platform=x86');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/commands/build/build_flutter.dart';
import 'package:oto_cli/oto/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -75,7 +76,7 @@ class BuildiOS extends Command {
shell.write(
' && xcodebuild $project -scheme ${data.scheme} -destination $destination$configuration$derivedDataPath$settings clean build');
var process = await ProcessExecutor.start(shell, printStderr: false);
var process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
var exitCode = await process.process.exitCode;
var success = exitCode == 0;
if (success) {
@ -107,7 +108,7 @@ class CodeSign extends Command {
' && codesign --deep --force --verify --verbose --timestamp --options runtime$entitlement --sign "${data.certificationName}" "${data.appPath}"');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -124,7 +125,7 @@ class CodeSignVerify extends Command {
shell.write(' && spctl --assess --verbose "${data.appPath}"');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -149,7 +150,7 @@ class ProductBuild extends Command {
' && productsign --sign "${data.installCertificationName}" "${data.unsignedResultPath}" "${data.signedResultPath}"');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -188,7 +189,7 @@ class Notarize extends Command {
}
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -209,7 +210,7 @@ class ArchiveiOS extends Command {
'xcodebuild -workspace $workspacePath -scheme ${data.scheme} -destination $destination -archivePath $archivePath archive');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -231,7 +232,7 @@ class ExportiOS extends Command {
'xcodebuild -exportArchive -archivePath $archivePath -exportPath $exportPath -exportOptionsPlist $exportOptionPlistPath');
var process = await ProcessExecutor.start(shell,
workspace: workspace, printStderr: false);
workspace: workspace, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -3,6 +3,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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -24,7 +25,7 @@ class BuildMSBuild extends Command {
shell.write(' && msbuild $param');
var process = await ProcessExecutor.start(shell,
decoder: SystemEncoding().decoder, printStderr: false);
decoder: SystemEncoding().decoder, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
}

View file

@ -237,16 +237,16 @@ abstract class Command {
// await CLI.println('[Return] $key : $value', color: Color.yellowStrong);
if(showPrint ?? true) {
if(value is List) {
print('[Return] $key :\n');
Application.log('[Return] $key :\n');
var index = 0;
var length = value.length.toString().length;
for(var item in value) {
var indexStr = index.toString().padLeft(length);
print('$indexStr - $item');
Application.log('$indexStr - $item');
index++;
}
} else {
print('[Return] $key : $value');
Application.log('[Return] $key : $value');
}
}
}
@ -263,7 +263,7 @@ abstract class Command {
data = map[param];
setted = true;
} else {
print('"$value" is not exist in property');
Application.log('"$value" is not exist in property');
data = null;
setted = true;
}
@ -457,7 +457,7 @@ abstract class Command {
if (passExitCodesMerge.contains(exitCode)) {
return simpleFuture;
} else {
print('Exit Code: $exitCode');
Application.log('Exit Code: $exitCode');
var data = ExceptionData();
data.phase = command.name;
data.message = errorMessage;
@ -477,7 +477,7 @@ abstract class Command {
class SimpleCommand extends Command {
@override
Future execute(DataCommand command) async {
print(command.param);
Application.log(command.param);
return simpleFuture;
}
}

View file

@ -1,5 +1,6 @@
import 'package:dart_framework/platform/process.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';
@ -17,7 +18,7 @@ class Docker extends Command {
for (String arg in args) {
shell.write(' $arg');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -2,6 +2,7 @@ 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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -52,7 +53,7 @@ class Copy extends Command {
var type = Path.getType(start);
if (FileType.none == type) {
print('[FileNotFound] - $start is not exist');
throw ArgumentError('[FileNotFound] - $start is not exist');
} else {
await Path.copy(start, dest, FileType.directory == type,
ignorePattern: data.ignorePattern,
@ -63,15 +64,14 @@ class Copy extends Command {
}
if (ignoredList.isNotEmpty) {
print('==================== Ignored list ====================');
Application.log('==================== Ignored list ====================');
for (var element in ignoredList) {
print(element);
Application.log(element);
}
print('======================================================');
Application.log('======================================================');
}
} on Exception catch (e) {
print('Copy General Exception: $e');
rethrow;
throw Exception('Copy General Exception: $e');
}
return complete(0, command);
}

View file

@ -2,6 +2,7 @@ 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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -34,23 +35,23 @@ class Delete extends Command {
var file = File(path);
if(file.existsSync()) {
await file.delete(recursive: true);
print('Deleted File: ${file.path}');
Application.log('Deleted File: ${file.path}');
}
var dir = Directory(path);
if(dir.existsSync()) {
await dir.delete(recursive: true);
print('Deleted Directory: ${dir.path}');
Application.log('Deleted Directory: ${dir.path}');
}
}
}
}
if (ignoredList.isNotEmpty) {
print('==================== Ignored list ====================');
Application.log('==================== Ignored list ====================');
for (var element in ignoredList) {
print(element);
Application.log(element);
}
print('======================================================');
Application.log('======================================================');
}
} on Exception {
rethrow;

View file

@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:io';
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -12,7 +13,7 @@ class DirectoryCreate extends Command {
var dir = Directory(data.path);
if(!dir.existsSync()) {
await dir.create(recursive: true);
print('Directory Created: ${data.path}');
Application.log('Directory Created: ${data.path}');
}
return complete(0, command);
}

View file

@ -6,6 +6,7 @@ import 'dart:io';
import 'package:dart_framework/utils/system_util.dart';
import 'package:file_hasher/file_hasher.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:convert/convert.dart';
@ -29,7 +30,7 @@ class FileDiffCheck extends Command {
}
var cacheFile = File('${cacheFolder.path}/$fileName');
var paths = data.paths;
print('Cache Path: ${cacheFile.path}, Exist: ${cacheFile.existsSync()}');
Application.log('Cache Path: ${cacheFile.path}, Exist: ${cacheFile.existsSync()}');
if (paths.isEmpty) {
throw Exception('The paths is Empty.');

View file

@ -3,6 +3,7 @@
import 'dart:async';
import 'dart:io';
import 'package:oto_cli/oto/application.dart';
import 'package:path/path.dart' as path;
import 'package:dart_framework/utils/path.dart';
import 'package:oto_cli/oto/commands/command.dart';
@ -26,10 +27,10 @@ class Rename extends Command {
await File(start).rename(newPath);
}
print('Rename: $start --> ${path.basename(newPath)}');
Application.log('Rename: $start --> ${path.basename(newPath)}');
}
} on Exception catch (e) {
print('Copy General Exception: $e');
Application.log('Copy General Exception: $e');
}
return complete(0, command);
}

View file

@ -1,3 +1,4 @@
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:dart_framework/platform/process.dart';
@ -6,7 +7,7 @@ class Git extends Command {
@override
Future execute(DataCommand command) async {
var data = DataGit.fromJson(getParam(command));
print(workspace);
Application.log(workspace);
var shell = StringBuffer(getCDPath(workspace));
var commands = data.commands;
@ -14,7 +15,7 @@ class Git extends Command {
shell.write(' && git ${Command.getPathNormal(item)}');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
}
@ -35,7 +36,7 @@ class GitCommit extends Command {
shell.write(' && git commit -am "$message"');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
}
@ -53,7 +54,7 @@ class GitPush extends Command {
shell.write(' && git push origin ${data.branch!}');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command,
passExitCodes: [1 /*Everything up-to-date*/]);
}
@ -70,7 +71,7 @@ class GitCheckout extends Git {
shell.write(' && git checkout origin/$branch');
shell.write(' && git checkout -b $branch');
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
var exitCode = await process.process.exitCode;
var ignores = [128 /*Already exists*/];
if (ignores.contains(exitCode)) {
@ -85,7 +86,7 @@ class GitCheckout extends Git {
shell.write(' && git pull origin $branch');
}
process = await ProcessExecutor.start(shell);
process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
exitCode = await process.process.exitCode;
}
@ -101,7 +102,7 @@ class GitCount extends Command {
var shell = StringBuffer(getCDPath(workspace));
shell.write(' && git rev-list --all HEAD --all --count');
var process = await ProcessExecutor.start(shell, printStderr: false);
var process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
var number = int.parse(process.stdoutArr.last);
await setProperty(data.setValue, number);
@ -119,7 +120,7 @@ class GitRev extends Command {
var target = data.branch ?? 'HEAD';
shell.write(' && git fetch origin');
shell.write(' && git rev-parse $target');
var process = await ProcessExecutor.start(shell, printStderr: false);
var process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
var hash = process.stdoutArr.last;
await setProperty(data.setValue, hash);
@ -137,7 +138,7 @@ class GitReset extends Command {
var force = data.force! ? 'f' : '';
shell.write(' && git reset --hard');
shell.write(' && git clean -${force}d');
var process = await ProcessExecutor.start(shell, printStderr: false);
var process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -176,12 +177,12 @@ class GitStashApply extends Command {
data.delete == null ? " pop" : (data.delete! ? " pop" : " apply");
if (data.message == null) {
shell.write(' && git stash$apply');
process = await ProcessExecutor.start(shell, printStderr: false);
process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
} else {
shell.write(' && git stash list');
var result = await ProcessExecutor.run(shell);
var exist = false;
print(result.stdout);
Application.log(result.stdout);
shell = StringBuffer(getCDPath(workspace));
if (result.exitCode == 0) {
var arr = result.stdout.toString().split('\n');
@ -200,7 +201,7 @@ class GitStashApply extends Command {
}
if (exist) {
process = await ProcessExecutor.start(shell, printStderr: false);
process = await ProcessExecutor.start(shell, printStderr: false, logHandler: Application.logWithType);
} else {
return await complete(0, command);
}

View file

@ -3,6 +3,7 @@
import 'dart:convert';
import 'dart:io';
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:dart_framework/platform/process.dart';
@ -18,7 +19,7 @@ class GitHub extends Command {
shell.write(' && gh ${Command.getPathNormal(item)}');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
@ -32,7 +33,7 @@ class GitHubPullRequestCreate extends Command {
var shell = StringBuffer(getCDPath(workspace));
shell.write(' && gh pr create --title "${data.title}" --body "${data.body}" -B ${data.branch}');
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
var passExitCodes = [0, 1 /*already exists*/];
var exitCode = await process.process.exitCode;
if(passExitCodes.contains(exitCode))
@ -77,7 +78,7 @@ class GitHubPullRequestList extends Command {
shell.write(' && gh pr list --json $keysString');
var decorder = Platform.isWindows ? SystemEncoding().decoder : utf8.decoder;
var process = await ProcessExecutor.start(shell, decoder: decorder);
var process = await ProcessExecutor.start(shell, decoder: decorder, logHandler: Application.logWithType);
var exitCode = await process.process.exitCode;
if(exitCode == 0)
@ -124,7 +125,7 @@ class GitHubPullRequestClose extends Command {
shell.write(' && gh pr close ${data.number}');
var decorder = Platform.isWindows ? SystemEncoding().decoder : utf8.decoder;
var process = await ProcessExecutor.start(shell, decoder: decorder);
var process = await ProcessExecutor.start(shell, decoder: decorder, logHandler: Application.logWithType);
return await completeProcess(process, command);
}
}

View file

@ -1,5 +1,6 @@
import 'package:dart_framework/platform/process.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';
@ -16,7 +17,7 @@ class Gradle extends Command {
for (String arg in args) {
shell.write(' $arg');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -5,6 +5,7 @@ import 'dart:convert';
import 'package:dart_framework/utils/slack/slack_data.dart';
import 'package:dart_framework/utils/system_util.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:http/http.dart' as http;
@ -38,12 +39,12 @@ class Jira extends Command {
'Authorization': 'Basic $base64'
};
var url = 'https://${data.domain}/rest/api/3/issue/${data.issue}';
print(url);
Application.log(url);
var response = await http.get(Uri.parse(url), headers: header);
if(response.statusCode < 300 && response.statusCode >= 200)
{
print(response.body);
Application.log(response.body);
var issue = DataJiraIssue.fromJson(jsonDecode(response.body));
var targetUser = issue.fields?.assignee?.emailAddress;
if(targetUser != null)
@ -108,7 +109,7 @@ class Jira extends Command {
}
}
} else {
print('User not found');
Application.log('User not found');
}
}

View file

@ -2,6 +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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -26,7 +27,7 @@ class ProcessRun extends Command {
var data = DataProcessRun.fromJson(getParam(command));
var exe = data.executable;
print('Process Start: $exe');
Application.log('Process Start: $exe');
var shell = StringBuffer(getCDPath(data.workspace!));
var dontKillme =
Platform.isWindows ? 'SET BUILD_ID=dontKillMe' : 'BUILD_ID=dontKillMe';
@ -48,9 +49,9 @@ class ProcessKill extends Command {
Future execute(DataCommand command) async {
var data = DataProcessKill.fromJson(getParam(command));
if (Process.killPid(int.parse(data.pid))) {
print('Process killed');
Application.log('Process killed');
} else {
print('Process not exist');
Application.log('Process not exist');
}
return complete(0, command);
}

View file

@ -1,3 +1,4 @@
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:dart_framework/platform/process.dart';
@ -13,7 +14,7 @@ class Protobuf extends Command {
shell.write(' && protoc ${Command.getPathNormal(item)}');
}
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -1,6 +1,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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -15,10 +16,10 @@ class Shell extends Command {
}
if(data.setMessage == null) {
var process = await ProcessExecutor.start(shell);
var process = await ProcessExecutor.start(shell, workspace: workspace, logHandler: Application.logWithType);
return await completeProcess(process, command);
} else {
var process = await ProcessExecutor.run(shell);
var process = await ProcessExecutor.run(shell, workspace: workspace, logHandler: Application.logWithType);
var str = process.stdout.toString();
var length = str.length;
str = str.substring(0, length - 1);
@ -39,7 +40,7 @@ class ShellFile extends Command {
} else {
shell.writeln('source $path');
}
var process = await ProcessExecutor.start(shell, workspace: workspace);
var process = await ProcessExecutor.start(shell, workspace: workspace, logHandler: Application.logWithType);
return await completeProcess(process, command);
}

View file

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:ftpconnect/ftpconnect.dart';
// ignore: implementation_imports
import 'package:dart_framework/utils/path.dart';
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/commands/command.dart';
class FTP {
@ -40,8 +41,8 @@ class FTP {
} on Exception catch (e) {
var code = e.hashCode;
var type = e.runtimeType;
print('========================= Connect Failed!');
print('$code = $type');
Application.log('========================= Connect Failed!');
Application.log('$code = $type');
await Future.delayed(Duration(seconds: 1));
}
}
@ -184,7 +185,7 @@ class FTP {
count++;
var remotePath = '$path/$name';
map[remotePath] = type!;
// print('$count = $type = $remotePath');
// Application.log('$count = $type = $remotePath');
}
}
} finally {}
@ -217,7 +218,7 @@ class FTP {
} else {
await _ftp!.deleteFile(name);
}
print('Deleted: $item');
Application.log('Deleted: $item');
}
}
} finally {
@ -233,11 +234,11 @@ class FTP {
await _ftp!.changeDirectory(parent!);
if (await _ftp!.checkFolderExistence(name)) {
c.complete(false);
print('Create failed: Already exist file or folder');
Application.log('Create failed: Already exist file or folder');
} else {
await _ftp!.makeDirectory(name);
c.complete(true);
print('Created Folder: $path');
Application.log('Created Folder: $path');
}
} finally {}
return c.future;
@ -289,7 +290,7 @@ class SFTP extends FTP {
'-r',
local,
'$_user@$_host:$remote'
]).then((ProcessResult results) => print(results.stdout));
]).then((ProcessResult results) => Application.log(results.stdout));
} else {
type = '[F]';
await Process.run('sshpass', [
@ -300,9 +301,9 @@ class SFTP extends FTP {
'$_port',
local,
'$_user@$_host:$remote'
]).then((ProcessResult results) => print(results.stdout));
]).then((ProcessResult results) => Application.log(results.stdout));
}
print('Uploaded: $type$local --> $remote');
Application.log('Uploaded: $type$local --> $remote');
} else {
throw ArgumentError('Remote target should be "Folder"');
}
@ -331,7 +332,7 @@ class SFTP extends FTP {
'-r',
'$_user@$_host:$remote',
local
]).then((ProcessResult result) => print(result.stdout));
]).then((ProcessResult result) => Application.log(result.stdout));
} else {
type = '[F]';
await Process.run('sshpass', [
@ -342,9 +343,9 @@ class SFTP extends FTP {
'$_port',
'$_user@$_host:$remote',
local
]).then((ProcessResult result) => print(result.stdout));
]).then((ProcessResult result) => Application.log(result.stdout));
}
print('Download: $type$remote --> $local');
Application.log('Download: $type$remote --> $local');
}
}
@ -380,7 +381,7 @@ class SFTP extends FTP {
type = FileType.link;
}
var mapKey = '$path/$fileName';
// print('$count = $type = $mapKey');
// Application.log('$count = $type = $mapKey');
map[mapKey] = type;
}
count++;
@ -392,7 +393,7 @@ class SFTP extends FTP {
@override
Future<void> delete(List<String> remoteList) async {
print('######################## delete ${remoteList.length}');
Application.log('######################## delete ${remoteList.length}');
//check file exist
for (var item in remoteList) {
await Process.run('sshpass', [
@ -402,8 +403,8 @@ class SFTP extends FTP {
'$_user@$_host',
'-p$_port',
'rm -rf $item'
]).then((ProcessResult results) => print(results.stdout));
print('Deleted: $item');
]).then((ProcessResult results) => Application.log(results.stdout));
Application.log('Deleted: $item');
}
}
@ -414,7 +415,7 @@ class SFTP extends FTP {
var map = await list(parent);
if (map.containsKey(path)) {
c.complete(false);
print('Create failed: Already exist file or folder');
Application.log('Create failed: Already exist file or folder');
} else {
await Process.run('sshpass', [
'-p',
@ -423,9 +424,9 @@ class SFTP extends FTP {
'$_user@$_host',
'-p$_port',
'mkdir $path'
]).then((ProcessResult results) => print(results.stdout));
]).then((ProcessResult results) => Application.log(results.stdout));
c.complete(true);
print('Created Folder: $path');
Application.log('Created Folder: $path');
}
return c.future;
}

View file

@ -22,17 +22,17 @@ class Uploader extends Command {
var ftp = data.sftp
? SFTP(data.host, port: port, user: data.user, password: data.password)
: FTP(data.host, port: port, user: data.user, password: data.password);
print(
Application.log(
'========================= [Try connection] =========================');
await ftp.connect();
print(
Application.log(
'========================= [Connected! Start Upload] ================');
var entries = map.entries;
for (var entry in entries) {
var local =
path.join(Application.instance.commonData!.workspace, entry.key);
var remote = entry.value;
print('[Upload]: $local ====> $remote');
Application.log('[Upload]: $local ====> $remote');
var parentRemote = Path.getParent(remote);
var remoteMap = await ftp.list(parentRemote!);
@ -67,7 +67,7 @@ class Uploader extends Command {
if (uploadMap.isNotEmpty) await ftp.upload(uploadMap);
await ftp.disconnect();
print(
Application.log(
'========================= [Upload completed!] ======================');
return complete(0, command);
}

View file

@ -1,5 +1,6 @@
import 'dart:async';
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:dart_framework/platform/process.dart';
@ -11,7 +12,7 @@ class ExecuteApp extends Command {
var exe = replaceTag(data.executable);
var desktop = replaceTag(data.desktopServicePath);
print('Process Start: $exe');
Application.log('Process Start: $exe');
var content = 'start "" "$exe" & exit';
var buffer = StringBuffer(content);

View file

@ -4,6 +4,7 @@ import 'dart:convert';
import 'package:dart_framework/utils/slack/slack_data.dart';
import 'package:dart_framework/utils/system_util.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:http/http.dart' as http;
@ -36,11 +37,11 @@ class Jira extends Command {
'Authorization': 'Basic $base64'
};
var url = 'https://${data.domain}/rest/api/3/issue/${data.issue}';
print(url);
Application.log(url);
var response = await http.get(Uri.parse(url), headers: header);
if (response.statusCode < 300 && response.statusCode >= 200) {
print(response.body);
Application.log(response.body);
var issue = DataJiraIssue.fromJson(jsonDecode(response.body));
var targetUser = issue.fields?.assignee?.emailAddress;
if (targetUser != null) {
@ -105,7 +106,7 @@ class Jira extends Command {
// }
}
} else {
print('User not found');
Application.log('User not found');
}
}
} else {

View file

@ -1,4 +1,5 @@
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -9,7 +10,7 @@ class PrintCommand extends Command {
Future execute(DataCommand command) async {
var data = DataPrint.fromJson(getParam(command));
// await CLI.println(data.message, color: Color.red);
print(data.message);
Application.log(data.message);
return complete(0, command);
}

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';
import 'package:oto_cli/oto/application.dart';
import 'package:oto_cli/oto/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
// ignore: depend_on_referenced_packages
@ -27,7 +28,7 @@ class PublishiOS extends Command {
var indexFile = File('$destinationPath/index.html');
await indexFile.writeAsString(indexContent);
print('Created "index.html" --> "$destinationPath/index.html"');
Application.log('Created "index.html" --> "$destinationPath/index.html"');
var menifestContent =
await File('$templatePath/manifest.plist').readAsString();
@ -41,7 +42,7 @@ class PublishiOS extends Command {
var menifestFile = File('$destinationPath/manifest.plist');
await menifestFile.writeAsString(menifestContent);
print('Created "manifest.plist" --> "$destinationPath/manifest.plist"');
Application.log('Created "manifest.plist" --> "$destinationPath/manifest.plist"');
return complete(0, command);
}

View file

@ -5,6 +5,7 @@ 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/commands/command.dart';
import 'package:oto_cli/oto/data/command_data.dart';
@ -14,7 +15,7 @@ class Zip extends Command {
var data = DataZip.fromJson(getParam(command));
try {
var zipFilePath = Path.getNormal(data.zipFile);
print('Start Compress...');
Application.log('Start Compress...');
var parent = Directory(Path.getParent(zipFilePath)!);
if (!parent.existsSync()) parent.createSync(recursive: true);
var zipFile = File(zipFilePath);
@ -35,41 +36,41 @@ class Zip extends Command {
var dir = Directory(item.path);
var file = File(item.path);
if (dir.existsSync()) {
print('- Compress Dir --> ${dir.path}');
Application.log('- Compress Dir --> ${dir.path}');
encoder.addDirectory(dir);
}
if (file.existsSync()) {
encoder.addFile(file);
print('- Compress File --> ${file.path}');
Application.log('- Compress File --> ${file.path}');
}
}
} else {
print('================== "$path" is not exist');
Application.log('================== "$path" is not exist');
}
} else {
var dir = Directory(path);
var file = File(path);
var added = false;
if (dir.existsSync()) {
print('- Compress Dir --> ${dir.path}');
Application.log('- Compress Dir --> ${dir.path}');
encoder.addDirectory(dir);
added = true;
}
if (file.existsSync()) {
encoder.addFile(file);
print('- Compress File --> ${file.path}');
Application.log('- Compress File --> ${file.path}');
added = true;
}
if (!added) print('================== "$path" is not exist');
if (!added) Application.log('================== "$path" is not exist');
}
}
encoder.close();
print('Compress success: $zipFilePath');
Application.log('Compress success: $zipFilePath');
} else {
throw Exception('"${tempDir.path}" is Directory');
}
} on Exception catch (e) {
print('Zip General Exception: $e');
Application.log('Zip General Exception: $e');
}
return complete(0, command);

View file

@ -1,5 +1,6 @@
import 'dart:async';
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 'dart:io';
@ -40,7 +41,7 @@ class WebRequest extends WebBase {
@override
Future execute(DataCommand command) async {
var data = DataWebBase.fromJson(getParam(command));
print('Request URL: ${data.url}');
Application.log('Request URL: ${data.url}');
data.method ??= 'GET';
var request = http.Request(data.method!, Uri.parse(data.url));
if(data.fields != null)
@ -58,7 +59,7 @@ class WebFile extends WebBase {
@override
Future execute(DataCommand command) async {
var data = DataWebFile.fromJson(getParam(command));
print('Upload URL: ${data.url}');
Application.log('Upload URL: ${data.url}');
var form = http.MultipartRequest('POST', Uri.parse(data.url));
if(data.fields != null)

View file

@ -4,6 +4,7 @@ import 'dart:io';
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/data/jenkins_data.dart';
import 'package:oto_cli/oto/core/defined_data.dart';
@ -40,8 +41,8 @@ class DataComposerJenkins extends DataComposer {
Map<String, dynamic>? jenkinsMap;
String os = Platform.operatingSystem;
var enable = true;
print('Current OS: $os');
print('Start build...');
Application.log('Current OS: $os');
Application.log('Start build...');
String jsonStr = '';
if (Platform.isMacOS || Platform.isLinux) {
var shellExe = Platform.isMacOS ? 'zsh' : 'bash';
@ -65,7 +66,7 @@ class DataComposerJenkins extends DataComposer {
}
if (enable) {
await printer('Jenkins Variables', Color.green);
print(jsonStr);
Application.log(jsonStr);
}
commonData = DataCommon.fromJson(jenkinsMap!);
buildYaml = await getBuildData();

View file

@ -572,6 +572,7 @@ class DataShell extends DataParam {
Map<String, dynamic> toJson() => _$DataShellToJson(this);
}
@JsonSerializable()
class DataShellFile extends DataParam {
DataShellFile();

View file

@ -22,7 +22,7 @@ abstract class PipelineExecutor {
static Future printCondition(String syntax, String condition, String postfix,
ConditionCheckResult result) async {
await CLI.println('[Pipeline-$syntax]', color: Color.magentaStrong);
print(
Application.log(
' - Condition: $condition\n - Values: ${result.conditionValue}\n - Result: ${result.result} ===> $postfix');
return simpleFuture;
@ -64,7 +64,7 @@ class PipelineExe extends PipelineExecutor {
// 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');
// Application.log('==================> [$time] Execute: $targetCommandID');
updateState(CommandState.progress);
var data = await commandData;
var command = Command.byType(data.command);

View file

@ -1,5 +1,6 @@
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/pipeline_data.dart';
import 'package:oto_cli/oto/pipeline/pipeline.dart';
@ -60,7 +61,7 @@ class PipelineForeach extends PipelineExecutor {
}
}
await CLI.println('[Pipeline-Foreach ($iteratorType)]', color: Color.magentaStrong);
print(' - Foreach complete. Loop out');
Application.log(' - Foreach complete. Loop out');
}
return simpleFuture;
}

View file

@ -1,8 +1,9 @@
import 'package:oto_cli/oto/application.dart';
import 'package:test/test.dart';
void main() {
setUp(() async {
print('[SetUp] Set up initalize enviroments');
Application.log('[SetUp] Set up initalize enviroments');
});
group('CLI', () {
test('calculate', () {
@ -15,6 +16,6 @@ void main() {
});
tearDown(() {
print('[TearDown] Post process. this doing event failed');
Application.log('[TearDown] Post process. this doing event failed');
});
}