packwise-skills 1.0.0 → 1.2.0
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/.cursorrules +23 -23
- package/CLAUDE.md +25 -25
- package/LICENSE +21 -0
- package/README.md +404 -295
- package/audit.md +224 -224
- package/bin/packwise.js +322 -155
- package/install.sh +123 -0
- package/package.json +32 -31
- package/skill.md +944 -719
- package/sub-skills/ai/local-llm.md +183 -183
- package/sub-skills/ai/python-ml.md +164 -164
- package/sub-skills/backend/go-server.md +184 -184
- package/sub-skills/backend/java-spring.md +241 -241
- package/sub-skills/backend/node-server.md +164 -164
- package/sub-skills/backend/php-laravel.md +175 -175
- package/sub-skills/backend/python-server.md +164 -164
- package/sub-skills/backend/rust-backend.md +118 -118
- package/sub-skills/cli/python-cli.md +236 -236
- package/sub-skills/cli/sdk-library.md +497 -497
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -350
- package/sub-skills/cloud/docker.md +191 -191
- package/sub-skills/cloud/kubernetes.md +277 -277
- package/sub-skills/cloud/payment-integration.md +307 -307
- package/sub-skills/cross-platform/multiplatform.md +252 -252
- package/sub-skills/desktop/electron.md +783 -783
- package/sub-skills/desktop/game-dev.md +443 -443
- package/sub-skills/desktop/native-app.md +123 -123
- package/sub-skills/desktop/scenarios.md +443 -443
- package/sub-skills/desktop/smart-platforms.md +324 -324
- package/sub-skills/desktop/tauri.md +428 -428
- package/sub-skills/desktop/vr-ar.md +252 -252
- package/sub-skills/desktop/web-to-desktop.md +153 -153
- package/sub-skills/embedded/car-infotainment.md +129 -129
- package/sub-skills/embedded/esp32.md +184 -184
- package/sub-skills/embedded/ros.md +150 -150
- package/sub-skills/embedded/stm32.md +160 -160
- package/sub-skills/mobile/android.md +322 -322
- package/sub-skills/mobile/capacitor.md +232 -232
- package/sub-skills/mobile/flutter-mobile.md +138 -138
- package/sub-skills/mobile/harmonyos.md +150 -150
- package/sub-skills/mobile/ios.md +245 -245
- package/sub-skills/mobile/react-native.md +443 -443
- package/sub-skills/mobile/wearables.md +230 -230
- package/sub-skills/plugins/browser-extension.md +308 -308
- package/sub-skills/plugins/jetbrains-plugin.md +226 -226
- package/sub-skills/plugins/vscode-extension.md +204 -204
- package/sub-skills/security/security-tools.md +174 -174
- package/sub-skills/web/monorepo.md +274 -274
- package/sub-skills/web/pwa.md +220 -220
- package/sub-skills/web/serverless-edge.md +295 -295
- package/sub-skills/web/spa.md +266 -266
- package/sub-skills/web/ssr.md +228 -228
- package/sub-skills/web/wasm.md +243 -243
|
@@ -1,236 +1,236 @@
|
|
|
1
|
-
# Python CLI Tool Packaging Sub-Skill
|
|
2
|
-
|
|
3
|
-
Package and distribute Python command-line tools as standalone executables or pip packages.
|
|
4
|
-
|
|
5
|
-
**Current version**: Python 3.12+ / PyInstaller 6.x / Nuitka 2.x / uv (2025-2026)
|
|
6
|
-
|
|
7
|
-
## When to Use
|
|
8
|
-
|
|
9
|
-
- Automation scripts for distribution to non-Python users
|
|
10
|
-
- DevOps/infrastructure tools
|
|
11
|
-
- Data processing pipelines
|
|
12
|
-
- Security tools, scanners
|
|
13
|
-
- Research tools for academic distribution
|
|
14
|
-
|
|
15
|
-
## Packaging Options Comparison
|
|
16
|
-
|
|
17
|
-
| Method | Size | Startup | Cross-compile | Best For |
|
|
18
|
-
|--------|------|---------|--------------|----------|
|
|
19
|
-
| PyInstaller | 15–80MB | 1–3s | No (build per platform) | Universal distribution |
|
|
20
|
-
| Nuitka | 10–50MB | < 1s | No | Performance, AV false positive avoidance |
|
|
21
|
-
| pip/PyPI | 0 (source) | Instant | N/A | Developer tools |
|
|
22
|
-
| pipx | 0 (isolated) | Instant | N/A | CLI tools for developers |
|
|
23
|
-
| Docker | 50–200MB | 1–2s | Yes | Server/container environments |
|
|
24
|
-
| uv | 0 (source) | Instant | N/A | Fast Python package management |
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## PyInstaller (Most Universal)
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
pip install pyinstaller
|
|
32
|
-
|
|
33
|
-
# Single file mode (self-extracting)
|
|
34
|
-
pyinstaller --onefile --name mytool mytool.py
|
|
35
|
-
|
|
36
|
-
# Directory mode (faster startup, recommended for production)
|
|
37
|
-
pyinstaller --name mytool mytool.py
|
|
38
|
-
|
|
39
|
-
# With hidden imports (common for dynamic imports)
|
|
40
|
-
pyinstaller --onefile \
|
|
41
|
-
--hidden-import=cryptography \
|
|
42
|
-
--hidden-import=paramiko \
|
|
43
|
-
--hidden-import=click \
|
|
44
|
-
--name mytool mytool.py
|
|
45
|
-
|
|
46
|
-
# Console app (default) vs GUI app
|
|
47
|
-
pyinstaller --onefile --console mytool.py # Console
|
|
48
|
-
pyinstaller --onefile --windowed mytool.py # GUI (no console window)
|
|
49
|
-
|
|
50
|
-
# Output: dist/mytool (Linux/macOS) or dist/mytool.exe (Windows)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Cross-Platform Build (GitHub Actions)
|
|
54
|
-
|
|
55
|
-
```yaml
|
|
56
|
-
name: Build CLI
|
|
57
|
-
on:
|
|
58
|
-
push:
|
|
59
|
-
tags: ['v*']
|
|
60
|
-
jobs:
|
|
61
|
-
build:
|
|
62
|
-
strategy:
|
|
63
|
-
matrix:
|
|
64
|
-
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
65
|
-
runs-on: ${{ matrix.os }}
|
|
66
|
-
steps:
|
|
67
|
-
- uses: actions/checkout@v4
|
|
68
|
-
- uses: actions/setup-python@v5
|
|
69
|
-
with:
|
|
70
|
-
python-version: '3.13'
|
|
71
|
-
- run: pip install pyinstaller
|
|
72
|
-
- run: pyinstaller --onefile --name mytool mytool.py
|
|
73
|
-
- uses: actions/upload-artifact@v4
|
|
74
|
-
with:
|
|
75
|
-
name: mytool-${{ matrix.os }}
|
|
76
|
-
path: dist/
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Nuitka (Better Performance)
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
pip install nuitka
|
|
85
|
-
|
|
86
|
-
# Standalone binary
|
|
87
|
-
python -m nuitka \
|
|
88
|
-
--standalone \
|
|
89
|
-
--onefile \
|
|
90
|
-
--output-filename=mytool \
|
|
91
|
-
--enable-plugin=anti-bloat \
|
|
92
|
-
mytool.py
|
|
93
|
-
|
|
94
|
-
# With module support
|
|
95
|
-
python -m nuitka \
|
|
96
|
-
--standalone \
|
|
97
|
-
--onefile \
|
|
98
|
-
--include-module=cryptography \
|
|
99
|
-
--include-package=click \
|
|
100
|
-
mytool.py
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## pip Distribution (PyPI)
|
|
106
|
-
|
|
107
|
-
```toml
|
|
108
|
-
# pyproject.toml
|
|
109
|
-
[build-system]
|
|
110
|
-
requires = ["setuptools>=75.0", "wheel"]
|
|
111
|
-
build-backend = "setuptools.backends._legacy:_Backend"
|
|
112
|
-
|
|
113
|
-
[project]
|
|
114
|
-
name = "mytool"
|
|
115
|
-
version = "1.0.0"
|
|
116
|
-
description = "My awesome CLI tool"
|
|
117
|
-
readme = "README.md"
|
|
118
|
-
license = "MIT"
|
|
119
|
-
requires-python = ">=3.10"
|
|
120
|
-
dependencies = [
|
|
121
|
-
"click>=8.0",
|
|
122
|
-
"requests>=2.28",
|
|
123
|
-
"rich>=13.0",
|
|
124
|
-
]
|
|
125
|
-
|
|
126
|
-
[project.scripts]
|
|
127
|
-
mytool = "mytool.cli:main"
|
|
128
|
-
|
|
129
|
-
[project.urls]
|
|
130
|
-
Homepage = "https://github.com/user/mytool"
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
# Build
|
|
135
|
-
python -m build
|
|
136
|
-
# Output: dist/mytool-1.0.0-py3-none-any.whl + dist/mytool-1.0.0.tar.gz
|
|
137
|
-
|
|
138
|
-
# Publish to PyPI
|
|
139
|
-
pip install twine
|
|
140
|
-
twine upload dist/*
|
|
141
|
-
|
|
142
|
-
# Or: use trusted publishing (recommended)
|
|
143
|
-
# Configure on pypi.org → Your project → Publishing → Add GitHub Actions
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## pipx (Isolated Installation)
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
# Install pipx
|
|
152
|
-
pip install pipx
|
|
153
|
-
pipx ensurepath
|
|
154
|
-
|
|
155
|
-
# Install CLI tool in isolated environment
|
|
156
|
-
pipx install mytool
|
|
157
|
-
|
|
158
|
-
# Install from local wheel
|
|
159
|
-
pipx install dist/mytool-1.0.0-py3-none-any.whl
|
|
160
|
-
|
|
161
|
-
# Install from Git
|
|
162
|
-
pipx install git+https://github.com/user/mytool.git
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## Docker Distribution
|
|
168
|
-
|
|
169
|
-
```dockerfile
|
|
170
|
-
FROM python:3.13-slim
|
|
171
|
-
WORKDIR /app
|
|
172
|
-
COPY requirements.txt .
|
|
173
|
-
RUN pip install --no-cache-dir -r requirements.txt
|
|
174
|
-
COPY . .
|
|
175
|
-
RUN pip install .
|
|
176
|
-
RUN groupadd -r tooluser && useradd -r -g tooluser tooluser
|
|
177
|
-
USER tooluser
|
|
178
|
-
ENTRYPOINT ["mytool"]
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## Rich CLI Framework (Recommended for Beautiful CLIs)
|
|
184
|
-
|
|
185
|
-
```python
|
|
186
|
-
# mytool/cli.py
|
|
187
|
-
import click
|
|
188
|
-
from rich.console import Console
|
|
189
|
-
from rich.table import Table
|
|
190
|
-
|
|
191
|
-
console = Console()
|
|
192
|
-
|
|
193
|
-
@click.group()
|
|
194
|
-
@click.version_option(version="1.0.0")
|
|
195
|
-
def cli():
|
|
196
|
-
"""My awesome CLI tool."""
|
|
197
|
-
pass
|
|
198
|
-
|
|
199
|
-
@cli.command()
|
|
200
|
-
@click.argument("name")
|
|
201
|
-
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
|
|
202
|
-
def greet(name: str, verbose: bool):
|
|
203
|
-
"""Greet someone."""
|
|
204
|
-
if verbose:
|
|
205
|
-
console.print(f"[dim]Processing request...[/dim]")
|
|
206
|
-
console.print(f"[bold green]Hello, {name}![/bold green]")
|
|
207
|
-
|
|
208
|
-
@cli.command()
|
|
209
|
-
def table():
|
|
210
|
-
"""Show a beautiful table."""
|
|
211
|
-
t = Table(title="Data")
|
|
212
|
-
t.add_column("Name", style="cyan")
|
|
213
|
-
t.add_column("Value", style="green")
|
|
214
|
-
t.add_row("Python", "3.13")
|
|
215
|
-
t.add_row("CLI", "mytool 1.0.0")
|
|
216
|
-
console.print(t)
|
|
217
|
-
|
|
218
|
-
if __name__ == "__main__":
|
|
219
|
-
cli()
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
---
|
|
223
|
-
|
|
224
|
-
## Common Pitfalls
|
|
225
|
-
|
|
226
|
-
| Issue | Fix |
|
|
227
|
-
|-------|-----|
|
|
228
|
-
| PyInstaller missing hidden imports | Use `--hidden-import`; check with `pyi-archive_viewer` |
|
|
229
|
-
| Antivirus false positive (PyInstaller) | Switch to Nuitka; sign binaries; submit to AV vendors |
|
|
230
|
-
| Cross-platform build fails | Build on each platform separately; use CI matrix builds |
|
|
231
|
-
| Large binary size | Use Nuitka (smaller); exclude unused packages; use `--exclude-module` |
|
|
232
|
-
| Slow startup (PyInstaller) | Use directory mode instead of `--onefile` |
|
|
233
|
-
| `pkg_resources` deprecation | Migrate to `importlib.metadata`; use `setuptools>=70` |
|
|
234
|
-
| pip install fails on Windows | Use `python -m pip install`; check PATH |
|
|
235
|
-
| Permission denied on Linux/macOS | `chmod +x dist/mytool` |
|
|
236
|
-
| Entry point not found | Check `[project.scripts]` in `pyproject.toml`; verify module path |
|
|
1
|
+
# Python CLI Tool Packaging Sub-Skill
|
|
2
|
+
|
|
3
|
+
Package and distribute Python command-line tools as standalone executables or pip packages.
|
|
4
|
+
|
|
5
|
+
**Current version**: Python 3.12+ / PyInstaller 6.x / Nuitka 2.x / uv (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Automation scripts for distribution to non-Python users
|
|
10
|
+
- DevOps/infrastructure tools
|
|
11
|
+
- Data processing pipelines
|
|
12
|
+
- Security tools, scanners
|
|
13
|
+
- Research tools for academic distribution
|
|
14
|
+
|
|
15
|
+
## Packaging Options Comparison
|
|
16
|
+
|
|
17
|
+
| Method | Size | Startup | Cross-compile | Best For |
|
|
18
|
+
|--------|------|---------|--------------|----------|
|
|
19
|
+
| PyInstaller | 15–80MB | 1–3s | No (build per platform) | Universal distribution |
|
|
20
|
+
| Nuitka | 10–50MB | < 1s | No | Performance, AV false positive avoidance |
|
|
21
|
+
| pip/PyPI | 0 (source) | Instant | N/A | Developer tools |
|
|
22
|
+
| pipx | 0 (isolated) | Instant | N/A | CLI tools for developers |
|
|
23
|
+
| Docker | 50–200MB | 1–2s | Yes | Server/container environments |
|
|
24
|
+
| uv | 0 (source) | Instant | N/A | Fast Python package management |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## PyInstaller (Most Universal)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install pyinstaller
|
|
32
|
+
|
|
33
|
+
# Single file mode (self-extracting)
|
|
34
|
+
pyinstaller --onefile --name mytool mytool.py
|
|
35
|
+
|
|
36
|
+
# Directory mode (faster startup, recommended for production)
|
|
37
|
+
pyinstaller --name mytool mytool.py
|
|
38
|
+
|
|
39
|
+
# With hidden imports (common for dynamic imports)
|
|
40
|
+
pyinstaller --onefile \
|
|
41
|
+
--hidden-import=cryptography \
|
|
42
|
+
--hidden-import=paramiko \
|
|
43
|
+
--hidden-import=click \
|
|
44
|
+
--name mytool mytool.py
|
|
45
|
+
|
|
46
|
+
# Console app (default) vs GUI app
|
|
47
|
+
pyinstaller --onefile --console mytool.py # Console
|
|
48
|
+
pyinstaller --onefile --windowed mytool.py # GUI (no console window)
|
|
49
|
+
|
|
50
|
+
# Output: dist/mytool (Linux/macOS) or dist/mytool.exe (Windows)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Cross-Platform Build (GitHub Actions)
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
name: Build CLI
|
|
57
|
+
on:
|
|
58
|
+
push:
|
|
59
|
+
tags: ['v*']
|
|
60
|
+
jobs:
|
|
61
|
+
build:
|
|
62
|
+
strategy:
|
|
63
|
+
matrix:
|
|
64
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
65
|
+
runs-on: ${{ matrix.os }}
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v4
|
|
68
|
+
- uses: actions/setup-python@v5
|
|
69
|
+
with:
|
|
70
|
+
python-version: '3.13'
|
|
71
|
+
- run: pip install pyinstaller
|
|
72
|
+
- run: pyinstaller --onefile --name mytool mytool.py
|
|
73
|
+
- uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: mytool-${{ matrix.os }}
|
|
76
|
+
path: dist/
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Nuitka (Better Performance)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install nuitka
|
|
85
|
+
|
|
86
|
+
# Standalone binary
|
|
87
|
+
python -m nuitka \
|
|
88
|
+
--standalone \
|
|
89
|
+
--onefile \
|
|
90
|
+
--output-filename=mytool \
|
|
91
|
+
--enable-plugin=anti-bloat \
|
|
92
|
+
mytool.py
|
|
93
|
+
|
|
94
|
+
# With module support
|
|
95
|
+
python -m nuitka \
|
|
96
|
+
--standalone \
|
|
97
|
+
--onefile \
|
|
98
|
+
--include-module=cryptography \
|
|
99
|
+
--include-package=click \
|
|
100
|
+
mytool.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## pip Distribution (PyPI)
|
|
106
|
+
|
|
107
|
+
```toml
|
|
108
|
+
# pyproject.toml
|
|
109
|
+
[build-system]
|
|
110
|
+
requires = ["setuptools>=75.0", "wheel"]
|
|
111
|
+
build-backend = "setuptools.backends._legacy:_Backend"
|
|
112
|
+
|
|
113
|
+
[project]
|
|
114
|
+
name = "mytool"
|
|
115
|
+
version = "1.0.0"
|
|
116
|
+
description = "My awesome CLI tool"
|
|
117
|
+
readme = "README.md"
|
|
118
|
+
license = "MIT"
|
|
119
|
+
requires-python = ">=3.10"
|
|
120
|
+
dependencies = [
|
|
121
|
+
"click>=8.0",
|
|
122
|
+
"requests>=2.28",
|
|
123
|
+
"rich>=13.0",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
[project.scripts]
|
|
127
|
+
mytool = "mytool.cli:main"
|
|
128
|
+
|
|
129
|
+
[project.urls]
|
|
130
|
+
Homepage = "https://github.com/user/mytool"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Build
|
|
135
|
+
python -m build
|
|
136
|
+
# Output: dist/mytool-1.0.0-py3-none-any.whl + dist/mytool-1.0.0.tar.gz
|
|
137
|
+
|
|
138
|
+
# Publish to PyPI
|
|
139
|
+
pip install twine
|
|
140
|
+
twine upload dist/*
|
|
141
|
+
|
|
142
|
+
# Or: use trusted publishing (recommended)
|
|
143
|
+
# Configure on pypi.org → Your project → Publishing → Add GitHub Actions
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## pipx (Isolated Installation)
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Install pipx
|
|
152
|
+
pip install pipx
|
|
153
|
+
pipx ensurepath
|
|
154
|
+
|
|
155
|
+
# Install CLI tool in isolated environment
|
|
156
|
+
pipx install mytool
|
|
157
|
+
|
|
158
|
+
# Install from local wheel
|
|
159
|
+
pipx install dist/mytool-1.0.0-py3-none-any.whl
|
|
160
|
+
|
|
161
|
+
# Install from Git
|
|
162
|
+
pipx install git+https://github.com/user/mytool.git
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Docker Distribution
|
|
168
|
+
|
|
169
|
+
```dockerfile
|
|
170
|
+
FROM python:3.13-slim
|
|
171
|
+
WORKDIR /app
|
|
172
|
+
COPY requirements.txt .
|
|
173
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
174
|
+
COPY . .
|
|
175
|
+
RUN pip install .
|
|
176
|
+
RUN groupadd -r tooluser && useradd -r -g tooluser tooluser
|
|
177
|
+
USER tooluser
|
|
178
|
+
ENTRYPOINT ["mytool"]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Rich CLI Framework (Recommended for Beautiful CLIs)
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# mytool/cli.py
|
|
187
|
+
import click
|
|
188
|
+
from rich.console import Console
|
|
189
|
+
from rich.table import Table
|
|
190
|
+
|
|
191
|
+
console = Console()
|
|
192
|
+
|
|
193
|
+
@click.group()
|
|
194
|
+
@click.version_option(version="1.0.0")
|
|
195
|
+
def cli():
|
|
196
|
+
"""My awesome CLI tool."""
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
@cli.command()
|
|
200
|
+
@click.argument("name")
|
|
201
|
+
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
|
|
202
|
+
def greet(name: str, verbose: bool):
|
|
203
|
+
"""Greet someone."""
|
|
204
|
+
if verbose:
|
|
205
|
+
console.print(f"[dim]Processing request...[/dim]")
|
|
206
|
+
console.print(f"[bold green]Hello, {name}![/bold green]")
|
|
207
|
+
|
|
208
|
+
@cli.command()
|
|
209
|
+
def table():
|
|
210
|
+
"""Show a beautiful table."""
|
|
211
|
+
t = Table(title="Data")
|
|
212
|
+
t.add_column("Name", style="cyan")
|
|
213
|
+
t.add_column("Value", style="green")
|
|
214
|
+
t.add_row("Python", "3.13")
|
|
215
|
+
t.add_row("CLI", "mytool 1.0.0")
|
|
216
|
+
console.print(t)
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
cli()
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Common Pitfalls
|
|
225
|
+
|
|
226
|
+
| Issue | Fix |
|
|
227
|
+
|-------|-----|
|
|
228
|
+
| PyInstaller missing hidden imports | Use `--hidden-import`; check with `pyi-archive_viewer` |
|
|
229
|
+
| Antivirus false positive (PyInstaller) | Switch to Nuitka; sign binaries; submit to AV vendors |
|
|
230
|
+
| Cross-platform build fails | Build on each platform separately; use CI matrix builds |
|
|
231
|
+
| Large binary size | Use Nuitka (smaller); exclude unused packages; use `--exclude-module` |
|
|
232
|
+
| Slow startup (PyInstaller) | Use directory mode instead of `--onefile` |
|
|
233
|
+
| `pkg_resources` deprecation | Migrate to `importlib.metadata`; use `setuptools>=70` |
|
|
234
|
+
| pip install fails on Windows | Use `python -m pip install`; check PATH |
|
|
235
|
+
| Permission denied on Linux/macOS | `chmod +x dist/mytool` |
|
|
236
|
+
| Entry point not found | Check `[project.scripts]` in `pyproject.toml`; verify module path |
|