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.
Files changed (56) hide show
  1. ak_py_bootstrap-0.9.4.dist-info/METADATA +427 -0
  2. ak_py_bootstrap-0.9.4.dist-info/RECORD +56 -0
  3. ak_py_bootstrap-0.9.4.dist-info/WHEEL +5 -0
  4. ak_py_bootstrap-0.9.4.dist-info/entry_points.txt +5 -0
  5. ak_py_bootstrap-0.9.4.dist-info/licenses/AUTHORS.md +8 -0
  6. ak_py_bootstrap-0.9.4.dist-info/licenses/LICENSE +201 -0
  7. ak_py_bootstrap-0.9.4.dist-info/top_level.txt +1 -0
  8. py_bootstrap/__init__.py +4 -0
  9. py_bootstrap/base/__init__.py +0 -0
  10. py_bootstrap/base/operations/__init__.py +10 -0
  11. py_bootstrap/base/operations/base.py +35 -0
  12. py_bootstrap/base/operations/recursive_container.py +69 -0
  13. py_bootstrap/base/operations/runner.py +53 -0
  14. py_bootstrap/files_processors/__init__.py +9 -0
  15. py_bootstrap/files_processors/base.py +106 -0
  16. py_bootstrap/files_processors/copy.py +45 -0
  17. py_bootstrap/files_processors/generate.py +65 -0
  18. py_bootstrap/operations/__init__.py +13 -0
  19. py_bootstrap/operations/base.py +52 -0
  20. py_bootstrap/operations/build_bootstrap.py +180 -0
  21. py_bootstrap/operations/dispatcher.py +82 -0
  22. py_bootstrap/operations/export_bootstrap.py +109 -0
  23. py_bootstrap/operations/list_bootstraps.py +38 -0
  24. py_bootstrap/operations/register_bootstrap.py +127 -0
  25. py_bootstrap/scripts/__init__.py +0 -0
  26. py_bootstrap/scripts/bootstrap.py +39 -0
  27. py_bootstrap/templates/__init__.py +7 -0
  28. py_bootstrap/templates/application/CHANGELOG.md.tmpl +13 -0
  29. py_bootstrap/templates/application/README.md.tmpl +52 -0
  30. py_bootstrap/templates/application/__entry_point__.py +37 -0
  31. py_bootstrap/templates/application/pyproject.toml.tmpl +57 -0
  32. py_bootstrap/templates/application/requirements-dev.txt +7 -0
  33. py_bootstrap/templates/application/requirements.txt +0 -0
  34. py_bootstrap/templates/application/tests/__init__.py +0 -0
  35. py_bootstrap/templates/application/tox.ini.tmpl +49 -0
  36. py_bootstrap/templates/application/{empty}.gitignore.tmpl +161 -0
  37. py_bootstrap/templates/bootstrap/__entry_point__.py +37 -0
  38. py_bootstrap/templates/bootstrap/__entry_point__.py.tmpl +58 -0
  39. py_bootstrap/templates/bootstrap/demo-file.txt.tmpl.tmpl +18 -0
  40. py_bootstrap/templates/package/AUTHORS.md.tmpl +8 -0
  41. py_bootstrap/templates/package/CHANGELOG.md.tmpl +13 -0
  42. py_bootstrap/templates/package/README.md.tmpl +94 -0
  43. py_bootstrap/templates/package/__entry_point__.py +63 -0
  44. py_bootstrap/templates/package/docs/Makefile +20 -0
  45. py_bootstrap/templates/package/docs/__init__.py +0 -0
  46. py_bootstrap/templates/package/docs/conf.py.tmpl +57 -0
  47. py_bootstrap/templates/package/docs/index.rst.tmpl +14 -0
  48. py_bootstrap/templates/package/docs/make.bat +35 -0
  49. py_bootstrap/templates/package/pyproject.toml.tmpl +169 -0
  50. py_bootstrap/templates/package/requirements-dev.txt +8 -0
  51. py_bootstrap/templates/package/requirements.txt +0 -0
  52. py_bootstrap/templates/package/tests/__init__.py +0 -0
  53. py_bootstrap/templates/package/tests/test_package.py.tmpl +12 -0
  54. py_bootstrap/templates/package/tox.ini.tmpl +81 -0
  55. py_bootstrap/templates/package/{empty}.gitignore.tmpl +161 -0
  56. 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
+ [![PyPI](https://img.shields.io/pypi/v/ak-py-bootstrap.svg)](https://pypi.org/project/ak-py-bootstrap/)
32
+ [![Python](https://img.shields.io/pypi/pyversions/ak-py-bootstrap.svg)](https://pypi.org/project/ak-py-bootstrap/)
33
+ [![ci](https://github.com/ABKorotky/py-bootstrap/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ABKorotky/py-bootstrap/actions/workflows/ci.yml)
34
+ [![coverage](https://codecov.io/gh/ABKorotky/py-bootstrap/branch/main/graph/badge.svg)](https://codecov.io/gh/ABKorotky/py-bootstrap)
35
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/ABKorotky/py-bootstrap/blob/main/LICENSE)
36
+ [![Documentation Status](https://app.readthedocs.org/projects/ak-py-bootstrap/badge/?version=stable)](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,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ bootstrap = py_bootstrap.scripts.bootstrap:main
3
+
4
+ [py_bootstrap_templates]
5
+ py_bootstrap = py_bootstrap.templates
@@ -0,0 +1,8 @@
1
+ Authors
2
+ =======
3
+
4
+ ## Owners:
5
+ * Aliaksandr Karotki, abkorotky@gmail.com.
6
+
7
+ ## Developers:
8
+ * Aliaksandr Karotki, abkorotky@gmail.com.