remote-docker-cli 0.2.0__tar.gz → 0.3.1__tar.gz

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.
@@ -150,4 +150,8 @@ cython_debug/
150
150
  /.hatch/
151
151
  /build_artifacts/
152
152
 
153
- uv.lock
153
+ .opencode
154
+ uv.lock
155
+
156
+ # rdocker kaggle notebook staging dir (created by `rdocker kaggle upload`)
157
+ .kaggle/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: remote-docker-cli
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: A CLI tool for managing remote Docker hosts
5
5
  Project-URL: Homepage, https://gitee.com/kzhuo/remote-docker
6
6
  Project-URL: Issues, https://gitee.com/kzhuo/remote-docker/issues
@@ -24,8 +24,8 @@ Classifier: Topic :: System :: Systems Administration
24
24
  Requires-Python: >=3.10
25
25
  Requires-Dist: click
26
26
  Requires-Dist: pyyaml
27
- Provides-Extra: all
28
- Requires-Dist: paramiko>=3.0; extra == 'all'
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == 'dev'
29
29
  Provides-Extra: ssh
30
30
  Requires-Dist: paramiko>=3.0; extra == 'ssh'
31
31
  Description-Content-Type: text/markdown
@@ -64,6 +64,29 @@ Description-Content-Type: text/markdown
64
64
 
65
65
  `skopeo copy` 会带上 `--override-arch` 选项,自动按本地机器架构 (`amd64` / `arm64` / ...) 拉取对应镜像清单。
66
66
 
