newstack 0.1.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 (77) hide show
  1. newstack-0.1.0/.gitignore +19 -0
  2. newstack-0.1.0/CHANGELOG.md +22 -0
  3. newstack-0.1.0/LICENSE +21 -0
  4. newstack-0.1.0/PKG-INFO +197 -0
  5. newstack-0.1.0/README.md +173 -0
  6. newstack-0.1.0/pyproject.toml +55 -0
  7. newstack-0.1.0/src/newstack/__init__.py +4 -0
  8. newstack-0.1.0/src/newstack/__main__.py +8 -0
  9. newstack-0.1.0/src/newstack/cli.py +387 -0
  10. newstack-0.1.0/src/newstack/data/stacks/fastapi/stack.json +42 -0
  11. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/.github/workflows/ci.yml +30 -0
  12. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/.gitignore +11 -0
  13. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/Dockerfile +13 -0
  14. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/LICENSE +21 -0
  15. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/README.md +30 -0
  16. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/pyproject.toml +31 -0
  17. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/src/{{package_name}}/__init__.py +4 -0
  18. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/src/{{package_name}}/main.py +50 -0
  19. newstack-0.1.0/src/newstack/data/stacks/fastapi/template/tests/test_api.py +41 -0
  20. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/stack.json +14 -0
  21. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/.github/workflows/ci.yml +28 -0
  22. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/.gitignore +6 -0
  23. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/LICENSE +21 -0
  24. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/README.md +24 -0
  25. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/package.json +26 -0
  26. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/src/app.ts +35 -0
  27. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/src/server.ts +7 -0
  28. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/tests/app.test.ts +32 -0
  29. newstack-0.1.0/src/newstack/data/stacks/node-express-ts/template/tsconfig.json +14 -0
  30. newstack-0.1.0/src/newstack/data/stacks/python-cli/stack.json +50 -0
  31. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/.github/workflows/ci.yml +32 -0
  32. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/.gitignore +11 -0
  33. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/LICENSE +21 -0
  34. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/README.md +35 -0
  35. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/pyproject.toml +32 -0
  36. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/src/{{package_name}}/__init__.py +4 -0
  37. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/src/{{package_name}}/__main__.py +6 -0
  38. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/src/{{package_name}}/cli.py +30 -0
  39. newstack-0.1.0/src/newstack/data/stacks/python-cli/template/tests/test_cli.py +20 -0
  40. newstack-0.1.0/src/newstack/data/stacks/python-lib/stack.json +42 -0
  41. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/.github/workflows/ci.yml +32 -0
  42. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/.gitignore +11 -0
  43. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/LICENSE +21 -0
  44. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/README.md +28 -0
  45. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/pyproject.toml +34 -0
  46. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/src/{{package_name}}/__init__.py +6 -0
  47. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/src/{{package_name}}/core.py +23 -0
  48. newstack-0.1.0/src/newstack/data/stacks/python-lib/template/tests/test_core.py +31 -0
  49. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/stack.json +15 -0
  50. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/.github/workflows/ci.yml +29 -0
  51. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/.gitignore +7 -0
  52. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/LICENSE +21 -0
  53. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/README.md +25 -0
  54. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/index.html +12 -0
  55. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/package.json +28 -0
  56. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/src/App.test.tsx +20 -0
  57. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/src/App.tsx +15 -0
  58. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/src/main.tsx +16 -0
  59. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/src/styles.css +26 -0
  60. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/tsconfig.json +16 -0
  61. newstack-0.1.0/src/newstack/data/stacks/react-vite-ts/template/vite.config.ts +10 -0
  62. newstack-0.1.0/src/newstack/data/stacks/static-site/stack.json +14 -0
  63. newstack-0.1.0/src/newstack/data/stacks/static-site/template/.github/workflows/deploy-pages.yml +30 -0
  64. newstack-0.1.0/src/newstack/data/stacks/static-site/template/.gitignore +2 -0
  65. newstack-0.1.0/src/newstack/data/stacks/static-site/template/LICENSE +21 -0
  66. newstack-0.1.0/src/newstack/data/stacks/static-site/template/README.md +21 -0
  67. newstack-0.1.0/src/newstack/data/stacks/static-site/template/index.html +34 -0
  68. newstack-0.1.0/src/newstack/data/stacks/static-site/template/main.js +15 -0
  69. newstack-0.1.0/src/newstack/data/stacks/static-site/template/styles.css +74 -0
  70. newstack-0.1.0/src/newstack/data/stacks/static-site/template/tests/site.test.mjs +22 -0
  71. newstack-0.1.0/src/newstack/registry.py +137 -0
  72. newstack-0.1.0/src/newstack/render.py +163 -0
  73. newstack-0.1.0/src/newstack/verify.py +133 -0
  74. newstack-0.1.0/tests/test_cli.py +106 -0
  75. newstack-0.1.0/tests/test_registry.py +86 -0
  76. newstack-0.1.0/tests/test_render.py +110 -0
  77. newstack-0.1.0/tests/test_stacks.py +152 -0
