devit-cli 0.1.0__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.
Files changed (52) hide show
  1. _devkit_entry.py +59 -0
  2. devit_cli-0.1.0.dist-info/METADATA +273 -0
  3. devit_cli-0.1.0.dist-info/RECORD +52 -0
  4. devit_cli-0.1.0.dist-info/WHEEL +5 -0
  5. devit_cli-0.1.0.dist-info/entry_points.txt +2 -0
  6. devit_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
  7. devit_cli-0.1.0.dist-info/top_level.txt +2 -0
  8. devkit_cli/__init__.py +4 -0
  9. devkit_cli/commands/__init__.py +0 -0
  10. devkit_cli/commands/archive.py +166 -0
  11. devkit_cli/commands/clean.py +130 -0
  12. devkit_cli/commands/env.py +156 -0
  13. devkit_cli/commands/find.py +122 -0
  14. devkit_cli/commands/info.py +119 -0
  15. devkit_cli/commands/init.py +451 -0
  16. devkit_cli/commands/run.py +236 -0
  17. devkit_cli/main.py +89 -0
  18. devkit_cli/templates/aws/.gitignore +43 -0
  19. devkit_cli/templates/aws/README.md +23 -0
  20. devkit_cli/templates/aws/requirements.txt +2 -0
  21. devkit_cli/templates/aws/scripts/__init__.py +0 -0
  22. devkit_cli/templates/aws/scripts/ec2.py +9 -0
  23. devkit_cli/templates/aws/scripts/main.py +25 -0
  24. devkit_cli/templates/aws/scripts/s3.py +10 -0
  25. devkit_cli/templates/aws/tests/test_scripts.py +6 -0
  26. devkit_cli/templates/django/.gitignore +43 -0
  27. devkit_cli/templates/django/README.md +15 -0
  28. devkit_cli/templates/django/apps/__init__.py +0 -0
  29. devkit_cli/templates/django/apps/core/__init__.py +0 -0
  30. devkit_cli/templates/django/apps/core/apps.py +6 -0
  31. devkit_cli/templates/django/apps/core/urls.py +6 -0
  32. devkit_cli/templates/django/apps/core/views.py +7 -0
  33. devkit_cli/templates/django/manage.py +20 -0
  34. devkit_cli/templates/django/requirements.txt +1 -0
  35. devkit_cli/templates/django/{{module_name}}/__init__.py +0 -0
  36. devkit_cli/templates/django/{{module_name}}/settings.py +61 -0
  37. devkit_cli/templates/django/{{module_name}}/urls.py +9 -0
  38. devkit_cli/templates/django/{{module_name}}/wsgi.py +7 -0
  39. devkit_cli/templates/fastapi/.gitignore +43 -0
  40. devkit_cli/templates/fastapi/README.md +21 -0
  41. devkit_cli/templates/fastapi/app/__init__.py +0 -0
  42. devkit_cli/templates/fastapi/app/routers/__init__.py +0 -0
  43. devkit_cli/templates/fastapi/app/routers/health.py +10 -0
  44. devkit_cli/templates/fastapi/main.py +13 -0
  45. devkit_cli/templates/fastapi/requirements.txt +6 -0
  46. devkit_cli/templates/fastapi/tests/test_api.py +17 -0
  47. devkit_cli/templates/package/.gitignore +43 -0
  48. devkit_cli/templates/package/README.md +15 -0
  49. devkit_cli/templates/package/pyproject.toml +29 -0
  50. devkit_cli/templates/package/tests/test_core.py +8 -0
  51. devkit_cli/templates/package/{{module_name}}/__init__.py +3 -0
  52. devkit_cli/templates/package/{{module_name}}/core.py +5 -0
