import 'dart:io'; import 'package:args/args.dart'; import 'package:koi_swagger_parser/koi_swagger_parser.dart'; Future main(List arguments) async { final parser = ArgParser() ..addFlag('help', abbr: 'h', negatable: false, help: 'Show command help.'); final generateParser = ArgParser() ..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: ${error.message}'); stderr.writeln(); stderr.writeln(_usage(parser)); exitCode = 64; return; } if ((result['help'] as bool?) ?? false) { stdout.writeln(_usage(parser)); return; } final command = result.command; 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; } stdout.writeln(_usage(parser)); } Future _runGenerate(ArgResults result, ArgParser parser) async { final generator = const KoiSwaggerParser(); try { final summary = await generator.generate( configPath: result['config'] as String?, workingDirectory: result['cwd'] as String?, dryRun: result['dry-run'] as bool? ?? false, verbose: result['verbose'] as bool? ?? false, buildRunnerWatch: result['watch'] as bool? ?? false, ); 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.'); if ((result['verbose'] as bool?) ?? false) { stderr.writeln(error); stderr.writeln(stackTrace); } else { stderr.writeln('Run with --verbose to see the underlying error.'); } stderr.writeln(); stderr.writeln(_generateUsage(parser)); exitCode = 1; } } String _usage(ArgParser parser) { return [ 'koi_swagger_parser', '', 'Generate Retrofit and Freezed Dart sources from OpenAPI 3.0 or 3.1.', '', 'Usage:', ' koi_swagger_parser [arguments]', ' dart run koi_swagger_parser [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'); }