swain-cli 0.3.15
Zero-setup SDK generator wrapping OpenAPI Generator
Requires Python: >=3.8
Keywords: openapi, swagger, sdk, codegen, cli

# swain_cli

`swain_cli` is a zero-setup CLI around OpenAPI Generator. It downloads a pinned OpenAPI Generator JAR plus a trimmed Temurin JRE on demand and caches everything per user so you can build SDKs consistently without installing Java yourself.

## Highlights
- Generate SDKs for multiple languages with a single command or an interactive wizard
- Ship exactly what you test with OpenAPI Generator `7.6.0` pinned inside the toolchain
- Launch the embedded OpenJDK 21 runtime automatically (or opt into your own `java`)
- Keep dependencies light (Typer, httpx, questionary, platformdirs, keyring, pooch) so `pipx`, CI, and ephemeral environments stay happy
- Inspect and manage the embedded engine with helper commands (`engine`, `doctor`, `list-generators`)
- Preview what will happen before you run it (`gen --dry-run`, `gen --plan-only` with text/JSON output)
- Persist defaults in a TOML config file and reuse named generation profiles (`config`, `profiles`, `gen --profile`)
- Opt into schema caching and post-generation hooks when you need them (`--schema-cache-ttl`, `--run-hooks`)

## Installation

### Binary (no Python required)
- macOS/Linux:
  ```bash
  curl -fsSL https://raw.githubusercontent.com/takifouhal/swain_cli/HEAD/scripts/install.sh | bash
  ```
- Windows (PowerShell):
  ```powershell
  iwr -useb https://raw.githubusercontent.com/takifouhal/swain_cli/HEAD/scripts/install.ps1 | iex
  ```

The single-file binary bundles a Python runtime, so no system Python is needed. On first run, `swain_cli` downloads a trimmed Temurin JRE plus the pinned OpenAPI Generator JAR and caches them.

Notes:
- Linux arm64 is supported (built via emulated runner).
- Windows on ARM uses the x86_64 binary and runs under emulation.
- Installers verify SHA-256 checksums when available; set `SWAIN_CLI_INSTALL_REQUIRE_CHECKSUM=1` to require them.

### Homebrew (macOS + Linux)
We publish the same single-file binaries through a lightweight tap so you can manage upgrades via Homebrew.

```bash
brew tap takifouhal/swain_cli https://github.com/takifouhal/swain_cli
brew install takifouhal/swain_cli/swain_cli
```

Homebrew installs the PyInstaller binary, so no additional Python dependencies are required. Upgrade with `brew upgrade takifouhal/swain_cli/swain_cli`.

### pip/pipx (requires Python 3.8+)
```bash
pipx install swain_cli
```

Installing with `pipx` keeps `swain_cli` isolated; alternatively run `pip install swain_cli` in a virtual environment.

## Quick start
```bash
# Prime the embedded runtime so the first real run is instant
swain_cli engine install-jre

# Create a config file (optional)
swain_cli config init

# Explore generators and craft a command via guided prompts
swain_cli interactive

# List all generators (delegates to the pinned OpenAPI Generator)
swain_cli list-generators

# Generate Python and TypeScript clients into ./sdks/<generator>
swain_cli gen -i ./openapi.yaml -l python -l typescript -o ./sdks \
  -p packageName=my_api_client -p packageVersion=0.3.0

# Preview the resolved plan without downloading/fetching anything
swain_cli gen --plan-only -i ./openapi.yaml -l python -o ./sdks
```
`swain_cli` streams generator output directly so you see progress in real time.

