Metadata-Version: 2.4
Name: alusta
Version: 2026.6.28
Summary: Detect the current platform: OS family, flavor, and CPU architecture.
Author-email: Stefan Hagen <stefan@hagen.link>
Maintainer-email: Stefan Hagen <stefan@hagen.link>
License-Expression: MIT
Project-URL: Documentation, https://codes.dilettant.life/docs/alusta
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0.3
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# alusta

Platform (Finnish: alusta) - detect the current platform: OS family, flavor, and CPU architecture.

Reports results as human-readable text, JSON, or shell export statements.
An embedded DSL lets scripts assert platform constraints and branch on the result via exit code alone.

Requires Python 3.11 or later.

## Install

```
pip install alusta
```

## Manual

The [man page](docs/alusta.1) provides the CLI reference (`man alusta` after placing the file on your `MANPATH`)

To use `man alusta`, copy `docs/alusta.1` to a directory on your `MANPATH`, for example:


```sh
mkdir -p ~/.local/share/man/man1
cp docs/alusta.1 ~/.local/share/man/man1/
```

## Quickstart

Run `alusta` with no arguments for a compact plain-text summary:

```sh
$ alusta
family=linux
flavor=linux
arch=x86_64
  distro=ubuntu
```

For a dedicated feature walkthrough you can follow in minutes visit [quickstart](quickstart/README.md).
A step-by-step guided build of a running registry is provided in the [tutorial](tutorial/README.md).

## Output formats

### JSON

`--json` prints a schema-validated JSON document, pretty-printed by default.
`--compact` collapses it to a single line; `--pretty` makes the default explicit.

```sh
alusta --json
alusta --json --compact
```

### Shell export

`--export` prints POSIX `export` statements for `eval`:

```sh
eval $(alusta --export)
echo $ALUSTA_FAMILY   # linux
echo $ALUSTA_FLAVOR   # linux
echo $ALUSTA_ARCH     # x86_64
```

Detail keys are uppercased and prefixed with `ALUSTA_`; hyphens in key names become underscores.

## Detection signals

`--explain` augments the output with the raw signals used to determine the platform —
file contents, environment variables, and syscall results.
Works with both plain text and `--json`.

## Assertions

`--assert EXPR` evaluates a DSL expression against the detected platform.
Exits 0 if the expression is true, 1 if false, 2 on a parse or semantic error.

```sh
alusta --assert "family=linux"
alusta --assert "family=linux and arch=x86_64"
alusta --assert "flavor in (linux, wsl)"
alusta --assert "flavor=wsl and detail.wsl_version=2"
alusta --assert "family not in (windows, macos)"
```

Add `--quiet` to suppress all output and rely on the exit code alone:

```sh
if alusta --quiet --assert "family=linux"; then
    echo "on Linux"
fi
```

### DSL reference

Fields: `family`, `flavor`, `arch`, `detail.KEY`.

Operators:

- `field = value` or `field == value` — equality
- `field != value` — inequality
- `field in (v1, v2, ...)` — membership
- `field not in (v1, v2, ...)` — non-membership
- `not expr` — logical negation
- `expr and expr` — logical conjunction (lower precedence than `not`)
- `expr or expr` — logical disjunction (lower precedence than `and`)
- `(expr)` — grouping

Values are unquoted words composed of alphanumerics and `_`, `-`, `.`.
Whitespace around operators is ignored.

## Single-field output

`--field NAME` prints the value of one field and exits:

```sh
alusta --field family          # linux
alusta --field arch            # x86_64
alusta --field detail.distro   # ubuntu
```

Combine with `--json` to receive the value as a JSON-encoded scalar.
Exits 1 if `detail.KEY` is requested but absent on this platform.

## JSON schema

`--schema` prints the embedded JSON schema for the output document.

## Platforms and detail keys

| Family    | Flavor    | Detail keys                                           |
|:----------|:----------|:------------------------------------------------------|
| `linux`   | `linux`   | `distro`, `distro_version`                            |
| `linux`   | `wsl`     | `wsl_version`, `wsl_name`, `distro`, `distro_version` |
| `windows` | `windows` | `windows_version`                                     |
| `windows` | `msys`    | `msystem`                                             |
| `windows` | `cygwin`  | —                                                     |
| `macos`   | `macos`   | `macos_version`                                       |

Detail keys are omitted when not available on the current system.

## Exit codes

- `0` — success; for `--assert`, the expression is true; for `--field`, the key was found and printed.
- `1` — for `--assert`, the expression is false; for `--field`, `detail.KEY` is absent on this platform.
- `2` — error: unknown flag, invalid `--assert` expression, or JSON schema validation failure.

## Python API

`alusta` exposes its detection and assertion logic as a library:

```python
from alusta import detect, evaluate, validate

info = detect()
print(info.family, info.flavor, info.arch)
print(info.detail)    # dict of flavor-specific keys, may be empty
print(info.signals)   # raw detection signals used to determine the platform

result = evaluate("family=linux and arch=x86_64", info)  # True or False

errors = validate({"family": info.family, "flavor": info.flavor, "arch": info.arch})
# empty list means valid
```

`detect()` accepts keyword-only injection arguments for deterministic testing:
`_sys_platform`, `_machine`, `_environ`, `_proc_version`, `_os_release`, `_mac_ver`, `_win_ver`.

## Design and requirements

| Document                            | Identifier  | File                                            |
|:------------------------------------|:------------|:------------------------------------------------|
| Software Requirements Specification | ALU-SRS-001 | [requirements/srs/](requirements/srs/README.md) |
| Software Design Description         | ALU-SDD-001 | [design/sdd/](design/sdd/README.md)             |

Both documents follow the MIL-STD-498 DID structure and are rendered into
the documentation site alongside the quickstart and tutorial.

## Bug Tracker

Any feature requests or bug reports shall go to the [todos of alusta](https://todo.sr.ht/~sthagen/alusta).

## Primary Source repository

The main source of `alusta` is on a mountain in Central Switzerland under
configuration control ([fossil](https://fossil-scm.org/)).

## Contributions

If you like to share small changes under the repositories license please kindly
do so by sending a patchset.
You can send such a patchset per email using [git send-email](https://git-send-email.io).

## Support

Please kindly submit issues at https://todo.sr.ht/~sthagen/alusta or write plain
text email to ~sthagen/alusta@lists.sr.ht to support.
Thanks.

## Changes

See `docs/changes.md` for the release history.

## Coverage

The test suite maintains 100% branch coverage.
The HTML report (if generated) is in `site/coverage/`.

## SBOM

Runtime dependency information is published in `docs/sbom/` in SPDX 3.0 (JSON-LD)
and CycloneDX 1.6 (JSON) formats.
See `docs/sbom/README.md` for the component inventory and validation guide.
