110 lines
3 KiB
Dart
110 lines
3 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:oto/cli/commands/command_base.dart';
|
|
import 'package:oto/oto/application.dart';
|
|
|
|
class CommandValidateCli extends CommandBase {
|
|
final Future<void> Function(String) _printString;
|
|
|
|
CommandValidateCli({Future<void> Function(String)? printString})
|
|
: _printString = printString ??
|
|
((value) async {
|
|
stdout.writeln(value);
|
|
});
|
|
|
|
@override
|
|
String get name => 'validate';
|
|
|
|
@override
|
|
String get usage => '[arguments]';
|
|
|
|
@override
|
|
String getDescription() =>
|
|
'Validate the pipeline yaml file structure and semantics without executing it.';
|
|
|
|
@override
|
|
Map<String, List<String>> get arguments => {
|
|
'-f {file path}': ['Validate the yaml file without executing it.'],
|
|
'--json': ['Output validation result as structured JSON format.'],
|
|
};
|
|
|
|
@override
|
|
bool shouldPrintExecuteLog(List<String> parameters) {
|
|
return !parameters.contains('--json');
|
|
}
|
|
|
|
@override
|
|
bool shouldExecuteWithoutParameters() => false;
|
|
|
|
@override
|
|
Future execute(List<String> parameters) async {
|
|
String? filePath;
|
|
bool isJson = false;
|
|
|
|
for (int i = 0; i < parameters.length; i++) {
|
|
final param = parameters[i];
|
|
if (param == '--json') {
|
|
isJson = true;
|
|
} else if (param.startsWith('-f')) {
|
|
if (param == '-f') {
|
|
if (i + 1 < parameters.length) {
|
|
filePath = parameters[++i];
|
|
} else {
|
|
throw Exception('Missing value for -f');
|
|
}
|
|
} else {
|
|
filePath = param.substring(2);
|
|
}
|
|
} else if (param.startsWith('--file=')) {
|
|
filePath = param.substring('--file='.length);
|
|
} else if (param == '--file') {
|
|
if (i + 1 < parameters.length) {
|
|
filePath = parameters[++i];
|
|
} else {
|
|
throw Exception('Missing value for --file');
|
|
}
|
|
} else {
|
|
throw Exception('Unknown option: $param');
|
|
}
|
|
}
|
|
|
|
if (filePath == null) {
|
|
throw Exception('Missing required option: -f {file path}');
|
|
}
|
|
|
|
final file = File(filePath);
|
|
YamlValidationResult result;
|
|
|
|
if (!file.existsSync()) {
|
|
result = YamlValidationResult.failure(
|
|
phase: 'Read YAML file',
|
|
message: 'There are no files in path "$filePath"',
|
|
exitCode: 10,
|
|
);
|
|
} else {
|
|
try {
|
|
final content = file.readAsStringSync();
|
|
result = Application.validateYamlContent(content);
|
|
} catch (e) {
|
|
result = YamlValidationResult.failure(
|
|
phase: 'Read YAML file',
|
|
message: e.toString(),
|
|
exitCode: 10,
|
|
);
|
|
}
|
|
}
|
|
|
|
exitCode = result.exitCode;
|
|
|
|
if (isJson) {
|
|
final jsonMap = result.toJson();
|
|
await _printString(const JsonEncoder.withIndent(' ').convert(jsonMap));
|
|
} else {
|
|
if (result.valid) {
|
|
await _printString('Valid YAML.');
|
|
} else {
|
|
await _printString('Invalid YAML: [${result.phase}] ${result.message}');
|
|
}
|
|
}
|
|
}
|
|
}
|