## Generating SDKs
- `swain_cli gen` accepts every OpenAPI Generator flag you already know (`-c`, `-t`, `-p`, etc.) and repeatable `-l/--lang` options.
- By default the CLI talks to `https://api.swain.technology` for Swain discovery and downloads the CrudSQL dynamic swagger from `https://api.swain.technology/crud`. Override with `--swain-base-url` (platform) and/or `--crudsql-url` (CrudSQL), or point to a local spec via `-i/--schema`. Example local backend: `swain_cli interactive --swain-base-url http://localhost:8080` (infers CrudSQL as `http://localhost:8080/crud`).
- When generating from a downloaded dynamic swagger, `swain_cli` patches the schema base URL (Swagger `host`/`schemes`/`basePath` or OpenAPI `servers`) so generated SDKs default to the same host/path you pointed the CLI at.
- Swain project integration: provide `--swain-project-id` and `--swain-connection-id` to resolve the deployed connection swagger automatically after authenticating. Discover IDs with `swain_cli projects` and `swain_cli connections`. The CLI will find the active build, fetch `/api/dynamic_swagger`, and feed it to the generator.
- JVM tuning: runs start with `-Xms2g -Xmx10g -XX:+UseG1GC`. If the build still runs out of memory the CLI retries at `-Xmx14g`. Supply extra options with `--java-opt` (repeatable) or export `SWAIN_CLI_JAVA_OPTS`.
- Docs/tests are disabled by default via `--global-property=apiDocs=false,apiTests=false,modelDocs=false,modelTests=false`; override with your own `--generator-arg` when you need them.
- Operation examples are skipped by default (`--skip-operation-example`) to avoid OpenAPI Generator blowing up on circular schemas; pass your own generator arg to opt back in if you really need them.
- To match modern OAS defaults the CLI automatically adds `-p disallowAdditionalPropertiesIfNotPresent=false`. Opt into stricter behaviour with `-p disallowAdditionalPropertiesIfNotPresent=true` or a generator config file.
- The `typescript` shortcut maps to `typescript-axios`; request `typescript-fetch` explicitly when you need that runtime.
- Plan output:
  - `--plan-only` is side-effect free (no network / no downloads).
  - `--dry-run` can resolve schemas (may fetch/auth) but does not invoke the generator.
  - Use `--plan-format json --pretty` for machine-readable plans.
- Schema caching: pass `--schema-cache-ttl 10m` (or `2h`) to cache fetched schemas; disable with `--no-schema-cache`.
- Hooks (dangerous): pass `--run-hooks` to enable `--post-hook` commands and any hooks configured in a profile.

## Command reference
- `swain_cli interactive` — guided prompts to build a `swain_cli gen` command (use `--no-run` to only print).
- `swain_cli list-generators` — enumerate all generators provided by the pinned OpenAPI Generator JAR. Add `--engine system` to validate a local Java installation instead.
- `swain_cli doctor` — print environment information, cache paths, installed JREs, and JAR availability (`--format json` for automation/support bundles).
- `swain_cli auth` — manage credentials for hosted Swain services (`login`, `logout`, `status`, `refresh`).
- `swain_cli config` — manage the TOML config file (`path`, `init`, `show`).
- `swain_cli profiles` — inspect named generation profiles from the config file (`list`, `show`).
- `swain_cli projects` — list Swain projects (non-interactive; JSON by default).
- `swain_cli connections` — list Swain connections by `--project-id`/`--connection-id` (non-interactive; JSON by default).
- `swain_cli schema` — fetch a Swain connection schema by `--connection-id` (prints to stdout, or write with `--out`).
- `swain_cli engine <action>` — inspect, clean, and manage the embedded runtime (`status`, `paths`, `clean`, `prune-jars`, `install-jre`, `update-jar`).
- `swain_cli plugins list` — list installed plugins (entry points group: `swain_cli.plugins`).
- `swain_cli self-update` — replace the running binary with a newer release (binary installs only).

Run `swain_cli --help` or `swain_cli <command> --help` for full usage.

## Authentication
Use the `auth` subcommands to prepare credentials before generating SDKs against hosted Swain projects.

- `swain_cli auth login` — authenticate via username/password (`POST /auth/login`). Access and refresh tokens are stored in the system keyring.
- Refresh tokens are stored for future use; use `swain_cli auth refresh` to refresh manually.
- For ephemeral automation, set `SWAIN_CLI_AUTH_TOKEN` (takes precedence over the keyring).
- For CI systems that prefer file-based secrets, set `SWAIN_CLI_AUTH_TOKEN_FILE` to a file containing the token.
- `swain_cli auth status` — inspect the active token source and storage location.
- `swain_cli auth logout` — clear the stored token.
- The interactive wizard checks for a token before listing projects and will prompt you to sign in if missing.

