# repostack run [options] -- <command>

> 

在选中的 repo 上批量执行 shell 命令。

```bash
repostack run [options] -- <command>
```

**重要**：命令前必须加 `--` 分隔符！

## 选项

| 选项                | 说明                  |
| ----------------- | ------------------- |
| `--repos <names>` | 逗号分隔的 repo 名称列表     |
| `--view <name>`   | 使用预定义的命名视图          |
| `--tags <tags>`   | 逗号分隔的标签列表（匹配所有指定标签） |

## 交互式 repo 选择

在 **TTY 终端**中，如果未提供 `--repos` 和 `--view`，`repostack run` 会自动进入交互式多选界面，使用空格勾选要执行命令的 repo，按回车确认。非 TTY 环境（如 CI）则会报错退出。

```bash
repostack run -- pnpm test
# TTY 下会弹出 repo 选择器
```

## 执行流程

<steps level="4">

#### **参数解析**- `--` 之后的所有内容会被捕获为要执行的命令数组。
- 如果未提供命令，报错并退出。





#### **加载配置**- 读取 `repostack.yaml` 和 `.repostackrc`（如果启用了用户配置）。





#### **解析目标 repo 列表**- 若未指定 `--repos` 和 `--view`：

  - **TTY 环境**：弹出交互式多选，让用户勾选目标 repo。
  - **非 TTY 环境**：报错退出，提示缺少 `--repos` 或 `--view`。
- 若已指定过滤条件，逐步过滤出最终要操作的 repo：

  1. 若指定 `--view`，先解析该视图（视图本身可嵌套引用其他视图）。
  2. 若指定 `--repos`，从视图结果中再过滤出指定的 repo 名称。
  3. 若指定 `--tags`，要求 repo **同时包含所有指定标签**才能保留。
- 若 `--view` 指向不存在的视图，抛出 `Unknown view: <view>`。





#### **确定 Shell**- 从 `config.settings.shell` 获取，支持字符串或按平台配置的对象（`windows` / `macos` / `linux`）。
- 未配置时回退到 `$SHELL` 环境变量，再回退到系统默认（Windows 为 `cmd.exe`，其他为 `bash`）。





#### **执行命令**- 使用并发池执行，并发数 = `min(config.settings.concurrency, 目标 repo 数量)`，默认并发数为 **4**。
- 每个 worker 在对应 repo 目录下执行：`<shell> -c "<command>"`。
- **TTY 进度提示**：在 TTY 终端中会显示 `spinner` 进度，实时展示当前正在执行的 repo 以及完成状态（`done` / `failed`）。





#### **结果输出**- 输出顺序为**任务完成顺序**，而不是配置中的定义顺序。
- 每个 repo 的结果前会打印 `== <repo> ==` 分隔符。
- 若 `settings.continueOnError` 为 `false`（默认），任一 repo 返回非零 exit code 时：

  - 已启动的任务会继续跑完。
  - 但不再启动新任务。
  - CLI 会以第一个遇到的非零 exit code 退出，且不会打印后续 repo 的结果。





</steps>

## 过滤规则示例

多个过滤条件组合时取**交集**：

```bash
# 属于 runtime view 且同时在 foo,bar 列表中
repostack run --view runtime --repos foo,bar -- pnpm test

# 有 runtime 标签且有 core 标签的 repo
repostack run --tags runtime,core -- pnpm build
```

## 涉及文件

| 文件               | 操作  |
| ---------------- | --- |
| `repostack.yaml` | 读取  |
| `.repostackrc`   | 读取  |

## 错误信息

| 场景                | 错误信息                                                                                                 |
| ----------------- | ---------------------------------------------------------------------------------------------------- |
| 缺少 shell 命令       | `Missing shell command for \`repostack run`. Usage: repostack run <span>options</span> -- <command>` |
| 缺少 repo 目标（非 TTY） | `Missing --repos or --view for non-interactive environment.`                                         |
| 未知视图              | `Unknown view: <view>`                                                                               |
| 命令执行失败            | 输出 stderr，并返回该命令的 exit code                                                                          |

## 边界情况

- 如果过滤后**没有匹配到任何 repo**，不会报错，只是没有任何输出。
- TTY 环境下未指定 `--repos` 或 `--view` 时会进入交互式 `multiselect`，可空格多选 repo。
- `--repos` 和 `--tags` 都支持逗号分隔，会自动去重并过滤空字符串。
- 命令中的空格和引号由 shell 解释，repostack 只负责透传字符串。

## 示例

```bash
# 在所有 repo 上执行
repostack run -- git status

# 在指定 repos 上执行
repostack run --repos foo,bar -- pnpm build

# 使用 view
repostack run --view runtime -- pnpm test

# 使用 tags
repostack run --tags core -- pnpm lint

# 复杂命令（注意 -- 分隔）
repostack run --repos foo -- -- sh -c "git log --oneline -5"

# 带额外参数的命令
repostack run --view frontend -- pnpm build --watch
```
