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.
Files changed (32) hide show
  1. pyforge_init-0.1.0/.github/workflows/release.yml +58 -0
  2. pyforge_init-0.1.0/.gitignore +25 -0
  3. pyforge_init-0.1.0/PKG-INFO +221 -0
  4. pyforge_init-0.1.0/README.md +204 -0
  5. pyforge_init-0.1.0/pyproject.toml +33 -0
  6. pyforge_init-0.1.0/src/pyforge/__init__.py +4 -0
  7. pyforge_init-0.1.0/src/pyforge/cli.py +194 -0
  8. pyforge_init-0.1.0/src/pyforge/config.py +119 -0
  9. pyforge_init-0.1.0/src/pyforge/generator.py +174 -0
  10. pyforge_init-0.1.0/src/pyforge/prompts.py +167 -0
  11. pyforge_init-0.1.0/src/pyforge/remote.py +179 -0
  12. pyforge_init-0.1.0/src/pyforge/templates/basic/tests/test_main.py.jinja +3 -0
  13. pyforge_init-0.1.0/src/pyforge/templates/cli/src/package/__main__.py.jinja +4 -0
  14. pyforge_init-0.1.0/src/pyforge/templates/cli/src/package/cli.py.jinja +7 -0
  15. pyforge_init-0.1.0/src/pyforge/templates/cli/tests/test_cli.py.jinja +8 -0
  16. pyforge_init-0.1.0/src/pyforge/templates/fastapi/src/package/main.py.jinja +7 -0
  17. pyforge_init-0.1.0/src/pyforge/templates/fastapi/tests/test_main.py.jinja +9 -0
  18. pyforge_init-0.1.0/src/pyforge/templates/flask/src/package/app.py.jinja +10 -0
  19. pyforge_init-0.1.0/src/pyforge/templates/flask/tests/test_app.py.jinja +19 -0
  20. pyforge_init-0.1.0/src/pyforge/templates/shared/Justfile.jinja +28 -0
  21. pyforge_init-0.1.0/src/pyforge/templates/shared/Makefile.jinja +30 -0
  22. pyforge_init-0.1.0/src/pyforge/templates/shared/README.md.jinja +28 -0
  23. pyforge_init-0.1.0/src/pyforge/templates/shared/env.example.jinja +5 -0
  24. pyforge_init-0.1.0/src/pyforge/templates/shared/gitignore.jinja +13 -0
  25. pyforge_init-0.1.0/src/pyforge/templates/shared/pre-commit-config.yaml.jinja +15 -0
  26. pyforge_init-0.1.0/src/pyforge/templates/shared/pyproject.toml.jinja +58 -0
  27. pyforge_init-0.1.0/src/pyforge/templates/shared/requirements.txt.jinja +1 -0
  28. pyforge_init-0.1.0/src/pyforge/templates/shared/src/package/__init__.py.jinja +3 -0
  29. pyforge_init-0.1.0/src/pyforge/utils.py +65 -0
  30. pyforge_init-0.1.0/tests/test_cli.py +62 -0
  31. pyforge_init-0.1.0/tests/test_config.py +132 -0
  32. 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"]
@@ -0,0 +1,4 @@
1
+ """
2
+ pyforge - Python Project Generator
3
+ """
4
+ __version__ = "0.1.0"