_devkit_entry.py ADDED
@@ -0,0 +1,59 @@
1
+ """
2
+ Thin bootstrap entry point for devit-cli.
3
+
4
+ Lives at the top level of site-packages so it is importable even when
5
+ devkit_cli itself is not installed in the active environment. Defers the
6
+ import of devkit_cli into a function body so an ImportError can be caught
7
+ and turned into a human-readable message before Python prints a traceback.
8
+ """
9
+
10
+ import sys
11
+
12
+ # Enable ANSI colour codes on Windows.
13
+ # colorama is a transitive dependency of click on Windows, so it is
14
+ # almost always present whenever devkit.exe itself exists.
15
+ if sys.platform == "win32":
16
+ try:
17
+ import colorama
18
+ colorama.init()
19
+ except ImportError:
20
+ pass # Win10+ Terminal supports ANSI natively; older CMD will show plain text
21
+
22
+
23
+ def main() -> None:
24
+ try:
25
+ from devkit_cli.main import cli # deferred — lets us catch install issues
26
+ except ModuleNotFoundError as exc:
27
+ _friendly_not_installed(exc)
28
+ return # unreachable — _friendly_not_installed calls sys.exit
29
+
30
+ cli() # outside the try so Click's own SystemExit propagates normally
31
+
32
+
33
+ def _friendly_not_installed(exc: ModuleNotFoundError) -> None: # noqa: ANN001
34
+ R = "\033[91m" # red
35
+ B = "\033[1m" # bold
36
+ Y = "\033[93m" # yellow
37
+ RST = "\033[0m" # reset
38
+
39
+ print(
40
+ f"\n{R}Error:{RST} devit-cli is not installed in the active Python environment.\n"
41
+ f"\n{B}Fix:{RST} pip install devit-cli\n"
42
+ f"\n{Y}Active Python:{RST} {sys.executable}\n"
43
+ f"{Y}Active env:{RST} "
44
+ + _env_name()
45
+ + f"\n\n{B}Details:{RST} {exc}",
46
+ file=sys.stderr,
47
+ )
48
+ sys.exit(1)
49
+
50
+
51
+ def _env_name() -> str:
52
+ """Return a short human-readable name for the active environment."""
53
+ import os
54
+ from pathlib import Path
55
+
56
+ prefix = os.environ.get("CONDA_DEFAULT_ENV") or os.environ.get("VIRTUAL_ENV")
57
+ if prefix:
58
+ return Path(prefix).name
59
+ return Path(sys.executable).parent.parent.name
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: devit-cli
3
+ Version: 0.1.0
4
+ Summary: A full-featured CLI framework for professional Python developers
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/dipenpadhiyar/devit-cli
7
+ Project-URL: Issues, https://github.com/dipenpadhiyar/devit-cli/issues
8
+ Keywords: cli,developer-tools,scaffold,devkit
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: click>=8.1
23
+ Requires-Dist: rich>=13.0
24
+ Requires-Dist: psutil>=5.9
25
+ Requires-Dist: questionary>=2.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0; extra == "dev"
28
+ Requires-Dist: pytest-click>=1.1; extra == "dev"
29
+ Requires-Dist: black>=24.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.4; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ <p align="center">
34
+ <img src="https://raw.githubusercontent.com/dipenpadhiyar/devit-cli/main/assets/devkit.png" alt="devit-cli" width="300"/>
35
+ </p>
36
+
37
+ <p align="center">
38
+ <b>A full-featured CLI toolkit for professional Python developers.</b><br/>
39
+ Scaffold projects &nbsp;·&nbsp; Clean builds &nbsp;·&nbsp; Inspect system &nbsp;·&nbsp; Search files &nbsp;·&nbsp; Manage archives &amp; env vars
40
+ </p>
41
+
42
+ <p align="center">
43
+ <a href="https://pypi.org/project/devit-cli/"><img src="https://img.shields.io/pypi/v/devit-cli.svg" alt="PyPI version"/></a>
44
+ <a href="https://pypistats.org/packages/devit-cli"><img src="https://img.shields.io/pypi/dm/devit-cli.svg?label=PyPI%20downloads" alt="Monthly downloads"/></a>
45
+ <a href="https://pypi.org/project/devit-cli/"><img src="https://img.shields.io/pypi/pyversions/devit-cli.svg" alt="Python versions"/></a>
46
+ <a href="https://pypi.org/project/devit-cli/"><img src="https://img.shields.io/pypi/l/devit-cli.svg" alt="License"/></a>
47
+ </p>
48
+
49
+ <p align="center">
50
+ <a href="https://pepy.tech/project/devit-cli"><img src="https://static.pepy.tech/badge/devit-cli" alt="Total downloads"/></a>
51
+ <a href="https://pepy.tech/project/devit-cli"><img src="https://static.pepy.tech/badge/devit-cli/month" alt="Monthly"/></a>
52
+ <a href="https://pepy.tech/project/devit-cli"><img src="https://static.pepy.tech/badge/devit-cli/week" alt="Weekly"/></a>
53
+ </p>
54
+
55
+ ---
56
+
57
+ ## Installation
58
+
59
+ ```bash
60
+ pip install devit-cli
61
+ ```
62
+
63
+ Requires **Python 3.10+**. Works on **Windows · Linux · macOS**.
64
+
65
+ ---
66
+
67
+ ## Quick Start
68
+
69
+ ```bash
70
+ devkit # show help + logo
71
+ devkit init # interactive project wizard
72
+ devkit info # system snapshot
73
+ devkit clean # remove caches & build artifacts
74
+ devkit dev # start dev server / install in dev mode
75
+ devkit test # run tests (auto-detects pytest / django)
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Commands
81
+
82
+ ### `devkit init` — Project wizard
83
+
84
+ Interactively scaffold a new project. Asks for:
85
+
86
+ | Question | Options |
87
+ |---|---|
88
+ | Project type | Python Package · FastAPI · Django · AWS Scripts |
89
+ | Environment | New venv · Existing Python interpreter · New conda · Existing conda env · Skip |
90
+ | Python version | e.g. `3.11` |
91
+
92
+ ```bash
93
+ devkit init # fully interactive
94
+ devkit init my-api --type fastapi --env venv
95
+ devkit init my-lib --type package --env conda --python 3.12
96
+ devkit init my-app -y # skip confirmation prompt
97
+ ```
98
+
99
+ #### Generated structures
100
+
101
+ **Python Package**
102
+ ```
103
+ my-lib/
104
+ ├── my_lib/
105
+ │ ├── __init__.py
106
+ │ └── core.py
107
+ ├── tests/
108
+ │ └── test_core.py
109
+ ├── docs/
110
+ ├── pyproject.toml
111
+ ├── README.md
112
+ └── .gitignore
113
+ ```
114
+
115
+ **FastAPI**
116
+ ```
117
+ my-api/
118
+ ├── main.py
119
+ ├── app/
120
+ │ └── routers/
121
+ │ └── health.py
122
+ ├── tests/
123
+ │ └── test_api.py
124
+ ├── requirements.txt
125
+ ├── README.md
126
+ └── .gitignore
127
+ ```
128
+
129
+ **Django**
130
+ ```
131
+ my-site/
132
+ ├── manage.py
133
+ ├── my_site/
134
+ │ ├── settings.py
135
+ │ ├── urls.py
136
+ │ └── wsgi.py
137
+ ├── apps/
138
+ │ └── core/
139
+ │ ├── views.py
140
+ │ └── urls.py
141
+ ├── requirements.txt
142
+ └── .gitignore
143
+ ```
144
+
145
+ **AWS Scripts**
146
+ ```
147
+ my-aws/
148
+ ├── scripts/
149
+ │ ├── main.py
150
+ │ ├── s3.py
151
+ │ └── ec2.py
152
+ ├── tests/
153
+ ├── requirements.txt
154
+ └── .gitignore
155
+ ```
156
+
157
+ ---
158
+
159
+ ### `devkit dev / run / build / test` — Unified task runner
160
+
161
+ Auto-detects project type and runs the right command:
162
+
163
+ | Command | Package | FastAPI | Django | AWS |
164
+ |---|---|---|---|---|
165
+ | `devkit dev` | `pip install -e .[dev]` | `uvicorn main:app --reload` | `manage.py runserver` | `sam local start-api` |
166
+ | `devkit run` | `python -m <module>` | `uvicorn main:app` | `manage.py runserver 0.0.0.0` | `python -m scripts.main` |
167
+ | `devkit build` | `python -m build` | `pip install -r requirements.txt` | `pip install -r requirements.txt` | `sam build` |
168
+ | `devkit test` | `pytest -v` | `pytest -v` | `manage.py test` | `pytest -v` |
169
+
170
+ ```bash
171
+ devkit dev
172
+ devkit test
173
+ devkit build
174
+ devkit run -- --port 9000 # extra args forwarded
175
+ ```
176
+
177
+ ---
178
+
179
+ ### `devkit clean` — Remove artifacts
180
+
181
+ ```bash
182
+ devkit clean # clean cwd
183
+ devkit clean ./my-project # clean specific dir
184
+ devkit clean --dry-run # preview only
185
+ devkit clean --include-venv # also remove .venv
186
+ devkit clean -y # skip confirmation
187
+ ```
188
+
189
+ Removes: `__pycache__`, `*.pyc`, `.pytest_cache`, `build/`, `dist/`, `*.egg-info`, `.DS_Store`, `*.log`, `node_modules`, `.coverage`, and more.
190
+
191
+ ---
192
+
193
+ ### `devkit info` — System snapshot
194
+
195
+ ```bash
196
+ devkit info
197
+ devkit info --json
198
+ ```
199
+
200
+ Shows: OS, hostname, Python version + executable, active venv/conda env, CPU count + frequency, RAM usage, disk usage.
201
+
202
+ ---
203
+
204
+ ### `devkit find` — Fast file search
205
+
206
+ ```bash
207
+ devkit find "*.py"
208
+ devkit find "config" -e toml -e ini
209
+ devkit find "*" --min-size 1mb --newer-than 7 # >1 MB, modified in last 7 days
210
+ devkit find --dirs-only "src"
211
+ devkit find "*" -l 500 # show up to 500 results
212
+ ```
213
+
214
+ ---
215
+
216
+ ### `devkit zip` / `devkit unzip` — Archive utilities
217
+
218
+ ```bash
219
+ devkit zip dist.zip src/ README.md
220
+ devkit zip dist.zip . -x __pycache__ -x "*.pyc" -l 9
221
+ devkit unzip dist.zip ./output
222
+ devkit unzip dist.zip --list # show contents without extracting
223
+ ```
224
+
225
+ ---
226
+
227
+ ### `devkit env` — Environment variable management
228
+
229
+ ```bash
230
+ devkit env list # list all env vars
231
+ devkit env list --filter AWS # filter by keyword
232
+ devkit env list --json # JSON output
233
+
234
+ devkit env export # save to .env (dotenv format)
235
+ devkit env export vars.json --format json
236
+ devkit env export activate.sh --format shell # bash / zsh
237
+ devkit env export activate.ps1 --format powershell # Windows PowerShell
238
+ devkit env export activate.bat --format cmd # Windows CMD
239
+
240
+ devkit env diff .env .env.production # show what changed
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Tech Stack
246
+
247
+ | Library | Purpose |
248
+ |---|---|
249
+ | [click](https://click.palletsprojects.com) | CLI framework |
250
+ | [rich](https://rich.readthedocs.io) | Beautiful terminal output, progress bars, tables |
251
+ | [questionary](https://questionary.readthedocs.io) | Interactive prompts |
252
+ | [psutil](https://github.com/giampaolo/psutil) | System metrics (CPU, RAM, disk) |
253
+
254
+ ---
255
+
256
+ ## Contributing
257
+
258
+ ```bash
259
+ git clone https://github.com/dipenpadhiyar/devit-cli
260
+ cd devit-cli
261
+ pip install -e ".[dev]"
262
+ pytest
263
+ ```
264
+
265
+ Pull requests are welcome!
266
+
267
+ ---
268
+
269
+ ## License
270
+
271
+ MIT — see [LICENSE](https://github.com/dipenpadhiyar/devit-cli/blob/main/LICENSE) for details.
272
+
273
+
@@ -0,0 +1,52 @@
1
+ _devkit_entry.py,sha256=gI7_Rw8p5BaT46PULrd5rpGCjBItyQ5LlwffVXUCtpE,2001
2
+ devit_cli-0.1.0.dist-info/licenses/LICENSE,sha256=Utkevq-mBXnLgQwI9kxl8b1jKr-Z-mRDqQ01uJDejN4,1091
3
+ devkit_cli/__init__.py,sha256=PjudVK6xjNIkF6iRD__uGdqXYDubIeN55aHk9Asgmes,138
4
+ devkit_cli/main.py,sha256=1DJ8eQrwnmAkMTtjyiN9qQZuXrO18foRTh1wjyzRYHA,3418
5
+ devkit_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ devkit_cli/commands/archive.py,sha256=KLjmoo67u4JC43tFDt7-w5EX8-4-PFxnQFf0TeGOjMY,5969
7
+ devkit_cli/commands/clean.py,sha256=3M4E_X_dvMB-gaiu8lFahulcUIY25iWWTPeifXsZGjA,3620
8
+ devkit_cli/commands/env.py,sha256=T-pKgDd6LoevTGV9P3VS6loITbm9kJps8MjdadLidGg,5347
9
+ devkit_cli/commands/find.py,sha256=4JSNyoZDASEwbwpLXmthyUxZDH3lRBKrkIHYMzloGXI,4377
10
+ devkit_cli/commands/info.py,sha256=1W-av4SfWRUreW5L-nAdQNZaM3uVT7KYXMzn0mWx4H8,3737
11
+ devkit_cli/commands/init.py,sha256=nJO_K1nG_mXqg8uiDVDgq8PKNBOinUlCPIK4Eertp20,18418
12
+ devkit_cli/commands/run.py,sha256=HZ8zrzbfeltlf4bg7R0vSOZMmNhUM16GQdY3gzFT_RQ,8996
13
+ devkit_cli/templates/aws/.gitignore,sha256=V9yZwen3aT5HHWcMxX5SUhFu4ITLOBmbun4rJjPJ_Ak,367
14
+ devkit_cli/templates/aws/README.md,sha256=ttr7pSh4wKQ6QwyfcZvQCDn8TsdqwtRPN_hOtWm5dDg,324
15
+ devkit_cli/templates/aws/requirements.txt,sha256=uyeWECNCrWBrNn6dgO3RI4yD2KRDyLNg_9_TCidg3Iw,29
16
+ devkit_cli/templates/aws/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ devkit_cli/templates/aws/scripts/ec2.py,sha256=sSW6wBbwr26SRoqL69aQEQXR6FvTT7Co_PjqAe_RwHA,230
18
+ devkit_cli/templates/aws/scripts/main.py,sha256=x7JoPfusAXqnpNPbOyPwhiPrMHvPMZlN2a-9niP9dso,648
19
+ devkit_cli/templates/aws/scripts/s3.py,sha256=keDReh8hUqGSuzT_m_WbWzpWI3q9A5snFfHW4-KU9iU,209
20
+ devkit_cli/templates/aws/tests/test_scripts.py,sha256=SpryxcA9IUpRO3qxi-nK9Vjia1ZDAUHnW6dXZj0PntA,151
21
+ devkit_cli/templates/django/.gitignore,sha256=V9yZwen3aT5HHWcMxX5SUhFu4ITLOBmbun4rJjPJ_Ak,367
22
+ devkit_cli/templates/django/README.md,sha256=iec-vUguqqCrxW1PzMuWS1fSgRzi5S0tw_zRSFyo29Y,195
23
+ devkit_cli/templates/django/manage.py,sha256=sIw_oyt1arveVPLwJkNkhGgrB_wpjejz6oC3fkwqS7M,569
24
+ devkit_cli/templates/django/requirements.txt,sha256=vQUx6anPK0Sv2AQpekhtFMpkEf5Ra5KM57ZPC_ADQuY,13
25
+ devkit_cli/templates/django/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ devkit_cli/templates/django/apps/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ devkit_cli/templates/django/apps/core/apps.py,sha256=kbGjkM2ifkNolj3XhS4i3LHTW-0tsRcrsYyxMvkOZ0w,151
28
+ devkit_cli/templates/django/apps/core/urls.py,sha256=uew5_i7pyR19Qw7XO14shhtSPdUnYe_NB9kNS9DaBTA,115
29
+ devkit_cli/templates/django/apps/core/views.py,sha256=wnBQTdoQ-HMOKEjUe5ABp9ps0WdYOlkqnr5MSOWNWBU,168
30
+ devkit_cli/templates/django/{{module_name}}/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ devkit_cli/templates/django/{{module_name}}/settings.py,sha256=pYhhM1f34dpNrni3MiSk0_gx_bQrP_Qb_Zn2iksF-js,1721
32
+ devkit_cli/templates/django/{{module_name}}/urls.py,sha256=ZwwkCDNIduQJldIjJ6UKR8zEffWR20LAAzHySDh-MP0,217
33
+ devkit_cli/templates/django/{{module_name}}/wsgi.py,sha256=XHF05_bx3pnlreeS4e_6AZU42mIlN7Wf6aPpGcxl1Hg,222
34
+ devkit_cli/templates/fastapi/.gitignore,sha256=V9yZwen3aT5HHWcMxX5SUhFu4ITLOBmbun4rJjPJ_Ak,367
35
+ devkit_cli/templates/fastapi/README.md,sha256=yoU2oTPgRA34OaipV_Ag0fj2KYho_dF9HWVoiWyRATw,209
36
+ devkit_cli/templates/fastapi/main.py,sha256=F3zI1xmg6MyfzLvQEOgdckv19IM1oRJgc7lgLsfNQbQ,314
37
+ devkit_cli/templates/fastapi/requirements.txt,sha256=ObwNW61KP5zyoZ7NLJaSe30Ocn0zmAHzr9ospe7zAPs,103
38
+ devkit_cli/templates/fastapi/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ devkit_cli/templates/fastapi/app/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ devkit_cli/templates/fastapi/app/routers/health.py,sha256=OxHjmi_bB7haaEPpR4FK8Hcz-tUnzcWenJspN0Nh4w8,189
41
+ devkit_cli/templates/fastapi/tests/test_api.py,sha256=XB--vVuR6NVNw-Hs3qgpjbloeSFIKCyNr8QxVkpaqEk,341
42
+ devkit_cli/templates/package/.gitignore,sha256=V9yZwen3aT5HHWcMxX5SUhFu4ITLOBmbun4rJjPJ_Ak,367
43
+ devkit_cli/templates/package/README.md,sha256=2UC-GSTm481oHBIIS5Kkv5HEtNmod4qBAeh1R2wM5zg,148
44
+ devkit_cli/templates/package/pyproject.toml,sha256=b9s4EUyeJLJj18uaiCyFHHnFTrg5sr4W9G4bifB5FWE,581
45
+ devkit_cli/templates/package/tests/test_core.py,sha256=Ws03fjSAGUpb-AwzceDJa8_jj2FyD0qx96lcUL-8S2U,187
46
+ devkit_cli/templates/package/{{module_name}}/__init__.py,sha256=mP_XOicx6Xi0Ca2EXkrTBqCoT5UGppCL62n96PtrCh4,69
47
+ devkit_cli/templates/package/{{module_name}}/core.py,sha256=l624VhIIxYJGP8re4FVBmiEDjNuRBZe7tcj9RfJzLh8,114
48
+ devit_cli-0.1.0.dist-info/METADATA,sha256=sRn4dWGa659piBlT_aMdOA7wNq8cVzsVaxP_bcjvIGU,8093
49
+ devit_cli-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
50
+ devit_cli-0.1.0.dist-info/entry_points.txt,sha256=aaew_Nvzhy3BNEXKqQv--JWa8JNihftFNXXwkwX5cUc,46
51
+ devit_cli-0.1.0.dist-info/top_level.txt,sha256=UmOPWna164DvKb2Pt3g5mhd3b1Xlz4OllFZKSPbulmU,25
52
+ devit_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ devkit = _devkit_entry:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dipenpadhiyar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ _devkit_entry
2
+ devkit_cli
devkit_cli/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ """devkit-cli — A professional developer toolkit for the terminal."""
2
+
3
+ __version__ = "0.1.0"
4
+ __author__ = "devkit-cli contributors"
File without changes
@@ -0,0 +1,166 @@
1
+ """devkit zip / devkit unzip — Archive utilities with progress bars."""
2
+
3
+ import zipfile
4
+ from pathlib import Path
5
+
6
+ import click
7
+ from rich.console import Console
8
+ from rich.progress import (
9
+ BarColumn,
10
+ FileSizeColumn,
11
+ Progress,
12
+ TaskProgressColumn,
13
+ TextColumn,
14
+ TimeRemainingColumn,
15
+ TransferSpeedColumn,
16
+ )
17
+
18
+ console = Console()
19
+
20
+
21
+ def _bytes_to_human(n: int) -> str:
22
+ for unit in ("B", "KB", "MB", "GB"):
23
+ if n < 1024:
24
+ return f"{n:.1f} {unit}"
25
+ n /= 1024
26
+ return f"{n:.1f} TB"
27
+
28
+
29
+ # ---------------------------------------------------------------------------
30
+ # ZIP
31
+ # ---------------------------------------------------------------------------
32
+
33
+ @click.command("zip")
34
+ @click.argument("output", metavar="OUTPUT.zip")
35
+ @click.argument("sources", nargs=-1, required=True, metavar="FILE_OR_DIR...")
36
+ @click.option("-l", "--level", default=6, show_default=True,
37
+ type=click.IntRange(0, 9), help="Compression level (0=none, 9=max).")
38
+ @click.option("-x", "--exclude", multiple=True,
39
+ help="Glob pattern(s) to exclude, e.g. -x '*.pyc' -x '__pycache__'")
40
+ def zip_cmd(output, sources, level, exclude):
41
+ """
42
+ Create a ZIP archive from files/directories.
43
+
44
+ \b
45
+ Examples:
46
+ devkit zip archive.zip src/ README.md
47
+ devkit zip dist.zip . -x __pycache__ -x '*.pyc' -l 9
48
+ """
49
+ out_path = Path(output)
50
+ if not out_path.suffix:
51
+ out_path = out_path.with_suffix(".zip")
52
+
53
+ # Collect all files
54
+ all_files: list[tuple[Path, str]] = []
55
+ for src_str in sources:
56
+ src = Path(src_str)
57
+ if not src.exists():
58
+ console.print(f"[red]Source not found: {src}[/red]")
59
+ raise click.Abort()
60
+ if src.is_dir():
61
+ for f in src.rglob("*"):
62
+ if f.is_file():
63
+ arc_name = str(f.relative_to(src.parent))
64
+ skip = any(f.match(pat) for pat in exclude)
65
+ if not skip:
66
+ all_files.append((f, arc_name))
67
+ else:
68
+ skip = any(src.match(pat) for pat in exclude)
69
+ if not skip:
70
+ all_files.append((src, src.name))
71
+
72
+ if not all_files:
73
+ console.print("[yellow]No files to archive.[/yellow]")
74
+ return
75
+
76
+ total_size = sum(f.stat().st_size for f, _ in all_files)
77
+ console.print(f"Archiving [bold]{len(all_files)}[/bold] files "
78
+ f"([cyan]{_bytes_to_human(total_size)}[/cyan]) → [green]{out_path}[/green]")
79
+
80
+ compress = zipfile.ZIP_DEFLATED if level > 0 else zipfile.ZIP_STORED
81
+
82
+ with Progress(
83
+ TextColumn("[bold blue]{task.description}"),
84
+ BarColumn(),
85
+ TaskProgressColumn(),
86
+ FileSizeColumn(),
87
+ TransferSpeedColumn(),
88
+ TimeRemainingColumn(),
89
+ console=console,
90
+ ) as progress:
91
+ task = progress.add_task("Compressing", total=total_size)
92
+ with zipfile.ZipFile(out_path, "w", compression=compress, compresslevel=level) as zf:
93
+ for fpath, arc_name in all_files:
94
+ zf.write(fpath, arc_name)
95
+ progress.advance(task, fpath.stat().st_size)
96
+
97
+ final_size = out_path.stat().st_size
98
+ ratio = (1 - final_size / total_size) * 100 if total_size else 0
99
+ console.print(f"[green]✔[/green] Created [bold]{out_path}[/bold] "
100
+ f"([cyan]{_bytes_to_human(final_size)}[/cyan], "
101
+ f"[dim]{ratio:.1f}% compression[/dim])")
102
+
103
+
104
+ # ---------------------------------------------------------------------------
105
+ # UNZIP
106
+ # ---------------------------------------------------------------------------
107
+
108
+ @click.command("unzip")
109
+ @click.argument("archive", type=click.Path(exists=True, dir_okay=False))
110
+ @click.argument("destination", default=".", metavar="DEST_DIR")
111
+ @click.option("-l", "--list", "list_only", is_flag=True, default=False,
112
+ help="List contents without extracting.")
113
+ def unzip_cmd(archive, destination, list_only):
114
+ """
115
+ Extract a ZIP archive with a progress bar.
116
+
117
+ \b
118
+ Examples:
119
+ devkit unzip archive.zip
120
+ devkit unzip archive.zip ./output
121
+ devkit unzip archive.zip --list
122
+ """
123
+ arc_path = Path(archive)
124
+
125
+ if not zipfile.is_zipfile(arc_path):
126
+ console.print(f"[red]{archive} is not a valid ZIP file.[/red]")
127
+ raise click.Abort()
128
+
129
+ with zipfile.ZipFile(arc_path, "r") as zf:
130
+ members = zf.infolist()
131
+
132
+ if list_only:
133
+ from rich.table import Table
134
+ table = Table(title=f"Contents of {arc_path.name}")
135
+ table.add_column("File", style="cyan")
136
+ table.add_column("Size", justify="right", style="green")
137
+ table.add_column("Compressed", justify="right", style="dim")
138
+ for m in members:
139
+ if not m.is_dir():
140
+ table.add_row(
141
+ m.filename,
142
+ _bytes_to_human(m.file_size),
143
+ _bytes_to_human(m.compress_size),
144
+ )
145
+ console.print(table)
146
+ return
147
+
148
+ dest = Path(destination)
149
+ dest.mkdir(parents=True, exist_ok=True)
150
+ total_size = sum(m.file_size for m in members if not m.is_dir())
151
+
152
+ with Progress(
153
+ TextColumn("[bold blue]{task.description}"),
154
+ BarColumn(),
155
+ TaskProgressColumn(),
156
+ FileSizeColumn(),
157
+ TimeRemainingColumn(),
158
+ console=console,
159
+ ) as progress:
160
+ task = progress.add_task("Extracting", total=total_size)
161
+ for member in members:
162
+ zf.extract(member, dest)
163
+ if not member.is_dir():
164
+ progress.advance(task, member.file_size)
165
+
166
+ console.print(f"[green]✔[/green] Extracted [bold]{len(members)}[/bold] items to [cyan]{dest}[/cyan]")