ak-py-bootstrap 0.9.4__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.
- ak_py_bootstrap-0.9.4.dist-info/METADATA +427 -0
- ak_py_bootstrap-0.9.4.dist-info/RECORD +56 -0
- ak_py_bootstrap-0.9.4.dist-info/WHEEL +5 -0
- ak_py_bootstrap-0.9.4.dist-info/entry_points.txt +5 -0
- ak_py_bootstrap-0.9.4.dist-info/licenses/AUTHORS.md +8 -0
- ak_py_bootstrap-0.9.4.dist-info/licenses/LICENSE +201 -0
- ak_py_bootstrap-0.9.4.dist-info/top_level.txt +1 -0
- py_bootstrap/__init__.py +4 -0
- py_bootstrap/base/__init__.py +0 -0
- py_bootstrap/base/operations/__init__.py +10 -0
- py_bootstrap/base/operations/base.py +35 -0
- py_bootstrap/base/operations/recursive_container.py +69 -0
- py_bootstrap/base/operations/runner.py +53 -0
- py_bootstrap/files_processors/__init__.py +9 -0
- py_bootstrap/files_processors/base.py +106 -0
- py_bootstrap/files_processors/copy.py +45 -0
- py_bootstrap/files_processors/generate.py +65 -0
- py_bootstrap/operations/__init__.py +13 -0
- py_bootstrap/operations/base.py +52 -0
- py_bootstrap/operations/build_bootstrap.py +180 -0
- py_bootstrap/operations/dispatcher.py +82 -0
- py_bootstrap/operations/export_bootstrap.py +109 -0
- py_bootstrap/operations/list_bootstraps.py +38 -0
- py_bootstrap/operations/register_bootstrap.py +127 -0
- py_bootstrap/scripts/__init__.py +0 -0
- py_bootstrap/scripts/bootstrap.py +39 -0
- py_bootstrap/templates/__init__.py +7 -0
- py_bootstrap/templates/application/CHANGELOG.md.tmpl +13 -0
- py_bootstrap/templates/application/README.md.tmpl +52 -0
- py_bootstrap/templates/application/__entry_point__.py +37 -0
- py_bootstrap/templates/application/pyproject.toml.tmpl +57 -0
- py_bootstrap/templates/application/requirements-dev.txt +7 -0
- py_bootstrap/templates/application/requirements.txt +0 -0
- py_bootstrap/templates/application/tests/__init__.py +0 -0
- py_bootstrap/templates/application/tox.ini.tmpl +49 -0
- py_bootstrap/templates/application/{empty}.gitignore.tmpl +161 -0
- py_bootstrap/templates/bootstrap/__entry_point__.py +37 -0
- py_bootstrap/templates/bootstrap/__entry_point__.py.tmpl +58 -0
- py_bootstrap/templates/bootstrap/demo-file.txt.tmpl.tmpl +18 -0
- py_bootstrap/templates/package/AUTHORS.md.tmpl +8 -0
- py_bootstrap/templates/package/CHANGELOG.md.tmpl +13 -0
- py_bootstrap/templates/package/README.md.tmpl +94 -0
- py_bootstrap/templates/package/__entry_point__.py +63 -0
- py_bootstrap/templates/package/docs/Makefile +20 -0
- py_bootstrap/templates/package/docs/__init__.py +0 -0
- py_bootstrap/templates/package/docs/conf.py.tmpl +57 -0
- py_bootstrap/templates/package/docs/index.rst.tmpl +14 -0
- py_bootstrap/templates/package/docs/make.bat +35 -0
- py_bootstrap/templates/package/pyproject.toml.tmpl +169 -0
- py_bootstrap/templates/package/requirements-dev.txt +8 -0
- py_bootstrap/templates/package/requirements.txt +0 -0
- py_bootstrap/templates/package/tests/__init__.py +0 -0
- py_bootstrap/templates/package/tests/test_package.py.tmpl +12 -0
- py_bootstrap/templates/package/tox.ini.tmpl +81 -0
- py_bootstrap/templates/package/{empty}.gitignore.tmpl +161 -0
- py_bootstrap/templates/package/{python_name}/__init__.py.tmpl +23 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ak-py-bootstrap
|
|
3
|
+
Version: 0.9.4
|
|
4
|
+
Summary: Provides functionality for generating skeletons for Python projects.
|
|
5
|
+
Author-email: Aliaksandr Karotki <abkorotky@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: documentation, https://ak-py-bootstrap.readthedocs.io/
|
|
8
|
+
Project-URL: repository, https://github.com/ABKorotky/py-bootstrap.git
|
|
9
|
+
Project-URL: changelog, https://github.com/ABKorotky/py-bootstrap/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: bootstrap,python,project,template
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Framework :: tox
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Operating System :: POSIX
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.13
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
License-File: AUTHORS.md
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Bootstrapping of Python projects
|
|
29
|
+
Provides functionality for generating skeletons for Python projects.
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/ak-py-bootstrap/)
|
|
32
|
+
[](https://pypi.org/project/ak-py-bootstrap/)
|
|
33
|
+
[](https://github.com/ABKorotky/py-bootstrap/actions/workflows/ci.yml)
|
|
34
|
+
[](https://codecov.io/gh/ABKorotky/py-bootstrap)
|
|
35
|
+
[](https://github.com/ABKorotky/py-bootstrap/blob/main/LICENSE)
|
|
36
|
+
[](https://ak-py-bootstrap.readthedocs.io/en/stable/)
|
|
37
|
+
|
|
38
|
+
<!-- Badge hrefs must be absolute: this README also renders on PyPI, where
|
|
39
|
+
relative links 404. -->
|
|
40
|
+
|
|
41
|
+
# For Consumers
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
Create and activate a virtual environment if missed:
|
|
45
|
+
```bash
|
|
46
|
+
python3.13 -m venv .venv
|
|
47
|
+
source .venv/bin/activate
|
|
48
|
+
pip install --upgrade pip
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Install the package:
|
|
52
|
+
```bash
|
|
53
|
+
pip install -i https://test.pypi.org/simple/ ak-py-bootstrap
|
|
54
|
+
```
|
|
55
|
+
During installing the package creates an entry-point `bootstrap`.
|
|
56
|
+
|
|
57
|
+
## Using
|
|
58
|
+
|
|
59
|
+
### Getting help
|
|
60
|
+
Call the tool with `-h`/`-help` argument:
|
|
61
|
+
```bash
|
|
62
|
+
bootstrap --help
|
|
63
|
+
```
|
|
64
|
+
It shows the following text:
|
|
65
|
+
```bash
|
|
66
|
+
usage: bootstrap [-h] {list,build,export,register} ...
|
|
67
|
+
...
|
|
68
|
+
Bootstraps management operations:
|
|
69
|
+
{list,build,export,register}
|
|
70
|
+
list Finds and prints the list of available bootstraps with brief description.
|
|
71
|
+
build Generates a skeleton of something from given bootstrap.
|
|
72
|
+
export Exports a bootstrap by given name.
|
|
73
|
+
register Registers a new bootstrap.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Getting a list of enabled / registered bootstraps
|
|
77
|
+
Call the following command:
|
|
78
|
+
```bash
|
|
79
|
+
bootstrap list
|
|
80
|
+
```
|
|
81
|
+
It should show something like:
|
|
82
|
+
```bash
|
|
83
|
+
...
|
|
84
|
+
application: Provides bootstrapping for Python Applications
|
|
85
|
+
package: Provides bootstrapping for Python Packages
|
|
86
|
+
...
|
|
87
|
+
```
|
|
88
|
+
Both of these subcommands provide a minimal skeleton of Python Project based on `black`, `isort`, `flake`, `mypy` and `tox` automation tool.
|
|
89
|
+
|
|
90
|
+
`Application` is a "final" project in `bootstrap` terms.
|
|
91
|
+
|
|
92
|
+
`Package` is an "intermediate" project in `bootstrap` terms.
|
|
93
|
+
|
|
94
|
+
The difference between them is the following: no need to build some package(s) from `applications` but it's important to do for `packages`.
|
|
95
|
+
So, `tox` tool provides for `applications` a minimal set of predefined `commands`:
|
|
96
|
+
- reformatting using `black` and `isort` tools.
|
|
97
|
+
- check code style using `black` and `flake` tools.
|
|
98
|
+
- check annotations using `mypy tool`.
|
|
99
|
+
- running tests based on `unittests` framework and calculating a level of coverage using `coverage` tool.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
`tox` tool provides several additional `commands` for `packages:
|
|
103
|
+
- generating documentation based on `sphinx` framework.
|
|
104
|
+
- building versions of packages.
|
|
105
|
+
- publishing prepared archives in PyPI or Test PyPI.
|
|
106
|
+
|
|
107
|
+
You can prepare and register your own bootstraps for speeding up your work.
|
|
108
|
+
See topics below how to do it.
|
|
109
|
+
|
|
110
|
+
### Generating a skeleton of something
|
|
111
|
+
The main feature of the tool.
|
|
112
|
+
|
|
113
|
+
First of all, let's show on the help text of `build` command:
|
|
114
|
+
```bash
|
|
115
|
+
bootstrap build --help
|
|
116
|
+
```
|
|
117
|
+
You should see something like:
|
|
118
|
+
```bash
|
|
119
|
+
usage: bootstrap build [-h] [--dest DESTINATION_DIR] {application,package} ...
|
|
120
|
+
...
|
|
121
|
+
options:
|
|
122
|
+
...
|
|
123
|
+
--dest DESTINATION_DIR
|
|
124
|
+
Specifies the destination directory for generating. Current directory by default.
|
|
125
|
+
Found bootstraps:
|
|
126
|
+
{application,package}
|
|
127
|
+
application Generates a skeleton of a Python Application
|
|
128
|
+
package Generates a skeleton of a Python Package
|
|
129
|
+
```
|
|
130
|
+
The important here is the following:
|
|
131
|
+
- `--dest` argument. It's a common argument for all bootstraps. It specifies a target directory on a file system. Current directory by default.
|
|
132
|
+
|
|
133
|
+
#### Getting help for every bootstrap
|
|
134
|
+
Every bootstrap can provide own CLI interface.
|
|
135
|
+
So, it's important to examine them before using.
|
|
136
|
+
|
|
137
|
+
Call the following command:
|
|
138
|
+
```bash
|
|
139
|
+
bootstrap build application --help
|
|
140
|
+
```
|
|
141
|
+
It should render something like:
|
|
142
|
+
```bash
|
|
143
|
+
usage: bootstrap build application [-h] --name NAME --description DESCRIPTION [--repo REPO]
|
|
144
|
+
...
|
|
145
|
+
options:
|
|
146
|
+
...
|
|
147
|
+
--name NAME Specifies name of the application
|
|
148
|
+
--description DESCRIPTIORepositoryN
|
|
149
|
+
Specifies description of the application.
|
|
150
|
+
```
|
|
151
|
+
As you can see, the required arguments are:
|
|
152
|
+
- `name`. it specifies a name of the application. It should be python-compatible.
|
|
153
|
+
- `description`. it specifies a brief description of a generated application.
|
|
154
|
+
|
|
155
|
+
#### Generating a skeleton of a python application
|
|
156
|
+
After working with help text, we are ready to generate something.
|
|
157
|
+
Call the following command:
|
|
158
|
+
```bash
|
|
159
|
+
bootstrap build application --name=demo-app --description="The Demo python Application"
|
|
160
|
+
```
|
|
161
|
+
Check the file system:
|
|
162
|
+
```bash
|
|
163
|
+
tree -L2
|
|
164
|
+
```
|
|
165
|
+
You should see something like:
|
|
166
|
+
```bash
|
|
167
|
+
├── CHANGELOG.md
|
|
168
|
+
├── pyproject.toml
|
|
169
|
+
├── README.md
|
|
170
|
+
├── requirements-dev.txt
|
|
171
|
+
├── requirements.txt
|
|
172
|
+
└── tests
|
|
173
|
+
└── __init__.py
|
|
174
|
+
```
|
|
175
|
+
So, you have got:
|
|
176
|
+
- prepared `pyproject.toml` file with minimal configuration for the mentioned above tools.
|
|
177
|
+
- minimal `README.md` file.
|
|
178
|
+
- `demo_app` directory where you will place code of your application in the future.
|
|
179
|
+
- `tests` directory where you will place future unit tests for testing you application.
|
|
180
|
+
|
|
181
|
+
Congratulations! Now you are ready to make the first commit in your new application.
|
|
182
|
+
|
|
183
|
+
Generating a skeleton of python package is similar.
|
|
184
|
+
|
|
185
|
+
### Preparing your own bootstraps
|
|
186
|
+
Bootstrap is a directory of the following structure:
|
|
187
|
+
- `__entry_point__.py` file. It's an entry point into every bootstrap. It provides logic for generating bootstraps.
|
|
188
|
+
- any set of any files or directories that provide content for the bootstrap.
|
|
189
|
+
|
|
190
|
+
There are two ways how to prepare a new custom bootstrap:
|
|
191
|
+
- from scratches.
|
|
192
|
+
- based on existed one.
|
|
193
|
+
|
|
194
|
+
#### Preparing new bootstrap from scratches
|
|
195
|
+
Working with `bootstrap list` command you can mention that exist one more bootstrap: `boostrap`.
|
|
196
|
+
Yes, this bootstrap provides generating new ... bootstraps.
|
|
197
|
+
|
|
198
|
+
Call the following command:
|
|
199
|
+
```bash
|
|
200
|
+
bootstrap build --dest=demo-bootstrap bootstrap --name=demo-bs --description="The Demo bootstrap"
|
|
201
|
+
```
|
|
202
|
+
Examine a local file system:
|
|
203
|
+
```bash
|
|
204
|
+
tree -L2 demo-bootstrap/
|
|
205
|
+
```
|
|
206
|
+
You should see something like:
|
|
207
|
+
```bash
|
|
208
|
+
demo-bootstrap/
|
|
209
|
+
├── demo-file.txt.tmpl
|
|
210
|
+
└── __entry_point__.py
|
|
211
|
+
|
|
212
|
+
1 directory, 2 files
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
It's a skeleton of new bootstrap.
|
|
216
|
+
Now it's able to prepare any static files or templates for generating a dynamic content for the bootstrap.
|
|
217
|
+
In `demo-file.txt.tmpl` you can find placeholders that the tool provides by default.
|
|
218
|
+
|
|
219
|
+
#### Export existed bootstrap
|
|
220
|
+
Instead developing bootstraps from scratches, it's able to export one of existed bootstraps and modify it.
|
|
221
|
+
|
|
222
|
+
Call the following command:
|
|
223
|
+
```bash
|
|
224
|
+
bootstrap export --dest=bs-application-copy application
|
|
225
|
+
```
|
|
226
|
+
In `bs-application-copy` you can find:
|
|
227
|
+
- original `__entry_point__.py` file.
|
|
228
|
+
- a set of static files and templates that provide content of `application` bootstrap.
|
|
229
|
+
|
|
230
|
+
Please examine these files. That's the best way to understand bootstrapping functionality in details.
|
|
231
|
+
|
|
232
|
+
Now it's able to modify a cloned bootstrap files for reaching your aims.
|
|
233
|
+
|
|
234
|
+
### Register new bootstraps
|
|
235
|
+
After developing new bootstrap but before using need to register this one in the tool.
|
|
236
|
+
`register` command is responsible to do it.
|
|
237
|
+
|
|
238
|
+
Call the following command for getting help text:
|
|
239
|
+
```bash
|
|
240
|
+
bootstrap register --help
|
|
241
|
+
```
|
|
242
|
+
You can see something like:
|
|
243
|
+
```bash
|
|
244
|
+
usage: bootstrap register [-h] --name BOOTSTRAP_NAME --source SOURCE_PATH [-y]
|
|
245
|
+
...
|
|
246
|
+
options:
|
|
247
|
+
--name BOOTSTRAP_NAME
|
|
248
|
+
Specifies name of registered bootstrap template.
|
|
249
|
+
--source SOURCE_PATH Specifies the source directory with metadata and bootstrap templates. Current directory by default.
|
|
250
|
+
-y, --yes-upload Do not prompt for confirmation.
|
|
251
|
+
```
|
|
252
|
+
The required arguments are:
|
|
253
|
+
- `--name`. It specifies the name of new bootstrap in the tool.
|
|
254
|
+
- `--source`. It specifies a directory with implemented bootstrap.
|
|
255
|
+
- `-y` / `--yes-upload`. The argument disables interactive mode. A system won't print a confirmation prompt with waiting an input from a developer.
|
|
256
|
+
|
|
257
|
+
So, let's register a prepared new bootstrap:
|
|
258
|
+
```bash
|
|
259
|
+
bootstrap register --name=demo --source=demo-bootstrap
|
|
260
|
+
```
|
|
261
|
+
Confirm uploading by typing `y`.
|
|
262
|
+
|
|
263
|
+
Check registering by calling `bootstrap list`. It should show new `demo` bootstrap in a list of enabled.
|
|
264
|
+
|
|
265
|
+
That's all. Now it's able to use a registered bootstrap in your work.
|
|
266
|
+
|
|
267
|
+
NB: the system is very straightforward, it doesn't make any conclusions instead of you. The system allows overriding bootstraps.
|
|
268
|
+
That's pros and cons at the same time.
|
|
269
|
+
On the one hand, it's very easy to test new bootstraps, just fix templates, upload changes and check a result of generating immediately.
|
|
270
|
+
On the other hand, it's easy to break a current bootstrap in case you make a decision to REPLACE existed one.
|
|
271
|
+
So, it's a developer's duty to care about what exactly they register.
|
|
272
|
+
|
|
273
|
+
### Embed package bootstraps as plugins
|
|
274
|
+
Define in yours `pyproject.toml` file the following section:
|
|
275
|
+
```toml
|
|
276
|
+
[project.entry-points.py_bootstrap_templates]
|
|
277
|
+
<your-package-name> = "<package-root-dir>.py_bootstrap.templates"
|
|
278
|
+
```
|
|
279
|
+
Create the following files structure:
|
|
280
|
+
```bash
|
|
281
|
+
<package-root-dir>
|
|
282
|
+
└── py_bootstrap
|
|
283
|
+
└── templates
|
|
284
|
+
├── <your-bootstrap-dir>
|
|
285
|
+
│ ├── __entry_point__.py
|
|
286
|
+
│ ...
|
|
287
|
+
├── <your-another-bootstrap-dir>
|
|
288
|
+
│ ├── __entry_point__.py
|
|
289
|
+
│ ...
|
|
290
|
+
└── __init__.py
|
|
291
|
+
```
|
|
292
|
+
Put into `<package-root-dir>/py_bootstraps/templates/__init__.py` file the following content:
|
|
293
|
+
```python
|
|
294
|
+
__all__ = ("ENABLED_TEMPLATES",)
|
|
295
|
+
|
|
296
|
+
ENABLED_TEMPLATES = [
|
|
297
|
+
"<your-bootstrap-dir>",
|
|
298
|
+
"your-another-bootstrap-dir",
|
|
299
|
+
]
|
|
300
|
+
```
|
|
301
|
+
That's all! Build a new version of the package, install it in some virtual environment together with `ak-py-bootstrap` package and enjoy of working with package's bootstraps.
|
|
302
|
+
|
|
303
|
+
Running `bootstrap list` you will see something like:
|
|
304
|
+
```bash
|
|
305
|
+
...
|
|
306
|
+
your-bootstrap-dir: Your bootstrap description.
|
|
307
|
+
your-another-bootstrap-dir: Your another bootstrap description.
|
|
308
|
+
...
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## For developers
|
|
312
|
+
|
|
313
|
+
### Cloning the project
|
|
314
|
+
Run the following commands:
|
|
315
|
+
```bash
|
|
316
|
+
git clone https://github.com/ABKorotky/py-bootstrap.git
|
|
317
|
+
cd py_bootstrap
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Prepare a virtual environment for developing
|
|
321
|
+
Run the following commands:
|
|
322
|
+
```bash
|
|
323
|
+
python3.13 -m venv .venv
|
|
324
|
+
source .venv/bin/activate
|
|
325
|
+
pip install --upgrade pip
|
|
326
|
+
pip install -e . --group dev
|
|
327
|
+
```
|
|
328
|
+
Dev tooling is declared as [PEP 735](https://peps.python.org/pep-0735/) dependency
|
|
329
|
+
groups in `pyproject.toml` (`test`, `format`, `cs`, `ann`, `doc`, `changelog`,
|
|
330
|
+
`scm`, `dist`, `release`, and the umbrella `dev`). The tool has no runtime
|
|
331
|
+
dependencies.
|
|
332
|
+
|
|
333
|
+
### Using make in development
|
|
334
|
+
Development and release tasks run through `make`. Each target installs the
|
|
335
|
+
dependency group it needs into a single `.venv` on demand, so the toolchain is
|
|
336
|
+
provisioned lazily rather than duplicated per task:
|
|
337
|
+
- `deps`. Installs every dev dependency into `.venv`.
|
|
338
|
+
- `cs`. Code Style. Checks project's code style using `isort`, `black` and `flake8` tools.
|
|
339
|
+
- `ann`. Annotation. Checks types annotations in the project using `mypy` tool.
|
|
340
|
+
- `test`. Unit Tests with Coverage. Checks that `tox.ini`, the `pyproject.toml` classifiers and the `ci.yml` matrix agree on the supported interpreters, then runs the suite on each of them via `tox`. `make test PY_ENV=py313` runs just one.
|
|
341
|
+
- `check`. Runs `cs`, `ann` and `test`.
|
|
342
|
+
- `format`. Formatting. Reformats code in the project using `black` and `isort` tools.
|
|
343
|
+
- `doc`. Documentation. Generates project's documentation using `sphinx` tool.
|
|
344
|
+
- `cl-preview VERSION=X.Y.Z`. Changelog Draft. Previews the section the `changelog.d/` fragments would produce.
|
|
345
|
+
- `cl-check`. Changelog Check. Fails if the branch adds no news fragment (CI runs this on every PR).
|
|
346
|
+
- `cl-build VERSION=X.Y.Z`. Changelog. Collates `changelog.d/` fragments into `CHANGELOG.md` and removes them.
|
|
347
|
+
- `cut-tag VERSION=X.Y.Z`. Verifies the version is releasable and unused and the working tree is clean, writes the `## [X.Y.Z]` section, commits it as `Prepare X.Y.Z version` and tags `vX.Y.Z`.
|
|
348
|
+
- `dist-build`. Builds the sdist and wheel into `dist/` from a clean working tree, then installs the wheel into a throwaway virtualenv and checks `bootstrap list` works.
|
|
349
|
+
- `dist-upload`. Uploads `DIST` (default `dist/*`) to `PYPI` (default `pypi`) after `twine check --strict`.
|
|
350
|
+
- `release VERSION=X.Y.Z [PYPI=testpypi]`. The whole flow: `cut-tag`, `dist-build`, `dist-upload`, stopping at the first failure.
|
|
351
|
+
- `clean` / `venvclean`. Removes build, test and doc artefacts / also removes the virtualenvs (`.venv` and `.tox/`).
|
|
352
|
+
|
|
353
|
+
Run `make` with no target for the full list.
|
|
354
|
+
|
|
355
|
+
### Using tox in development
|
|
356
|
+
`tox` is kept for one job: running the test suite against every supported
|
|
357
|
+
interpreter. `tox` runs `py313` and `py314`; `tox -e py313` runs just one.
|
|
358
|
+
Everything else lives in the `Makefile`.
|
|
359
|
+
|
|
360
|
+
### Development rules and agreements
|
|
361
|
+
Follow Python's principles [PEP 20 – The Zen of Python](https://peps.python.org/pep-0020/):
|
|
362
|
+
- Simple is better than complex.
|
|
363
|
+
- Explicit is better than implicit. And so on...
|
|
364
|
+
|
|
365
|
+
Follow ["SOLID"](https://en.wikipedia.org/wiki/SOLID) principles:
|
|
366
|
+
- Single responsibility principle.
|
|
367
|
+
- Open–closed principle.
|
|
368
|
+
- Liskov substitution principle.
|
|
369
|
+
- Interface segregation principle.
|
|
370
|
+
- Dependency inversion principle.
|
|
371
|
+
|
|
372
|
+
### Branching model
|
|
373
|
+
Based on "GitHub-Flow", extended by release branches on demand.
|
|
374
|
+
|
|
375
|
+
**Branches**
|
|
376
|
+
- `main` is the default stable branch; stable distributions are released from it.
|
|
377
|
+
- Develop on `<feature>` branches — commit count and messages there are not limited.
|
|
378
|
+
- Older lines live on `release/<major>.<minor>` branches, cut from that line's last tag. A release branch carries its own `CHANGELOG.md` and `changelog.d/`.
|
|
379
|
+
|
|
380
|
+
**Merging** — enforced by GitHub, not done by hand:
|
|
381
|
+
- The only enabled merge method is **squash**, so every PR lands as one commit.
|
|
382
|
+
- A ruleset on `main` and `release/*` requires a PR, passing `ci` checks (`cs`, `ann`, `utc`, `doc`), the `changelog` check, **linear history** (no merge commits), and the **merge queue**.
|
|
383
|
+
- The merge queue rebases the PR onto the current target, re-runs the checks, and fast-forwards it in — no manual squash, rebase, or `--ff-only`. Enable auto-merge on the PR and leave it.
|
|
384
|
+
|
|
385
|
+
**Tags & releases**
|
|
386
|
+
- Tag per [PEP 440](https://peps.python.org/pep-0440/), `v`-prefixed: `vX.Y.Z`, `vX.Y.ZrcN`. Merging into `main` is an intention to release, so almost every commit on `main` is tagged.
|
|
387
|
+
- Cut a release the same way on `main` or a release branch: `make release VERSION=X.Y.Z` (see [Releasing new distributions flow](#releasing-new-distributions-flow)). The `release` workflow accepts any `v*` tag whose commit is reachable from `main` or a `release/*` branch.
|
|
388
|
+
- Tags on `main` must increase monotonically. Do **not** tag `v0.2.0 -> v0.2.1 -> v0.3.0 -> v0.2.2`; instead branch `release/0.2` from `v0.2.1`, fix there, and tag `v0.2.2`.
|
|
389
|
+
- Move fixes between lines with `cherry-pick` — e.g. cherry-pick the `v0.2.2` fix from `release/0.2` into `main` and ship it as `v0.3.2`.
|
|
390
|
+
|
|
391
|
+
Recap: history on `main` stays a straight line, with release branches forking off tag points.
|
|
392
|
+
|
|
393
|
+
### Releasing new distributions flow
|
|
394
|
+
|
|
395
|
+
The project version comes from the git tag (`setuptools-scm`), `CHANGELOG.md` is
|
|
396
|
+
assembled by `towncrier` from news fragments in `changelog.d/`, and publishing is
|
|
397
|
+
done by the `release` GitHub Actions workflow through PyPI Trusted Publishing — no
|
|
398
|
+
version constant to bump, no tokens, no manual `twine`. Setup and details:
|
|
399
|
+
[`docs/releasing/`](docs/releasing/). Tags are `v`-prefixed (`v0.10.0`);
|
|
400
|
+
`setuptools-scm` also reads the older bare tags.
|
|
401
|
+
|
|
402
|
+
1. Create a `feature` branch from `main` or a release one.
|
|
403
|
+
2. Make the changes. Run `make format` and `make check` during development.
|
|
404
|
+
3. Add a news fragment under `changelog.d/` describing the change (see
|
|
405
|
+
[`changelog.d/README.md`](changelog.d/README.md)); `make cl-check` mirrors
|
|
406
|
+
what CI enforces on the PR.
|
|
407
|
+
4. Run `make doc` and examine the generated documentation.
|
|
408
|
+
5. Squash to one commit, rebase on the target branch, clean the diff.
|
|
409
|
+
6. Run `make format`, then `make check`, on the final commit; ensure both pass.
|
|
410
|
+
Run `tox` too if the change could be interpreter-sensitive.
|
|
411
|
+
7. Merge the `feature` branch into the target (`main` or `release/<major>.<minor>`).
|
|
412
|
+
8. On the merge commit, decide the version and cut the release:
|
|
413
|
+
```
|
|
414
|
+
make cl-preview VERSION=0.10.0 # read the section the fragments will produce
|
|
415
|
+
make cut-tag VERSION=0.10.0 # verify, write CHANGELOG.md, commit, tag v0.10.0
|
|
416
|
+
make dist-build # build and check the wheel installs
|
|
417
|
+
make dist-upload # -> PyPI; PYPI=testpypi to rehearse
|
|
418
|
+
git push origin <branch> --follow-tags
|
|
419
|
+
```
|
|
420
|
+
`make release VERSION=0.10.0` runs those three steps in one go.
|
|
421
|
+
9. Validate in a fresh environment: `pip install ak-py-bootstrap`.
|
|
422
|
+
|
|
423
|
+
To rebuild an already released version, check out its tag and run
|
|
424
|
+
`make dist-build dist-upload` — `dist-build` derives the version from the tag,
|
|
425
|
+
so the artefacts are identical to the original.
|
|
426
|
+
|
|
427
|
+
Use the same flow for releasing distributions from release branches.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
ak_py_bootstrap-0.9.4.dist-info/licenses/AUTHORS.md,sha256=yJyk5stpaN9H_VxoOjkwZx9_7XtBICrbTjJ1k0qS_TM,130
|
|
2
|
+
ak_py_bootstrap-0.9.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
3
|
+
py_bootstrap/__init__.py,sha256=8sMQJioy112dSKvkbtHT6F983TAQx3OfBkoYNbPV6jE,80
|
|
4
|
+
py_bootstrap/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
py_bootstrap/base/operations/__init__.py,sha256=eR99tJBx6x9aY77oh4-tOTZ7eCmxtV8A_lMxeU2UnIs,285
|
|
6
|
+
py_bootstrap/base/operations/base.py,sha256=lrlK_vkg7yzFJv2I7cghlIbDsrIHhrNAbatS-rqc56w,795
|
|
7
|
+
py_bootstrap/base/operations/recursive_container.py,sha256=jnouVabpbYkIbTH5b1zvtiP0HtUO4ECCYGtEpb8IlSw,2281
|
|
8
|
+
py_bootstrap/base/operations/runner.py,sha256=RCPy_UgM_dnuhWCSCvp5CdghGmDYxBc9IIWcfwHH5LU,1668
|
|
9
|
+
py_bootstrap/files_processors/__init__.py,sha256=AMZ4R8WZ4LanFp3bQ2IMayykYzIsxBeANTaI6HYjuZY,216
|
|
10
|
+
py_bootstrap/files_processors/base.py,sha256=LSabbce3gDxgscXB7NzPVSjUQsmM1dcIGhUkL86LmW8,3582
|
|
11
|
+
py_bootstrap/files_processors/copy.py,sha256=EnBtEK3Tgtwfndw6vgjUFDjSlMQZnE23EFr10dVAAPA,1405
|
|
12
|
+
py_bootstrap/files_processors/generate.py,sha256=NGMxoKI7JVmPW9b5d8V5K7ShhEfOYDxAUrDz2muH2Gc,2035
|
|
13
|
+
py_bootstrap/operations/__init__.py,sha256=2bFMGgEZtI8VF7kqIPf9ixde1AyODC2dp3aNSNs1Jag,358
|
|
14
|
+
py_bootstrap/operations/base.py,sha256=Xau7eEupBe995-N0nettQHtUwD6UZiFHNg03KMlKVO4,1766
|
|
15
|
+
py_bootstrap/operations/build_bootstrap.py,sha256=SK893Dyj2ccMXLIf6G0GnoEQCvhbEuUb04QwIdIdjlA,5756
|
|
16
|
+
py_bootstrap/operations/dispatcher.py,sha256=m1r85lPLvkeYx-F0ediJABJyqKcJ6BMQl9V5x4ts3NE,2876
|
|
17
|
+
py_bootstrap/operations/export_bootstrap.py,sha256=SqZBfZP0KQ9TzvjEwCvjiXzgwVcpj1Pi0XWagiOMtGw,3407
|
|
18
|
+
py_bootstrap/operations/list_bootstraps.py,sha256=UXdMNnQnlORSKqTiK3j7HzSfXvMsWk6xxI1dy-3MsAY,1047
|
|
19
|
+
py_bootstrap/operations/register_bootstrap.py,sha256=ECwD00SOy1Xm72XAuU7QG3mhTMCvD3E3nsCgkTeFatw,3949
|
|
20
|
+
py_bootstrap/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
py_bootstrap/scripts/bootstrap.py,sha256=8ANRFA01e5R2-ud_vVn_pQDngT-howC6qq9tgFS7eYM,981
|
|
22
|
+
py_bootstrap/templates/__init__.py,sha256=_iXlowF0j0prnTgJSvdTkA9yWEgD-DcAxXRjjCZN8Rk,109
|
|
23
|
+
py_bootstrap/templates/application/CHANGELOG.md.tmpl,sha256=vui5OXXy7z6mMYkscl9ehT7iTGYHxGCZTZ2Ju-mr4IA,387
|
|
24
|
+
py_bootstrap/templates/application/README.md.tmpl,sha256=QS-o6LcTJEc65Gca0c-b2OB-LA1YkHsAAKyrlGq7ftY,2907
|
|
25
|
+
py_bootstrap/templates/application/__entry_point__.py,sha256=Hy8gxP99ZBuWPeYSgwKieKf2vAW_kMOUebjt6BJAmEQ,1022
|
|
26
|
+
py_bootstrap/templates/application/pyproject.toml.tmpl,sha256=kqPvIFUwkA04amnKbRaFpY0-fzbZmrh6UZx6CdFg8yY,1177
|
|
27
|
+
py_bootstrap/templates/application/requirements-dev.txt,sha256=FX5kh1SkWZa67_XaO_Ad35d4DgRb-5ELb20quTKfcMk,54
|
|
28
|
+
py_bootstrap/templates/application/requirements.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
py_bootstrap/templates/application/tox.ini.tmpl,sha256=dkBJbkwowyEDsdU5cCCU20038zp7wFTl-nzn96KuNd4,828
|
|
30
|
+
py_bootstrap/templates/application/{empty}.gitignore.tmpl,sha256=zEWskV48Q3ds2Dmgojw-S46oH7RcbM4ppyuGuNSbfi4,3097
|
|
31
|
+
py_bootstrap/templates/application/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
py_bootstrap/templates/bootstrap/__entry_point__.py,sha256=mxkmLIsl4McByCkoBExJoOHi7dYMzyoFZ7uNFsmDB90,989
|
|
33
|
+
py_bootstrap/templates/bootstrap/__entry_point__.py.tmpl,sha256=eSmWP80aQVFRgoUKZxGLOiC_aPIFHDn4NBVhxNkfw0w,1689
|
|
34
|
+
py_bootstrap/templates/bootstrap/demo-file.txt.tmpl.tmpl,sha256=dzI0vGOElWgIxAK6kHuwGSRWwrYeZQTln6LvQSisGz4,612
|
|
35
|
+
py_bootstrap/templates/package/AUTHORS.md.tmpl,sha256=swTFUjqsO_NrbYsA2-lI5kCjv8ZTahqGGVXWsiXMEvY,100
|
|
36
|
+
py_bootstrap/templates/package/CHANGELOG.md.tmpl,sha256=vui5OXXy7z6mMYkscl9ehT7iTGYHxGCZTZ2Ju-mr4IA,387
|
|
37
|
+
py_bootstrap/templates/package/README.md.tmpl,sha256=PvBag7fTRfJw4-TfMNePwm-DP77LmhnMCKZzaa8Jam8,5159
|
|
38
|
+
py_bootstrap/templates/package/__entry_point__.py,sha256=i-nlJ3Oljef_GiC7BmQsDCD-Q2XD1qnKN3rCvxnIMf8,1736
|
|
39
|
+
py_bootstrap/templates/package/pyproject.toml.tmpl,sha256=7nyb21tNQekEMBl9VM3NWk_supHtC5JTGEo_USi-3c0,4278
|
|
40
|
+
py_bootstrap/templates/package/requirements-dev.txt,sha256=fzgbDz8gHsU3ZAG21nHGhSZ84grp7EiRs-8VeE1NLNU,61
|
|
41
|
+
py_bootstrap/templates/package/requirements.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
+
py_bootstrap/templates/package/tox.ini.tmpl,sha256=uGJ795AEuiTdFDgXPxpgHp5cQ0T_JcKYjLqYCCf6LWg,1737
|
|
43
|
+
py_bootstrap/templates/package/{empty}.gitignore.tmpl,sha256=zEWskV48Q3ds2Dmgojw-S46oH7RcbM4ppyuGuNSbfi4,3097
|
|
44
|
+
py_bootstrap/templates/package/docs/Makefile,sha256=i2WHuFlgfyAPEW4ssEP8NY4cOibDJrVjvzSEU8_Ggwc,634
|
|
45
|
+
py_bootstrap/templates/package/docs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
py_bootstrap/templates/package/docs/conf.py.tmpl,sha256=snsxuQ2HHoUL16hKR_jaEsQ1A3wCT-k2o3QvYv1-S2U,2120
|
|
47
|
+
py_bootstrap/templates/package/docs/index.rst.tmpl,sha256=tztcZBmQwy10S0SRIQBxpACWB5_DZMRurXFQMrtoUEI,187
|
|
48
|
+
py_bootstrap/templates/package/docs/make.bat,sha256=tZPNHaGTFKQ9uaCFT2-S8sWSF1cVAtozIflJjAL6Fsg,795
|
|
49
|
+
py_bootstrap/templates/package/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
+
py_bootstrap/templates/package/tests/test_package.py.tmpl,sha256=Vi4HZj9-U-59tJVjxATf5iN_YIj2_T8o4DBezbA16a8,285
|
|
51
|
+
py_bootstrap/templates/package/{python_name}/__init__.py.tmpl,sha256=HRLRb7bgJk3aPUlhcWApPaNp3ITzpDzutsncj300T5I,314
|
|
52
|
+
ak_py_bootstrap-0.9.4.dist-info/METADATA,sha256=isGBDqbjkourvdFp-SEJ6W5IYsi7T2cHaExXLzaSd3g,18546
|
|
53
|
+
ak_py_bootstrap-0.9.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
54
|
+
ak_py_bootstrap-0.9.4.dist-info/entry_points.txt,sha256=m8p6jA51u6-KlsY03JXZALIj7E1_Pu3I5gvZjPXnJw0,130
|
|
55
|
+
ak_py_bootstrap-0.9.4.dist-info/top_level.txt,sha256=teLmokdzQDuOqv37kUZsieWXz4KSzW2nCM8Jo9rls8w,13
|
|
56
|
+
ak_py_bootstrap-0.9.4.dist-info/RECORD,,
|