small-toolkit 0.1.1__tar.gz → 0.1.3__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.
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/.github/workflows/publish-test.yml +4 -4
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/.github/workflows/publish.yml +4 -4
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/PKG-INFO +12 -3
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/README.md +9 -2
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/pyproject.toml +5 -1
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/small_toolkit/cli.py +9 -9
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/tests/test_cli.py +23 -3
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/uv.lock +1 -1
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/.gitignore +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/small_toolkit/__init__.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/small_toolkit/logs.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/small_toolkit/outputs.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/small_toolkit/table.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/tests/test_logs.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/tests/test_outputs.py +0 -0
- {small_toolkit-0.1.1 → small_toolkit-0.1.3}/tests/test_table.py +0 -0
|
@@ -9,10 +9,10 @@ jobs:
|
|
|
9
9
|
permissions:
|
|
10
10
|
contents: read
|
|
11
11
|
steps:
|
|
12
|
-
- uses: actions/checkout@
|
|
13
|
-
- uses: astral-sh/setup-uv@
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- uses: astral-sh/setup-uv@v6
|
|
14
14
|
- run: uv build
|
|
15
|
-
- uses: actions/upload-artifact@
|
|
15
|
+
- uses: actions/upload-artifact@v5
|
|
16
16
|
with:
|
|
17
17
|
name: dist
|
|
18
18
|
path: dist/
|
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
permissions:
|
|
25
25
|
id-token: write
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/download-artifact@
|
|
27
|
+
- uses: actions/download-artifact@v5
|
|
28
28
|
with:
|
|
29
29
|
name: dist
|
|
30
30
|
path: dist/
|
|
@@ -10,7 +10,7 @@ jobs:
|
|
|
10
10
|
permissions:
|
|
11
11
|
contents: read
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@v5
|
|
14
14
|
|
|
15
15
|
- name: 校验 tag 与 pyproject 版本一致
|
|
16
16
|
# PyPI 同版本不可覆盖,tag/版本不一致会在上传时才报错,这里提前拦
|
|
@@ -18,11 +18,11 @@ jobs:
|
|
|
18
18
|
version=$(python3 -c "import pathlib,tomllib;print(tomllib.loads(pathlib.Path('pyproject.toml').read_text(encoding='utf-8'))['project']['version'])")
|
|
19
19
|
test "v${version}" = "${GITHUB_REF_NAME}"
|
|
20
20
|
|
|
21
|
-
- uses: astral-sh/setup-uv@
|
|
21
|
+
- uses: astral-sh/setup-uv@v6
|
|
22
22
|
|
|
23
23
|
- run: uv build
|
|
24
24
|
|
|
25
|
-
- uses: actions/upload-artifact@
|
|
25
|
+
- uses: actions/upload-artifact@v5
|
|
26
26
|
with:
|
|
27
27
|
name: dist
|
|
28
28
|
path: dist/
|
|
@@ -34,7 +34,7 @@ jobs:
|
|
|
34
34
|
permissions:
|
|
35
35
|
id-token: write # Trusted Publishing(OIDC),无需 API token
|
|
36
36
|
steps:
|
|
37
|
-
- uses: actions/download-artifact@
|
|
37
|
+
- uses: actions/download-artifact@v5
|
|
38
38
|
with:
|
|
39
39
|
name: dist
|
|
40
40
|
path: dist/
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: small_toolkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: 纯标准库的通用小工具:产物目录、日志初始化、命令行参数与终端表格
|
|
5
|
+
Project-URL: Homepage, https://github.com/jalousiex/py-small_toolkit
|
|
6
|
+
Project-URL: Repository, https://github.com/jalousiex/py-small_toolkit
|
|
5
7
|
Requires-Python: >=3.11
|
|
6
8
|
Description-Content-Type: text/markdown
|
|
7
9
|
|
|
@@ -14,13 +16,20 @@ Description-Content-Type: text/markdown
|
|
|
14
16
|
- **零第三方依赖**:只用标准库(`pathlib` / `logging` / `argparse` / `unicodedata`)。
|
|
15
17
|
- **无凭据、无内网地址**:不读环境里的密钥,不内置任何内网域名;环境变量只做**名字**层面的回退。
|
|
16
18
|
- 只抽跨项目复用的通用能力,业务逻辑(平台 SDK、数据源客户端、领域规则)留在各自仓库。
|
|
19
|
+
- **不接收需要三方依赖或本机环境的能力**(如 SSH、端口转发、系统命令调用):这些留在各自的本地工具包。
|
|
17
20
|
|
|
18
21
|
## 安装
|
|
19
22
|
|
|
20
|
-
从
|
|
23
|
+
从 PyPI 安装(发版后):
|
|
21
24
|
|
|
22
25
|
```bash
|
|
23
|
-
uv add
|
|
26
|
+
uv add small_toolkit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
固定到 tag 的 git 安装(尚未发版时用):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv add "small_toolkit @ git+https://github.com/jalousiex/py-small_toolkit.git@v0.1.1"
|
|
24
33
|
```
|
|
25
34
|
|
|
26
35
|
本地开发:
|
|
@@ -7,13 +7,20 @@
|
|
|
7
7
|
- **零第三方依赖**:只用标准库(`pathlib` / `logging` / `argparse` / `unicodedata`)。
|
|
8
8
|
- **无凭据、无内网地址**:不读环境里的密钥,不内置任何内网域名;环境变量只做**名字**层面的回退。
|
|
9
9
|
- 只抽跨项目复用的通用能力,业务逻辑(平台 SDK、数据源客户端、领域规则)留在各自仓库。
|
|
10
|
+
- **不接收需要三方依赖或本机环境的能力**(如 SSH、端口转发、系统命令调用):这些留在各自的本地工具包。
|
|
10
11
|
|
|
11
12
|
## 安装
|
|
12
13
|
|
|
13
|
-
从
|
|
14
|
+
从 PyPI 安装(发版后):
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
|
-
uv add
|
|
17
|
+
uv add small_toolkit
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
固定到 tag 的 git 安装(尚未发版时用):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv add "small_toolkit @ git+https://github.com/jalousiex/py-small_toolkit.git@v0.1.1"
|
|
17
24
|
```
|
|
18
25
|
|
|
19
26
|
本地开发:
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "small_toolkit"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.3"
|
|
4
4
|
description = "纯标准库的通用小工具:产物目录、日志初始化、命令行参数与终端表格"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
7
|
dependencies = []
|
|
8
8
|
|
|
9
|
+
[project.urls]
|
|
10
|
+
Homepage = "https://github.com/jalousiex/py-small_toolkit"
|
|
11
|
+
Repository = "https://github.com/jalousiex/py-small_toolkit"
|
|
12
|
+
|
|
9
13
|
[build-system]
|
|
10
14
|
requires = ["hatchling"]
|
|
11
15
|
build-backend = "hatchling.build"
|
|
@@ -116,10 +116,11 @@ def resolve_env_var(env: str, base_name: str) -> str | None:
|
|
|
116
116
|
|
|
117
117
|
1. ``{base_name}_LIST`` — 分号分隔的 ``env=value`` 格式(最高优先级)
|
|
118
118
|
2. ``{base_name}_{ENV}`` — 单环境变量
|
|
119
|
-
3. ``{base_name}`` —
|
|
119
|
+
3. ``{base_name}`` — 原生变量名(任何环境都回退)
|
|
120
120
|
|
|
121
|
-
任一来源有值(含空字符串)即返回,全缺失返回 ``None
|
|
122
|
-
|
|
121
|
+
任一来源有值(含空字符串)即返回,全缺失返回 ``None``。三层对所有环境一致:
|
|
122
|
+
``tst`` / ``uat`` 在没有 ``_LIST`` 条目、也没有 ``_{ENV}`` 后缀变量时同样回退到原生名,
|
|
123
|
+
便于变量整合后只保留裸名的场景。
|
|
123
124
|
|
|
124
125
|
例(值由外部注入,本库不读写凭据)::
|
|
125
126
|
|
|
@@ -133,14 +134,13 @@ def resolve_env_var(env: str, base_name: str) -> str | None:
|
|
|
133
134
|
part = part.strip()
|
|
134
135
|
if "=" in part:
|
|
135
136
|
k, v = part.split("=", 1)
|
|
136
|
-
|
|
137
|
+
# 环境键大小写不敏感:PROD=/Prod= 与 prod= 等价
|
|
138
|
+
if k.strip().lower() == env.strip().lower():
|
|
137
139
|
return v.strip()
|
|
138
140
|
# 2. 单环境变量 {KEY}_{ENV}
|
|
139
141
|
env_val = os.environ.get(f"{base_name}_{env.upper()}", "").strip()
|
|
140
142
|
if env_val:
|
|
141
143
|
return env_val
|
|
142
|
-
# 3.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return fallback or None
|
|
146
|
-
return None
|
|
144
|
+
# 3. 回退原生变量(所有环境统一)
|
|
145
|
+
fallback = os.environ.get(base_name, "").strip()
|
|
146
|
+
return fallback or None
|
|
@@ -90,11 +90,31 @@ def test_resolve_env_var_reads_list_first(monkeypatch):
|
|
|
90
90
|
assert resolve_env_var("tst", "TOOLKIT_TEST_URL") == "a:8030"
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
def
|
|
93
|
+
def test_resolve_env_var_list_key_is_case_insensitive(monkeypatch):
|
|
94
|
+
monkeypatch.setenv("TOOLKIT_TEST_URL_LIST", "PROD=b:8030;Uat=c:8030")
|
|
94
95
|
monkeypatch.setenv("TOOLKIT_TEST_URL", "native")
|
|
96
|
+
|
|
97
|
+
assert resolve_env_var("prod", "TOOLKIT_TEST_URL") == "b:8030"
|
|
98
|
+
assert resolve_env_var("uat", "TOOLKIT_TEST_URL") == "c:8030"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_resolve_env_var_falls_back_to_native_for_any_env(monkeypatch):
|
|
102
|
+
monkeypatch.setenv("TOOLKIT_TEST_URL", "native")
|
|
103
|
+
|
|
95
104
|
assert resolve_env_var("prod", "TOOLKIT_TEST_URL") == "native"
|
|
96
|
-
# 非 prod
|
|
97
|
-
assert resolve_env_var("
|
|
105
|
+
# 非 prod 环境同样回退原生变量
|
|
106
|
+
assert resolve_env_var("tst", "TOOLKIT_TEST_URL") == "native"
|
|
107
|
+
assert resolve_env_var("uat", "TOOLKIT_TEST_URL") == "native"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_resolve_env_var_list_and_suffix_win_over_native(monkeypatch):
|
|
111
|
+
monkeypatch.setenv("TOOLKIT_TEST_URL", "native")
|
|
112
|
+
monkeypatch.setenv("TOOLKIT_TEST_URL_TST", "single")
|
|
113
|
+
|
|
114
|
+
assert resolve_env_var("tst", "TOOLKIT_TEST_URL") == "single"
|
|
115
|
+
|
|
116
|
+
monkeypatch.setenv("TOOLKIT_TEST_URL_LIST", "tst=listed")
|
|
117
|
+
assert resolve_env_var("tst", "TOOLKIT_TEST_URL") == "listed"
|
|
98
118
|
|
|
99
119
|
|
|
100
120
|
def test_resolve_env_var_missing_returns_none(monkeypatch):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|