Skip to content

Building from Source

melonfleet edited this page Oct 10, 2026 · 4 revisions

Building from source

macOS

Apple silicon, macOS 26, Swift 6.2 or newer.

swift build
swift test          # 335 tests; uses captured fixtures, does not need `container`
swift run Flotilla

There is no Xcode project. The app builds as the Flotilla SwiftPM executable. An Xcode project becomes necessary when app-bundle metadata, signing and distribution need it, and that migration is not documented as done because it is not.

To get a real app bundle:

Scripts/make-app.sh              # bundle id, Info.plist, icons, version stamping, ad-hoc signature
Scripts/make-app.sh --menubar    # flips LSUIElement, for testing menu-bar-only mode

With container installed, the probe exercises the live JSON surface:

swift run flotilla-probe

Linux

Swift 6.1. SwiftPM selects Package@swift-6.1.swift, which exposes only the Foundation-only core, the probe and the tests.

swift build
swift test

FlotillaCore is kept free of SwiftUI, AppKit and every other Apple-only framework on purpose, so core and data work stays independently verifiable off a Mac. Do not add Apple-only imports to it — that breaks the build that provides the verification.

This is not theoretical. A concurrency bug in the process runner was only reproducible on Linux: the drain scheduled on a global dispatch queue never ran, and both output streams came back empty and marked truncated. It was fixed by using dedicated threads. Running it on Linux is what found it.

The invariant checks

Some things the compiler cannot check are enforced by script. Each exists because it already went wrong once, and each has been proved to fail by planting the defect it looks for.

Script What it refuses
Scripts/check-settings-consumers.sh a setting marked available that no code reads
Scripts/check-defaults.sh a screenshot scaffold or wrong @State default reaching a build
Scripts/check-test-isolation.sh a test that passes only because another ran first
Scripts/check-hygiene.sh real identity, credentials or key files in tracked files
Scripts/check-history.sh the same, anywhere in the history — run before publishing

The first two run as part of make-app.sh, so a build cannot package a known-bad state.

check-hygiene.sh derives the names it looks for from the host at runtime rather than storing them, so it checks your identity rather than someone else's — and does not itself contain the thing it protects.

Fixtures

Capture them from the real CLI. Never write one.

A hand-written volumes.json once matched the models instead of reality. The real payload nests under configuration/status, so one decoder read only id and another threw the moment a real volume existed — with a green test suite throughout.

If a fixture for a failure mode is needed, capture its exit code too, not just its output. A scripted failure that returns exit 0 tests a path the CLI never produces.

Clone this wiki locally