plesty-sdk 0.1.0.dev1__tar.gz → 0.1.0.dev2__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.1.0.dev2/.coverage +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/.gitignore +0 -1
- plesty_sdk-0.1.0.dev2/.gitlab-ci.yml +25 -0
- plesty_sdk-0.1.0.dev2/CHANGELOG.md +35 -0
- plesty_sdk-0.1.0.dev2/PKG-INFO +85 -0
- plesty_sdk-0.1.0.dev2/README.md +51 -0
- plesty_sdk-0.1.0.dev2/docs/commands/check.md +74 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/commands/docs.md +18 -14
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/commands/init.md +27 -9
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/getting-started.md +25 -11
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/index.md +2 -1
- plesty_sdk-0.1.0.dev2/docs/toc.yaml +16 -0
- plesty_sdk-0.1.0.dev2/gl-secret-detection-report.json +50 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/copier.yml +0 -4
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/extras/device/base_device.py +10 -10
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/extras/device/device.py +5 -5
- plesty_sdk-0.1.0.dev2/plesty/sdk/assets/templates/template/CHANGELOG.md.jinja +8 -0
- plesty_sdk-0.1.0.dev2/plesty/sdk/assets/templates/template/docs/index.md.jinja +36 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/plesty/{{module_name}}/__init__.py.jinja +9 -2
- plesty_sdk-0.1.0.dev2/plesty/sdk/assets/templates/template/plesty/{{module_name}}/__main__.py.jinja +54 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/pyproject.toml.jinja +8 -7
- plesty_sdk-0.1.0.dev2/plesty/sdk/assets/templates/template/tests/__init__.py +1 -0
- plesty_sdk-0.1.0.dev2/plesty/sdk/assets/templates/template/tests/test_{{module_name}}.py.jinja +79 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/cli.py +8 -8
- plesty_sdk-0.1.0.dev2/plesty/sdk/commands/check.py +679 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/docs/__init__.py +4 -4
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/docs/deploy.py +9 -22
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/docs/serve.py +7 -10
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/docs/sphinx_builder.py +14 -5
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/init.py +68 -69
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/license.py +10 -24
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/manual.py +8 -14
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/update.py +32 -47
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/context.py +5 -14
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/pyproject.toml +11 -4
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_cache.py +2 -4
- plesty_sdk-0.1.0.dev2/tests/test_check.py +823 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_cli.py +1 -1
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_context.py +1 -1
- plesty_sdk-0.1.0.dev2/tests/test_docs_deploy.py +241 -0
- plesty_sdk-0.1.0.dev2/tests/test_docs_serve.py +215 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_init.py +116 -89
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_license.py +2 -2
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_manual.py +6 -12
- plesty_sdk-0.1.0.dev2/tests/test_sphinx_builder.py +303 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/test_update.py +23 -34
- plesty_sdk-0.1.0.dev2/uv.lock +2287 -0
- plesty_sdk-0.1.0.dev1/.gitlab-ci.yml +0 -52
- plesty_sdk-0.1.0.dev1/PKG-INFO +0 -51
- plesty_sdk-0.1.0.dev1/README.md +0 -21
- plesty_sdk-0.1.0.dev1/docs/commands/check.md +0 -56
- plesty_sdk-0.1.0.dev1/docs/toc.yaml +0 -4
- plesty_sdk-0.1.0.dev1/plesty_sdk/assets/templates/template/docs/index.md +0 -1
- plesty_sdk-0.1.0.dev1/plesty_sdk/assets/templates/template/plesty/{{module_name}}/__main__.py.jinja +0 -35
- plesty_sdk-0.1.0.dev1/plesty_sdk/commands/check.py +0 -161
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/COPYING +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/COPYING.LESSER +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/LICENSE +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/commands/license.md +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/commands/manual.md +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/docs/commands/update.md +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/__init__.py +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/docs-build-gitlab-ci.yml +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/gitlab-ci.yml +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/logos/plesty_icon.png +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/logos/plesty_logo.png +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/ruff.toml +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/.gitignore +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/COPYING +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/LICENSE +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/LICENSES/GPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/README.md.jinja +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/assets/templates/template/spdx.tmpl.jinja +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/cache.py +0 -0
- {plesty_sdk-0.1.0.dev1/plesty_sdk → plesty_sdk-0.1.0.dev2/plesty/sdk}/commands/__init__.py +0 -0
- {plesty_sdk-0.1.0.dev1 → plesty_sdk-0.1.0.dev2}/tests/__init__.py +0 -0
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
workflow:
|
|
2
|
+
rules:
|
|
3
|
+
# Create pipelines for merge requests
|
|
4
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
5
|
+
# Create branch pipelines for main and exp
|
|
6
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
7
|
+
- if: $CI_COMMIT_BRANCH == "exp"
|
|
8
|
+
# Create pipelines for tags (dev and stable releases)
|
|
9
|
+
- if: $CI_COMMIT_TAG
|
|
10
|
+
# Otherwise do not create a pipeline
|
|
11
|
+
- when: never
|
|
12
|
+
|
|
13
|
+
stages:
|
|
14
|
+
- check
|
|
15
|
+
- security
|
|
16
|
+
- deploy
|
|
17
|
+
- release
|
|
18
|
+
|
|
19
|
+
include:
|
|
20
|
+
- component: $CI_SERVER_FQDN/plesty/plesty-ci/hub-module@exp
|
|
21
|
+
inputs:
|
|
22
|
+
standard: quantum
|
|
23
|
+
extra_branch: exp
|
|
24
|
+
access_token: $CI_BOT_TOKEN
|
|
25
|
+
pypi_token: $PYPI_TOKEN
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com).
|
|
4
|
+
|
|
5
|
+
## [2026-06-24]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `plesty init device/experiment` now scaffolds a `tests/` directory with smoke tests
|
|
9
|
+
covering all public methods, so gate 7 (≥80% coverage) passes without manual edits.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `plesty init` CI generation switched from per-component includes to the unified
|
|
13
|
+
`hub-module@exp` component; `--ci-stages` replaced by `--standard` / `--no-ci`.
|
|
14
|
+
- `plesty init` (`--standard`, default `quantum`) and `plesty update` share the same
|
|
15
|
+
interface for regenerating `.gitlab-ci.yml`.
|
|
16
|
+
- `__main__.py` template now guards entry-point code behind `if __name__ == "__main__"`
|
|
17
|
+
to prevent import-time side effects in generated projects.
|
|
18
|
+
- Gate 2 mypy run now excludes `tests/` to avoid namespace-package double-discovery
|
|
19
|
+
when test files import from the `plesty` namespace.
|
|
20
|
+
|
|
21
|
+
## [2026-06-22]
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- Implemented all nine HUB module validation gates in `plesty check` (Gates 1–9),
|
|
25
|
+
covering metadata, code hygiene, API interfaces, data compliance, documentation,
|
|
26
|
+
dependency coexistence, test coverage, semantic versioning, and licensing.
|
|
27
|
+
- `plesty init` now installs a pre-push git hook enforcing `plesty check --standard nebula`.
|
|
28
|
+
- New dependencies: `mypy>=1.0`, `pytest-cov>=5.0`.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
- Restructured package from `plesty_sdk` to `plesty.sdk` namespace package for
|
|
32
|
+
consistency with the HUB module convention.
|
|
33
|
+
- `plesty check` default standard changed from `pixel` to `nebula`.
|
|
34
|
+
- Removed Bluesky runtime device check; API interface matching is now static (AST-based).
|
|
35
|
+
- `pydata-sphinx-theme` pin relaxed from `==0.17.1` to `>=0.17.1,<1.0`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plesty-sdk
|
|
3
|
+
Version: 0.1.0.dev2
|
|
4
|
+
Summary: Command-line application for developing Python modules compliant with the Plesty standard.
|
|
5
|
+
Author: Plesty Development Team
|
|
6
|
+
License-Expression: LGPL-3.0-or-later
|
|
7
|
+
License-File: COPYING
|
|
8
|
+
License-File: COPYING.LESSER
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Requires-Dist: bluesky>=1.14.6
|
|
12
|
+
Requires-Dist: click>=3.8
|
|
13
|
+
Requires-Dist: copier>=9.15.1
|
|
14
|
+
Requires-Dist: licenseheaders>=0.8.8
|
|
15
|
+
Requires-Dist: livereload>=2.7.1
|
|
16
|
+
Requires-Dist: md2pdf>=3.1.1
|
|
17
|
+
Requires-Dist: mypy>=1.0
|
|
18
|
+
Requires-Dist: myst-parser>=5.0.0
|
|
19
|
+
Requires-Dist: pydata-sphinx-theme<1.0,>=0.17.1
|
|
20
|
+
Requires-Dist: pytest-cov>=5.0
|
|
21
|
+
Requires-Dist: pytest>=9.0.0
|
|
22
|
+
Requires-Dist: reuse>=6.2.0
|
|
23
|
+
Requires-Dist: ruff>=0.14
|
|
24
|
+
Requires-Dist: sphinx-autoapi>=3.6.1
|
|
25
|
+
Requires-Dist: sphinx-copybutton>=0.5.2
|
|
26
|
+
Requires-Dist: sphinx-design>=0.7.0
|
|
27
|
+
Requires-Dist: sphinx-external-toc>=1.1.0
|
|
28
|
+
Requires-Dist: sphinx>=9.1.0
|
|
29
|
+
Requires-Dist: sphinxcontrib-mermaid>=2.0.0
|
|
30
|
+
Requires-Dist: watchfiles>=1.1.1
|
|
31
|
+
Provides-Extra: gui
|
|
32
|
+
Requires-Dist: pyside6-essentials>=6.11.0; extra == 'gui'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# plesty-sdk
|
|
36
|
+
|
|
37
|
+
The official command-line tool for developing Python modules compliant with the
|
|
38
|
+
[Plesty standard](https://gitlab.com/plesty/governance). It provides project scaffolding,
|
|
39
|
+
compliance checking, documentation tooling, license header management, and device manual
|
|
40
|
+
generation.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install plesty-sdk
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
After installation the `plesty` command is available in your environment. For development
|
|
49
|
+
inside the SDK repository itself, use `uv run plesty`.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# 1. Scaffold a new device module
|
|
55
|
+
mkdir plesty-power-meter && cd plesty-power-meter
|
|
56
|
+
plesty init device --author "Jane Doe" --email jane@example.com
|
|
57
|
+
|
|
58
|
+
# 2. Develop your module — the pre-push hook runs compliance checks automatically
|
|
59
|
+
|
|
60
|
+
# 3. Run the full [SDK] compliance check manually at any time
|
|
61
|
+
plesty check
|
|
62
|
+
|
|
63
|
+
# 4. Preview the documentation locally
|
|
64
|
+
plesty docs serve
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
| Command | Description |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `plesty init` | Scaffold a new device or experiment module from the official template |
|
|
72
|
+
| `plesty check` | Validate a project against the Plesty compliance standard |
|
|
73
|
+
| `plesty docs serve` | Preview documentation locally with live reload |
|
|
74
|
+
| `plesty docs deploy` | Build and push documentation to a remote pages branch |
|
|
75
|
+
| `plesty license update` | Apply SPDX license headers to all Python source files |
|
|
76
|
+
| `plesty manual generate` | Generate Markdown/PDF reference manuals from a `DocDevice` class |
|
|
77
|
+
| `plesty update` | Update author, name, or CI stages in an existing project |
|
|
78
|
+
|
|
79
|
+
Full documentation is available at the project's GitLab Pages site and locally via
|
|
80
|
+
`plesty docs serve` run from within this repository.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
plesty-sdk is free software licensed under the
|
|
85
|
+
[GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later)](LICENSE).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# plesty-sdk
|
|
2
|
+
|
|
3
|
+
The official command-line tool for developing Python modules compliant with the
|
|
4
|
+
[Plesty standard](https://gitlab.com/plesty/governance). It provides project scaffolding,
|
|
5
|
+
compliance checking, documentation tooling, license header management, and device manual
|
|
6
|
+
generation.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install plesty-sdk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
After installation the `plesty` command is available in your environment. For development
|
|
15
|
+
inside the SDK repository itself, use `uv run plesty`.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Scaffold a new device module
|
|
21
|
+
mkdir plesty-power-meter && cd plesty-power-meter
|
|
22
|
+
plesty init device --author "Jane Doe" --email jane@example.com
|
|
23
|
+
|
|
24
|
+
# 2. Develop your module — the pre-push hook runs compliance checks automatically
|
|
25
|
+
|
|
26
|
+
# 3. Run the full [SDK] compliance check manually at any time
|
|
27
|
+
plesty check
|
|
28
|
+
|
|
29
|
+
# 4. Preview the documentation locally
|
|
30
|
+
plesty docs serve
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
| Command | Description |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `plesty init` | Scaffold a new device or experiment module from the official template |
|
|
38
|
+
| `plesty check` | Validate a project against the Plesty compliance standard |
|
|
39
|
+
| `plesty docs serve` | Preview documentation locally with live reload |
|
|
40
|
+
| `plesty docs deploy` | Build and push documentation to a remote pages branch |
|
|
41
|
+
| `plesty license update` | Apply SPDX license headers to all Python source files |
|
|
42
|
+
| `plesty manual generate` | Generate Markdown/PDF reference manuals from a `DocDevice` class |
|
|
43
|
+
| `plesty update` | Update author, name, or CI stages in an existing project |
|
|
44
|
+
|
|
45
|
+
Full documentation is available at the project's GitLab Pages site and locally via
|
|
46
|
+
`plesty docs serve` run from within this repository.
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
plesty-sdk is free software licensed under the
|
|
51
|
+
[GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later)](LICENSE).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# plesty check
|
|
2
|
+
|
|
3
|
+
Validate a project against the Plesty compliance standard. Runs a suite of static analysis
|
|
4
|
+
and runtime gates organised into two enforcement tiers.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
plesty check [--standard LEVEL]
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Options
|
|
11
|
+
|
|
12
|
+
| Option | Default | Description |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `--standard` | `quantum` | Compliance level: `pixel`, `nebula`, or `quantum` |
|
|
15
|
+
|
|
16
|
+
## Enforcement tiers
|
|
17
|
+
|
|
18
|
+
Gates are divided into two tiers depending on whether they require network access or a clean
|
|
19
|
+
install environment:
|
|
20
|
+
|
|
21
|
+
- **`[SDK]`** — enforced locally by `plesty check`; pure static analysis, no network.
|
|
22
|
+
The pre-push git hook installed by `plesty init` runs these gates automatically before
|
|
23
|
+
every push.
|
|
24
|
+
- **`[SDK+CI]`** — enforced locally and repeated by CI in a clean environment as the
|
|
25
|
+
authoritative final gate.
|
|
26
|
+
|
|
27
|
+
## Compliance levels
|
|
28
|
+
|
|
29
|
+
### Pixel
|
|
30
|
+
|
|
31
|
+
Metadata and code hygiene only — fast check suitable for pre-commit hooks.
|
|
32
|
+
|
|
33
|
+
| Gate | Tier | What is checked |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| Metadata & Namespace | `[SDK]` | `pyproject.toml` has required fields; package name matches `plesty-<module>`; `plesty/<module>/` directory exists |
|
|
36
|
+
| Code Hygiene | `[SDK]` | `ruff` lint (E, F, W, D rules); `ruff format --check`; `mypy` type checking |
|
|
37
|
+
|
|
38
|
+
### Nebula
|
|
39
|
+
|
|
40
|
+
All Pixel gates plus the remaining `[SDK]` gates. This is the standard enforced by the
|
|
41
|
+
pre-push hook.
|
|
42
|
+
|
|
43
|
+
| Gate | Tier | What is checked |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| API Interface Matching | `[SDK]` | Classes that import from `plesty.lib.*` must inherit from the imported base class (e.g. `BaseDeviceSyncModel`) |
|
|
46
|
+
| Data Layer Compliance | `[SDK]` | All public methods have explicit return type annotations |
|
|
47
|
+
| Documentation Completeness | `[SDK]` | `docs/index.md` (or `index.rst`) exists; `CHANGELOG.md` exists and has been updated since the last git tag |
|
|
48
|
+
| Dependency Coexistence | `[SDK]` | No exact pins (`==x.y.z`) in `pyproject.toml`; use `>=x.y,<x+1` |
|
|
49
|
+
|
|
50
|
+
### Quantum
|
|
51
|
+
|
|
52
|
+
Everything in Nebula plus the `[SDK+CI]` gates, run locally for full verification before a
|
|
53
|
+
release. This is the default `plesty check` standard.
|
|
54
|
+
|
|
55
|
+
| Gate | Tier | What is checked |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| Automated Test Coverage | `[SDK+CI]` | `pytest --cov` with a minimum threshold of **80%** |
|
|
58
|
+
| Semantic Versioning | `[SDK+CI]` | Reminder to tag a new release when commits exist since the last tag; API-level diff against the published PyPI release runs in CI |
|
|
59
|
+
| Licensing Compliance | `[SDK+CI]` | `LICENSE` and `COPYING` files present; `license` field declared in `pyproject.toml` |
|
|
60
|
+
| Vulnerability Audit | `[SDK+CI]` | No known CVEs in declared dependencies; queries the OSV database via `pip-audit` |
|
|
61
|
+
| Docs Build | `[SDK+CI]` | Full Sphinx build must complete with zero errors and zero warnings |
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Default quantum check in the current directory
|
|
67
|
+
plesty check
|
|
68
|
+
|
|
69
|
+
# Quick pixel check (metadata + code hygiene only)
|
|
70
|
+
plesty check --standard pixel
|
|
71
|
+
|
|
72
|
+
# Full quantum check on a project in another directory
|
|
73
|
+
plesty --project-dir ../plesty-power-meter check --standard quantum
|
|
74
|
+
```
|
|
@@ -41,31 +41,35 @@ Press **Ctrl+C** to stop the server.
|
|
|
41
41
|
## deploy
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
plesty docs deploy
|
|
44
|
+
plesty docs deploy REMOTE_URL TARGET_BRANCH (--release | --latest)
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Builds the Sphinx documentation and pushes it to
|
|
48
|
-
suitable for GitLab Pages
|
|
47
|
+
Builds the Sphinx documentation and pushes it to `TARGET_BRANCH` on the repository at
|
|
48
|
+
`REMOTE_URL`, suitable for GitLab Pages. The branch is created as an orphan if it does not
|
|
49
|
+
yet exist.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
`--release` and `--latest` are mutually exclusive and one is required:
|
|
51
52
|
|
|
52
|
-
|
|
|
53
|
-
|
|
54
|
-
| `--
|
|
55
|
-
| `--
|
|
56
|
-
| `--release` | off | Build as a versioned release; without this flag the docs are published as the latest development snapshot |
|
|
53
|
+
| Flag | Behaviour |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `--latest` | Publishes to `html/latest/` — for commits to the default branch |
|
|
56
|
+
| `--release` | Publishes to `html/releases/<major>.<minor>/` — for tagged releases |
|
|
57
57
|
|
|
58
58
|
### Example
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
# Deploy development snapshot
|
|
61
|
+
# Deploy development snapshot (latest)
|
|
62
62
|
plesty docs deploy \
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
https://gitlab-ci-token:${CI_BOT_TOKEN}@gitlab.com/plesty/my-device.git \
|
|
64
|
+
docs-build \
|
|
65
|
+
--latest
|
|
65
66
|
|
|
66
67
|
# Deploy a versioned release
|
|
67
68
|
plesty docs deploy \
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
https://gitlab-ci-token:${CI_BOT_TOKEN}@gitlab.com/plesty/my-device.git \
|
|
70
|
+
docs-build \
|
|
70
71
|
--release
|
|
71
72
|
```
|
|
73
|
+
|
|
74
|
+
In practice this command is called by the `deploy-docs` CI component and does not need to
|
|
75
|
+
be run manually.
|
|
@@ -23,7 +23,7 @@ All Plesty projects follow a consistent naming scheme derived from the module na
|
|
|
23
23
|
| Artifact | Convention | Example |
|
|
24
24
|
|---|---|---|
|
|
25
25
|
| Project folder | `plesty-<kebab-name>` | `plesty-foo-bar` |
|
|
26
|
-
| Source folder |
|
|
26
|
+
| Source folder | `plesty/<module_name>/` | `plesty/foo_bar/` |
|
|
27
27
|
| PyPI distribution | `plesty-<kebab-name>` | `plesty-foo-bar` |
|
|
28
28
|
| Python import | `plesty.<module_name>` | `plesty.foo_bar` |
|
|
29
29
|
|
|
@@ -48,6 +48,17 @@ name, so `plesty-foo-bar` → `foo_bar` without needing `--name`.
|
|
|
48
48
|
- If `--project-dir` does not exist it is created automatically.
|
|
49
49
|
- If it already exists it must be empty (hidden entries such as `.git` are ignored).
|
|
50
50
|
|
|
51
|
+
## What init does
|
|
52
|
+
|
|
53
|
+
After copying the template, `plesty init` automatically:
|
|
54
|
+
|
|
55
|
+
1. **Formats generated files** — runs `ruff format` so the scaffold is already
|
|
56
|
+
`plesty check`-clean from the first commit.
|
|
57
|
+
2. **Creates the initial git commit** — required by `versioningit` to resolve a package
|
|
58
|
+
version from git history.
|
|
59
|
+
3. **Installs the pre-push hook** — writes `.git/hooks/pre-push` to run
|
|
60
|
+
`plesty check --standard nebula` automatically before every `git push`.
|
|
61
|
+
|
|
51
62
|
## Examples
|
|
52
63
|
|
|
53
64
|
```bash
|
|
@@ -76,14 +87,20 @@ plesty --project-dir ~/projects/plesty-internal-tool init device \
|
|
|
76
87
|
|
|
77
88
|
```
|
|
78
89
|
plesty-foo-bar/
|
|
79
|
-
├──
|
|
80
|
-
│
|
|
81
|
-
│
|
|
82
|
-
│
|
|
83
|
-
│
|
|
90
|
+
├── plesty/
|
|
91
|
+
│ └── foo_bar/
|
|
92
|
+
│ ├── __init__.py
|
|
93
|
+
│ └── __main__.py
|
|
94
|
+
│ └── base_device.py # device only
|
|
95
|
+
│ └── device.py # device only
|
|
84
96
|
├── docs/
|
|
85
97
|
│ └── index.md
|
|
86
|
-
├──
|
|
98
|
+
├── tests/
|
|
99
|
+
├── CHANGELOG.md
|
|
100
|
+
├── .git/
|
|
101
|
+
│ └── hooks/
|
|
102
|
+
│ └── pre-push # runs plesty check --standard nebula
|
|
103
|
+
├── .gitlab-ci.yml # omitted when --ci-stages ""
|
|
87
104
|
├── .gitignore
|
|
88
105
|
├── COPYING
|
|
89
106
|
├── LICENSE
|
|
@@ -94,10 +111,11 @@ plesty-foo-bar/
|
|
|
94
111
|
```
|
|
95
112
|
|
|
96
113
|
The `pyproject.toml` is pre-configured with:
|
|
97
|
-
- The PyPI distribution name `plesty-foo-bar` (kebab-case
|
|
98
|
-
-
|
|
114
|
+
- The PyPI distribution name `plesty-foo-bar` (kebab-case)
|
|
115
|
+
- `packages = ["plesty"]` so the module installs under the `plesty` namespace (`import plesty.foo_bar`)
|
|
99
116
|
- Dynamic versioning via `versioningit`
|
|
100
117
|
- `plesty-lib` as a dependency
|
|
118
|
+
- `pytest`, `pytest-cov`, and `mypy` under `[optional-dependencies] dev`
|
|
101
119
|
- Sphinx docs settings under `[tool.plesty.docs]`
|
|
102
120
|
|
|
103
121
|
Use `plesty update` to change author info, the PyPI name, or CI stages after initialisation.
|
|
@@ -13,8 +13,9 @@ mkdir plesty-power-meter && cd plesty-power-meter
|
|
|
13
13
|
plesty init device
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
This produces a `power_meter/` source folder, a PyPI distribution named
|
|
17
|
-
and a package importable as `plesty.power_meter`. Alternatively,
|
|
16
|
+
This produces a `plesty/power_meter/` source folder, a PyPI distribution named
|
|
17
|
+
`plesty-power-meter`, and a package importable as `plesty.power_meter`. Alternatively,
|
|
18
|
+
specify everything explicitly:
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
21
|
plesty --project-dir ~/projects/plesty-power-meter init device \
|
|
@@ -24,8 +25,11 @@ plesty --project-dir ~/projects/plesty-power-meter init device \
|
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
This generates a project pre-configured with the expected repository structure,
|
|
27
|
-
`pyproject.toml`, example source files, CI pipeline (`.gitlab-ci.yml`),
|
|
28
|
-
stubs
|
|
28
|
+
`pyproject.toml`, example source files, CI pipeline (`.gitlab-ci.yml`), documentation
|
|
29
|
+
stubs, and a `CHANGELOG.md`. A pre-push git hook is also installed automatically —
|
|
30
|
+
it runs `plesty check --standard nebula` before every `git push`.
|
|
31
|
+
|
|
32
|
+
Use `--ci-stages` to select which pipeline stages to include, or `--ci-stages ""`
|
|
29
33
|
to omit the CI file entirely.
|
|
30
34
|
|
|
31
35
|
## 2. Check compliance
|
|
@@ -37,9 +41,10 @@ cd plesty-power-meter
|
|
|
37
41
|
plesty check
|
|
38
42
|
```
|
|
39
43
|
|
|
40
|
-
By default this checks against the **
|
|
41
|
-
`--standard
|
|
42
|
-
|
|
44
|
+
By default this checks against the **Nebula** level (all `[SDK]` gates). Add
|
|
45
|
+
`--standard pixel` for a faster metadata + code hygiene only check, or
|
|
46
|
+
`--standard quantum` to also run test coverage and semantic versioning gates locally.
|
|
47
|
+
Fix any reported issues and re-run until the check passes.
|
|
43
48
|
|
|
44
49
|
## 3. Preview the documentation
|
|
45
50
|
|
|
@@ -81,10 +86,19 @@ plesty update --ci-stages "check,build,release"
|
|
|
81
86
|
|
|
82
87
|
## 6. Deploy documentation
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
Documentation deployment is handled automatically by the `deploy-docs` CI component when
|
|
90
|
+
commits land on the default branch or a release tag is pushed. To deploy manually:
|
|
85
91
|
|
|
86
92
|
```bash
|
|
87
|
-
|
|
93
|
+
# Development snapshot
|
|
94
|
+
plesty docs deploy \
|
|
95
|
+
https://gitlab-ci-token:${TOKEN}@gitlab.com/plesty/my-device.git \
|
|
96
|
+
docs-build \
|
|
97
|
+
--latest
|
|
98
|
+
|
|
99
|
+
# Versioned release
|
|
100
|
+
plesty docs deploy \
|
|
101
|
+
https://gitlab-ci-token:${TOKEN}@gitlab.com/plesty/my-device.git \
|
|
102
|
+
docs-build \
|
|
103
|
+
--release
|
|
88
104
|
```
|
|
89
|
-
|
|
90
|
-
Use `--release` to tag it as a versioned release instead of the development snapshot.
|
|
@@ -31,7 +31,8 @@ this directory.
|
|
|
31
31
|
| Command | Description |
|
|
32
32
|
|---|---|
|
|
33
33
|
| [`plesty check`](commands/check.md) | Validate a project against a Plesty compliance level |
|
|
34
|
-
| [`plesty
|
|
34
|
+
| [`plesty init`](commands/init.md) | Scaffold new device or experiment projects from templates |
|
|
35
35
|
| [`plesty docs`](commands/docs.md) | Serve or deploy the project documentation |
|
|
36
36
|
| [`plesty license`](commands/license.md) | Apply and sync SPDX license headers |
|
|
37
37
|
| [`plesty manual`](commands/manual.md) | Generate Markdown/PDF manuals from a device's `DocDevice` |
|
|
38
|
+
| [`plesty update`](commands/update.md) | Update author, name, or CI stages in an existing project |
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
root: index.md
|
|
2
|
+
entries:
|
|
3
|
+
- file: getting-started.md
|
|
4
|
+
title: Getting started
|
|
5
|
+
- file: commands/check.md
|
|
6
|
+
title: check
|
|
7
|
+
- file: commands/init.md
|
|
8
|
+
title: init
|
|
9
|
+
- file: commands/docs.md
|
|
10
|
+
title: docs
|
|
11
|
+
- file: commands/license.md
|
|
12
|
+
title: license
|
|
13
|
+
- file: commands/manual.md
|
|
14
|
+
title: manual
|
|
15
|
+
- file: commands/update.md
|
|
16
|
+
title: update
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scan": {
|
|
3
|
+
"analyzer": {
|
|
4
|
+
"id": "secrets",
|
|
5
|
+
"name": "secrets",
|
|
6
|
+
"url": "https://gitlab.com/gitlab-org/security-products/analyzers/secrets",
|
|
7
|
+
"vendor": {
|
|
8
|
+
"name": "GitLab"
|
|
9
|
+
},
|
|
10
|
+
"version": "7.37.0"
|
|
11
|
+
},
|
|
12
|
+
"scanner": {
|
|
13
|
+
"id": "gitleaks",
|
|
14
|
+
"name": "Gitleaks",
|
|
15
|
+
"url": "https://github.com/gitleaks/gitleaks",
|
|
16
|
+
"vendor": {
|
|
17
|
+
"name": "GitLab"
|
|
18
|
+
},
|
|
19
|
+
"version": "8.30.1"
|
|
20
|
+
},
|
|
21
|
+
"type": "secret_detection",
|
|
22
|
+
"start_time": "2026-06-24T10:28:20",
|
|
23
|
+
"end_time": "2026-06-24T10:28:21",
|
|
24
|
+
"status": "success",
|
|
25
|
+
"observability": {
|
|
26
|
+
"events": [
|
|
27
|
+
{
|
|
28
|
+
"event": "collect_secrets_analyzer_scan_metrics_from_pipeline",
|
|
29
|
+
"time_s": 0.521656153,
|
|
30
|
+
"exit_code": 0,
|
|
31
|
+
"git_strategy": "FetchShallow",
|
|
32
|
+
"repo_size_kb": 553,
|
|
33
|
+
"commit_count": 1,
|
|
34
|
+
"bytes_scanned": 798,
|
|
35
|
+
"pipeline_type": "Tag"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"event": "collect_secrets_analyzer_ruleset_adoption_metrics_from_pipeline",
|
|
39
|
+
"custom_ruleset": false,
|
|
40
|
+
"passthrough_types": null,
|
|
41
|
+
"passthrough_count": 0,
|
|
42
|
+
"passthrough_auth_used": false,
|
|
43
|
+
"rules_version": "0.24.3"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"version": "15.2.4",
|
|
49
|
+
"vulnerabilities": []
|
|
50
|
+
}
|
|
@@ -12,40 +12,40 @@ class BaseDevice(BaseDeviceSyncModel):
|
|
|
12
12
|
## Device-specific meta info initialization can be added here
|
|
13
13
|
|
|
14
14
|
# *---- Mandatory methods to implement ----*#
|
|
15
|
-
def init(self, main=None):
|
|
15
|
+
def init(self, main=None) -> None:
|
|
16
16
|
"""Initialize the device hardware and internal state."""
|
|
17
17
|
## Device-specific initialization can be added here
|
|
18
18
|
pass
|
|
19
19
|
|
|
20
|
-
def connect(self):
|
|
20
|
+
def connect(self) -> bool:
|
|
21
21
|
"""Establish a connection to the device."""
|
|
22
22
|
## Device-specific connection logic can be added here
|
|
23
23
|
return True
|
|
24
24
|
|
|
25
|
-
def disconnect(self):
|
|
25
|
+
def disconnect(self) -> None:
|
|
26
26
|
"""Disconnect from the device and release resources."""
|
|
27
27
|
## Device-specific disconnection logic can be added here
|
|
28
28
|
pass
|
|
29
29
|
|
|
30
|
-
def _write_(self, key: str, value):
|
|
30
|
+
def _write_(self, key: str, value: object) -> None:
|
|
31
31
|
## Device-specific write logic can be added here
|
|
32
32
|
pass
|
|
33
33
|
|
|
34
|
-
def _query_(self, key):
|
|
34
|
+
def _query_(self, key: str) -> object:
|
|
35
35
|
## Device-specific query logic can be added here
|
|
36
|
-
|
|
36
|
+
return None
|
|
37
37
|
|
|
38
38
|
def identity(self) -> str:
|
|
39
39
|
"""Return a string identifying the device model and serial number."""
|
|
40
40
|
## Device-specific identity query logic can be added here
|
|
41
41
|
return "Base Device, Model 1.0, SN00000"
|
|
42
42
|
|
|
43
|
-
def check_errors(self):
|
|
43
|
+
def check_errors(self) -> None:
|
|
44
44
|
"""Check the device for errors and raise if any are found."""
|
|
45
45
|
## Device-specific error checking logic can be added here
|
|
46
46
|
pass
|
|
47
47
|
|
|
48
|
-
def check_operatability(self):
|
|
48
|
+
def check_operatability(self) -> bool:
|
|
49
49
|
"""Return True if the device is ready to operate."""
|
|
50
50
|
## Device-specific operatability check logic can be added here
|
|
51
51
|
return True
|
|
@@ -56,12 +56,12 @@ class BaseDevice(BaseDeviceSyncModel):
|
|
|
56
56
|
## Device-specific query range logic can be added here
|
|
57
57
|
return [None, None]
|
|
58
58
|
|
|
59
|
-
def reset(self):
|
|
59
|
+
def reset(self) -> None:
|
|
60
60
|
"""Reset the device to its default state."""
|
|
61
61
|
## Device-specific reset logic can be added here
|
|
62
62
|
pass
|
|
63
63
|
|
|
64
|
-
def clear(self):
|
|
64
|
+
def clear(self) -> None:
|
|
65
65
|
"""Clear any buffered data or pending state on the device."""
|
|
66
66
|
## Device-specific clear logic can be added here
|
|
67
67
|
pass
|
|
@@ -6,16 +6,16 @@ from .base_device import BaseDevice
|
|
|
6
6
|
class Device(BaseDevice):
|
|
7
7
|
"""Concrete device class extending BaseDevice with custom functionality."""
|
|
8
8
|
|
|
9
|
-
def __init__(self, id: str, param_schema=None, op_schema=None
|
|
9
|
+
def __init__(self, id: str, param_schema=None, op_schema=None) -> None:
|
|
10
10
|
"""Initialize the device with an id and optional parameter and operation schemas."""
|
|
11
11
|
super().__init__(id, op_schema=op_schema, param_schema=param_schema)
|
|
12
12
|
## Device-specific initialization can be added here
|
|
13
13
|
|
|
14
|
-
def custom_method(self
|
|
14
|
+
def custom_method(self) -> None:
|
|
15
15
|
"""Implement a custom device-specific operation."""
|
|
16
|
-
## Example of a custom method specific to this device
|
|
16
|
+
## Example of a custom method specific to this device.
|
|
17
17
|
## These are not required by the base model but can be added
|
|
18
|
-
## for enhanced functionality in
|
|
18
|
+
## for enhanced functionality in addition to the functionalities
|
|
19
19
|
## provided by the base model and the registered configuration
|
|
20
|
-
## parameters and operations
|
|
20
|
+
## parameters and operations.
|
|
21
21
|
pass
|