scheduler 작업중
This commit is contained in:
parent
1f2e6c5d0a
commit
e0b377fc02
16 changed files with 458 additions and 45 deletions
21
.vscode/launch.json
vendored
21
.vscode/launch.json
vendored
|
|
@ -80,6 +80,27 @@
|
|||
"type": "dart",
|
||||
"program": "./bin/main.dart",
|
||||
"args": ["exe", "-f", "C:/Work/automation/iot/script/windows/startup.yaml"]
|
||||
},
|
||||
{
|
||||
"name": "scheduler regist",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "./bin/main.dart",
|
||||
"args": ["scheduler", "-r", "./assets/scheduler.yaml"]
|
||||
},
|
||||
{
|
||||
"name": "scheduler unregist",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "./bin/main.dart",
|
||||
"args": ["scheduler", "-u", "test"]
|
||||
},
|
||||
{
|
||||
"name": "scheduler background",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "./bin/main.dart",
|
||||
"args": ["scheduler", "-s"]
|
||||
}
|
||||
]
|
||||
}
|
||||
20
assets/scheduler.yaml
Normal file
20
assets/scheduler.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
scheduler:
|
||||
alias: test
|
||||
cron: '*/5 * * * *'
|
||||
enableLog: false # (Optional) default: false
|
||||
|
||||
property:
|
||||
workspace: .
|
||||
|
||||
pipeline:
|
||||
id: main
|
||||
workflow:
|
||||
- exe: print
|
||||
|
||||
commands:
|
||||
### Print
|
||||
- command: Print
|
||||
id: print
|
||||
param:
|
||||
message: test
|
||||
|
|
@ -7,8 +7,9 @@ import 'package:oto_cli/cli/commands/command_exe.dart';
|
|||
// import 'package:oto_cli/cli/commands/command_start.dart';
|
||||
|
||||
void main(List<String> arguments) async {
|
||||
initialize();
|
||||
CLI.initialize('OTO', arguments, [
|
||||
await initialize('oto', 'com.toki-labs.oto');
|
||||
|
||||
CLI.initialize('oto', arguments, [
|
||||
CommandTemplate(),
|
||||
CommandExe(),
|
||||
CommandScheduler()
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ class CLIConfig {
|
|||
CLIConfig(this.serviceName, this.arguments, this.commands) {
|
||||
var fileName = path.basename(Platform.resolvedExecutable);
|
||||
fileName = fileName.replaceAll(path.extension(fileName), '');
|
||||
if(fileName == 'dart') {
|
||||
//debug
|
||||
fileName = 'dart bin/main.dart';
|
||||
}
|
||||
executableFileName = fileName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
// ignore_for_file: avoid_init_to_null
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_framework/charset/euc_kr.dart';
|
||||
import 'package:dart_framework/data/isolate_data.dart';
|
||||
import 'package:dart_framework/platform/isolate_manager.dart';
|
||||
import 'package:oto_cli/cli/cli.dart';
|
||||
|
|
@ -33,12 +31,11 @@ class CommandExe extends CommandBase {
|
|||
_handler = IsolateManager.create(IsolateExe(BuildType.jenkins));
|
||||
await isComplete();
|
||||
break;
|
||||
}
|
||||
if (item.startsWith('-t')) {
|
||||
} else if (item.startsWith('-t')) {
|
||||
_handler = IsolateManager.create(IsolateExe(BuildType.test));
|
||||
await isComplete();
|
||||
}
|
||||
if (item.startsWith('-f')) {
|
||||
break;
|
||||
} else if (item.startsWith('-f')) {
|
||||
var file = '';
|
||||
if (parameters.length > i + 1) {
|
||||
file = parameters[i + 1];
|
||||
|
|
@ -47,6 +44,8 @@ class CommandExe extends CommandBase {
|
|||
}
|
||||
await startYaml(file);
|
||||
break;
|
||||
} else {
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
return simpleFuture;
|
||||
|
|
|
|||
|
|
@ -35,9 +35,20 @@ class CommandManager {
|
|||
}
|
||||
|
||||
if (!printHelp) {
|
||||
await CLI.println('Execute command: $command$argStr',
|
||||
if(parameters.isEmpty) {
|
||||
commandItem.printHelp();
|
||||
} else {
|
||||
await CLI.println('Execute command: $command$argStr',
|
||||
color: Color.green);
|
||||
await commandItem.execute(parameters);
|
||||
try {
|
||||
await commandItem.execute(parameters);
|
||||
} on Exception catch(e, stacktace) {
|
||||
print('');
|
||||
var message = e.toString().replaceAll('Exception:', '');
|
||||
await CLI.println('${CLI.style('Error:', background: Color.red)} $message');
|
||||
print('');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printHelp(append: [
|
||||
|
|
|
|||
|
|
@ -1,33 +1,55 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:oto_cli/cli/commands/command_base.dart';
|
||||
import 'package:dart_framework/utils/system_util.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_manager.dart';
|
||||
|
||||
class CommandScheduler extends CommandBase {
|
||||
|
||||
@override
|
||||
Map<String, List<String>> get arguments => {
|
||||
'-l': ["Shows the currently operational schedulers."],
|
||||
'-k {alias}': ["Shut down the active scheduler."]
|
||||
'-r {file}': ["Register the defined file (yaml) with the scheduler."],
|
||||
'-u {alias}': ["Unregister schedules registered with the scheduler based on alias."]
|
||||
};
|
||||
@override
|
||||
String get name => 'scheduler';
|
||||
final Scheduler _scheduler = Scheduler();
|
||||
final SchedulerManager _scheduler = SchedulerManager();
|
||||
|
||||
@override
|
||||
Future execute(List<String> parameters) async {
|
||||
for (var i = 0; i < parameters.length; ++i) {
|
||||
var item = parameters[i];
|
||||
if (item.startsWith('-l')) {
|
||||
} else if (item.startsWith('-k')) {
|
||||
_scheduler.showList();
|
||||
break;
|
||||
} else if (item.startsWith('-r')) {
|
||||
var file = '';
|
||||
if (parameters.length > i + 1) {
|
||||
file = parameters[i + 1];
|
||||
} else {
|
||||
file = item.replaceFirst('-r', '').trimLeft();
|
||||
}
|
||||
await _scheduler.regist(file);
|
||||
exit(0);
|
||||
} else if (item.startsWith('-u')) {
|
||||
var alias = '';
|
||||
if (parameters.length > i + 1) {
|
||||
alias = parameters[i + 1];
|
||||
} else {
|
||||
alias = item.replaceFirst('-f', '').trimLeft();
|
||||
alias = item.replaceFirst('-u', '').trimLeft();
|
||||
}
|
||||
print('======================> $alias');
|
||||
await _scheduler.unregist(alias);
|
||||
break;
|
||||
} else if (item.startsWith('-s')) { //hidden: start process
|
||||
await _scheduler.start();
|
||||
break;
|
||||
} else if (item.startsWith('-t')) { //hidden: terminate process
|
||||
await _scheduler.terminate();
|
||||
break;
|
||||
} else {
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
return simpleFuture;
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_linux.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_osx.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_windows.dart';
|
||||
|
||||
abstract class Scheduler {
|
||||
factory Scheduler() {
|
||||
if(Platform.isMacOS) {
|
||||
return SchedulerOsx();
|
||||
} else if(Platform.isWindows) {
|
||||
return SchedulerWindows();
|
||||
} else if(Platform.isLinux) {
|
||||
return SchedulerLinux();
|
||||
} else {
|
||||
throw UnsupportedError('This platform not supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_manager.dart';
|
||||
|
||||
class SchedulerLinux implements Scheduler {
|
||||
|
||||
class SchedulerLinux extends SchedulerManager {
|
||||
}
|
||||
325
lib/cli/commands/scheduler/scheduler_manager.dart
Normal file
325
lib/cli/commands/scheduler/scheduler_manager.dart
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
|
||||
import 'dart:collection';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cron/cron.dart';
|
||||
import 'package:dart_framework/data/isolate_data.dart';
|
||||
import 'package:dart_framework/platform/isolate_manager.dart';
|
||||
import 'package:dart_framework/platform/process.dart';
|
||||
import 'package:dart_framework/utils/os_startup.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/scheduler/scheduler_linux.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_osx.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_windows.dart';
|
||||
import 'package:oto_cli/oto/application.dart';
|
||||
import 'package:oto_cli/oto/data/command_data.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
class SchedulerManager {
|
||||
|
||||
static String get schedulerPath {
|
||||
var debugPath = isDebug ? '/debug' : '';
|
||||
return '$dataPath$debugPath/scheduler';
|
||||
}
|
||||
|
||||
static String get logsPath {
|
||||
return '$schedulerPath/logs';
|
||||
}
|
||||
|
||||
ProcessInfo? currentScheduler;
|
||||
final Map<String, IsolateHandler> _map = {};
|
||||
|
||||
HashSet<String> get schedulers {
|
||||
HashSet<String> hash = HashSet();
|
||||
var dir = Directory(schedulerPath);
|
||||
if(dir.existsSync()) {
|
||||
var fileList = dir.listSync();
|
||||
for(var item in fileList) {
|
||||
if(item is File) {
|
||||
if(path.extension(item.path).toLowerCase().contains('.yaml')) {
|
||||
hash.add(path.basenameWithoutExtension(item.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
SchedulerManager();
|
||||
|
||||
factory SchedulerManager.create() {
|
||||
if(Platform.isMacOS) {
|
||||
return SchedulerOsx();
|
||||
} else if(Platform.isWindows) {
|
||||
return SchedulerWindows();
|
||||
} else if(Platform.isLinux) {
|
||||
return SchedulerLinux();
|
||||
} else {
|
||||
throw UnsupportedError('This platform not supported.');
|
||||
}
|
||||
}
|
||||
|
||||
Future regist(String filePath) async {
|
||||
var file = File(filePath);
|
||||
if(!file.existsSync()) {
|
||||
return throw Exception("The file '$filePath' does not exist.");
|
||||
}
|
||||
Map<String, dynamic>? map;
|
||||
DataBuild? build;
|
||||
try {
|
||||
map = Application.getMapFromYamlA(await file.readAsString());
|
||||
build = DataBuild.fromJson(map!);
|
||||
} on Exception catch(e, stacktace) {
|
||||
print(stacktace);
|
||||
return throw Exception("The file '$filePath' is not in yaml format or is an unsupported build format.");
|
||||
}
|
||||
|
||||
if(build.scheduler == null) {
|
||||
return throw Exception('Scheduler entry does not exist within yaml.');
|
||||
}
|
||||
|
||||
var dirLogs = Directory(logsPath);
|
||||
var alias = build.scheduler!.alias;
|
||||
var hash = schedulers;
|
||||
if(hash.contains(alias)) {
|
||||
return throw Exception('A scheduler with the same alias is registered. Please do it with a different alias.');
|
||||
}
|
||||
await checkStartup();
|
||||
await checkProcess();
|
||||
await startProcess();
|
||||
|
||||
if(!dirLogs.existsSync()) {
|
||||
dirLogs.createSync(recursive: true);
|
||||
}
|
||||
await file.copy('$schedulerPath/$alias.yaml');
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future unregist(String alias) async {
|
||||
if(schedulers.contains(alias)) {
|
||||
var file = File('$schedulerPath/$alias.yaml');
|
||||
file.deleteSync();
|
||||
} else {
|
||||
return throw Exception("There is no scheduler called '$alias'.");
|
||||
}
|
||||
|
||||
if(schedulers.isEmpty) {
|
||||
await terminate();
|
||||
await unregistStartup();
|
||||
}
|
||||
}
|
||||
|
||||
void showList() {
|
||||
print('');
|
||||
var scheduleList = schedulers;
|
||||
if(scheduleList.isEmpty) {
|
||||
print(':::: There are no registered schedulers.');
|
||||
print('');
|
||||
} else {
|
||||
print(':::: List of currently registered schedulers.');
|
||||
print('');
|
||||
print('${' [Enable]'.padRight(20)}${'[Alias]'.padRight(20)}[Path]');
|
||||
for(var item in schedulers) {
|
||||
print('${' - true'.padRight(20)}${item.padRight(20)}$schedulerPath/$item.yaml');
|
||||
}
|
||||
print('');
|
||||
}
|
||||
}
|
||||
|
||||
Future terminate() async {
|
||||
await checkProcess();
|
||||
if(currentScheduler != null) {
|
||||
Process.killPid(currentScheduler!.pid);
|
||||
print('Scheduler operation stopped.');
|
||||
}
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future startProcess() async {
|
||||
//Launchd로 자동 실행이 되지 않은경우 직접실행
|
||||
if(currentScheduler == null) {
|
||||
var script = isDebug ? ' $scriptPath' : '';
|
||||
var shell = StringBuffer();
|
||||
shell.writeln('nohup $executablePath$script scheduler -s &');
|
||||
shell.writeln('disown');
|
||||
ProcessExecutor.run(shell, workspace: Directory.systemTemp.path, printStdout: false);
|
||||
await checkProcess();
|
||||
}
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future checkSchedules() async {
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future checkProcess() async {
|
||||
//process check
|
||||
var processes = await findProcess('scheduler -s');
|
||||
for(var process in processes) {
|
||||
print(process.name);
|
||||
var processName = process.name;
|
||||
if(processName.contains('main.dart scheduler -s') || processName.contains('$appName scheduler -s')) {
|
||||
currentScheduler = process;
|
||||
print('Scheduler is running on pid ${currentScheduler!.pid}.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future checkStartup() async {
|
||||
if(!await OSStartup.isRegistedStartup(appIdendifier)) {
|
||||
List<String> param = [];
|
||||
if(isDebug) {
|
||||
param.add(scriptPath);
|
||||
}
|
||||
param.add('scheduler');
|
||||
param.add('-s');
|
||||
await OSStartup.registStartup(executablePath, appIdendifier, arguments: param);
|
||||
}
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
Future unregistStartup() async {
|
||||
if(await OSStartup.isRegistedStartup(appIdendifier)) {
|
||||
await OSStartup.unregistStartup(appIdendifier);
|
||||
}
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
//======================== other process ========================//
|
||||
final logFile = File('$logsPath/scheduler.txt');
|
||||
Future start() async {
|
||||
while(true) {
|
||||
//매초 마다 등록된 파일이 있나 체크
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
var scheduleList = schedulers;
|
||||
for(var alias in scheduleList) {
|
||||
if(!_map.containsKey(alias)) {
|
||||
await logFile.writeAsString('Schduler started: $alias\n', mode: FileMode.append);
|
||||
var handler = IsolateManager.create(IsolateScheduler({'alias': alias, 'root': schedulerPath, 'logs': logsPath}));
|
||||
//To-do: 종료시 사유(by user, by error)에 따라 json에 내용을 기입하여 재실행 안하도록
|
||||
handler.addListener('terminated', onTerminated );
|
||||
_map[alias] = handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onTerminated(Object? data) {
|
||||
var map = data as Map;
|
||||
var alias = data['alias'] as String;
|
||||
var type = data['type'] as String;
|
||||
var message = data['message'] as String;
|
||||
_map.remove(alias);
|
||||
}
|
||||
}
|
||||
|
||||
class IsolateScheduler extends IsolateBase {
|
||||
late String schedulerPath;
|
||||
late String logsPath;
|
||||
late String alias;
|
||||
late File file;
|
||||
late File logFile;
|
||||
int fileHash = 0;
|
||||
|
||||
bool logEnable = false;
|
||||
bool notProgress = true;
|
||||
bool cronClosed = true;
|
||||
late DataBuild build;
|
||||
late String cronExpress;
|
||||
|
||||
Cron? cron;
|
||||
int nextStartTime = 0;
|
||||
|
||||
IsolateScheduler(Map data) {
|
||||
alias = data['alias'];
|
||||
schedulerPath = data['root'];
|
||||
logsPath = data['logs'];
|
||||
file = File('$schedulerPath/$alias.yaml');
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady(Object? initData) async {
|
||||
while(true) {
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
|
||||
if(file.existsSync()) {
|
||||
var hash = await FileHasher.hash(file);
|
||||
if(hash != fileHash) {
|
||||
fileHash = hash;
|
||||
//파일 내용이 바뀔때 마다 새로 읽어 들임
|
||||
var map = Application.getMapFromYamlA(await file.readAsString());
|
||||
|
||||
//Validate yaml format
|
||||
try {
|
||||
build = DataBuild.fromJson(map!);
|
||||
} on Exception catch(e, stacktace) {
|
||||
onError('Failed to parse yaml file.');
|
||||
logError(e, stacktace);
|
||||
return;
|
||||
}
|
||||
if(build.scheduler == null) {
|
||||
onError('Scheduler entry does not exist within yaml.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Schedule.parse(build.scheduler!.cron);
|
||||
cronExpress = build.scheduler!.cron;
|
||||
} on Error catch(e, stacktace) {
|
||||
onError("Cron express '${build.scheduler!.cron}' is not a suitable format.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(cronClosed) {
|
||||
cronClosed = false;
|
||||
cron = Cron();
|
||||
cron!.schedule(Schedule.parse(cronExpress), () async {
|
||||
if(notProgress) {
|
||||
await execute(build);
|
||||
cronClosed = true;
|
||||
await cron!.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//file이 없을시 종료
|
||||
onError("The file '${file.path}' does not exist.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future execute(DataBuild data) async {
|
||||
notProgress = false;
|
||||
logFile = File('$logsPath/${alias}_${getDate()}_${getTime().replaceAll(':', '.')}.txt');
|
||||
log('Execute task: ${DateTime.now().toString()}');
|
||||
await Future.delayed(Duration(minutes: 1, seconds: 30));
|
||||
notProgress = true;
|
||||
return simpleFuture;
|
||||
}
|
||||
|
||||
void log(String message) {
|
||||
logFile.writeAsStringSync('[${getDates()}] $message\n', mode: FileMode.append, flush: true);
|
||||
}
|
||||
|
||||
void logError(Exception e, StackTrace stacktace) {
|
||||
log('[${e.toString()}]\n${stacktace.toString()}');
|
||||
}
|
||||
|
||||
void onErrorStacktrace(Exception e, StackTrace stacktrace) {
|
||||
onError('$e\n$stacktrace');
|
||||
}
|
||||
|
||||
void onError(String message) {
|
||||
sendTerminated('error', message);
|
||||
}
|
||||
|
||||
void sendTerminated(String type, String message) {
|
||||
send(IsoMessege('terminated', data: {'type': type, 'message': message, 'alias': alias}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:oto_cli/cli/commands/scheduler/scheduler_manager.dart';
|
||||
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler.dart';
|
||||
|
||||
class SchedulerOsx implements Scheduler {
|
||||
class SchedulerOsx extends SchedulerManager {
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler.dart';
|
||||
import 'package:oto_cli/cli/commands/scheduler/scheduler_manager.dart';
|
||||
|
||||
class SchedulerWindows implements Scheduler {
|
||||
class SchedulerWindows extends SchedulerManager {
|
||||
|
||||
}
|
||||
|
|
@ -119,7 +119,7 @@ class Application {
|
|||
return simpleFuture;
|
||||
}
|
||||
|
||||
Map<String, dynamic>? getMapFromYamlA(String yamlStr) {
|
||||
static Map<String, dynamic>? getMapFromYamlA(String yamlStr) {
|
||||
Map<String, dynamic>? map;
|
||||
if (yamlStr.length > 5) {
|
||||
YamlMap data = loadYaml(yamlStr);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ part 'command_data.g.dart';
|
|||
/// ***************************** Base Data ****************************///
|
||||
@JsonSerializable()
|
||||
class DataBuild {
|
||||
late DataScheduler? scheduler;
|
||||
late Map<String, dynamic>? property;
|
||||
late DataPipeline? pipeline;
|
||||
late List<DataCommand> commands;
|
||||
|
|
@ -25,6 +26,19 @@ class DataBuild {
|
|||
Map<String, dynamic> toJson() => _$DataBuildToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class DataScheduler {
|
||||
late String alias;
|
||||
late String cron;
|
||||
late bool? enableLog;
|
||||
|
||||
DataScheduler();
|
||||
|
||||
factory DataScheduler.fromJson(Map<String, dynamic> json) =>
|
||||
_$DataSchedulerFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$DataSchedulerToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class DataCommand {
|
||||
DataCommand();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ part of 'command_data.dart';
|
|||
// **************************************************************************
|
||||
|
||||
DataBuild _$DataBuildFromJson(Map<String, dynamic> json) => DataBuild()
|
||||
..scheduler = json['scheduler'] == null
|
||||
? null
|
||||
: DataScheduler.fromJson(json['scheduler'] as Map<String, dynamic>)
|
||||
..property = json['property'] as Map<String, dynamic>?
|
||||
..pipeline = json['pipeline'] == null
|
||||
? null
|
||||
|
|
@ -16,11 +19,25 @@ DataBuild _$DataBuildFromJson(Map<String, dynamic> json) => DataBuild()
|
|||
.toList();
|
||||
|
||||
Map<String, dynamic> _$DataBuildToJson(DataBuild instance) => <String, dynamic>{
|
||||
'scheduler': instance.scheduler,
|
||||
'property': instance.property,
|
||||
'pipeline': instance.pipeline,
|
||||
'commands': instance.commands,
|
||||
};
|
||||
|
||||
DataScheduler _$DataSchedulerFromJson(Map<String, dynamic> json) =>
|
||||
DataScheduler()
|
||||
..alias = json['alias'] as String
|
||||
..cron = json['cron'] as String
|
||||
..enableLog = json['enableLog'] as bool?;
|
||||
|
||||
Map<String, dynamic> _$DataSchedulerToJson(DataScheduler instance) =>
|
||||
<String, dynamic>{
|
||||
'alias': instance.alias,
|
||||
'cron': instance.cron,
|
||||
'enableLog': instance.enableLog,
|
||||
};
|
||||
|
||||
DataCommand _$DataCommandFromJson(Map<String, dynamic> json) => DataCommand()
|
||||
..command = $enumDecode(_$CommandTypeEnumMap, json['command'])
|
||||
..id = json['id'] as String
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ dependencies:
|
|||
ref: master
|
||||
color: ^3.0.0
|
||||
file_hasher: ^0.1.0+0
|
||||
cron: ^0.6.1
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^5.0.0
|
||||
|
|
|
|||
Loading…
Reference in a new issue