@@ -0,0 +1,19 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ build/
7
+ dist/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+
13
+ # Node (used when checking the node stacks locally)
14
+ node_modules/
15
+
16
+ # tooling
17
+ .DS_Store
18
+ .idea/
19
+ .vscode/
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-11-02
10
+
11
+ ### Added
12
+
13
+ - `newstack new <stack> <path>` — render a stack, initialise git, first commit.
14
+ - `newstack new … --github [OWNER/REPO]` — create the GitHub repository and push.
15
+ - `newstack list` — every stack with its toolchain requirements, `--json` supported.
16
+ - `newstack check <stack…> | --all` — generate into a temp dir and run the stack's own
17
+ verification steps (`install`, `lint`, `test`, `build`), reported per step.
18
+ - `newstack doctor` — which toolchains are installed, which stacks can be verified here.
19
+ - Six stacks: `python-lib`, `python-cli`, `fastapi`, `react-vite-ts`, `node-express-ts`,
20
+ `static-site`.
21
+ - Stack registry is extensible through the `NEWSTACK_STACKS` environment variable.
22
+ - Zero runtime dependencies: standard library only.
newstack-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Priyansh Kansara
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,197 @@
1
+ Metadata-Version: 2.5
2
+ Name: newstack
3
+ Version: 0.1.0
4
+ Summary: Scaffold a new project on any popular stack — every generated starter is proven green in CI.
5
+ Project-URL: Homepage, https://github.com/DawnofGenX/newstack
6
+ Project-URL: Repository, https://github.com/DawnofGenX/newstack
7
+ Project-URL: Issues, https://github.com/DawnofGenX/newstack/issues
8
+ Project-URL: Changelog, https://github.com/DawnofGenX/newstack/blob/main/CHANGELOG.md
9
+ Author-email: Priyansh Kansara <pkansara0412@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: boilerplate,cli,generator,scaffold,scaffolding,starter,template
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Code Generators
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+
25
+ # newstack
26
+
27
+ [![CI](https://github.com/DawnofGenX/newstack/actions/workflows/ci.yml/badge.svg)](https://github.com/DawnofGenX/newstack/actions/workflows/ci.yml)
28
+ ![python](https://img.shields.io/badge/python-3.10%2B-blue)
29
+ ![dependencies](https://img.shields.io/badge/runtime%20dependencies-0-brightgreen)
30
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
31
+
32
+ **Scaffold a new project on any popular stack — and every starter it emits is proven green in CI.**
33
+
34
+ ```console
35
+ $ newstack new python-lib ~/code/mylib
36
+ newstack 0.1.0 · python-lib → /home/you/code/mylib
37
+
38
+ created 8 files
39
+ git initialised on main, first commit made
40
+
41
+ next:
42
+ cd /home/you/code/mylib
43
+ uv sync
44
+ uv run pytest
45
+ ```
46
+
47
+ ## Why this exists
48
+
49
+ `cookiecutter`, `copier`, `yeoman`, `degit`, `npm create …` and `gh repo create --template`
50
+ all solve *part* of the problem. Two things are still missing in practice:
51
+
52
+ 1. **One tool for every stack.** Python templates are Python-only, JS templates are
53
+ JS-only, and `gh repo create --template` clones a whole repository with no variables.
54
+ 2. **A guarantee that the template still works.** Templates rot silently. You find out
55
+ the starter is broken *after* you have already started building on top of it.
56
+
57
+ `newstack` fixes both. It is one zero-dependency CLI that carries a curated stack
58
+ registry, and **every stack in that registry is generated and checked on every push**
59
+ (`newstack check --all` in CI). If a starter breaks, the badge goes red — not your
60
+ first day of work.
61
+
62
+ ## Install
63
+
64
+ Not on PyPI yet — install straight from the repository:
65
+
66
+ ```bash
67
+ uv tool install git+https://github.com/DawnofGenX/newstack
68
+ # or, without installing:
69
+ uvx --from git+https://github.com/DawnofGenX/newstack newstack list
70
+ ```
71
+
72
+ From a clone:
73
+
74
+ ```bash
75
+ git clone https://github.com/DawnofGenX/newstack && cd newstack
76
+ uv sync && uv run newstack list
77
+ ```
78
+
79
+ ## Use
80
+
81
+ ```bash
82
+ newstack list # what is available, and what each stack needs
83
+ newstack new react-vite-ts ~/code/app
84
+ newstack new fastapi ~/code/api -d "Billing service" --author "Your Name"
85
+ newstack new python-lib ~/code/lib --dry-run # preview, write nothing
86
+ newstack new python-cli ~/code/tool --github # create the repo and push it too
87
+ newstack check --all # prove every stack on this machine
88
+ newstack doctor # which toolchains do I have?
89
+ ```
90
+
91
+ Every command takes `--json` where it makes sense, so the tool is scriptable.
92
+
93
+ `newstack new` renders variables, initialises git with a first commit, and (with
94
+ `--github`) creates the remote repository and pushes — one command from empty
95
+ directory to CI-ready project.
96
+
97
+ ## Stacks
98
+
99
+ | Stack | What you get | Toolchain |
100
+ | --- | --- | --- |
101
+ | `python-lib` | src layout, hatchling build, pytest, ruff, 4-version CI matrix | `uv` |
102
+ | `python-cli` | console entry point on argparse, zero runtime deps, tested CLI | `uv` |
103
+ | `fastapi` | typed JSON API, pydantic models, TestClient tests, Dockerfile | `uv` |
104
+ | `react-vite-ts` | React 19 + Vite + TS, Vitest + Testing Library, typecheck + build | `node`, `npm` |
105
+ | `node-express-ts` | Express 5 API, typed handlers, supertest tests | `node`, `npm` |
106
+ | `static-site` | HTML/CSS/JS page with a GitHub Pages deploy workflow | `node` |
107
+
108
+ Each generated project ships its own `.github/workflows/` that is ready to run, plus a
109
+ README, an MIT licence and a `.gitignore`.
110
+
111
+ ## The green guarantee
112
+
113
+ A template is only as good as its last successful run, so `newstack` treats
114
+ verification as a first-class command:
115
+
116
+ ```console
117
+ $ newstack check --all
118
+ fastapi PASS 1.0s 3 step(s)
119
+ node-express-ts PASS 2.2s 3 step(s)
120
+ python-cli PASS 0.5s 4 step(s)
121
+ python-lib PASS 0.4s 3 step(s)
122
+ react-vite-ts PASS 3.2s 4 step(s)
123
+ static-site PASS 0.1s 3 step(s)
124
+ ```
125
+
126
+ (Real timings from a warm package cache — a cold run takes about a minute because
127
+ `npm install` and `uv pip install` have to fetch packages.)
128
+
129
+ `check` generates the stack into a throwaway directory, runs the commands listed in its
130
+ manifest (`install → lint → test → build`), reports per-step timings, and deletes the
131
+ directory unless you pass `--keep`. The same command runs in this repository's CI, once
132
+ per stack, on every push.
133
+
134
+ ## How it compares
135
+
136
+ | | newstack | cookiecutter | copier | yeoman | degit / `npm create` | `gh repo create --template` |
137
+ | --- | --- | --- | --- | --- | --- | --- |
138
+ | Cross-language stacks in one tool | **yes** | no | no | partial | no | n/a |
139
+ | Runtime dependencies | **0** | Python | Python + git | Node | Node | gh |
140
+ | Generated starter verified in CI | **yes, per stack** | no | no | no | no | no |
141
+ | Template updates after generation | no (roadmap) | no | **yes** (`copier update`) | no | no | no |
142
+ | Creates the git repo + remote | **yes** (`--github`) | no | via hooks | no | no | yes |
143
+
144
+ Pick `copier` if you need `copier update` three-way merges against a single template you
145
+ own. Pick `newstack` when you want the same standard applied across several languages
146
+ without maintaining one template per stack.
147
+
148
+ ## Adding a stack
149
+
150
+ A stack is a directory with a manifest and a template tree:
151
+
152
+ ```text
153
+ src/newstack/data/stacks/my-stack/
154
+ ├── stack.json
155
+ └── template/
156
+ ├── README.md
157
+ └── ... # {{ project_name }}, {{ package_name }}, {{ npm_name }},
158
+ # {{ title }}, {{ description }}, {{ author }}, {{ email }},
159
+ # {{ year }}, {{ date }}
160
+ ```
161
+
162
+ ```json
163
+ {
164
+ "name": "my-stack",
165
+ "title": "My stack",
166
+ "language": "python",
167
+ "blurb": "One line shown by `newstack list`",
168
+ "requires": ["uv"],
169
+ "next_steps": ["cd {path}", "uv run pytest"],
170
+ "verify": [
171
+ {"name": "test", "cmd": "uv run pytest", "tools": ["uv"], "timeout": 600}
172
+ ]
173
+ }
174
+ ```
175
+
176
+ `{{!` escapes a literal `{{`, and `${{ ... }}` (GitHub Actions) is left untouched.
177
+ Point `NEWSTACK_STACKS` at a directory of your own stacks to use private ones — same
178
+ manifest format, no fork required.
179
+
180
+ ## Design
181
+
182
+ - **Zero runtime dependencies.** `argparse` and the standard library only, so `uvx newstack`
183
+ starts instantly and works offline.
184
+ - **Templates are plain files.** No Jinja, no DSL — a reviewer can read a template and know
185
+ exactly what gets written.
186
+ - **Verification is a product feature, not an afterthought.** `check` is the same code path
187
+ CI uses.
188
+
189
+ ## Roadmap
190
+
191
+ - `newstack update` — re-apply upstream template changes to an existing project.
192
+ - More stacks: Go service, Rust CLI, Django, Vue, SvelteKit.
193
+ - `--license apache-2.0|bsd-3` and other variable choices beyond the current defaults.
194
+
195
+ ## Licence
196
+
197
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,173 @@
1
+ # newstack
2
+
3
+ [![CI](https://github.com/DawnofGenX/newstack/actions/workflows/ci.yml/badge.svg)](https://github.com/DawnofGenX/newstack/actions/workflows/ci.yml)
4
+ ![python](https://img.shields.io/badge/python-3.10%2B-blue)
5
+ ![dependencies](https://img.shields.io/badge/runtime%20dependencies-0-brightgreen)
6
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ **Scaffold a new project on any popular stack — and every starter it emits is proven green in CI.**
9
+
10
+ ```console
11
+ $ newstack new python-lib ~/code/mylib
12
+ newstack 0.1.0 · python-lib → /home/you/code/mylib
13
+
14
+ created 8 files
15
+ git initialised on main, first commit made
16
+
17
+ next:
18
+ cd /home/you/code/mylib
19
+ uv sync
20
+ uv run pytest
21
+ ```
22
+
23
+ ## Why this exists
24
+
25
+ `cookiecutter`, `copier`, `yeoman`, `degit`, `npm create …` and `gh repo create --template`
26
+ all solve *part* of the problem. Two things are still missing in practice:
27
+
28
+ 1. **One tool for every stack.** Python templates are Python-only, JS templates are
29
+ JS-only, and `gh repo create --template` clones a whole repository with no variables.
30
+ 2. **A guarantee that the template still works.** Templates rot silently. You find out
31
+ the starter is broken *after* you have already started building on top of it.
32
+
33
+ `newstack` fixes both. It is one zero-dependency CLI that carries a curated stack
34
+ registry, and **every stack in that registry is generated and checked on every push**
35
+ (`newstack check --all` in CI). If a starter breaks, the badge goes red — not your
36
+ first day of work.
37
+
38
+ ## Install
39
+
40
+ Not on PyPI yet — install straight from the repository:
41
+
42
+ ```bash
43
+ uv tool install git+https://github.com/DawnofGenX/newstack
44
+ # or, without installing:
45
+ uvx --from git+https://github.com/DawnofGenX/newstack newstack list
46
+ ```
47
+
48
+ From a clone:
49
+
50
+ ```bash
51
+ git clone https://github.com/DawnofGenX/newstack && cd newstack
52
+ uv sync && uv run newstack list
53
+ ```
54
+
55
+ ## Use
56
+
57
+ ```bash
58
+ newstack list # what is available, and what each stack needs
59
+ newstack new react-vite-ts ~/code/app
60
+ newstack new fastapi ~/code/api -d "Billing service" --author "Your Name"
61
+ newstack new python-lib ~/code/lib --dry-run # preview, write nothing
62
+ newstack new python-cli ~/code/tool --github # create the repo and push it too
63
+ newstack check --all # prove every stack on this machine
64
+ newstack doctor # which toolchains do I have?
65
+ ```
66
+
67
+ Every command takes `--json` where it makes sense, so the tool is scriptable.
68
+
69
+ `newstack new` renders variables, initialises git with a first commit, and (with
70
+ `--github`) creates the remote repository and pushes — one command from empty
71
+ directory to CI-ready project.
72
+
73
+ ## Stacks
74
+
75
+ | Stack | What you get | Toolchain |
76
+ | --- | --- | --- |
77
+ | `python-lib` | src layout, hatchling build, pytest, ruff, 4-version CI matrix | `uv` |
78
+ | `python-cli` | console entry point on argparse, zero runtime deps, tested CLI | `uv` |
79
+ | `fastapi` | typed JSON API, pydantic models, TestClient tests, Dockerfile | `uv` |
80
+ | `react-vite-ts` | React 19 + Vite + TS, Vitest + Testing Library, typecheck + build | `node`, `npm` |
81
+ | `node-express-ts` | Express 5 API, typed handlers, supertest tests | `node`, `npm` |
82
+ | `static-site` | HTML/CSS/JS page with a GitHub Pages deploy workflow | `node` |
83
+
84
+ Each generated project ships its own `.github/workflows/` that is ready to run, plus a
85
+ README, an MIT licence and a `.gitignore`.
86
+
87
+ ## The green guarantee
88
+
89
+ A template is only as good as its last successful run, so `newstack` treats
90
+ verification as a first-class command:
91
+
92
+ ```console
93
+ $ newstack check --all
94
+ fastapi PASS 1.0s 3 step(s)
95
+ node-express-ts PASS 2.2s 3 step(s)
96
+ python-cli PASS 0.5s 4 step(s)
97
+ python-lib PASS 0.4s 3 step(s)
98
+ react-vite-ts PASS 3.2s 4 step(s)
99
+ static-site PASS 0.1s 3 step(s)
100
+ ```
101
+
102
+ (Real timings from a warm package cache — a cold run takes about a minute because
103
+ `npm install` and `uv pip install` have to fetch packages.)
104
+
105
+ `check` generates the stack into a throwaway directory, runs the commands listed in its
106
+ manifest (`install → lint → test → build`), reports per-step timings, and deletes the
107
+ directory unless you pass `--keep`. The same command runs in this repository's CI, once
108
+ per stack, on every push.
109
+
110
+ ## How it compares
111
+
112
+ | | newstack | cookiecutter | copier | yeoman | degit / `npm create` | `gh repo create --template` |
113
+ | --- | --- | --- | --- | --- | --- | --- |
114
+ | Cross-language stacks in one tool | **yes** | no | no | partial | no | n/a |
115
+ | Runtime dependencies | **0** | Python | Python + git | Node | Node | gh |
116
+ | Generated starter verified in CI | **yes, per stack** | no | no | no | no | no |
117
+ | Template updates after generation | no (roadmap) | no | **yes** (`copier update`) | no | no | no |
118
+ | Creates the git repo + remote | **yes** (`--github`) | no | via hooks | no | no | yes |
119
+
120
+ Pick `copier` if you need `copier update` three-way merges against a single template you
121
+ own. Pick `newstack` when you want the same standard applied across several languages
122
+ without maintaining one template per stack.
123
+
124
+ ## Adding a stack
125
+
126
+ A stack is a directory with a manifest and a template tree:
127
+
128
+ ```text
129
+ src/newstack/data/stacks/my-stack/
130
+ ├── stack.json
131
+ └── template/
132
+ ├── README.md
133
+ └── ... # {{ project_name }}, {{ package_name }}, {{ npm_name }},
134
+ # {{ title }}, {{ description }}, {{ author }}, {{ email }},
135
+ # {{ year }}, {{ date }}
136
+ ```
137
+
138
+ ```json
139
+ {
140
+ "name": "my-stack",
141
+ "title": "My stack",
142
+ "language": "python",
143
+ "blurb": "One line shown by `newstack list`",
144
+ "requires": ["uv"],
145
+ "next_steps": ["cd {path}", "uv run pytest"],
146
+ "verify": [
147
+ {"name": "test", "cmd": "uv run pytest", "tools": ["uv"], "timeout": 600}
148
+ ]
149
+ }
150
+ ```
151
+
152
+ `{{!` escapes a literal `{{`, and `${{ ... }}` (GitHub Actions) is left untouched.
153
+ Point `NEWSTACK_STACKS` at a directory of your own stacks to use private ones — same
154
+ manifest format, no fork required.
155
+
156
+ ## Design
157
+
158
+ - **Zero runtime dependencies.** `argparse` and the standard library only, so `uvx newstack`
159
+ starts instantly and works offline.
160
+ - **Templates are plain files.** No Jinja, no DSL — a reviewer can read a template and know
161
+ exactly what gets written.
162
+ - **Verification is a product feature, not an afterthought.** `check` is the same code path
163
+ CI uses.
164
+
165
+ ## Roadmap
166
+
167
+ - `newstack update` — re-apply upstream template changes to an existing project.
168
+ - More stacks: Go service, Rust CLI, Django, Vue, SvelteKit.
169
+ - `--license apache-2.0|bsd-3` and other variable choices beyond the current defaults.
170
+
171
+ ## Licence
172
+
173
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "newstack"
7
+ version = "0.1.0"
8
+ description = "Scaffold a new project on any popular stack — every generated starter is proven green in CI."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Priyansh Kansara", email = "pkansara0412@gmail.com" }]
14
+ keywords = ["scaffold", "scaffolding", "boilerplate", "template", "generator", "cli", "starter"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Code Generators",
25
+ ]
26
+
27
+ [project.scripts]
28
+ newstack = "newstack.cli:main"
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/DawnofGenX/newstack"
32
+ Repository = "https://github.com/DawnofGenX/newstack"
33
+ Issues = "https://github.com/DawnofGenX/newstack/issues"
34
+ Changelog = "https://github.com/DawnofGenX/newstack/blob/main/CHANGELOG.md"
35
+
36
+ [dependency-groups]
37
+ dev = ["pytest>=8.0", "ruff>=0.6"]
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/newstack"]
41
+
42
+ [tool.hatch.build.targets.sdist]
43
+ include = ["src/newstack", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
44
+
45
+ [tool.ruff]
46
+ line-length = 100
47
+ target-version = "py310"
48
+ extend-exclude = ["src/newstack/data"]
49
+
50
+ [tool.ruff.lint]
51
+ select = ["E", "F", "W", "I", "UP", "B", "SIM"]
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
55
+ addopts = "-q"
@@ -0,0 +1,4 @@
1
+ """newstack — scaffold a new project on any popular stack, proven green in CI."""
2
+
3
+ __version__ = "0.1.0"
4
+ __all__ = ["__version__"]
@@ -0,0 +1,8 @@
1
+ """Allow `python -m newstack`."""
2
+
3
+ import sys
4
+
5
+ from .cli import main
6
+
7
+ if __name__ == "__main__":
8
+ sys.exit(main())