bitool 0.1.2__py3-none-any.whl
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.
- bitool/__init__.py +27 -0
- bitool/cmd/__init__.py +65 -0
- bitool/cmd/_base.py +105 -0
- bitool/cmd/_condition.py +60 -0
- bitool/cmd/_scheduler.py +548 -0
- bitool/cmd/env.py +454 -0
- bitool/cmd/git.py +123 -0
- bitool/cmd/io.py +248 -0
- bitool/cmd/pdf.py +385 -0
- bitool/cmd/run.py +300 -0
- bitool/cmd/toml.py +237 -0
- bitool/cmd/version.py +630 -0
- bitool/consts.py +14 -0
- bitool/core/__init__.py +7 -0
- bitool/core/app.py +142 -0
- bitool/core/commands.py +194 -0
- bitool/core/config.py +647 -0
- bitool/core/env.py +18 -0
- bitool/core/logger.py +237 -0
- bitool/core/plugin.py +117 -0
- bitool/core/workspace.py +76 -0
- bitool/models/__init__.py +3 -0
- bitool/models/version.py +173 -0
- bitool/scripts/__init__.py +1 -0
- bitool/scripts/bumpversion.py +189 -0
- bitool/scripts/clearscreen.py +37 -0
- bitool/scripts/envpy.py +161 -0
- bitool/scripts/envrs.py +119 -0
- bitool/scripts/filedate.py +246 -0
- bitool/scripts/filelevel.py +191 -0
- bitool/scripts/gittool.py +178 -0
- bitool/scripts/img2pdf.py +151 -0
- bitool/scripts/pdf2img.py +139 -0
- bitool/scripts/piptool.py +130 -0
- bitool/scripts/pymake.py +345 -0
- bitool/scripts/sshcopyid.py +491 -0
- bitool/scripts/taskkill.py +366 -0
- bitool/scripts/which.py +227 -0
- bitool/types.py +7 -0
- bitool/utils/__init__.py +9 -0
- bitool/utils/cli_parser.py +412 -0
- bitool/utils/executor.py +881 -0
- bitool/utils/profiler.py +369 -0
- bitool/utils/task.py +133 -0
- bitool/utils/task_group.py +668 -0
- bitool/utils/tests/__init__.py +0 -0
- bitool/utils/tests/test_profiler.py +487 -0
- bitool-0.1.2.dist-info/METADATA +154 -0
- bitool-0.1.2.dist-info/RECORD +51 -0
- bitool-0.1.2.dist-info/WHEEL +4 -0
- bitool-0.1.2.dist-info/entry_points.txt +15 -0
bitool/scripts/pymake.py
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"""Python构建工具模块.
|
|
2
|
+
|
|
3
|
+
完全替代传统的 Makefile, 提供更好的跨平台兼容性和 Python 生态集成.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from bitool.cmd import BuiltinConditions, CommandScheduler, RunCommand
|
|
13
|
+
from bitool.consts import Constants
|
|
14
|
+
from bitool.core import ConfigMixin, logger
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PyMakeConfig(ConfigMixin):
|
|
18
|
+
"""PyMake 配置类."""
|
|
19
|
+
|
|
20
|
+
# 项目根目录
|
|
21
|
+
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent
|
|
22
|
+
CORE_DIR = PROJECT_ROOT / "bitool-core"
|
|
23
|
+
BUILD_TIMEOUT = 600
|
|
24
|
+
|
|
25
|
+
# Python 构建
|
|
26
|
+
BUILD_TOOL = "uv"
|
|
27
|
+
BUILD_COMMAND = [BUILD_TOOL, "build"] # noqa: RUF012
|
|
28
|
+
|
|
29
|
+
# Rust 构建 (maturin)
|
|
30
|
+
MATURIN_TOOL = "maturin"
|
|
31
|
+
MATURIN_BUILD_COMMAND = ["maturin", "build", "-r"] # noqa: RUF012
|
|
32
|
+
MATURIN_DEV_COMMAND = ["maturin", "develop"] # noqa: RUF012
|
|
33
|
+
MATURIN_BUILD_OPTIONS_WIN7 = [ # noqa: RUF012
|
|
34
|
+
"--target",
|
|
35
|
+
"x86_64-win7-windows-msvc",
|
|
36
|
+
"-Zbuild-std",
|
|
37
|
+
"-i",
|
|
38
|
+
"python3.8",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
# 文档
|
|
42
|
+
DOC_BUILD_TOOL = "sphinx-build"
|
|
43
|
+
DOC_BUILD_COMMAND = ["sphinx-build", "-b", "html", "docs", "docs/_build"] # noqa: RUF012
|
|
44
|
+
|
|
45
|
+
# 清理
|
|
46
|
+
DIRS_TO_IGNORE: list[str] = [".venv"] # noqa: RUF012
|
|
47
|
+
PYTHON_BUILD_DIRS = ["dist", "build", "*.egg-info", "src/*.egg-info"] # noqa: RUF012
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
conf = PyMakeConfig()
|
|
51
|
+
|
|
52
|
+
# 命令条件判断
|
|
53
|
+
_MATURIN_CONDITION = BuiltinConditions.HAS_APP_INSTALLED(conf.MATURIN_TOOL)
|
|
54
|
+
_PYTEST_CONDITION = BuiltinConditions.HAS_APP_INSTALLED("pytest")
|
|
55
|
+
_UV_CONDITION = BuiltinConditions.HAS_APP_INSTALLED(conf.BUILD_TOOL)
|
|
56
|
+
_RUFF_CONDITION = BuiltinConditions.HAS_APP_INSTALLED("ruff")
|
|
57
|
+
_GIT_CONDITION = BuiltinConditions.HAS_APP_INSTALLED("git")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _get_maturin_build_command() -> list[str]:
|
|
61
|
+
"""获取 maturin 构建命令(根据平台自动添加参数).
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
list[str]
|
|
66
|
+
完整的 maturin 构建命令列表.
|
|
67
|
+
"""
|
|
68
|
+
base_cmd = conf.MATURIN_BUILD_COMMAND.copy()
|
|
69
|
+
if Constants.IS_WINDOWS:
|
|
70
|
+
base_cmd.extend(conf.MATURIN_BUILD_OPTIONS_WIN7)
|
|
71
|
+
return base_cmd
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def create_scheduler_map() -> dict[str, CommandScheduler]:
|
|
75
|
+
"""创建命令调度器映射.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
dict[str, CommandScheduler]
|
|
80
|
+
操作名称到命令调度器的映射字典.
|
|
81
|
+
"""
|
|
82
|
+
return {
|
|
83
|
+
# === 构建命令 ===
|
|
84
|
+
# 构建 Python 包
|
|
85
|
+
"b": CommandScheduler(
|
|
86
|
+
commands=[
|
|
87
|
+
RunCommand(
|
|
88
|
+
cmd=conf.BUILD_COMMAND,
|
|
89
|
+
allow_conditions=[_UV_CONDITION],
|
|
90
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
91
|
+
)
|
|
92
|
+
]
|
|
93
|
+
),
|
|
94
|
+
# 构建 Rust 核心模块
|
|
95
|
+
"bc": CommandScheduler(
|
|
96
|
+
commands=[
|
|
97
|
+
RunCommand(
|
|
98
|
+
cmd=_get_maturin_build_command(),
|
|
99
|
+
cwd=conf.CORE_DIR,
|
|
100
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
101
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
102
|
+
)
|
|
103
|
+
]
|
|
104
|
+
),
|
|
105
|
+
# 构建双包(先 Rust 后 Python)
|
|
106
|
+
"ba": CommandScheduler(
|
|
107
|
+
commands=[
|
|
108
|
+
RunCommand(
|
|
109
|
+
cmd=_get_maturin_build_command(),
|
|
110
|
+
cwd=conf.CORE_DIR,
|
|
111
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
112
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
113
|
+
),
|
|
114
|
+
RunCommand(
|
|
115
|
+
cmd=conf.BUILD_COMMAND,
|
|
116
|
+
allow_conditions=[_UV_CONDITION],
|
|
117
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
118
|
+
),
|
|
119
|
+
]
|
|
120
|
+
),
|
|
121
|
+
# === 安装命令(开发模式) ===
|
|
122
|
+
# 安装 Rust 核心模块
|
|
123
|
+
"ic": CommandScheduler(
|
|
124
|
+
commands=[
|
|
125
|
+
RunCommand(
|
|
126
|
+
cmd=conf.MATURIN_DEV_COMMAND,
|
|
127
|
+
cwd=conf.CORE_DIR,
|
|
128
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
129
|
+
)
|
|
130
|
+
]
|
|
131
|
+
),
|
|
132
|
+
# 安装 Python 主包
|
|
133
|
+
"ip": CommandScheduler(
|
|
134
|
+
commands=[
|
|
135
|
+
RunCommand(
|
|
136
|
+
cmd=["uv", "pip", "install", "-e", "."],
|
|
137
|
+
allow_conditions=[_UV_CONDITION],
|
|
138
|
+
)
|
|
139
|
+
]
|
|
140
|
+
),
|
|
141
|
+
# 安装双包(开发模式)
|
|
142
|
+
"ia": CommandScheduler(
|
|
143
|
+
commands=[
|
|
144
|
+
RunCommand(
|
|
145
|
+
cmd=conf.MATURIN_DEV_COMMAND,
|
|
146
|
+
cwd=conf.CORE_DIR,
|
|
147
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
148
|
+
),
|
|
149
|
+
RunCommand(
|
|
150
|
+
cmd=["uv", "pip", "install", "-e", "."],
|
|
151
|
+
allow_conditions=[_UV_CONDITION],
|
|
152
|
+
),
|
|
153
|
+
]
|
|
154
|
+
),
|
|
155
|
+
# === 清理命令 ===
|
|
156
|
+
# 清理 Python 构建产物
|
|
157
|
+
"cp": CommandScheduler(
|
|
158
|
+
commands=[
|
|
159
|
+
RunCommand(
|
|
160
|
+
cmd=["rm", "-rf", *conf.PYTHON_BUILD_DIRS],
|
|
161
|
+
allow_conditions=[_GIT_CONDITION], # 使用 git clean 更安全
|
|
162
|
+
)
|
|
163
|
+
]
|
|
164
|
+
),
|
|
165
|
+
# 清理 Rust 构建产物
|
|
166
|
+
"cc": CommandScheduler(
|
|
167
|
+
commands=[
|
|
168
|
+
RunCommand(
|
|
169
|
+
cmd=["cargo", "clean"],
|
|
170
|
+
cwd=conf.CORE_DIR,
|
|
171
|
+
allow_conditions=[_MATURIN_CONDITION], # 有 maturin 说明有 cargo
|
|
172
|
+
)
|
|
173
|
+
]
|
|
174
|
+
),
|
|
175
|
+
# 清理所有构建产物
|
|
176
|
+
"ca": CommandScheduler(
|
|
177
|
+
commands=[
|
|
178
|
+
RunCommand(
|
|
179
|
+
cmd=["cargo", "clean"],
|
|
180
|
+
cwd=conf.CORE_DIR,
|
|
181
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
182
|
+
),
|
|
183
|
+
RunCommand(
|
|
184
|
+
cmd=["git", "clean", "-xfd", "-e", *conf.DIRS_TO_IGNORE],
|
|
185
|
+
allow_conditions=[_GIT_CONDITION],
|
|
186
|
+
),
|
|
187
|
+
]
|
|
188
|
+
),
|
|
189
|
+
# === 开发工具 ===
|
|
190
|
+
# 运行测试
|
|
191
|
+
"t": CommandScheduler(
|
|
192
|
+
commands=[
|
|
193
|
+
RunCommand(
|
|
194
|
+
cmd=["pytest", "-n", "8"], allow_conditions=[_PYTEST_CONDITION]
|
|
195
|
+
)
|
|
196
|
+
]
|
|
197
|
+
),
|
|
198
|
+
# 运行测试并生成覆盖率报告
|
|
199
|
+
"tc": CommandScheduler(
|
|
200
|
+
commands=[
|
|
201
|
+
RunCommand(
|
|
202
|
+
cmd=["pytest", "--cov", "-n", "8"],
|
|
203
|
+
allow_conditions=[_PYTEST_CONDITION],
|
|
204
|
+
)
|
|
205
|
+
]
|
|
206
|
+
),
|
|
207
|
+
# 代码格式化与检查
|
|
208
|
+
"lint": CommandScheduler(
|
|
209
|
+
commands=[
|
|
210
|
+
RunCommand(
|
|
211
|
+
cmd=["ruff", "format", "src/bitool"],
|
|
212
|
+
allow_conditions=[_RUFF_CONDITION],
|
|
213
|
+
),
|
|
214
|
+
RunCommand(
|
|
215
|
+
cmd=["ruff", "check", "--fix", "--unsafe-fixes", "src/bitool"],
|
|
216
|
+
allow_conditions=[_RUFF_CONDITION],
|
|
217
|
+
),
|
|
218
|
+
]
|
|
219
|
+
),
|
|
220
|
+
# 类型检查
|
|
221
|
+
"typecheck": CommandScheduler(
|
|
222
|
+
commands=[
|
|
223
|
+
RunCommand(
|
|
224
|
+
cmd=["ty", "check", "src/bitool"],
|
|
225
|
+
allow_conditions=[BuiltinConditions.HAS_APP_INSTALLED("ty")],
|
|
226
|
+
)
|
|
227
|
+
]
|
|
228
|
+
),
|
|
229
|
+
# 构建文档
|
|
230
|
+
"doc": CommandScheduler(
|
|
231
|
+
commands=[
|
|
232
|
+
RunCommand(
|
|
233
|
+
cmd=conf.DOC_BUILD_COMMAND,
|
|
234
|
+
allow_conditions=[
|
|
235
|
+
BuiltinConditions.HAS_APP_INSTALLED(conf.DOC_BUILD_TOOL)
|
|
236
|
+
],
|
|
237
|
+
)
|
|
238
|
+
]
|
|
239
|
+
),
|
|
240
|
+
# 发布到 PyPI(先发布 Rust 核心模块,再发布 Python 主包)
|
|
241
|
+
"pb": CommandScheduler(
|
|
242
|
+
commands=[
|
|
243
|
+
# 发布 Rust 核心模块
|
|
244
|
+
RunCommand(
|
|
245
|
+
cmd=["maturin", "publish", "-r"],
|
|
246
|
+
cwd=conf.CORE_DIR,
|
|
247
|
+
allow_conditions=[_MATURIN_CONDITION],
|
|
248
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
249
|
+
),
|
|
250
|
+
# 发布 Python 主包
|
|
251
|
+
RunCommand(
|
|
252
|
+
cmd=["uv", "publish"],
|
|
253
|
+
allow_conditions=[_UV_CONDITION],
|
|
254
|
+
timeout=conf.BUILD_TIMEOUT,
|
|
255
|
+
),
|
|
256
|
+
]
|
|
257
|
+
),
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
OPTIONS: list[str] = list(create_scheduler_map().keys())
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def show_help() -> str:
|
|
265
|
+
"""显示帮助信息."""
|
|
266
|
+
help_text = """
|
|
267
|
+
╔══════════════════════════════════════════════════════════╗
|
|
268
|
+
║ Bitool PyMake 构建工具 ║
|
|
269
|
+
╚══════════════════════════════════════════════════════════╝
|
|
270
|
+
|
|
271
|
+
🔨 构建命令:
|
|
272
|
+
pymake b - 构建 Python 主包 (uv build)
|
|
273
|
+
pymake bc - 构建 Rust 核心模块 (maturin build)
|
|
274
|
+
pymake ba - 构建所有包 (先 Rust 后 Python)
|
|
275
|
+
|
|
276
|
+
📦 安装命令 (开发模式):
|
|
277
|
+
pymake ic - 安装 Rust 核心模块 (maturin develop)
|
|
278
|
+
pymake ip - 安装 Python 主包 (uv pip install -e .)
|
|
279
|
+
pymake ia - 安装所有包 (开发模式,推荐)
|
|
280
|
+
|
|
281
|
+
🧹 清理命令:
|
|
282
|
+
pymake cp - 清理 Python 构建产物
|
|
283
|
+
pymake cc - 清理 Rust 构建产物 (cargo clean)
|
|
284
|
+
pymake ca - 清理所有构建产物
|
|
285
|
+
|
|
286
|
+
🛠️ 开发工具:
|
|
287
|
+
pymake t - 运行测试 (pytest)
|
|
288
|
+
pymake tc - 运行测试并生成覆盖率报告
|
|
289
|
+
pymake lint - 代码格式化与检查 (ruff)
|
|
290
|
+
pymake typecheck - 类型检查 (ty)
|
|
291
|
+
pymake doc - 构建文档 (sphinx)
|
|
292
|
+
|
|
293
|
+
📦 发布命令:
|
|
294
|
+
pymake pb - 发布到 PyPI (先 Rust 后 Python)
|
|
295
|
+
|
|
296
|
+
💡 常用工作流:
|
|
297
|
+
1. 初始化开发环境: pymake ia
|
|
298
|
+
2. 日常开发: pymake lint && pymake t
|
|
299
|
+
3. 构建发布包: pymake ba
|
|
300
|
+
4. 发布到 PyPI: pymake pb
|
|
301
|
+
5. 清理重新开始: pymake ca && pymake ia
|
|
302
|
+
|
|
303
|
+
📝 示例:
|
|
304
|
+
pymake ba # 构建所有包
|
|
305
|
+
pymake ia # 安装开发环境
|
|
306
|
+
pymake t # 运行测试
|
|
307
|
+
pymake lint # 格式化代码
|
|
308
|
+
pymake ca # 清理所有构建产物
|
|
309
|
+
"""
|
|
310
|
+
return help_text
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def parse_args() -> tuple[argparse.ArgumentParser, argparse.Namespace]:
|
|
314
|
+
"""解析命令行参数.
|
|
315
|
+
|
|
316
|
+
Returns
|
|
317
|
+
-------
|
|
318
|
+
argparse.Namespace
|
|
319
|
+
解析后的命令行参数对象.
|
|
320
|
+
"""
|
|
321
|
+
parser = argparse.ArgumentParser(
|
|
322
|
+
description="Bitool PyMake - Python构建工具(支持双包构建)",
|
|
323
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
324
|
+
epilog=show_help(),
|
|
325
|
+
)
|
|
326
|
+
parser.add_argument(
|
|
327
|
+
"action",
|
|
328
|
+
nargs="?",
|
|
329
|
+
type=str,
|
|
330
|
+
help="要执行的操作, 可选值: " + ", ".join(OPTIONS),
|
|
331
|
+
)
|
|
332
|
+
return parser, parser.parse_args()
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def main() -> None:
|
|
336
|
+
"""主函数, 执行Python构建工具命令."""
|
|
337
|
+
parser, args = parse_args()
|
|
338
|
+
|
|
339
|
+
scheduler: CommandScheduler | None = create_scheduler_map().get(args.action, None)
|
|
340
|
+
if not scheduler:
|
|
341
|
+
logger.error(f"无效的操作: {args.action}")
|
|
342
|
+
parser.print_help(sys.stderr)
|
|
343
|
+
sys.exit(1)
|
|
344
|
+
|
|
345
|
+
scheduler.run()
|