## Engine modes and caching
- **Embedded engine (default)** — the first run downloads a platform-specific Temurin JRE and caches it alongside the pinned OpenAPI Generator JAR under `~/.cache/swain_cli` (Linux), `~/Library/Caches/swain_cli` (macOS), or `%LOCALAPPDATA%\swain_cli\cache` (Windows). Override with `SWAIN_CLI_CACHE_DIR`.
- **Custom asset base (advanced)** — set `SWAIN_CLI_ASSET_BASE` to override where embedded JRE archives are downloaded from.
- **System engine** — add `--engine system` (or export `SWAIN_CLI_ENGINE=system`) to run with whatever `java` is already on `PATH`.
- **Offline use** — prime the cache via `swain_cli engine install-jre` and `swain_cli engine update-jar --version 7.6.0` (or run `swain_cli list-generators` once) or copy an existing cache directory between machines.
- **Integrity checks** — downloads are verified by checksum by default. Set `SWAIN_CLI_VERIFY_SIGNATURES=1` to additionally verify GPG signatures for release assets when available (requires `gpg`).

## Running in CI
1. Install the package (`pipx install swain_cli` or `pip install swain_cli`).
2. Pre-install the embedded runtime during setup: `swain_cli engine install-jre`.
3. Cache the swain_cli cache directory between jobs to reuse downloads.
4. Invoke `swain_cli gen` with your schema and desired generators; capture `./sdks` (or your chosen output path) as build artefacts.
5. Optional: run `swain_cli gen --plan-only ...` as a fast “configuration validation” step.

Swain discovery helpers for automation:
- `swain_cli projects --format json`
- `swain_cli connections --project-id 123 --format json`
- `swain_cli schema --connection-id 456 --out openapi.json`

## YAML patching (optional)
Schema patching works for JSON out of the box. If you need to patch YAML specs, install the extra:
```bash
pipx install "swain_cli[yaml]"
```

## Container image (CI)
We publish a container image with the embedded toolchain pre-warmed (JRE + pinned generator jar). Run:
```bash
docker run --rm ghcr.io/<owner>/swain_cli --help
```

## Troubleshooting
- **Download failures** — check proxy/firewall configuration, or download the JRE asset manually from the GitHub release and place it under the cache path from `swain_cli doctor`.
- **Missing generators** — run `swain_cli list-generators --engine system` to validate your local Java installation or after updating the JAR with `engine update-jar`.
- **Cache cleanup** — delete the directory printed by `swain_cli doctor` to force a clean fetch of the runtime and JAR.
- **OutOfMemoryError** — the CLI already retries with a larger heap. For massive specs raise the ceiling with repeatable `--java-opt -Xmx16g` or set `SWAIN_CLI_JAVA_OPTS`.

## Contributing
1. Create a virtual environment (`python -m venv .venv`) and activate it.
2. Install the project with dev + lint extras: `pip install -e .[dev,lint]`.
3. Run the CLI locally via `python -m swain_cli --help`, `python -m swain_cli.cli --help`, or the `swain_cli` entry point.
4. Run checks: `./scripts/check.sh` (macOS/Linux) or `powershell -File scripts/check.ps1` (Windows).

## Maintainers
- Trigger the `build-jre` workflow (workflow dispatch) to build trimmed JRE archives for Linux (x86_64 + arm64), macOS (Intel + Apple Silicon), and Windows. Provide an optional `release_tag` to publish directly to a `jre-<version>` release.
- Use `python scripts/sync-jre-checksums.py combined-checksums.txt --write` to update `swain_cli/constants.py` (the `JRE_ASSETS` mapping) and update `ASSET_BASE` (or set `SWAIN_CLI_ASSET_BASE`) if you move assets to a new release tag.
- Tag releases (`git tag vX.Y.Z`) once assets are ready. The full release runbook lives in `docs/RELEASING.md`.

## Third-party notices
- OpenAPI Generator (Apache 2.0)
- Eclipse Temurin OpenJDK (GPLv2 with Classpath Exception)

## License
swain_cli is released under the Apache 2.0 license. See `LICENSE` for details.