worktree-bay 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# worktree-bay
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/worktree-bay)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
> 配置驱动、与语言/技术栈无关的 **git worktree 槽位 + 端口编排器**——为多服务并行开发而生。
|
|
7
|
+
|
|
8
|
+
一个功能来了,先**占一个槽位**,用到哪个服务就在哪个服务开一个 worktree 挂进这个槽。同一槽里的所有服务共享一套**端口块**、各自独立进程,前端自动接上同槽的后端。工具替你管好 worktree 路径、端口分配、依赖、`.env` 注入与回收。
|
|
9
|
+
|
|
10
|
+
## 为什么
|
|
11
|
+
|
|
12
|
+
在 monorepo / 多仓工作区里并行开发多个功能时,git worktree 能隔离代码,但隔离不了运行时——端口会撞、依赖要重装、前端连不上你本地起在偏移端口的后端。`worktree-bay` 在 worktree 之上补一层「**功能 = 槽位**」的编排:
|
|
13
|
+
|
|
14
|
+
- **端口不撞**:每个功能占一个槽 `N`,得到端口块 `6000 + N*10`,块内各服务按固定偏移取端口。
|
|
15
|
+
- **免重装**:依赖从主 checkout 拷贝(或按服务自定义安装命令),不必每个 worktree 从头装。
|
|
16
|
+
- **前端自接后端**:前端按「同槽上游服务」自动把 api base 指向本槽后端端口。
|
|
17
|
+
- **不泄漏**:槽位占用从文件系统派生;`gc` 合并感知回收(已并入主分支且干净才删,保守不误删)。
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm i -g worktree-bay
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
需要 Node ≥ 20。
|
|
26
|
+
|
|
27
|
+
## 快速上手
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 占一个槽位
|
|
31
|
+
worktree-bay claim drill-fix # → 槽 1,端口块 6010
|
|
32
|
+
|
|
33
|
+
# 把服务挂进这个功能的槽(开 worktree + 跑该服务的步骤)
|
|
34
|
+
worktree-bay add drill-fix api feature/drill-fix # api 起在 6011
|
|
35
|
+
worktree-bay add drill-fix lms feature/drill-ui # 前端自动接 6011
|
|
36
|
+
|
|
37
|
+
# 看占用
|
|
38
|
+
worktree-bay ls
|
|
39
|
+
|
|
40
|
+
# 在服务运行体里跑命令(透传)
|
|
41
|
+
worktree-bay run drill-fix api test
|
|
42
|
+
|
|
43
|
+
# 收尾
|
|
44
|
+
worktree-bay rm drill-fix # 整槽拆除(默认查脏/未推保护,-f 强删)
|
|
45
|
+
worktree-bay gc # 合并感知回收(默认 dry-run,--apply 实际执行)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 配置
|
|
49
|
+
|
|
50
|
+
在工作区根放一份 `worktree-bay.config.json`,集中声明所有服务。工具运行时自下而上查找它(或用环境变量 `WORKTREE_BAY_CONFIG` 指定)。
|
|
51
|
+
|
|
52
|
+
```jsonc
|
|
53
|
+
{
|
|
54
|
+
"workspaceRoot": "/path/to/workspace",
|
|
55
|
+
"portBase": 6000,
|
|
56
|
+
"slotSpan": 10,
|
|
57
|
+
"maxSlots": 9,
|
|
58
|
+
"services": {
|
|
59
|
+
"api": {
|
|
60
|
+
"offset": 1,
|
|
61
|
+
"vars": { "project": "myapi-{slug}" },
|
|
62
|
+
"copy": [".env", "vendor"], // 从主 checkout 递归拷文件/目录
|
|
63
|
+
"env": { ".env": { "APP_PORT": "{port}" } }, // 合并键值进 dotenv(保留其它键)
|
|
64
|
+
"setup": "docker compose -p {project} up -d", // 挂入时执行
|
|
65
|
+
"teardown": "docker compose -p {project} down -v", // 拆除时执行
|
|
66
|
+
"exec": ["docker", "exec", "-i", "{project}-app-1", "{cmd...}"], // 透传模板(argv)
|
|
67
|
+
"run": { "test": ["composer", "run", "test"] } // 命名命令
|
|
68
|
+
},
|
|
69
|
+
"lms": {
|
|
70
|
+
"offset": 2,
|
|
71
|
+
"upstream": { "service": "api", "fallback": "http://localhost:6001" }, // → {upstreamBase}
|
|
72
|
+
"env": { ".env.dev.local": { "VITE_API_BASE_URL": "{upstreamBase}" } },
|
|
73
|
+
"setup": "pnpm install",
|
|
74
|
+
"start": "pnpm dev --port {port}" // 长进程:只打印命令,交你自起
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 原语
|
|
81
|
+
|
|
82
|
+
| 原语 | 说明 |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `offset`(必填) | 本服务端口 = `块基址 + offset`,各服务互不相同、`1 ≤ offset < slotSpan` |
|
|
85
|
+
| `repo` | 仓库目录名(相对 workspaceRoot),默认 = 服务名 |
|
|
86
|
+
| `vars` | 自定义模板变量 |
|
|
87
|
+
| `copy` | 从主 checkout 递归拷贝的文件/目录(含依赖目录) |
|
|
88
|
+
| `env` | 按文件合并 dotenv 键值,文件不存在则建 |
|
|
89
|
+
| `upstream` | 声明依赖的上游服务,产出 `{upstreamBase}` |
|
|
90
|
+
| `setup` / `teardown` | 挂入 / 拆除时执行的 shell 命令 |
|
|
91
|
+
| `start` | 长进程命令,只打印不阻塞 |
|
|
92
|
+
| `exec` | 透传命令模板(argv 数组,`{cmd...}` splice) |
|
|
93
|
+
| `run` | 命名命令(argv 数组),供 `worktree-bay run <feature> <service> <name>` |
|
|
94
|
+
|
|
95
|
+
### 模板变量
|
|
96
|
+
|
|
97
|
+
`{slot}` `{blockBase}` `{port}` `{slug}` `{worktree}` `{repo}` `{upstreamBase}` `{cmd...}`,以及 `vars` 里自定义的。
|
|
98
|
+
|
|
99
|
+
## 工作原理
|
|
100
|
+
|
|
101
|
+
- **槽位 = 端口块**:功能占槽 `N`(1..`maxSlots`)→ 端口块 `portBase + N*slotSpan`;块内服务按 `offset` 取端口。
|
|
102
|
+
- **占用从文件系统派生**:槽是否被占,看各服务 `<repo>/.worktrees/s<N>-*` 目录是否存在;`.worktree-bay-slots.json` 只是「功能名 → 槽号」的标签账本(预约)。删了 worktree,槽自动空出。
|
|
103
|
+
- **并发安全**:`claim/add/rm/gc` 全程持工作区原子锁。
|
|
104
|
+
- **前端自接**:前端有 `upstream` 时,若同槽已起该上游服务的 worktree,就把 api base 指向本槽端口;否则用 `fallback`。
|
|
105
|
+
- **合并感知回收**:`gc` 先 `git fetch`,用 `merge-base --is-ancestor` 判断是否并入主分支;**只在「已合并 + 工作区干净 + 无未推」时才自动删**,判不准一律保守不删、只标记。
|
|
106
|
+
|
|
107
|
+
## Shell 补全
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
worktree-bay completion bash >> ~/.bashrc # 或 zsh / fish
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 许可证
|
|
114
|
+
|
|
115
|
+
[MIT](./LICENSE)
|