# plesty init Initialize a new Plesty project from the official template. The project is created in the directory specified by the global `--project-dir` option (defaults to the current working directory), making the standard workflow as simple as: ```bash mkdir plesty-my-device && cd plesty-my-device plesty init device ``` ```bash plesty init [PROJECT_TYPE] [OPTIONS] ``` `PROJECT_TYPE` is one of `device` or `experiment` (default: `default`, not yet available). ## Naming conventions All Plesty projects follow a consistent naming scheme derived from the module name (e.g. `foo_bar`): | Artifact | Convention | Example | |---|---|---| | Project folder | `plesty-` | `plesty-foo-bar` | | Source folder | `plesty//` | `plesty/foo_bar/` | | PyPI distribution | `plesty-` | `plesty-foo-bar` | | Python import | `plesty.` | `plesty.foo_bar` | The `plesty-` prefix in the folder name is automatically stripped when inferring the module name, so `plesty-foo-bar` → `foo_bar` without needing `--name`. ## Options | Option | Default | Description | |---|---|---| | `--name` | inferred | Python module name — lowercase letters, digits, and `_` only (e.g. `foo_bar`). Inferred from the directory name by stripping the `plesty-` prefix and converting hyphens to underscores. | | `--author` | `John Doe` | Author name written into `pyproject.toml` and `REUSE.toml` | | `--email` | `john.doe@example.com` | Author email written into `pyproject.toml` | | `--standard` | `quantum` | Compliance standard for the generated CI pipeline: `pixel`, `nebula`, or `quantum`. | | `--no-ci` | off | Skip generating `.gitlab-ci.yml` entirely. | ## Directory rules - If `--project-dir` does not exist it is created automatically. - If it already exists it must be empty (hidden entries such as `.git` are ignored). ## What init does After copying the template, `plesty init` automatically: 1. **Formats generated files** — runs `ruff format` so the scaffold is already `plesty check`-clean from the first commit. 2. **Creates the initial git commit** — required by `versioningit` to resolve a package version from git history. 3. **Installs the pre-push hook** — writes `.git/hooks/pre-push` to run `plesty check` automatically before every `git push` (standard read from `[tool.plesty] standard` in `pyproject.toml`, default: `quantum`). ## Examples ```bash # Minimal: module name inferred from directory, quantum CI, default author mkdir plesty-power-meter && cd plesty-power-meter plesty init device # Explicit name and author plesty --project-dir ~/projects/plesty-power-meter init device \ --name power_meter \ --author "Jane Doe" \ --email jane@example.com # Use nebula standard in CI (gates 1–6 only) plesty --project-dir ~/projects/plesty-scan-exp init experiment \ --name scan_exp \ --standard nebula # Skip CI file entirely plesty --project-dir ~/projects/plesty-internal-tool init device \ --name internal_tool \ --no-ci ``` ## Generated project layout ``` plesty-foo-bar/ ├── plesty/ │ └── foo_bar/ │ ├── __init__.py │ ├── __main__.py │ ├── base_device.py # device only │ └── device.py # device only ├── docs/ │ ├── index.md │ └── toc.yaml ├── tests/ │ ├── __init__.py │ └── test_foo_bar.py # smoke tests covering all public methods ├── CHANGELOG.md ├── .env.example # device only — connection credential template ├── .git/ │ └── hooks/ │ └── pre-push # runs plesty check (standard from pyproject.toml) ├── .gitlab-ci.yml # omitted when --no-ci ├── .gitignore # ignores .env (keeps .env.example tracked) ├── LICENSE # LGPL text, kept for forge (GitLab) detection ├── LICENSES/ │ └── LGPL-3.0-or-later.txt ├── REUSE.toml # declares copyright/license for every file ├── pyproject.toml └── README.md ``` The `pyproject.toml` is pre-configured with: - The PyPI distribution name `plesty-foo-bar` (kebab-case) - `packages = ["plesty"]` so the module installs under the `plesty` namespace (`import plesty.foo_bar`) - Dynamic versioning via `versioningit` - `plesty-lib` as a runtime dependency - `pytest`, `pytest-cov`, `mypy`, and `plesty-sdk` under `[dependency-groups] dev` (included automatically by `uv run` — no `--extra dev` needed) - Sphinx docs settings under `[tool.plesty.docs]` The generated `.gitlab-ci.yml` uses the unified `plesty-standard-ci` CI component from `plesty-ci` and passes `access_token: $CI_BOT_TOKEN`. Configure a project access token with `read_repository` + `write_repository` scopes and **Maintainer** role, then set it as a masked CI/CD variable named `CI_BOT_TOKEN`. Use `plesty update` to change author info, the PyPI name, or CI standard after initialisation. ## Device connection credentials (device only) Device projects are scaffolded to read their connection credentials from the environment rather than hard-coding them. The generated `__main__.py` loads three variables via [`plesty.lib.utils.EnvSettings`](https://gitlab.com/plesty/core/plesty-lib): | Variable | Meaning | Required | |---|---|---| | `DEVICE_HOST` | Target device host / IP | yes | | `DEVICE_PORT` | Target device port | yes | | `DEVICE_TCP_PORT` | ZMQ port the device server binds (default `5555`) | no | Resolution precedence per value is **CLI argument > environment variable > default**. The required `DEVICE_HOST`/`DEVICE_PORT` are validated with `parser.error(...)`, so a missing credential produces a clean usage message instead of a traceback. `EnvSettings.load()` reads `./.env` and then the process environment (the process environment wins) and, by default, also registers the parsed `.env` values into `os.environ`. Rename these variables per device as needed — the names are just the scaffold defaults, not a fixed contract. **Workflow:** ```bash cp .env.example .env # then fill in DEVICE_HOST / DEVICE_PORT python -m plesty.foo_bar # credentials read from .env python -m plesty.foo_bar --host 10.0.0.5 --tcp-port 6000 # CLI overrides env ``` `.env.example` is committed as a template; the real `.env` is gitignored. The generated `tests/test_foo_bar.py` includes a `skipif` real-device test that consumes the **same** variables, so one `.env` drives both the server and the tests. It is skipped unless `DEVICE_HOST` is set.