run method

  1. @override
Future<void> run(
  1. Iterable<String> args
)
override

Parses args and invokes Command.run on the chosen command.

This always returns a Future in case the command is asynchronous. The Future will throw a UsageException if args was invalid.

Implementation

@override
Future<void> run(Iterable<String> args) async {
  // Contextual backend is used by default; no hierarchical setup required.

  try {
    // Parse arguments
    final argResults = argParser.parse(args);

    if (argResults['help'] as bool) {
      throw UsageException(usage, usage);
    }

    final config = LuaLikeConfig();
    final useIr = argResults['ir'] as bool;
    final useLuaBytecode = argResults['lua-bytecode'] as bool;
    final useAst = argResults['ast'] as bool;
    if (useLuaBytecode) {
      config.defaultEngineMode = EngineMode.luaBytecode;
    } else if (useIr || !useAst) {
      config.defaultEngineMode = EngineMode.ir;
    } else {
      config.defaultEngineMode = EngineMode.ast;
    }
    config.dumpIr = argResults['dump-ir'] as bool;
    BaseCommand.resetBridge();

    // Handle debug mode
    if (argResults['debug'] as bool) {
      debugMode = true;
      print('Debug mode enabled');
    }

    // Set up logging
    final logLevel = argResults['level'] as String?;
    final logCategories =
        (argResults['category'] as List<String>?) ?? const <String>[];

    ctx.Level? cliLevel;
    if (logLevel != null && logLevel.isNotEmpty) {
      cliLevel = parseLogLevel(logLevel) ?? ctx.Level.warning;
    }

    setLualikeLogging(
      enabled: debugMode,
      level: cliLevel,
      categories: logCategories.isEmpty ? null : logCategories,
    );

    // Note: execution mode is handled by individual commands

    // Handle special case where no arguments provided
    if (args.isEmpty) {
      if (stdin.hasTerminal) {
        // Terminal mode: show version and enter interactive mode
        final versionCmd = VersionCommand();
        await versionCmd.run();
        final interactiveCmd = InteractiveCommandWrapper(
          debugMode: debugMode,
        );
        await interactiveCmd.run();
      } else {
        // Non-terminal mode: read from stdin
        final stdinCmd = StdinCommand([], args.toList());
        await stdinCmd.run();
      }
      return;
    }

    // Handle special case for single '-' argument (stdin)
    if (args.length == 1 && args.first == '-') {
      final stdinCmd = StdinCommand([], args.toList());
      await stdinCmd.run();
      return;
    }

    // Handle version flag
    if (argResults['version'] as bool) {
      final versionCmd = VersionCommand();
      await versionCmd.run();
    }

    // Handle LUA_INIT using BaseCommand functionality
    final baseCmd = _LuaInitCommand();
    await baseCmd.handleLuaInit();

    // Handle require files (-l)
    final requireFiles = argResults['require'] as List<String>;
    for (final file in requireFiles) {
      final requireCmd = RequireCommand(file, args.toList());
      await requireCmd.run();
    }

    // Handle execute strings (-e)
    final executeStrings = argResults['execute'] as List<String>;
    for (final code in executeStrings) {
      final executeCmd = ExecuteCommand(code, args.toList());
      await executeCmd.run();
    }

    // Handle script file and arguments
    final restArgs = argResults.rest;
    if (restArgs.isNotEmpty) {
      final scriptPath = restArgs.first;
      final scriptArgs = restArgs.skip(1).toList();
      final scriptCmd = ScriptCommand(scriptPath, scriptArgs, args.toList());
      await scriptCmd.run();
    }

    // Handle interactive mode (-i)
    if (argResults['interactive'] as bool) {
      final interactiveCmd = InteractiveCommandWrapper(debugMode: debugMode);
      await interactiveCmd.run();
    }
  } catch (e) {
    if (e is UsageException) {
      print(usage);
      exit(1);
    }
    rethrow;
  }
}