67
+ ### 可选通道:Kaggle(无需 SSH 跳板机)
68
+
69
+ ```
70
+ 本地机器 Kaggle (Notebook)
71
+ ┌────────────────────┐ ┌──────────────────────────────┐
72
+ │ docker-compose.yml │ │ /kaggle/working/<name>/ │
73
+ └────────┬───────────┘ │ ├── nginx_latest.tar │
74
+ │ 解析 + 自动补 :latest │ ├── redis_7-alpine.tar │
75
+ ▼ │ └── ... │
76
+ 镜像列表 ──`kaggle kernels push`───▶ │ skopeo copy --override-arch │
77
+ (在 .kaggle/<name>/ 暂存) │ │
78
+ │ tar -czf <name>.tar.gz . │
79
+ └──────────────┬───────────────┘
80
+ │ output
81
+ ▼
82
+ ./<name>.tar.gz ← 本地产物
83
+ │ docker load
84
+ ▼
85
+ 本地 Docker 引擎
86
+ ```
87
+
88
+ 详见 [Kaggle 通道](#kaggle-通道) 一节。
89
+
67
90
  ---
68
91
 
69
92
  ## 安装
@@ -73,16 +96,16 @@ Description-Content-Type: text/markdown
73
96
  ### 使用 pip
74
97
 
75
98
  ```bash
76
- pip install remote-docker
99
+ pip install remote-docker-cli
77
100
 
78
101
  # 可选:启用 paramiko 后端(当前版本使用系统 ssh,可不装)
79
- pip install "remote-docker[ssh]"
102
+ pip install "remote-docker-cli[ssh]"
80
103
  ```
81
104
 
82
105
  ### 从源码安装(推荐使用 uv)
83
106
 
84
107
  ```bash
85
- git clone https://github.com/kzhuo/remote-docker.git
108
+ git clone https://gitee.com/kzhuo/remote-docker.git
86
109
  cd remote-docker
87
110
  uv sync
88
111
  uv pip install -e .
@@ -92,6 +115,7 @@ uv pip install -e .
92
115
 
93
116
  ```bash
94
117
  rdocker --help
118
+ rdocker version # 查看版本
95
119
  ```
96
120
 
97
121
  ### 远端机器前置条件
@@ -211,7 +235,20 @@ $ rdocker_HOST=override.host rdocker config show
211
235
 
212
236
  所有动作命令均支持 `--try` 干跑:仅打印将要执行的 ssh / scp / skopeo 命令,不实际执行。
213
237
 
214
- `--name` 缺省规则:
238
+ ### `rdocker version`
239
+
240
+ 打印当前安装的 rdocker 版本:
241
+
242
+ ```bash
243
+ $ rdocker version
244
+ rdocker 0.3.1
245
+ ```
246
+
247
+ ### 通用选项
248
+
249
+ - `--host / --user / --port / --key` — 可在任意子命令上直接覆盖 SSH 连接参数(默认从配置文件/环境变量读取),优先级与配置一致。
250
+
251
+ ### `--name` 缺省规则:
215
252
  - **compose 模式**(`pull` / `all` / `save` / `fetch` / `cleanup`) → 当前目录最后一级目录名
216
253
  - **image 模式**(`spull`) → 镜像去除 tag 后的最后一段(如 `nginx:1.25-alpine` → `nginx`,`registry:5000/myapp:v1` → `myapp`)
217
254
 
@@ -285,18 +322,18 @@ rdocker fetch --name mybundle --output-dir ./dist --try
285
322
  - `--output-dir, -o` — 本地输出目录(默认:`.`)
286
323
  - `--try` — 干跑模式
287
324
 
288
- ### `rdocker load [--name <bundle> | --file <tar.gz>] [--try]`
289
- 解压本地 `.tar.gz` 并依次 `docker load` 每个镜像;如果本地文件不存在且指定了 `--name`,会自动从远端 fetch。
325
+ ### `rdocker load <tar.gz> [--try]`
326
+ 解压本地 `.tar.gz` 并依次 `docker load` 每个镜像。`FILE` 是必填的位置参数;不再支持 `--name`/`--file` 选项,也不再自动从远端 fetch —— 需要远端文件时请显式 `rdocker fetch` / `rdocker kaggle fetch` 之后再 `rdocker load`。
290
327
 
291
328
  ```bash
292
- rdocker load --name mybundle
293
- rdocker load --file ./mybundle.tar.gz
294
- rdocker load --name mybundle --try # 本地无文件时打印会触发的 scp + load
329
+ rdocker load ./mybundle.tar.gz
330
+ rdocker load ./myapp.tar.gz --try # 打印将要执行的 tar 解压 + docker load 命令
295
331
  ```
296
332
 
333
+ 参数:
334
+ - `FILE` — 本地 `.tar.gz` 文件路径(必填,必须存在)
335
+
297
336
  选项:
298
- - `--name, -n` — Bundle 名称(与 `--file` 二选一)
299
- - `--file, -f` — 本地 `.tar.gz` 文件路径
300
337
  - `--try` — 干跑模式
301
338
 
302
339
  ### `rdocker cleanup [--name <bundle>] [--try]`
@@ -313,6 +350,84 @@ rdocker cleanup --name mybundle --try
313
350
 
314
351
  ---
315
352
 
353
+ ## Kaggle 通道
354
+
355
+ 无 SSH 跳板机时,可把镜像拉取与打包放到 Kaggle 的一次性 notebook 上跑,产出的 `.tar.gz` 走 `kaggle kernels output` 下载到本地,再被 `rdocker load` 直接消费。
356
+
357
+ ### 前置条件
358
+
359
+ 1. Kaggle 账号(任意注册方式都可)。
360
+ 2. `pip install kaggle`(Python ≥ 3.10)。
361
+ 3. 配置 Kaggle 凭据,使 `kaggle config view` 能输出非空 `username`:
362
+ - 首次会引导你把 API token 放到 `~/.kaggle/credentials.json`,**或**
363
+ - 设置环境变量 `KAGGLE_USERNAME` / `KAGGLE_KEY`。
364
+ 4. 验证:`kaggle config view` 应当看到一行 `- username: <你的名字>`。
365
+
366
+ ### 三步工作流
367
+
368
+ ```bash
369
+ # 1. 解析 compose 并推送一个 notebook 到 Kaggle
370
+ rdocker kaggle upload docker-compose.yml --name myapp
371
+
372
+ # 2. 等待 kernel 在 Kaggle 网站跑完(通常几分钟)
373
+ # 可在 https://www.kaggle.com/<username>/rdocker-myapp 看日志
374
+
375
+ # 3. 下载产出的 .tar.gz 到本地
376
+ rdocker kaggle fetch --name myapp
377
+
378
+ # 4. 加载到本地 Docker
379
+ rdocker load ./myapp.tar.gz
380
+ ```
381
+
382
+ ### `rdocker kaggle upload <compose_file> [--name <bundle>] [--try]`
383
+
384
+ 解析 `docker-compose.yml`、在 `.kaggle/<bundle>/` 暂存一个 `rdocker.py` 与 `kernel-metadata.json`、调用 `kaggle kernels push` 推上去。`--try` 模式下不写盘也不推送,只在 stdout 打印将要上传的 notebook 完整内容(含 skopeo 安装段、镜像循环、最终 tar 打包),方便审核。
385
+
386
+ ```bash
387
+ rdocker kaggle upload docker-compose.yml # --name 缺省 = cwd 短名
388
+ rdocker kaggle upload docker-compose.yml --name prod --registry-auth admin:pass
389
+ rdocker kaggle upload docker-compose.yml --arch arm64 # 覆盖镜像架构
390
+ rdocker kaggle upload docker-compose.yml --try # 只打印不推送
391
+ ```
392
+
393
+ 选项:
394
+ - `--name, -n` — Bundle 名称(缺省 = cwd 短名)
395
+ - `--registry-auth, -a` — 镜像仓库认证 `user:pass`
396
+ - `--arch` — 覆盖镜像架构(如 `amd64`、`arm64`、`ppc64le`、`s390x`、`386`、`arm`;缺省 = 本地自动探测)
397
+ - `--try` — 干跑:只打印 notebook 内容
398
+
399
+ ### `rdocker kaggle fetch [--name <bundle>] [--output-dir <dir>] [--try]`
400
+
401
+ 从 Kaggle 下载 `<bundle>.tar.gz` 到本地。下载后可被 `rdocker load <bundle>.tar.gz` 直接消费。
402
+
403
+ ```bash
404
+ rdocker kaggle fetch --name myapp # 下载到 cwd
405
+ rdocker kaggle fetch --name myapp --output-dir ./dist # 下载到 ./dist
406
+ rdocker kaggle fetch --name myapp --try # 只打印命令
407
+ ```
408
+
409
+ 选项:
410
+ - `--name, -n` — Bundle 名称(缺省 = cwd 短名)
411
+ - `--output-dir, -o` — 本地输出目录(默认:`.`)
412
+ - `--try` — 干跑:只打印 `kaggle kernels output` 命令
413
+
414
+ ### 内部机制
415
+
416
+ - **username 解析**:`rdocker` 不直接读 `~/.kaggle/credentials.json`,而是 `subprocess.run(["kaggle", "config", "view"])` 并解析 `- username: <name>` 行 —— 自动跟随 Kaggle CLI 自身的配置源优先级(环境变量 > `~/.kaggle/` > `/etc/kaggle.json`)。
417
+ - **kernel 命名**:固定为 `<username>/rdocker-<bundle>`,私有(`is_private: true`),便于 `fetch` 端稳定定位。
418
+ - **架构**:`skopeo --override-arch <local_arch>` 的 arch 在本地计算后注入 notebook,确保拉到的镜像清单与本地 Docker 引擎匹配。
419
+ - **skopeo 兜底**:notebook 第一段是 `which skopeo || apt-get install -y skopeo || pip install skopeo`(Kaggle 基础镜像通常自带,但本工具不依赖此假设)。
420
+
421
+ ### 常见问题
422
+
423
+ - **kaggle CLI 缺失 / 未配置** → `pip install kaggle` 后 `kaggle config view` 验证。`rdocker` 会把错误指向这两步。
424
+ - **kernel 跑失败** → 在 https://www.kaggle.com/<username>/rdocker-<bundle> 看 stderr;常因镜像仓库私有需 `--registry-auth`,或 compose 中含 Kaggle 网络策略拉不到的镜像。
425
+ - **arch 不匹配** → `rdocker` 默认按本地 `platform.machine()` 注入 `--override-arch`;如需拉取其他架构的镜像,使用 `rdocker kaggle upload --arch <arch>` 覆盖(如 `amd64`、`arm64`)。
426
+ - **output 还没生成** → `kaggle kernels output` 报错时直接看返回的 stderr;常见原因是 kernel 仍在排队(免费版 CPU 偶尔排队几分钟)或已失败。
427
+ - **`.kaggle/` 目录膨胀** → 该目录在 CWD 下,是 `kaggle kernels push` 的暂存区,可随时 `rm -rf .kaggle`。
428
+
429
+ ---
430
+
316
431
  ## 环境变量
317
432
 
318
433
  | 变量 | 对应配置 | 说明 |
@@ -361,7 +476,9 @@ remote-docker/
361
476
  │ └── remote_docker/
362
477
  │ ├── __init__.py # 包元信息 (__version__)
363
478
  │ ├── __main__.py # python -m remote_docker 入口
364
- │ └── cli.py # Click CLI 主体
479
+ │ ├── cli.py # Click CLI 主体
480
+ │ └── tests/ # pytest 测试
481
+ ├── openspec/ # OpenSpec 变更规格(如 add-kaggle-support)
365
482
  ├── pyproject.toml # 项目与依赖配置(hatchling 构建)
366
483
  ├── uv.lock # uv 锁定文件
367
484
  └── README.md
@@ -32,6 +32,29 @@
32
32
 
33
33
  `skopeo copy` 会带上 `--override-arch` 选项,自动按本地机器架构 (`amd64` / `arm64` / ...) 拉取对应镜像清单。
34
34
 
35
+ ### 可选通道:Kaggle(无需 SSH 跳板机)
36
+
37
+ ```
38
+ 本地机器 Kaggle (Notebook)
39
+ ┌────────────────────┐ ┌──────────────────────────────┐
40
+ │ docker-compose.yml │ │ /kaggle/working/<name>/ │
41
+ └────────┬───────────┘ │ ├── nginx_latest.tar │
42
+ │ 解析 + 自动补 :latest │ ├── redis_7-alpine.tar │
43
+ ▼ │ └── ... │
44
+ 镜像列表 ──`kaggle kernels push`───▶ │ skopeo copy --override-arch │
45
+ (在 .kaggle/<name>/ 暂存) │ │
46
+ │ tar -czf <name>.tar.gz . │
47
+ └──────────────┬───────────────┘
48
+ │ output
49
+ ▼
50
+ ./<name>.tar.gz ← 本地产物
51
+ │ docker load
52
+ ▼
53
+ 本地 Docker 引擎
54
+ ```
55
+
56
+ 详见 [Kaggle 通道](#kaggle-通道) 一节。
57
+
35
58
  ---
36
59
 
37
60
  ## 安装
@@ -41,16 +64,16 @@
41
64
  ### 使用 pip
42
65
 
43
66
  ```bash
44
- pip install remote-docker
67
+ pip install remote-docker-cli
45
68
 
46
69
  # 可选:启用 paramiko 后端(当前版本使用系统 ssh,可不装)
47
- pip install "remote-docker[ssh]"
70
+ pip install "remote-docker-cli[ssh]"
48
71
  ```
49
72
 
50
73
  ### 从源码安装(推荐使用 uv)
51
74
 
52
75
  ```bash
53
- git clone https://github.com/kzhuo/remote-docker.git
76
+ git clone https://gitee.com/kzhuo/remote-docker.git
54
77
  cd remote-docker
55
78
  uv sync
56
79
  uv pip install -e .
@@ -60,6 +83,7 @@ uv pip install -e .
60
83
 
61
84
  ```bash
62
85
  rdocker --help
86
+ rdocker version # 查看版本
63
87
  ```
64
88
 
65
89
  ### 远端机器前置条件
@@ -179,7 +203,20 @@ $ rdocker_HOST=override.host rdocker config show
179
203
 
180
204
  所有动作命令均支持 `--try` 干跑:仅打印将要执行的 ssh / scp / skopeo 命令,不实际执行。
181
205
 
182
- `--name` 缺省规则:
206
+ ### `rdocker version`
207
+
208
+ 打印当前安装的 rdocker 版本:
209
+
210
+ ```bash
211
+ $ rdocker version
212
+ rdocker 0.3.1
213
+ ```
214
+
215
+ ### 通用选项
216
+
217
+ - `--host / --user / --port / --key` — 可在任意子命令上直接覆盖 SSH 连接参数(默认从配置文件/环境变量读取),优先级与配置一致。
218
+
219
+ ### `--name` 缺省规则:
183
220
  - **compose 模式**(`pull` / `all` / `save` / `fetch` / `cleanup`) → 当前目录最后一级目录名
184
221
  - **image 模式**(`spull`) → 镜像去除 tag 后的最后一段(如 `nginx:1.25-alpine` → `nginx`,`registry:5000/myapp:v1` → `myapp`)
185
222
 
@@ -253,18 +290,18 @@ rdocker fetch --name mybundle --output-dir ./dist --try
253
290
  - `--output-dir, -o` — 本地输出目录(默认:`.`)
254
291
  - `--try` — 干跑模式
255
292
 
256
- ### `rdocker load [--name <bundle> | --file <tar.gz>] [--try]`
257
- 解压本地 `.tar.gz` 并依次 `docker load` 每个镜像;如果本地文件不存在且指定了 `--name`,会自动从远端 fetch。
293
+ ### `rdocker load <tar.gz> [--try]`
294
+ 解压本地 `.tar.gz` 并依次 `docker load` 每个镜像。`FILE` 是必填的位置参数;不再支持 `--name`/`--file` 选项,也不再自动从远端 fetch —— 需要远端文件时请显式 `rdocker fetch` / `rdocker kaggle fetch` 之后再 `rdocker load`。
258
295
 
259
296
  ```bash
260
- rdocker load --name mybundle
261
- rdocker load --file ./mybundle.tar.gz
262
- rdocker load --name mybundle --try # 本地无文件时打印会触发的 scp + load
297
+ rdocker load ./mybundle.tar.gz
298
+ rdocker load ./myapp.tar.gz --try # 打印将要执行的 tar 解压 + docker load 命令
263
299
  ```
264
300
 
301
+ 参数:
302
+ - `FILE` — 本地 `.tar.gz` 文件路径(必填,必须存在)
303
+
265
304
  选项:
266
- - `--name, -n` — Bundle 名称(与 `--file` 二选一)
267
- - `--file, -f` — 本地 `.tar.gz` 文件路径
268
305
  - `--try` — 干跑模式
269
306
 
270
307
  ### `rdocker cleanup [--name <bundle>] [--try]`
@@ -281,6 +318,84 @@ rdocker cleanup --name mybundle --try
281
318
 
282
319
  ---
283
320
 
321
+ ## Kaggle 通道
322
+
323
+ 无 SSH 跳板机时,可把镜像拉取与打包放到 Kaggle 的一次性 notebook 上跑,产出的 `.tar.gz` 走 `kaggle kernels output` 下载到本地,再被 `rdocker load` 直接消费。
324
+
325
+ ### 前置条件
326
+
327
+ 1. Kaggle 账号(任意注册方式都可)。
328
+ 2. `pip install kaggle`(Python ≥ 3.10)。
329
+ 3. 配置 Kaggle 凭据,使 `kaggle config view` 能输出非空 `username`:
330
+ - 首次会引导你把 API token 放到 `~/.kaggle/credentials.json`,**或**
331
+ - 设置环境变量 `KAGGLE_USERNAME` / `KAGGLE_KEY`。
332
+ 4. 验证:`kaggle config view` 应当看到一行 `- username: <你的名字>`。
333
+
334
+ ### 三步工作流
335
+
336
+ ```bash
337
+ # 1. 解析 compose 并推送一个 notebook 到 Kaggle
338
+ rdocker kaggle upload docker-compose.yml --name myapp
339
+
340
+ # 2. 等待 kernel 在 Kaggle 网站跑完(通常几分钟)
341
+ # 可在 https://www.kaggle.com/<username>/rdocker-myapp 看日志
342
+
343
+ # 3. 下载产出的 .tar.gz 到本地
344
+ rdocker kaggle fetch --name myapp
345
+
346
+ # 4. 加载到本地 Docker
347
+ rdocker load ./myapp.tar.gz
348
+ ```
349
+
350
+ ### `rdocker kaggle upload <compose_file> [--name <bundle>] [--try]`
351
+
352
+ 解析 `docker-compose.yml`、在 `.kaggle/<bundle>/` 暂存一个 `rdocker.py` 与 `kernel-metadata.json`、调用 `kaggle kernels push` 推上去。`--try` 模式下不写盘也不推送,只在 stdout 打印将要上传的 notebook 完整内容(含 skopeo 安装段、镜像循环、最终 tar 打包),方便审核。
353
+
354
+ ```bash
355
+ rdocker kaggle upload docker-compose.yml # --name 缺省 = cwd 短名
356
+ rdocker kaggle upload docker-compose.yml --name prod --registry-auth admin:pass
357
+ rdocker kaggle upload docker-compose.yml --arch arm64 # 覆盖镜像架构
358
+ rdocker kaggle upload docker-compose.yml --try # 只打印不推送
359
+ ```
360
+
361
+ 选项:
362
+ - `--name, -n` — Bundle 名称(缺省 = cwd 短名)
363
+ - `--registry-auth, -a` — 镜像仓库认证 `user:pass`
364
+ - `--arch` — 覆盖镜像架构(如 `amd64`、`arm64`、`ppc64le`、`s390x`、`386`、`arm`;缺省 = 本地自动探测)
365
+ - `--try` — 干跑:只打印 notebook 内容
366
+
367
+ ### `rdocker kaggle fetch [--name <bundle>] [--output-dir <dir>] [--try]`
368
+
369
+ 从 Kaggle 下载 `<bundle>.tar.gz` 到本地。下载后可被 `rdocker load <bundle>.tar.gz` 直接消费。
370
+
371
+ ```bash
372
+ rdocker kaggle fetch --name myapp # 下载到 cwd
373
+ rdocker kaggle fetch --name myapp --output-dir ./dist # 下载到 ./dist
374
+ rdocker kaggle fetch --name myapp --try # 只打印命令
375
+ ```
376
+
377
+ 选项:
378
+ - `--name, -n` — Bundle 名称(缺省 = cwd 短名)
379
+ - `--output-dir, -o` — 本地输出目录(默认:`.`)
380
+ - `--try` — 干跑:只打印 `kaggle kernels output` 命令
381
+
382
+ ### 内部机制
383
+
384
+ - **username 解析**:`rdocker` 不直接读 `~/.kaggle/credentials.json`,而是 `subprocess.run(["kaggle", "config", "view"])` 并解析 `- username: <name>` 行 —— 自动跟随 Kaggle CLI 自身的配置源优先级(环境变量 > `~/.kaggle/` > `/etc/kaggle.json`)。
385
+ - **kernel 命名**:固定为 `<username>/rdocker-<bundle>`,私有(`is_private: true`),便于 `fetch` 端稳定定位。
386
+ - **架构**:`skopeo --override-arch <local_arch>` 的 arch 在本地计算后注入 notebook,确保拉到的镜像清单与本地 Docker 引擎匹配。
387
+ - **skopeo 兜底**:notebook 第一段是 `which skopeo || apt-get install -y skopeo || pip install skopeo`(Kaggle 基础镜像通常自带,但本工具不依赖此假设)。
388
+
389
+ ### 常见问题
390
+
391
+ - **kaggle CLI 缺失 / 未配置** → `pip install kaggle` 后 `kaggle config view` 验证。`rdocker` 会把错误指向这两步。
392
+ - **kernel 跑失败** → 在 https://www.kaggle.com/<username>/rdocker-<bundle> 看 stderr;常因镜像仓库私有需 `--registry-auth`,或 compose 中含 Kaggle 网络策略拉不到的镜像。
393
+ - **arch 不匹配** → `rdocker` 默认按本地 `platform.machine()` 注入 `--override-arch`;如需拉取其他架构的镜像,使用 `rdocker kaggle upload --arch <arch>` 覆盖(如 `amd64`、`arm64`)。
394
+ - **output 还没生成** → `kaggle kernels output` 报错时直接看返回的 stderr;常见原因是 kernel 仍在排队(免费版 CPU 偶尔排队几分钟)或已失败。
395
+ - **`.kaggle/` 目录膨胀** → 该目录在 CWD 下,是 `kaggle kernels push` 的暂存区,可随时 `rm -rf .kaggle`。
396
+
397
+ ---
398
+
284
399
  ## 环境变量
285
400
 
286
401
  | 变量 | 对应配置 | 说明 |
@@ -329,7 +444,9 @@ remote-docker/
329
444
  │ └── remote_docker/
330
445
  │ ├── __init__.py # 包元信息 (__version__)
331
446
  │ ├── __main__.py # python -m remote_docker 入口
332
- │ └── cli.py # Click CLI 主体
447
+ │ ├── cli.py # Click CLI 主体
448
+ │ └── tests/ # pytest 测试
449
+ ├── openspec/ # OpenSpec 变更规格(如 add-kaggle-support)
333
450
  ├── pyproject.toml # 项目与依赖配置(hatchling 构建)
334
451
  ├── uv.lock # uv 锁定文件
335
452
  └── README.md
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "remote-docker-cli"
7
- version = "0.2.0"
7
+ dynamic = ["version"]
8
8
  description = "A CLI tool for managing remote Docker hosts"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -37,8 +37,8 @@ dependencies = [
37
37
  ssh = [
38
38
  "paramiko>=3.0",
39
39
  ]
40
- all = [
41
- "remote-docker-cli[ssh]",
40
+ dev = [
41
+ "pytest>=7.0",
42
42
  ]
43
43
 
44
44
  [project.scripts]
@@ -49,13 +49,15 @@ Homepage = "https://gitee.com/kzhuo/remote-docker"
49
49
  Issues = "https://gitee.com/kzhuo/remote-docker/issues"
50
50
  Repository = "https://gitee.com/kzhuo/remote-docker"
51
51
 
52
+ [tool.hatch.version]
53
+ path = "src/remote_docker/__init__.py"
54
+
52
55
  [tool.hatch.build.targets.wheel]
53
56
  packages = ["src/remote_docker"]
54
57
 
55
58
  [tool.hatch.build.targets.sdist]
56
59
  include = [
57
60
  "src/remote_docker",
58
- "tests",
59
61
  "README.md",
60
62
  "LICENSE",
61
63
  "pyproject.toml",
@@ -65,4 +67,8 @@ exclude = [
65
67
  ".venv",
66
68
  "venv",
67
69
  "__pycache__",
68
- ]
70
+ ]
71
+
72
+ [tool.pytest.ini_options]
73
+ testpaths = ["src"]
74
+ pythonpath = ["src"]
@@ -1,3 +1,3 @@
1
1
  """remote-docker: A CLI tool for managing remote Docker hosts."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.3.1"