runCommand static method

Future<int> runCommand({
  1. required CliInvocation invocation,
  2. required Logger logger,
  3. required WorkspaceConfig workspaceConfig,
  4. required TaskExecutor executor,
  5. required GroupStore groupStore,
  6. required CommandEnvironmentBuilder envBuilder,
  7. required PluginResolver plugins,
  8. required Future<int> fallbackCommand(),
})

Implementation

static Future<int> runCommand({
  required CliInvocation invocation,
  required Logger logger,
  required WorkspaceConfig workspaceConfig,
  required TaskExecutor executor,
  required GroupStore groupStore,
  required CommandEnvironmentBuilder envBuilder,
  required PluginResolver plugins,
  required Future<int> Function() fallbackCommand,
}) async {
  final inv = invocation;

  final taskName = inv.commandPath.first;

  // Load config and merged tasks
  final loaded = await workspaceConfig.loadRootConfig();
  final extra = await workspaceConfig.readMonocfgTasks(loaded.monocfgPath);
  final mergedTasks = <String, TaskDefinition>{
    ...loaded.config.tasks,
    ..._taskDefsFromExtra(extra),
  };
  final def = mergedTasks[taskName];
  if (def == null) return fallbackCommand();

  // Determine plugin and validate target requirement for external tasks
  final pluginId = PluginId(def.plugin ?? 'exec');
  if (pluginId.value == 'exec' && inv.targets.isEmpty) {
    logger.log(
        'External tasks require explicit targets. Use "all" to run on all packages.',
        level: 'error');
    return 2;
  }

  // Build TaskSpec from definition
  final CommandId commandId;
  if (pluginId.value == 'exec') {
    if (def.run.isEmpty || def.run.first.trim().isEmpty) {
      logger.log('Task "$taskName" has no run command.', level: 'error');
      return 1;
    }
    // Execute only the first run entry for now
    commandId = CommandId('exec:${def.run.first.trim()}');
  } else if (pluginId.value == 'pub') {
    final name = taskName.trim();
    if (name == 'get') {
      commandId = const CommandId('get');
    } else if (name == 'clean') {
      commandId = const CommandId('clean');
    } else {
      logger.log('Unsupported pub task: $name', level: 'error');
      return 1;
    }
  } else if (pluginId.value == 'format') {
    final check = inv.options['check']?.isNotEmpty == true;
    commandId = CommandId(check ? 'format:check' : 'format');
  } else if (pluginId.value == 'test') {
    commandId = const CommandId('test');
  } else {
    logger.log('Unknown plugin for task "$taskName": ${pluginId.value}',
        level: 'error');
    return 1;
  }
  // Additional policy: external tasks require explicit targets
  if (pluginId.value == 'exec' && inv.targets.isEmpty) {
    logger.log(
        'External tasks require explicit targets. Use "all" to run on all packages.',
        level: 'error');
    return 2;
  }

  final task = TaskSpec(id: commandId, plugin: pluginId);
  return await executor.execute(
    task: task,
    invocation: inv,
    logger: logger,
    groupStore: groupStore,
    envBuilder: envBuilder,
    plugins: plugins,
    env: def.env,
    dryRunLabel: taskName,
  );
}