Release 0.2.0

Complete OpenAPI 3.0/3.1 generation, diagnostics, lifecycle safety, enum and naming mappings, bilingual documentation, examples, and pub.dev release validation.
This commit is contained in:
mr.koi
2026-07-31 16:47:39 +08:00
parent ea93f09154
commit 454e6c51d7
56 changed files with 14506 additions and 491 deletions
+116 -22
View File
@@ -5,22 +5,59 @@ import 'package:koi_swagger_parser/koi_swagger_parser.dart';
Future<void> main(List<String> arguments) async {
final parser = ArgParser()
..addFlag('help', abbr: 'h', negatable: false, help: '显示帮助信息。');
..addFlag('help', abbr: 'h', negatable: false, help: 'Show command help.');
final generateParser = ArgParser()
..addFlag('all', abbr: 'a', negatable: false, help: '兼容旧命令格式,当前等价于生成全部资源。')
..addOption('config', abbr: 'c', help: '配置文件路径。')
..addOption('cwd', help: '工作目录。')
..addFlag('dry-run', negatable: false, help: '只解析与渲染,不落盘。')
..addFlag('verbose', abbr: 'v', negatable: false, help: '打印更多诊断信息。');
..addFlag(
'help',
abbr: 'h',
negatable: false,
help: 'Show help for the generate command.',
)
..addFlag(
'all',
abbr: 'a',
negatable: false,
help:
'Generate all resources. Retained for compatibility with the '
'legacy command.',
)
..addOption(
'config',
abbr: 'c',
help: 'Path to the YAML configuration file.',
valueHelp: 'path',
)
..addOption(
'cwd',
help: 'Working directory used to resolve project-relative paths.',
valueHelp: 'directory',
)
..addFlag(
'dry-run',
negatable: false,
help: 'Parse and render without writing or deleting files.',
)
..addFlag(
'watch',
negatable: false,
help: 'Start build_runner watch after generation.',
)
..addFlag(
'verbose',
abbr: 'v',
negatable: false,
help: 'Print detailed diagnostics and stack traces.',
);
parser.addCommand('generate', generateParser);
late final ArgResults result;
try {
result = parser.parse(arguments);
} on FormatException catch (error) {
stderr.writeln(error.message);
stderr.writeln(parser.usage);
stderr.writeln('Error: ${error.message}');
stderr.writeln();
stderr.writeln(_usage(parser));
exitCode = 64;
return;
}
@@ -31,9 +68,16 @@ Future<void> main(List<String> arguments) async {
}
final command = result.command;
if (command == null || command.name == 'generate') {
final commandArgs = command ?? result;
await _runGenerate(commandArgs, parser);
if (command == null) {
stdout.writeln(_usage(parser));
return;
}
if (command.name == 'generate') {
if ((command['help'] as bool?) ?? false) {
stdout.writeln(_generateUsage(generateParser));
return;
}
await _runGenerate(command, generateParser);
return;
}
@@ -48,22 +92,50 @@ Future<void> _runGenerate(ArgResults result, ArgParser parser) async {
workingDirectory: result['cwd'] as String?,
dryRun: result['dry-run'] as bool? ?? false,
verbose: result['verbose'] as bool? ?? false,
buildRunnerWatch: result['watch'] as bool? ?? false,
);
final mode = summary.dryRun ? 'dry-run' : 'written';
stdout.writeln(
'[koi_swagger_parser] $mode ${summary.writtenFiles.length} file(s), '
'${summary.operationsCount} operation(s), '
'${summary.modelsCount} model(s).',
);
for (final diagnostic in summary.diagnostics) {
if (diagnostic.severity == DiagnosticSeverity.info &&
!(result['verbose'] as bool? ?? false)) {
continue;
}
stderr.writeln('[koi_swagger_parser] ${diagnostic.format()}');
}
if (summary.dryRun) {
stdout.writeln(
'[koi_swagger_parser] dry-run: '
'${summary.wouldWriteFiles.length} file(s) would be written, '
'${summary.wouldDeleteFiles.length} stale file(s) would be deleted; '
'${summary.operationsCount} operation(s), '
'${summary.modelsCount} model(s).',
);
} else if (summary.skippedUnchanged) {
stdout.writeln(
'[koi_swagger_parser] unchanged: skipped '
'${summary.generatedFiles.length} generated file(s); '
'${summary.operationsCount} operation(s), '
'${summary.modelsCount} model(s).',
);
} else {
stdout.writeln(
'[koi_swagger_parser] wrote ${summary.writtenFiles.length} file(s), '
'deleted ${summary.deletedFiles.length} stale file(s), '
'manages ${summary.generatedFiles.length} file(s); '
'${summary.operationsCount} operation(s), '
'${summary.modelsCount} model(s).',
);
}
} on Object catch (error, stackTrace) {
stderr.writeln('[koi_swagger_parser] generation failed: $error');
stderr.writeln('[koi_swagger_parser] Generation failed.');
if ((result['verbose'] as bool?) ?? false) {
stderr.writeln(error);
stderr.writeln(stackTrace);
} else {
stderr.writeln('使用 --verbose 可以查看详细堆栈。');
stderr.writeln('Run with --verbose to see the underlying error.');
}
stderr.writeln(parser.usage);
stderr.writeln();
stderr.writeln(_generateUsage(parser));
exitCode = 1;
}
}
@@ -72,9 +144,31 @@ String _usage(ArgParser parser) {
return [
'koi_swagger_parser',
'',
'用法:',
' dart run koi_swagger_parser generate --all',
'Generate Retrofit and Freezed Dart sources from OpenAPI 3.0 or 3.1.',
'',
'Usage:',
' koi_swagger_parser <command> [arguments]',
' dart run koi_swagger_parser <command> [arguments]',
'',
'Global options:',
parser.usage,
'',
'Available commands:',
' generate Generate API clients and models.',
'',
'Run "koi_swagger_parser generate --help" for command options.',
].join('\n');
}
String _generateUsage(ArgParser parser) {
return [
'Generate API clients and models.',
'',
'Usage:',
' koi_swagger_parser generate [options]',
' dart run koi_swagger_parser generate [options]',
'',
'Options:',
parser.usage,
].join('\n');
}