pyforge-init 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.
- pyforge_init-0.1.0/.github/workflows/release.yml +58 -0
- pyforge_init-0.1.0/.gitignore +25 -0
- pyforge_init-0.1.0/PKG-INFO +221 -0
- pyforge_init-0.1.0/README.md +204 -0
- pyforge_init-0.1.0/pyproject.toml +33 -0
- pyforge_init-0.1.0/src/pyforge/__init__.py +4 -0
- pyforge_init-0.1.0/src/pyforge/cli.py +194 -0
- pyforge_init-0.1.0/src/pyforge/config.py +119 -0
- pyforge_init-0.1.0/src/pyforge/generator.py +174 -0
- pyforge_init-0.1.0/src/pyforge/prompts.py +167 -0
- pyforge_init-0.1.0/src/pyforge/remote.py +179 -0
- pyforge_init-0.1.0/src/pyforge/templates/basic/tests/test_main.py.jinja +3 -0
- pyforge_init-0.1.0/src/pyforge/templates/cli/src/package/__main__.py.jinja +4 -0
- pyforge_init-0.1.0/src/pyforge/templates/cli/src/package/cli.py.jinja +7 -0
- pyforge_init-0.1.0/src/pyforge/templates/cli/tests/test_cli.py.jinja +8 -0
- pyforge_init-0.1.0/src/pyforge/templates/fastapi/src/package/main.py.jinja +7 -0
- pyforge_init-0.1.0/src/pyforge/templates/fastapi/tests/test_main.py.jinja +9 -0
- pyforge_init-0.1.0/src/pyforge/templates/flask/src/package/app.py.jinja +10 -0
- pyforge_init-0.1.0/src/pyforge/templates/flask/tests/test_app.py.jinja +19 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/Justfile.jinja +28 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/Makefile.jinja +30 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/README.md.jinja +28 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/env.example.jinja +5 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/gitignore.jinja +13 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/pre-commit-config.yaml.jinja +15 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/pyproject.toml.jinja +58 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/requirements.txt.jinja +1 -0
- pyforge_init-0.1.0/src/pyforge/templates/shared/src/package/__init__.py.jinja +3 -0
- pyforge_init-0.1.0/src/pyforge/utils.py +65 -0
- pyforge_init-0.1.0/tests/test_cli.py +62 -0
- pyforge_init-0.1.0/tests/test_config.py +132 -0
- pyforge_init-0.1.0/tests/test_generator.py +185 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Publish Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Run Test Suite
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout Code
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: '3.11'
|
|
20
|
+
cache: 'pip'
|
|
21
|
+
|
|
22
|
+
- name: Install Dependencies
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Run Tests
|
|
28
|
+
run: |
|
|
29
|
+
python -m pytest -v
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
name: Build and Publish to PyPI
|
|
33
|
+
needs: test
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment: release
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write # Required for trusted publishing (OIDC)
|
|
38
|
+
contents: read
|
|
39
|
+
steps:
|
|
40
|
+
- name: Checkout Code
|
|
41
|
+
uses: actions/checkout@v4
|
|
42
|
+
|
|
43
|
+
- name: Set up Python
|
|
44
|
+
uses: actions/setup-python@v5
|
|
45
|
+
with:
|
|
46
|
+
python-version: '3.11'
|
|
47
|
+
|
|
48
|
+
- name: Install Build CLI
|
|
49
|
+
run: |
|
|
50
|
+
python -m pip install --upgrade pip
|
|
51
|
+
pip install build
|
|
52
|
+
|
|
53
|
+
- name: Build Source and Binary Distributions
|
|
54
|
+
run: |
|
|
55
|
+
python -m build
|
|
56
|
+
|
|
57
|
+
- name: Publish Package to PyPI
|
|
58
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python cache files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Testing / coverage
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.coverage
|
|
9
|
+
htmlcov/
|
|
10
|
+
|
|
11
|
+
# Build and distribution
|
|
12
|
+
build/
|
|
13
|
+
dist/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
|
|
16
|
+
# Environments
|
|
17
|
+
.venv/
|
|
18
|
+
env/
|
|
19
|
+
venv/
|
|
20
|
+
ENV/
|
|
21
|
+
.env
|
|
22
|
+
|
|
23
|
+
# IDEs
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyforge-init
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A CLI tool to scaffold new Python projects, similar to create-react-app.
|
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Requires-Dist: click>=8.0.0
|
|
8
|
+
Requires-Dist: httpx>=0.27.0
|
|
9
|
+
Requires-Dist: jinja2>=3.0.0
|
|
10
|
+
Requires-Dist: questionary>=2.0.0
|
|
11
|
+
Requires-Dist: rich>=13.0.0
|
|
12
|
+
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest-mock>=3.0.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# pyforge
|
|
19
|
+
|
|
20
|
+
`pyforge` is a lightweight, interactive command-line interface (CLI) tool designed to scaffold production-ready Python projects in seconds. Inspired by standard scaffolding tools, `pyforge` automates project initialization, environment setup, testing configuration, linting, formatting, and dependency management.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Key Features
|
|
25
|
+
|
|
26
|
+
* **Interactive TUI**: Driven by `questionary` for guided project configuration (supports non-interactive overrides).
|
|
27
|
+
* **Multiple Built-in Templates**: Native templates for `basic` packages, `cli` tools, `fastapi` microservices, and `flask` applications.
|
|
28
|
+
* **Remote Templates**: Pull custom project layouts directly from public GitHub repositories using the `gh:owner/repo` syntax.
|
|
29
|
+
* **Configurable Defaults**: Save persistent author, license, and tool choices in a `~/.newpythonrc` configuration file.
|
|
30
|
+
* **Standards-Compliant**: Generates PEP 621-compliant `pyproject.toml` using `hatchling` as the build backend.
|
|
31
|
+
* **Tooling Configuration**: Preconfigured integration with `pytest`, `ruff` (linter and formatter), and `pre-commit` hooks.
|
|
32
|
+
* **Task Automation**: Automated creation of a local virtual environment, Git repository initialization, and generation of a template-aware `Makefile` or `Justfile`.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Install `pyforge-init` globally via PyPI:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install pyforge-init
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or install it in an isolated environment using `pipx`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pipx install pyforge-init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
Initialize a new project by running:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
newpython myproject
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The CLI will start the interactive configuration wizard:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
? Project description: A new Python project
|
|
64
|
+
? Author name: Jane Doe
|
|
65
|
+
? License: MIT
|
|
66
|
+
? Initialize a virtual environment (.venv)? Yes
|
|
67
|
+
? Initialize a git repository? Yes
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Once the wizard completes, your project directory is created and populated. Execute the following commands to begin development:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cd myproject
|
|
74
|
+
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
|
|
75
|
+
make install # Installs the package and all dev dependencies
|
|
76
|
+
make run # Runs the application (varies by template)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## CLI Reference
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Usage: newpython [OPTIONS] PROJECT_NAME
|
|
85
|
+
|
|
86
|
+
Scaffold a new Python project.
|
|
87
|
+
|
|
88
|
+
Arguments:
|
|
89
|
+
PROJECT_NAME Name of the project (must be a valid Python identifier)
|
|
90
|
+
|
|
91
|
+
Options:
|
|
92
|
+
--template TEXT Built-in template (basic, cli, fastapi, flask)
|
|
93
|
+
or a remote GitHub repo (gh:owner/repo[@ref]) [default: basic]
|
|
94
|
+
--no-pre-commit Skip generating .pre-commit-config.yaml
|
|
95
|
+
--justfile Generate a Justfile instead of a Makefile
|
|
96
|
+
-y, --yes Skip interactive prompts and accept defaults
|
|
97
|
+
--help Show this message and exit.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Project Structure (Basic Template)
|
|
103
|
+
|
|
104
|
+
The default template (`basic`) generates the following directory structure:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
myproject/
|
|
108
|
+
├── src/
|
|
109
|
+
│ └── myproject/
|
|
110
|
+
│ └── __init__.py # Package initialization
|
|
111
|
+
├── tests/
|
|
112
|
+
│ └── test_main.py # Starter unit test
|
|
113
|
+
├── .env.example # Example environment variables
|
|
114
|
+
├── .gitignore # Standard Python git ignore rules
|
|
115
|
+
├── .pre-commit-config.yaml # Pre-configured linting/formatting hooks
|
|
116
|
+
├── Makefile # Task runner
|
|
117
|
+
├── README.md # Generated project documentation
|
|
118
|
+
├── pyproject.toml # Metadata, dependencies, and tool settings
|
|
119
|
+
└── requirements.txt # Project dependencies
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Templates
|
|
125
|
+
|
|
126
|
+
### Built-in Templates
|
|
127
|
+
|
|
128
|
+
| Template | Primary Stack | Generated Entry Point | Run Command |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| `basic` | Pure Python | `src/package/__init__.py` | `python -m package` |
|
|
131
|
+
| `cli` | `click` | `src/package/cli.py` & `__main__.py` | Registered console script |
|
|
132
|
+
| `fastapi` | `fastapi`, `uvicorn`, `httpx` | `src/package/main.py` | `uvicorn src.package.main:app` |
|
|
133
|
+
| `flask` | `flask` (Factory pattern) | `src/package/app.py` | `flask run` |
|
|
134
|
+
|
|
135
|
+
### Remote Templates
|
|
136
|
+
|
|
137
|
+
You can import any public GitHub repository to use as a project template:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Uses the main/master branch
|
|
141
|
+
newpython myproject --template gh:username/repo-name
|
|
142
|
+
|
|
143
|
+
# Pin to a specific branch, tag, or commit hash
|
|
144
|
+
newpython myproject --template gh:username/repo-name@v1.0.0
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Remote Repository Requirements
|
|
148
|
+
Remote templates are fetched and copied as-is (no Jinja template rendering is performed on remote files).
|
|
149
|
+
* If the remote repository has a top-level `template/` directory, only the contents of that folder are copied to the destination.
|
|
150
|
+
* If no `template/` directory is present, the entire contents of the repository root will be copied.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Configuration File (`~/.newpythonrc`)
|
|
155
|
+
|
|
156
|
+
You can persist configuration defaults in a `~/.newpythonrc` (TOML format) file to pre-fill prompt values and skip entering them on every run.
|
|
157
|
+
|
|
158
|
+
```toml
|
|
159
|
+
# ~/.newpythonrc
|
|
160
|
+
author = "Jane Doe"
|
|
161
|
+
license = "MIT"
|
|
162
|
+
template = "basic"
|
|
163
|
+
pre_commit = true
|
|
164
|
+
justfile = false
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Precedence Order
|
|
168
|
+
When resolving configurations, `pyforge` applies overrides in the following order (highest to lowest):
|
|
169
|
+
1. **CLI Flags** (e.g. `--template`, `--justfile`)
|
|
170
|
+
2. **Configuration file** (`~/.newpythonrc`)
|
|
171
|
+
3. **Interactive Prompt Defaults**
|
|
172
|
+
|
|
173
|
+
To override the default config location, set the `NEWPYTHON_CONFIG` environment variable:
|
|
174
|
+
```bash
|
|
175
|
+
export NEWPYTHON_CONFIG="/path/to/custom/config.toml"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Automated Task Runner
|
|
181
|
+
|
|
182
|
+
The generated `Makefile` (or `Justfile` if `--justfile` is passed) exposes standard commands for project maintenance:
|
|
183
|
+
|
|
184
|
+
* `make install`: Installs the project locally in editable mode alongside all development dependencies (`pip install -e ".[dev]"`).
|
|
185
|
+
* `make test`: Executes the test suite using `pytest`.
|
|
186
|
+
* `make lint`: Performs static analysis checking with `ruff`.
|
|
187
|
+
* `make format`: Auto-formats code styles using `ruff format`.
|
|
188
|
+
* `make run`: Starts the application server or CLI script (template-aware).
|
|
189
|
+
* `make clean`: Recursively cleans local cache directories (`__pycache__`, `.pytest_cache`, `.ruff_cache`, `build`, `dist`).
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Publishing to PyPI
|
|
194
|
+
|
|
195
|
+
Projects generated by `pyforge` use `hatchling` as the build system and are ready to be built and uploaded to PyPI:
|
|
196
|
+
|
|
197
|
+
1. Install build and publication dependencies:
|
|
198
|
+
```bash
|
|
199
|
+
pip install build twine
|
|
200
|
+
```
|
|
201
|
+
2. Build the project distribution packages (source archive and wheel):
|
|
202
|
+
```bash
|
|
203
|
+
python -m build
|
|
204
|
+
```
|
|
205
|
+
3. Upload to PyPI (or TestPyPI first):
|
|
206
|
+
```bash
|
|
207
|
+
python -m twine upload dist/*
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
Contributions to `pyforge` are welcome. To set up a local development environment:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
git clone https://github.com/your-name/pyforge.git
|
|
218
|
+
cd pyforge
|
|
219
|
+
pip install -e ".[dev]"
|
|
220
|
+
python -m pytest -v
|
|
221
|
+
```
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# pyforge
|
|
2
|
+
|
|
3
|
+
`pyforge` is a lightweight, interactive command-line interface (CLI) tool designed to scaffold production-ready Python projects in seconds. Inspired by standard scaffolding tools, `pyforge` automates project initialization, environment setup, testing configuration, linting, formatting, and dependency management.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
* **Interactive TUI**: Driven by `questionary` for guided project configuration (supports non-interactive overrides).
|
|
10
|
+
* **Multiple Built-in Templates**: Native templates for `basic` packages, `cli` tools, `fastapi` microservices, and `flask` applications.
|
|
11
|
+
* **Remote Templates**: Pull custom project layouts directly from public GitHub repositories using the `gh:owner/repo` syntax.
|
|
12
|
+
* **Configurable Defaults**: Save persistent author, license, and tool choices in a `~/.newpythonrc` configuration file.
|
|
13
|
+
* **Standards-Compliant**: Generates PEP 621-compliant `pyproject.toml` using `hatchling` as the build backend.
|
|
14
|
+
* **Tooling Configuration**: Preconfigured integration with `pytest`, `ruff` (linter and formatter), and `pre-commit` hooks.
|
|
15
|
+
* **Task Automation**: Automated creation of a local virtual environment, Git repository initialization, and generation of a template-aware `Makefile` or `Justfile`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Install `pyforge-init` globally via PyPI:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install pyforge-init
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or install it in an isolated environment using `pipx`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pipx install pyforge-init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
Initialize a new project by running:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
newpython myproject
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The CLI will start the interactive configuration wizard:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
? Project description: A new Python project
|
|
47
|
+
? Author name: Jane Doe
|
|
48
|
+
? License: MIT
|
|
49
|
+
? Initialize a virtual environment (.venv)? Yes
|
|
50
|
+
? Initialize a git repository? Yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Once the wizard completes, your project directory is created and populated. Execute the following commands to begin development:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cd myproject
|
|
57
|
+
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
|
|
58
|
+
make install # Installs the package and all dev dependencies
|
|
59
|
+
make run # Runs the application (varies by template)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## CLI Reference
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Usage: newpython [OPTIONS] PROJECT_NAME
|
|
68
|
+
|
|
69
|
+
Scaffold a new Python project.
|
|
70
|
+
|
|
71
|
+
Arguments:
|
|
72
|
+
PROJECT_NAME Name of the project (must be a valid Python identifier)
|
|
73
|
+
|
|
74
|
+
Options:
|
|
75
|
+
--template TEXT Built-in template (basic, cli, fastapi, flask)
|
|
76
|
+
or a remote GitHub repo (gh:owner/repo[@ref]) [default: basic]
|
|
77
|
+
--no-pre-commit Skip generating .pre-commit-config.yaml
|
|
78
|
+
--justfile Generate a Justfile instead of a Makefile
|
|
79
|
+
-y, --yes Skip interactive prompts and accept defaults
|
|
80
|
+
--help Show this message and exit.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Project Structure (Basic Template)
|
|
86
|
+
|
|
87
|
+
The default template (`basic`) generates the following directory structure:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
myproject/
|
|
91
|
+
├── src/
|
|
92
|
+
│ └── myproject/
|
|
93
|
+
│ └── __init__.py # Package initialization
|
|
94
|
+
├── tests/
|
|
95
|
+
│ └── test_main.py # Starter unit test
|
|
96
|
+
├── .env.example # Example environment variables
|
|
97
|
+
├── .gitignore # Standard Python git ignore rules
|
|
98
|
+
├── .pre-commit-config.yaml # Pre-configured linting/formatting hooks
|
|
99
|
+
├── Makefile # Task runner
|
|
100
|
+
├── README.md # Generated project documentation
|
|
101
|
+
├── pyproject.toml # Metadata, dependencies, and tool settings
|
|
102
|
+
└── requirements.txt # Project dependencies
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Templates
|
|
108
|
+
|
|
109
|
+
### Built-in Templates
|
|
110
|
+
|
|
111
|
+
| Template | Primary Stack | Generated Entry Point | Run Command |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `basic` | Pure Python | `src/package/__init__.py` | `python -m package` |
|
|
114
|
+
| `cli` | `click` | `src/package/cli.py` & `__main__.py` | Registered console script |
|
|
115
|
+
| `fastapi` | `fastapi`, `uvicorn`, `httpx` | `src/package/main.py` | `uvicorn src.package.main:app` |
|
|
116
|
+
| `flask` | `flask` (Factory pattern) | `src/package/app.py` | `flask run` |
|
|
117
|
+
|
|
118
|
+
### Remote Templates
|
|
119
|
+
|
|
120
|
+
You can import any public GitHub repository to use as a project template:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Uses the main/master branch
|
|
124
|
+
newpython myproject --template gh:username/repo-name
|
|
125
|
+
|
|
126
|
+
# Pin to a specific branch, tag, or commit hash
|
|
127
|
+
newpython myproject --template gh:username/repo-name@v1.0.0
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Remote Repository Requirements
|
|
131
|
+
Remote templates are fetched and copied as-is (no Jinja template rendering is performed on remote files).
|
|
132
|
+
* If the remote repository has a top-level `template/` directory, only the contents of that folder are copied to the destination.
|
|
133
|
+
* If no `template/` directory is present, the entire contents of the repository root will be copied.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Configuration File (`~/.newpythonrc`)
|
|
138
|
+
|
|
139
|
+
You can persist configuration defaults in a `~/.newpythonrc` (TOML format) file to pre-fill prompt values and skip entering them on every run.
|
|
140
|
+
|
|
141
|
+
```toml
|
|
142
|
+
# ~/.newpythonrc
|
|
143
|
+
author = "Jane Doe"
|
|
144
|
+
license = "MIT"
|
|
145
|
+
template = "basic"
|
|
146
|
+
pre_commit = true
|
|
147
|
+
justfile = false
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Precedence Order
|
|
151
|
+
When resolving configurations, `pyforge` applies overrides in the following order (highest to lowest):
|
|
152
|
+
1. **CLI Flags** (e.g. `--template`, `--justfile`)
|
|
153
|
+
2. **Configuration file** (`~/.newpythonrc`)
|
|
154
|
+
3. **Interactive Prompt Defaults**
|
|
155
|
+
|
|
156
|
+
To override the default config location, set the `NEWPYTHON_CONFIG` environment variable:
|
|
157
|
+
```bash
|
|
158
|
+
export NEWPYTHON_CONFIG="/path/to/custom/config.toml"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Automated Task Runner
|
|
164
|
+
|
|
165
|
+
The generated `Makefile` (or `Justfile` if `--justfile` is passed) exposes standard commands for project maintenance:
|
|
166
|
+
|
|
167
|
+
* `make install`: Installs the project locally in editable mode alongside all development dependencies (`pip install -e ".[dev]"`).
|
|
168
|
+
* `make test`: Executes the test suite using `pytest`.
|
|
169
|
+
* `make lint`: Performs static analysis checking with `ruff`.
|
|
170
|
+
* `make format`: Auto-formats code styles using `ruff format`.
|
|
171
|
+
* `make run`: Starts the application server or CLI script (template-aware).
|
|
172
|
+
* `make clean`: Recursively cleans local cache directories (`__pycache__`, `.pytest_cache`, `.ruff_cache`, `build`, `dist`).
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Publishing to PyPI
|
|
177
|
+
|
|
178
|
+
Projects generated by `pyforge` use `hatchling` as the build system and are ready to be built and uploaded to PyPI:
|
|
179
|
+
|
|
180
|
+
1. Install build and publication dependencies:
|
|
181
|
+
```bash
|
|
182
|
+
pip install build twine
|
|
183
|
+
```
|
|
184
|
+
2. Build the project distribution packages (source archive and wheel):
|
|
185
|
+
```bash
|
|
186
|
+
python -m build
|
|
187
|
+
```
|
|
188
|
+
3. Upload to PyPI (or TestPyPI first):
|
|
189
|
+
```bash
|
|
190
|
+
python -m twine upload dist/*
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Contributing
|
|
196
|
+
|
|
197
|
+
Contributions to `pyforge` are welcome. To set up a local development environment:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
git clone https://github.com/your-name/pyforge.git
|
|
201
|
+
cd pyforge
|
|
202
|
+
pip install -e ".[dev]"
|
|
203
|
+
python -m pytest -v
|
|
204
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pyforge-init"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A CLI tool to scaffold new Python projects, similar to create-react-app."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Your Name", email = "your.email@example.com" }
|
|
13
|
+
]
|
|
14
|
+
dependencies = [
|
|
15
|
+
"click>=8.0.0",
|
|
16
|
+
"jinja2>=3.0.0",
|
|
17
|
+
"rich>=13.0.0",
|
|
18
|
+
"questionary>=2.0.0",
|
|
19
|
+
"httpx>=0.27.0",
|
|
20
|
+
"tomli>=2.0.0; python_version < '3.11'",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
newpython = "pyforge.cli:main"
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
dev = [
|
|
28
|
+
"pytest>=7.0.0",
|
|
29
|
+
"pytest-mock>=3.0.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["src/pyforge"]
|