qtcloud-devops-cli 0.1.0__tar.gz → 0.2.0__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.
Files changed (46) hide show
  1. qtcloud_devops_cli-0.2.0/.gitignore +90 -0
  2. qtcloud_devops_cli-0.2.0/AGENTS.md +165 -0
  3. qtcloud_devops_cli-0.2.0/CHANGELOG.md +71 -0
  4. qtcloud_devops_cli-0.2.0/CONTRIBUTING.md +84 -0
  5. qtcloud_devops_cli-0.2.0/Cargo.lock +1100 -0
  6. qtcloud_devops_cli-0.2.0/Cargo.toml +45 -0
  7. {qtcloud_devops_cli-0.1.0 → qtcloud_devops_cli-0.2.0}/PKG-INFO +3 -3
  8. qtcloud_devops_cli-0.2.0/README.md +107 -0
  9. qtcloud_devops_cli-0.2.0/ROADMAP.md +61 -0
  10. qtcloud_devops_cli-0.2.0/STATUS.md +44 -0
  11. qtcloud_devops_cli-0.2.0/TODO.md +35 -0
  12. qtcloud_devops_cli-0.2.0/conftest.py +6 -0
  13. qtcloud_devops_cli-0.2.0/docs/code.md +110 -0
  14. qtcloud_devops_cli-0.2.0/docs/index.md +70 -0
  15. qtcloud_devops_cli-0.2.0/docs/release.md +156 -0
  16. qtcloud_devops_cli-0.2.0/integrated_tests/conftest.py +66 -0
  17. qtcloud_devops_cli-0.2.0/integrated_tests/test_code_integration.py +238 -0
  18. qtcloud_devops_cli-0.2.0/integrated_tests/test_release_integration.py +113 -0
  19. qtcloud_devops_cli-0.2.0/pyproject.toml +31 -0
  20. qtcloud_devops_cli-0.2.0/src/commands/code.rs +495 -0
  21. qtcloud_devops_cli-0.2.0/src/commands.rs +69 -0
  22. qtcloud_devops_cli-0.2.0/src/lib.rs +5 -0
  23. qtcloud_devops_cli-0.2.0/src/main.rs +366 -0
  24. qtcloud_devops_cli-0.2.0/src/model.rs +1089 -0
  25. qtcloud_devops_cli-0.2.0/src/python.rs +132 -0
  26. qtcloud_devops_cli-0.2.0/src/qtcloud_devops_cli/cli.py +139 -0
  27. qtcloud_devops_cli-0.2.0/src/qtcloud_devops_cli/code.py +47 -0
  28. qtcloud_devops_cli-0.2.0/tests/python/test_cli_commands.py +163 -0
  29. {qtcloud_devops_cli-0.1.0/tests → qtcloud_devops_cli-0.2.0/tests/python}/test_config.py +2 -1
  30. {qtcloud_devops_cli-0.1.0/tests → qtcloud_devops_cli-0.2.0/tests/python}/test_release.py +189 -77
  31. qtcloud_devops_cli-0.2.0/tests/rust/code.rs +174 -0
  32. qtcloud_devops_cli-0.2.0/uv.lock +411 -0
  33. qtcloud_devops_cli-0.1.0/README.md +0 -65
  34. qtcloud_devops_cli-0.1.0/app/cli.py +0 -57
  35. qtcloud_devops_cli-0.1.0/pyproject.toml +0 -26
  36. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/PKG-INFO +0 -7
  37. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/SOURCES.txt +0 -15
  38. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/dependency_links.txt +0 -1
  39. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/entry_points.txt +0 -2
  40. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/requires.txt +0 -2
  41. qtcloud_devops_cli-0.1.0/qtcloud_devops_cli.egg-info/top_level.txt +0 -1
  42. qtcloud_devops_cli-0.1.0/setup.cfg +0 -4
  43. qtcloud_devops_cli-0.1.0/tests/test_cli_commands.py +0 -62
  44. {qtcloud_devops_cli-0.1.0/app → qtcloud_devops_cli-0.2.0/src/qtcloud_devops_cli}/__init__.py +0 -0
  45. {qtcloud_devops_cli-0.1.0/app → qtcloud_devops_cli-0.2.0/src/qtcloud_devops_cli}/config.py +0 -0
  46. {qtcloud_devops_cli-0.1.0/app → qtcloud_devops_cli-0.2.0/src/qtcloud_devops_cli}/release.py +0 -0
