Files
latchd/docs/development.md
Zane Walker f2a885d621 refactor: split the TUI and refresh project docs
Move login state, authentication, discovery, input, rendering, and tests into focused TUI modules. Add detailed CLI error reports with recovery commands, align the build and host-check documentation, and keep the legacy Go tree outside normal builds.

Checks: make check; make integration-test; go test ./... (legacy/go).
2026-10-05 21:37:15 +05:30

4.1 KiB

Development and release

This page lists the commands to build, test, and package latchd. The service configuration is /etc/latchd/config.toml.

Toolchain

Install Rustup with Rust 1.88, then install the native packages used by the PAM link step:

sudo apt-get install build-essential pkg-config libpam0g-dev libpam-modules

Keep Cargo.lock with dependency changes.

Build commands

Command Result
make deps Checks Cargo, rustfmt, pkg-config, and the PAM development files
make build Builds the optimized binary and copies it to build/latchd
make run-preview Builds the binary and opens preview mode
make version Prints version, commit, epoch, and target metadata
make package Creates a deterministic archive and SHA-256 file in dist/
make clean Removes build/, dist/, and Cargo build output

make build reads the version from Cargo.toml, embeds the current commit, and uses SOURCE_DATE_EPOCH for repeatable package metadata. Set VERSION, TARGET, or SOURCE_DATE_EPOCH when you need a different release value.

Build for another Rust target with:

make build TARGET=x86_64-unknown-linux-gnu

The target toolchain and system libraries must already be installed.

Test commands

Run the fast checks before the host checks:

make fmt
make test
make lint
make doc
make integration-test

make check runs the first four commands together. The integration script uses preview mode and checks metadata, configuration validation, preflight, and safe CLI paths.

Run the optional security audit after you install the tool:

cargo install cargo-audit --locked
make audit

The Go prototype has its own opt-in checks:

make legacy-check
make legacy-build

The release build never calls these targets.

Docker check

make docker-test builds Dockerfile.test as latchd-test:local. The image installs the PAM development files, Xvfb, and xauth, then runs formatting, workspace tests, Clippy, rustdoc, a release build, the CLI script, the capability probe, and the disposable PAM fixture.

The container checks build, test, preview, and fixture paths. Run the host checks in a disposable VM when you need a real VT, user session, compositor, or systemd-logind seat.

Remove the local image after a test run if you need the space:

docker image rm latchd-test:local

PAM fixture

make pam-fixture-test must run as root because it writes temporary files below /etc/pam.d/. The script uses unique service names, runs the ignored Rust fixture tests, and removes the files in its exit trap.

The fixture checks authentication failure, password-change failure, selected session metadata, and environment values returned by the session module.

Host checks

Use make system-e2e to inspect the binary, PAM library, faillock helper, VT device, Xvfb, Wayland socket, and systemd-logind.

Use the strict form only in a disposable VM:

make system-e2e-strict

The VM needs a test policy, a real VT, a working logind seat, and the X11 or Wayland stack under test. See End-to-end testing for the setup and limits.

Release archive

Run the release gates before packaging:

make check
make audit
make integration-test
make docker-test
make package

make package stages the binary, configuration, login policy, systemd unit, README, license, changelog, and build metadata. It sorts the archive, sets a fixed owner and timestamp, then writes the archive checksum and dist/release.env.

GitLab CI runs the verification and Docker jobs on branch and merge-request pipelines. A tag that matches the SemVer rule runs the package and release jobs. The package job checks that the tag version matches Cargo.toml before it creates the artifact.

Repository changes

Keep Rust source under the workspace crates, keep host scripts in scripts/, and put sample service files in extra/. Add tests beside the behavior they cover, update the changelog with the implementation detail and the user-visible result, then run git diff --check before you commit.