plesty-sdk 0.3.4__tar.gz → 0.3.5.dev1__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.
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/CHANGELOG.md +16 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/PKG-INFO +1 -1
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/init.md +12 -1
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/gl-secret-detection-report.json +5 -5
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/pyproject.toml.jinja +3 -3
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/init.py +64 -1
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_init.py +55 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/.coverage +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/.gitignore +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/.gitlab-ci.yml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/.mailmap +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/LICENSE +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/README.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/REUSE.toml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/architecture.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/check.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/docs.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/license.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/manual.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/commands/update.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/getting-started.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/index.md +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/docs/toc.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/__init__.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/check/guidance.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/docs-build-gitlab-ci.yml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/hub-theme/plesty-hub.css +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/hub-theme/plesty-logo.svg +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/hub-theme/plesty-mark.svg +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/client-field-test.py.template +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/field-test-env.example +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/field-test-questions.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/field-test.py.template +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/mock-test.py.template +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/next-steps.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/manual/pdf-common.css +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/manual/pdf-page-landscape.css +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/manual/pdf-page-portrait.css +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/ruff.toml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/copier.yml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/analyzer/analyzer.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/device/base_device.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/device/device.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/experiment/experiment.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/.gitignore +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/CHANGELOG.md.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/LICENSE +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/README.md.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/REUSE.toml.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/docs/index.md.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/docs/toc.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/__init__.py.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/config.yaml.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/{% if project_type in ['device', 'experiment'] %}__main__.py{% endif %}.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/tests/__init__.py.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/tests/test_{{module_name}}.py.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/{% if project_type == 'experiment' %}config{% endif %}/default.yaml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/{% if project_type in ['device', 'experiment'] %}.env.example{% endif %}.jinja +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/authorship.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/cache.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/cli.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/__init__.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/check.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/docs/__init__.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/docs/deploy.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/docs/generate.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/docs/serve.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/docs/sphinx_builder.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/field_test.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/license.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/manual.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/mock_test.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/commands/update.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/context.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/report.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/semver.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/tui.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/pyproject.toml +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/__init__.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_authorship.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_cache.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_check.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_cli.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_context.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_docs_deploy.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_docs_generate.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_docs_serve.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_field_test_scaffold.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_license.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_manual.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_mock_test_scaffold.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_report.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_semver.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_sphinx_builder.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_tui.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/tests/test_update.py +0 -0
- {plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/uv.lock +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com).
|
|
4
4
|
|
|
5
|
+
## [0.3.5.dev1] — 2026-08-21
|
|
6
|
+
|
|
7
|
+
Development pre-release: the tutorial needs the pin option before 0.3.5 is
|
|
8
|
+
ready to be called finished.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `plesty init --lib-version VERSION` pins `plesty-lib` to what the caller
|
|
12
|
+
names instead of to the newest release on PyPI, and skips the lookup. A bare
|
|
13
|
+
version becomes a lower bound (`0.3.5.dev3` → `>=0.3.5.dev3`); a complete
|
|
14
|
+
specifier is written as given (`==0.4.0`, `>=0.3.5.dev3,<0.4`). One that PEP
|
|
15
|
+
440 cannot read is refused at the command line, before a directory is
|
|
16
|
+
created. For the tutorial: a lesson quoting a `pyproject.toml` and the file
|
|
17
|
+
its reader ends up with have to keep saying the same thing however far the
|
|
18
|
+
library has moved since the page was written — and a scaffold on an
|
|
19
|
+
air-gapped machine now pins what was asked for rather than a fallback.
|
|
20
|
+
|
|
5
21
|
## [0.3.4] — 2026-08-21
|
|
6
22
|
|
|
7
23
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: plesty-sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5.dev1
|
|
4
4
|
Summary: Command-line application for developing Python modules compliant with the Plesty standard.
|
|
5
5
|
Author: Plesty Development Team, Yunshuang Yuan, Christopher Borchers, fvrehlinger, Maximilian Heller, Michael Zopf
|
|
6
6
|
License-Expression: LGPL-3.0-or-later
|
|
@@ -41,6 +41,7 @@ name, so `plesty-foo-bar` → `foo_bar` without needing `--name`.
|
|
|
41
41
|
| `--author` | `John Doe` | Author name written into `pyproject.toml` and `REUSE.toml` |
|
|
42
42
|
| `--email` | `john.doe@example.com` | Author email written into `pyproject.toml` |
|
|
43
43
|
| `--standard` | `pixel` | Compliance standard for the generated CI pipeline: `pixel`, `nebula`, or `quantum`. A fresh scaffold is a prototype, so CI starts at `pixel`; bump it alongside your releases. |
|
|
44
|
+
| `--lib-version` | newest on PyPI | Pin `plesty-lib` to this version instead of looking it up. A bare version becomes a lower bound (`0.3.5.dev3` → `>=0.3.5.dev3`); a complete specifier is written as given (`==0.4.0`, `'>=0.3.5.dev3,<0.4'`). PyPI is not consulted, so the scaffold is reproducible. |
|
|
44
45
|
| `--no-ci` | off | Skip generating `.gitlab-ci.yml` entirely. |
|
|
45
46
|
|
|
46
47
|
## Directory rules
|
|
@@ -126,7 +127,17 @@ The `pyproject.toml` is pre-configured with:
|
|
|
126
127
|
no route to PyPI the pin falls back to `PLESTY_LIB_VERSION` in
|
|
127
128
|
`plesty/sdk/commands/init.py`, the library the templates are written against.
|
|
128
129
|
The pin is never lower than that floor: the scaffold uses that library's
|
|
129
|
-
operation kinds and rig start-up, and an older one would not run it
|
|
130
|
+
operation kinds and rig start-up, and an older one would not run it.
|
|
131
|
+
`--lib-version` overrides all of that and skips the lookup — for a tutorial,
|
|
132
|
+
whose lesson text and reader's `pyproject.toml` have to keep agreeing however
|
|
133
|
+
far the library has moved since the page was written:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
plesty init experiment --name scan_exp --lib-version 0.3.5.dev3
|
|
137
|
+
# → "plesty-lib>=0.3.5.dev3"
|
|
138
|
+
plesty init experiment --name scan_exp --lib-version '>=0.3.5.dev3,<0.4'
|
|
139
|
+
# → "plesty-lib>=0.3.5.dev3,<0.4"
|
|
140
|
+
```
|
|
130
141
|
- `pytest`, `pytest-cov`, `mypy`, and `plesty-sdk` under `[dependency-groups] dev`
|
|
131
142
|
(included automatically by `uv run` — no `--extra dev` needed)
|
|
132
143
|
- Sphinx docs settings under `[tool.plesty.docs]`
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"version": "8.30.1"
|
|
20
20
|
},
|
|
21
21
|
"type": "secret_detection",
|
|
22
|
-
"start_time": "2026-08-21T18:
|
|
23
|
-
"end_time": "2026-08-21T18:
|
|
22
|
+
"start_time": "2026-08-21T18:31:49",
|
|
23
|
+
"end_time": "2026-08-21T18:31:49",
|
|
24
24
|
"status": "success",
|
|
25
25
|
"observability": {
|
|
26
26
|
"events": [
|
|
27
27
|
{
|
|
28
28
|
"event": "collect_secrets_analyzer_scan_metrics_from_pipeline",
|
|
29
|
-
"time_s": 0.
|
|
29
|
+
"time_s": 0.480570925,
|
|
30
30
|
"exit_code": 0,
|
|
31
31
|
"git_strategy": "FetchShallow",
|
|
32
|
-
"repo_size_kb":
|
|
32
|
+
"repo_size_kb": 468,
|
|
33
33
|
"commit_count": 1,
|
|
34
|
-
"bytes_scanned":
|
|
34
|
+
"bytes_scanned": 136,
|
|
35
35
|
"pipeline_type": "Tag"
|
|
36
36
|
},
|
|
37
37
|
{
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/pyproject.toml.jinja
RENAMED
|
@@ -16,9 +16,9 @@ dependencies = [
|
|
|
16
16
|
# plesty.lib.utils.config (which load_config() below uses), the operation
|
|
17
17
|
# kinds @expose_to_api declares and the field test drives, and the rig
|
|
18
18
|
# start-up connect_rig()/preflight(). Pinned to the newest library published
|
|
19
|
-
# when this project was scaffolded
|
|
20
|
-
# pre-release resolvable at all.
|
|
21
|
-
"plesty-lib
|
|
19
|
+
# when this project was scaffolded, or to whatever `plesty init --lib-version`
|
|
20
|
+
# asked for; a .devN bound is also what makes a pre-release resolvable at all.
|
|
21
|
+
"plesty-lib{{ plesty_lib_specifier }}",
|
|
22
22
|
]
|
|
23
23
|
|
|
24
24
|
[tool.plesty]
|
|
@@ -21,6 +21,7 @@ from pathlib import Path
|
|
|
21
21
|
import click
|
|
22
22
|
import copier
|
|
23
23
|
import yaml
|
|
24
|
+
from packaging.specifiers import InvalidSpecifier, SpecifierSet
|
|
24
25
|
from packaging.version import InvalidVersion, Version
|
|
25
26
|
|
|
26
27
|
from plesty.sdk.commands.field_test import scaffold_field_test
|
|
@@ -93,6 +94,50 @@ def _parse_version(version: str) -> Version | None:
|
|
|
93
94
|
return None
|
|
94
95
|
|
|
95
96
|
|
|
97
|
+
def lib_specifier(requested: str | None = None) -> str:
|
|
98
|
+
"""Return the version specifier to write after ``plesty-lib`` in pyproject.
|
|
99
|
+
|
|
100
|
+
Without *requested* the pin follows PyPI (:func:`resolve_lib_version`).
|
|
101
|
+
With it, the caller decides and no lookup happens — a tutorial pins the
|
|
102
|
+
library its lesson text was written against, so the page and the file the
|
|
103
|
+
reader ends up with keep saying the same thing however far the library has
|
|
104
|
+
moved since; an air-gapped machine gets the same determinism.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
requested: A bare version (``"0.3.5.dev3"`` → ``">=0.3.5.dev3"``) or a
|
|
108
|
+
complete specifier, which is taken as written
|
|
109
|
+
(``"==0.4.0"``, ``">=0.3.5.dev3,<0.4"``).
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
The specifier, leading operator included.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
click.ClickException: If *requested* is neither a version nor a
|
|
116
|
+
specifier PEP 440 can read.
|
|
117
|
+
"""
|
|
118
|
+
if requested is None:
|
|
119
|
+
return f">={resolve_lib_version()}"
|
|
120
|
+
text = requested.strip()
|
|
121
|
+
if not text:
|
|
122
|
+
raise click.ClickException("--lib-version was given nothing to pin to.")
|
|
123
|
+
if text[0] in "<>=!~":
|
|
124
|
+
try:
|
|
125
|
+
SpecifierSet(text)
|
|
126
|
+
except InvalidSpecifier as exc:
|
|
127
|
+
raise click.ClickException(
|
|
128
|
+
f"--lib-version {requested!r} is not a valid version specifier: {exc}"
|
|
129
|
+
) from exc
|
|
130
|
+
return text
|
|
131
|
+
try:
|
|
132
|
+
Version(text)
|
|
133
|
+
except InvalidVersion as exc:
|
|
134
|
+
raise click.ClickException(
|
|
135
|
+
f"--lib-version {requested!r} is not a valid version: {exc}. Give a version "
|
|
136
|
+
"(0.3.5.dev3) or a full specifier (>=0.3.5.dev3,<0.4)."
|
|
137
|
+
) from exc
|
|
138
|
+
return f">={text}"
|
|
139
|
+
|
|
140
|
+
|
|
96
141
|
@click.command(name="init", short_help="Initialize a new Plesty project from a template.")
|
|
97
142
|
@click.argument(
|
|
98
143
|
"project_type",
|
|
@@ -125,6 +170,19 @@ def _parse_version(version: str) -> Version | None:
|
|
|
125
170
|
"quantum) — bump the CI input alongside your releases."
|
|
126
171
|
),
|
|
127
172
|
)
|
|
173
|
+
@click.option(
|
|
174
|
+
"--lib-version",
|
|
175
|
+
default=None,
|
|
176
|
+
metavar="VERSION",
|
|
177
|
+
help=(
|
|
178
|
+
"Pin plesty-lib to this version instead of the newest published one. "
|
|
179
|
+
"A bare version becomes a lower bound (0.3.5.dev3 → >=0.3.5.dev3); a "
|
|
180
|
+
"complete specifier is written as given (==0.4.0, '>=0.3.5.dev3,<0.4'). "
|
|
181
|
+
"PyPI is not consulted, so the scaffold is reproducible — which is what "
|
|
182
|
+
"a tutorial needs: the lesson text and the reader's pyproject.toml keep "
|
|
183
|
+
"agreeing however far the library has moved since."
|
|
184
|
+
),
|
|
185
|
+
)
|
|
128
186
|
@click.option(
|
|
129
187
|
"--no-ci",
|
|
130
188
|
is_flag=True,
|
|
@@ -150,6 +208,7 @@ def init_command(
|
|
|
150
208
|
author: str | None,
|
|
151
209
|
email: str | None,
|
|
152
210
|
standard: str,
|
|
211
|
+
lib_version: str | None,
|
|
153
212
|
no_ci: bool,
|
|
154
213
|
force: bool,
|
|
155
214
|
) -> None:
|
|
@@ -192,6 +251,10 @@ def init_command(
|
|
|
192
251
|
scaffold_mock_test(target_dir, force=force)
|
|
193
252
|
return
|
|
194
253
|
|
|
254
|
+
# Settle the pin before anything is created: an unreadable --lib-version
|
|
255
|
+
# should not leave a directory behind for a project that never happened.
|
|
256
|
+
lib_pin = lib_specifier(lib_version)
|
|
257
|
+
|
|
195
258
|
if module_name is None:
|
|
196
259
|
inferred = target_dir.name.removeprefix("plesty-").replace("-", "_")
|
|
197
260
|
if not MODULE_NAME_PATTERN.match(inferred):
|
|
@@ -220,7 +283,7 @@ def init_command(
|
|
|
220
283
|
"pypi_name": pypi_name,
|
|
221
284
|
"project_type": project_type,
|
|
222
285
|
"year": str(datetime.date.today().year),
|
|
223
|
-
"
|
|
286
|
+
"plesty_lib_specifier": lib_pin,
|
|
224
287
|
"plesty_sdk_version": PLESTY_SDK_VERSION,
|
|
225
288
|
}
|
|
226
289
|
if author is not None:
|
|
@@ -9,6 +9,7 @@ import json
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from unittest.mock import patch
|
|
11
11
|
|
|
12
|
+
import click
|
|
12
13
|
import pytest
|
|
13
14
|
from click.testing import CliRunner
|
|
14
15
|
|
|
@@ -19,6 +20,7 @@ from plesty.sdk.commands.init import (
|
|
|
19
20
|
PLESTY_SDK_VERSION,
|
|
20
21
|
_STANDARD_CI_STAGES,
|
|
21
22
|
generate_gitlab_ci,
|
|
23
|
+
lib_specifier,
|
|
22
24
|
resolve_lib_version,
|
|
23
25
|
)
|
|
24
26
|
|
|
@@ -590,3 +592,56 @@ class TestResolveLibVersion:
|
|
|
590
592
|
def test_answer_without_releases_falls_back(self):
|
|
591
593
|
"""A body that is JSON but not the expected document is not a version list."""
|
|
592
594
|
assert self._resolve({"info": {"version": "9.9.9"}}) == PLESTY_LIB_VERSION
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
class TestLibSpecifier:
|
|
598
|
+
"""`--lib-version` decides the pin, and asking PyPI is then skipped."""
|
|
599
|
+
|
|
600
|
+
@pytest.fixture(autouse=True)
|
|
601
|
+
def no_network(self):
|
|
602
|
+
"""Any lookup during these tests is a bug: a requested pin asks nobody."""
|
|
603
|
+
resolve_lib_version.cache_clear()
|
|
604
|
+
with patch(
|
|
605
|
+
"plesty.sdk.commands.init.urllib.request.urlopen",
|
|
606
|
+
side_effect=AssertionError("PyPI must not be consulted for a requested pin"),
|
|
607
|
+
):
|
|
608
|
+
yield
|
|
609
|
+
resolve_lib_version.cache_clear()
|
|
610
|
+
|
|
611
|
+
@pytest.mark.parametrize(
|
|
612
|
+
("requested", "expected"),
|
|
613
|
+
[
|
|
614
|
+
("0.3.5.dev3", ">=0.3.5.dev3"),
|
|
615
|
+
(" 0.4.0 ", ">=0.4.0"),
|
|
616
|
+
("==0.4.0", "==0.4.0"),
|
|
617
|
+
(">=0.3.5.dev3,<0.4", ">=0.3.5.dev3,<0.4"),
|
|
618
|
+
("~=0.4.0", "~=0.4.0"),
|
|
619
|
+
],
|
|
620
|
+
)
|
|
621
|
+
def test_requested_pin(self, requested, expected):
|
|
622
|
+
"""A bare version becomes a lower bound; a specifier is taken as written."""
|
|
623
|
+
assert lib_specifier(requested) == expected
|
|
624
|
+
|
|
625
|
+
@pytest.mark.parametrize("requested", ["", " ", "not-a-version", ">=", "=>0.4.0"])
|
|
626
|
+
def test_unreadable_request_is_refused(self, requested):
|
|
627
|
+
"""A pin nothing can resolve is named at the command line, not written out."""
|
|
628
|
+
with pytest.raises(click.ClickException):
|
|
629
|
+
lib_specifier(requested)
|
|
630
|
+
|
|
631
|
+
def test_scaffold_pins_what_was_asked_for(self, tmp_path):
|
|
632
|
+
"""The requested pin is what lands in the generated pyproject.toml."""
|
|
633
|
+
result = _invoke_init(
|
|
634
|
+
tmp_path, "device", "--name", "my_sensor", "--lib-version", ">=0.3.5.dev3,<0.4"
|
|
635
|
+
)
|
|
636
|
+
assert result.exit_code == 0, result.output
|
|
637
|
+
assert '"plesty-lib>=0.3.5.dev3,<0.4"' in (tmp_path / "pyproject.toml").read_text()
|
|
638
|
+
|
|
639
|
+
def test_bad_pin_creates_nothing(self, tmp_path):
|
|
640
|
+
"""A refused --lib-version leaves no half-scaffolded directory behind."""
|
|
641
|
+
target = tmp_path / "plesty-my-sensor"
|
|
642
|
+
result = _invoke_init(
|
|
643
|
+
target, "device", "--name", "my_sensor", "--lib-version", "not-a-version"
|
|
644
|
+
)
|
|
645
|
+
assert result.exit_code != 0
|
|
646
|
+
assert "not a valid version" in result.output
|
|
647
|
+
assert not target.exists()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/init/client-field-test.py.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/analyzer/analyzer.py
RENAMED
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/device/base_device.py
RENAMED
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/extras/device/device.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/CHANGELOG.md.jinja
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/README.md.jinja
RENAMED
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/REUSE.toml.jinja
RENAMED
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/docs/index.md.jinja
RENAMED
|
File without changes
|
{plesty_sdk-0.3.4 → plesty_sdk-0.3.5.dev1}/plesty/sdk/assets/templates/template/docs/toc.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|