@@ -0,0 +1,90 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ build/
7
+ develop-eggs/
8
+ dist/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ share/python-wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+ *.manifest
24
+ *.spec
25
+ pip-log.txt
26
+ pip-delete-this-directory.txt
27
+ htmlcov/
28
+ .tox/
29
+ .nox/
30
+ .coverage
31
+ .coverage.*
32
+ .cache
33
+ nosetests.xml
34
+ coverage.xml
35
+ *.cover
36
+ *.py,cover
37
+ .hypothesis/
38
+ .pytest_cache/
39
+ cover/
40
+ *.mo
41
+ *.pot
42
+ *.log
43
+ local_settings.py
44
+ db.sqlite3
45
+ db.sqlite3-journal
46
+ instance/
47
+ .webassets-cache
48
+ .scrapy
49
+ docs/_build/
50
+ .pybuilder/
51
+ target/
52
+ .ipynb_checkpoints
53
+ profile_default/
54
+ ipython_config.py
55
+ .python-version
56
+ poetry.lock
57
+ .pdm.toml
58
+ .pdm-python
59
+ .pdm-build
60
+ __pypackages__/
61
+ celerybeat-schedule
62
+ celerybeat.pid
63
+ *.sage.py
64
+ .env
65
+ .venv
66
+ env/
67
+ venv/
68
+ ENV/
69
+ env.bak/
70
+ venv.bak/
71
+ .spyderproject
72
+ .spyproject
73
+ .ropeproject
74
+ /site
75
+ .mypy_cache/
76
+ .dmypy.json
77
+ dmypy.json
78
+ .pyre/
79
+ .pytype/
80
+ cython_debug/
81
+ .idea/
82
+ pdm.lock
83
+
84
+ # Editor / OS
85
+ *~
86
+ *.swp
87
+ *.swo
88
+ .DS_Store
89
+ *.iml
90
+ .vscode/
@@ -0,0 +1,165 @@
1
+ # AGENTS
2
+
3
+ ## ROADMAP
4
+
5
+ - 只记录**未完成**的事项,已完成的及时删除
6
+ - 按 P0-P3 优先级分组
7
+ - 基本假设放在末尾,不随版本迭代删除
8
+ - 新增需求先定优先级再放入对应分组
9
+
10
+ ## 开发规范
11
+
12
+ ### 单元测试覆盖率(红线 95%,黄线 98%)
13
+
14
+ 所有公开发布的公共函数和模块必须达到一定的单元测试行覆盖率。
15
+
16
+ | 级别 | 阈值 | 含义 |
17
+ |------|------|------|
18
+ | 红线 | 95% | CI 拦截线,低于此值构建失败 |
19
+ | 黄线 | 98% | 目标值,低于此值应补充测试 |
20
+
21
+ 命令:
22
+
23
+ ```sh
24
+ # Python(红线 95%)
25
+ uv run pytest --cov=app/python --cov-report=term-missing --cov-fail-under=95
26
+
27
+ # Rust(黄线 98%,仅报告不失败)
28
+ cargo llvm-cov --html --output-dir target/coverage
29
+ ```
30
+
31
+ **例外**(不纳入覆盖率统计):
32
+ - `__init__.py`(空文件)
33
+ - 纯类型定义(`pydantic` Settings 等,无业务逻辑的 `__init__.py`)
34
+ - CI 配置、入口脚本
35
+
36
+ 集成测试(`integrated_tests/`)不要求覆盖率,但单元测试(`tests/`)必须达标。
37
+
38
+ ### 糟糕单元测试示例(禁止)
39
+
40
+ 以下类型测试不会增加质量,只是徒增维护成本,AI 禁止生成:
41
+
42
+ **1. 测类型**
43
+
44
+ ```python
45
+ # ❌ pydantic Settings 类型在导入时已校验,运行时测试无意义
46
+ def test_settings_is_basemodel():
47
+ assert isinstance(settings, BaseSettings)
48
+ ```
49
+
50
+ **2. 测恒真条件**
51
+
52
+ ```python
53
+ # ❌ assert True 是凑行数
54
+ def test_version_string_not_empty():
55
+ assert __version__ != ""
56
+ ```
57
+
58
+ **3. 测框架行为**
59
+
60
+ ```python
61
+ # ❌ clap/typer 的参数解析不需要你来测
62
+ def test_help_exits_with_zero():
63
+ """这是集成测试的工作,不是单元测试的"""
64
+ ```
65
+
66
+ **4. 用 mock 模拟简单计算**
67
+
68
+ ```python
69
+ # ❌ mock 了所有输入和输出,实际测的是 mock 本身
70
+ mock_return = {"name": "test", "status": "Clean"}
71
+ monkeypatch.setattr("app.code.rust_call", lambda _: mock_return)
72
+ result = status(".")
73
+ assert result == mock_return # 永远通过
74
+ ```
75
+
76
+ **5. 测内部实现而非公开行为**
77
+
78
+ ```python
79
+ # ❌ 测私有函数的调用次数,重构时必碎
80
+ def test_sync_calls_internal():
81
+ spy = mocker.spy(editor, "_do_sync")
82
+ editor.sync_to_parent("lib")
83
+ assert spy.called_once
84
+ ```
85
+
86
+ **原则**:单元测试只测公开接口的**输入→输出**逻辑,不测类型、不测框架、不测 mock。
87
+
88
+ ## 提交消息
89
+
90
+ - `feat:` — 新功能
91
+ - `chore:` — 版本号变更、配置更新
92
+ - `docs:` — 文档更新
93
+ - `fix:` — 修 bug
94
+ - `test:` — 测试
95
+
96
+ ## CLI 设计规则
97
+
98
+ ### `code` 子命令行为
99
+
100
+ ```
101
+ qtcloud-devops code status [path] # 三路 commit 比对 + 聚合统计
102
+ qtcloud-devops code sync [name] [--repo path] # 同步子模块指针到父仓库
103
+ qtcloud-devops code retire <name> [--repo path] # 退役子模块
104
+ ```
105
+
106
+ ### 规则
107
+
108
+ - `status`:路径默认为当前目录 `.`
109
+ - `sync`:`name` 省略时同步全部子模块
110
+ - `retire`:`name` 为必填参数
111
+ - 所有命令通过 `app/qtcloud_devops_cli/code.py` 封装 Rust native 调用,错误处理在该层完成
112
+
113
+ ### release 命令行为
114
+
115
+ ```
116
+ qtcloud-devops release --version v0.1.0 # 标签 + GitHub Release(默认)
117
+ qtcloud-devops release --version v0.1.0 --tag-only # 仅标签
118
+ qtcloud-devops release --version v0.1.0 --release-only # 仅 GitHub Release
119
+ ```
120
+
121
+ ### 规则
122
+
123
+ - **默认** = 标签 + GitHub Release(仓库从 git remote 自动检测)
124
+ - `--tag-only` 和 `--release-only` 互斥
125
+ - tag 是否已存在的处理:
126
+ - `--release-only`:tag **必须**存在,否则拒绝
127
+ - 默认 / `--tag-only`:tag 存在则跳过创建,不影响后续
128
+ - `--repo` 参数**不存在**,仓库名通过 `get_remote_repo()` 从 `git remote get-url origin` 解析
129
+ - 发布后**不验证** GitHub Release(`verify_release` 函数未使用)
130
+ - 创建标签失败:返回错误码 1
131
+ - 推送标签失败:自动回滚本地标签
132
+ - GitHub Release 创建失败:若之前创建了标签则自动回滚
133
+
134
+ ## 测试目录结构
135
+
136
+ tests/ ← Python 单元测试
137
+ integrated_tests/ ← Python 集成测试(需要真实 git 仓库等外部依赖)
138
+
139
+ ## 测试覆盖率
140
+
141
+ ### Python
142
+
143
+ ```sh
144
+ uv run pytest --cov=app/python --cov-report=term-missing --cov-fail-under=100
145
+ ```
146
+
147
+ 依赖 `pytest-cov`(已配置在 `[dependency-groups] dev` 中)。
148
+
149
+ ### Rust
150
+
151
+ 使用 `cargo-llvm-cov`(推荐):
152
+
153
+ ```sh
154
+ cargo install cargo-llvm-cov
155
+ cargo llvm-cov --lcov --output-path target/coverage/lcov.info
156
+ # HTML 报告
157
+ cargo llvm-cov --html --output-dir target/coverage
158
+ ```
159
+
160
+ 也可使用 `cargo-tarpaulin`:
161
+
162
+ ```sh
163
+ cargo install cargo-tarpaulin
164
+ cargo tarpaulin --out Html
165
+ ```
@@ -0,0 +1,71 @@
1
+ # CHANGELOG
2
+
3
+ ## [0.2.0] - 2026-05-24
4
+
5
+ Rust 原生子模块管理引擎(`code` 命令)。
6
+
7
+ ### Added
8
+
9
+ - `code status` 命令:三路 commit 比对 + 7 种子模块状态分类,格式化表格输出
10
+ - `code sync` 命令:端到端子模块同步(推送子模块 → 更新父指针 → 推送父仓库)
11
+ - `code retire` 命令:自动化反注册(deinit + .gitmodules + index 清理)
12
+ - `code status` 输出 `parent_dirty` 字段,无子模块时退化到普通 git 状态检测
13
+ - Rust 64 个测试(48 单元 + 6 二进制 + 10 集成),Python 88 个测试
14
+ - 覆盖率(Python 94%, Rust 95.8%)记录到 STATUS.md
15
+ - 子模组管理文档 docs/code.md
16
+
17
+ ### Changed
18
+
19
+ - Python 包名 `python` → `qtcloud_devops_cli`,native 模块改为 `._native` 子模块
20
+ - `app/` 目录重组为 `src/`,Rust 代码移至 `src/` 根目录
21
+ - `sync` 从只更新本地指针改为完整端到端同步(含 push)
22
+ - 测试目录分组:`tests/python/`、`tests/rust/`、`integrated_tests/`
23
+
24
+ ### Fixed
25
+
26
+ - `code.py` sync/retire 函数改为 try/except 返回 dict(之前返回 None 导致 TypeError)
27
+ - `#[pymodule]` 函数名与 `module-name` 不匹配导致的 ImportError
28
+ - 子模块 orphaned 判定中 `merge_base` 无共同祖先时应为 orphaned
29
+
30
+ ## [0.1.0] - 2026-05-22
31
+
32
+ CLI 接口重构与文档体系建立。
33
+
34
+ ### Added
35
+
36
+ - `--tag-only` / `--release-only` 参数,支持分开执行 tag 和 GitHub Release
37
+ - 从 `git remote get-url origin` 自动检测 GitHub 仓库,移除 `--repo` 参数
38
+ - AGENTS.md CLI 设计规则固化
39
+ - README.md、docs/index.md、docs/commands.md、docs/low-level-api.md 文档体系
40
+
41
+ ### Changed
42
+
43
+ - 默认行为:标签 + GitHub Release(之前仅标签)
44
+ - Tag 已存在时默认模式跳过 tag 创建继续发 release
45
+
46
+ ### Fixed
47
+
48
+ - `--release-only` 预检查验证 tag 必须存在
49
+ - 默认模式预检查不再因 tag 已存在而拒绝
50
+
51
+ ## [0.0.2] - 2026-05-21
52
+
53
+ ### Fixed
54
+
55
+ - 版本号格式校验支持 scope 前缀(`cli/vX.Y.Z` / `python/vX.Y.Z`)
56
+ - CHANGELOG 版本提取逻辑修正,scope 前缀版本不再影响查询
57
+
58
+ ### Added
59
+
60
+ - STATUS.md:记录工具已知盲区(依赖完整性、uv.lock 同步等)
61
+
62
+ ## [0.0.1] - 2026-05-21
63
+
64
+ 初始版本。
65
+
66
+ ### Added
67
+
68
+ - `release` 命令:预检查、发布前确认、执行发布、验证、回滚全流程自动化
69
+ - `release --version/-V`:版本号参数
70
+ - `release --dry-run`:仅检查不执行
71
+ - `release -y`:跳过确认直接发布
@@ -0,0 +1,84 @@
1
+ # CONTRIBUTING
2
+
3
+ ## 开发环境
4
+
5
+ ### Rust 工具链
6
+
7
+ ```bash
8
+ # 安装 Rust
9
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
10
+
11
+ # 验证
12
+ rustc --version
13
+ cargo --version
14
+ ```
15
+
16
+ ### 系统依赖
17
+
18
+ ```bash
19
+ # Ubuntu / Debian
20
+ sudo apt install libgit2-dev
21
+
22
+ # macOS
23
+ brew install libgit2
24
+ ```
25
+
26
+ ### 构建
27
+
28
+ ```bash
29
+ # 完整安装(自动编译 Rust + 安装 Python CLI)
30
+ pip install -e .[code]
31
+
32
+ # 仅编译 Rust 核心(独立调试)
33
+ cd packages/code
34
+ cargo build
35
+ cargo build --release
36
+
37
+ # 仅安装 Python CLI(不编译 Rust)
38
+ pip install -e .
39
+ ```
40
+
41
+ ## 目录结构
42
+
43
+ ```
44
+ packages/code/ ← Rust crate
45
+ ├── Cargo.toml
46
+ ├── src/
47
+ │ ├── lib.rs ← crate 入口
48
+ │ ├── main.rs ← standalone CLI 入口
49
+ │ ├── python.rs ← PyO3 绑定层
50
+ │ ├── model/mod.rs ← SubmoduleStatus, RepoState 等核心模型
51
+ │ └── commands/
52
+ │ ├── mod.rs ← SubmoduleEditor trait
53
+ │ └── editor.rs ← GitSubmoduleEditor 实现
54
+ ├── tests/integration.rs
55
+ └── docs/user-guide.md
56
+
57
+ src/cli/ ← Python CLI
58
+ ├── app/
59
+ │ ├── cli.py ← Typer 入口(release + code 子命令)
60
+ │ └── code.py ← Rust native 调用封装
61
+ ├── pyproject.toml ← maturin 构建配置(source-dir 指向 packages/code)
62
+ └── ...
63
+ ```
64
+
65
+ ## 测试
66
+
67
+ ```bash
68
+ # Rust 测试
69
+ cd packages/code && cargo test
70
+
71
+ # Python 测试
72
+ pytest
73
+
74
+ # 全部测试
75
+ cd packages/code && cargo test && cd ../.. && pytest
76
+ ```
77
+
78
+ ## 提交消息
79
+
80
+ - `feat:` — 新功能
81
+ - `chore:` — 版本号变更、配置更新
82
+ - `docs:` — 文档更新
83
+ - `fix:` — 修 bug
84
+ - `test:` — 测试