ADR-2610080915: install with one command
Status: Accepted
Date: 2026-10-08
Drivers: The user asked for the easiest way for people to install Wardian, as a curl script, and
said "do it". Today a user needs Rust, a clone and cargo build. A test the same day showed the next
problem: wardian started in another folder looked for ./data there, could not write it, and found
no example apps.
Context#
scripts/package-macos.sh and scripts/package-linux.sh build a Wardian.app zip and a Linux
tarball. Their launchers (scripts/macos/Launcher.swift, scripts/linux/wardian-desktop) set
DATA_DIR to ~/Library/Application Support/Wardian or ~/.local/share/wardian and start the
server from the folder that holds the example apps. The plain wardian command does neither: its
data folder is ./data and its example apps are ./apps, both under the folder it starts in. No
GitHub Release has been published, and the repository is private.
Decision#
- The command finds its own folders. With no
DATA_DIR,wardianuses./datawhen it starts in a Wardian checkout (aCargo.tomlnaming thewardianpackage, besideapps/) or when./dataalready exists; otherwise the platform's folder:~/Library/Application Support/Wardianon macOS,$XDG_DATA_HOME/wardian(default~/.local/share/wardian) on Linux. It says which one at start (it already prints the full path, and refuses one it cannot write). - The command finds its example apps. For the first-start seeding, the source of example apps is,
in order:
./appsin a checkout;../share/wardian/appsbeside the program (the Linux layout);../Resources/appsbeside it (the macOS app). If none exists, the working folder starts empty. - Releases. A workflow
.github/workflows/release.ymlruns on a tagv*: it builds the four targets (macOS arm64 and x86_64; Linux x86_64 and aarch64, on native runners), packages each aswardian-<version>-<os>-<arch>.tar.gzholdingbin/wardianandshare/wardian/apps(the tracked example apps only), writesSHA256SUMS, and publishes a GitHub Release with them. install.sh. One POSIXshscript atscripts/install.sh, used ascurl -fsSL <url>/install.sh | sh. It finds the OS and CPU, downloads the matching tarball andSHA256SUMSfromWARDIAN_DOWNLOAD(default: the latest GitHub Release), refuses a file whose checksum does not match, and installs intoWARDIAN_PREFIX(default~/.local):bin/wardianandshare/wardian/apps, replacing an older copy by remove-then-copy. Nosudo. It installs a version given asWARDIAN_VERSION, or the latest. It ends by saying how to start Wardian and, if~/.local/binis not onPATH, the line to add. It never runs Wardian itself and never edits shell files.- Where users get it. The README's first section is the one line. The download address is one
setting (
WARDIAN_DOWNLOAD), so the files can move from GitHub to another host without a new script. While the repository is private, the default address works only for people with access; making the releases public is the owner's decision, not this ADR's.
Amended while implementing (2026-10-08): the example apps are installed in
lib/wardian/example-apps, not share/wardian/apps, and the rule in 2 looks for
../lib/wardian/example-apps. With the default prefix ~/.local, share/wardian is
~/.local/share/wardian, the Linux data folder itself: installing would replace the user's
working folder (apps/), and a data folder that is never empty never shows the first-run setup.
The tarball and install.sh (3, 4) and the Linux package use the same layout.
install.sh finds its tarball through SHA256SUMS, which lists one file per platform, so the
"latest" address needs no version and the tarballs keep the version in their names.
Consequences#
- A user installs with one line, then runs
wardianfrom anywhere and finds the example apps. - Running from a checkout behaves as before:
./dataand./apps. - A user who ran
wardianoutside a checkout before this change had a./datathere; it is still used, because it exists. - Each release costs four builds on GitHub's runners.
Implementation#
src/config.rs: the data folder and example-apps rules, as pure functions of what exists (tested with temporary folders);src/main.rsuses them..github/workflows/release.yml;scripts/install.sh;scripts/release-tarball.sh(builds one tarball, used by the workflow and by the test).- README (install first), CHANGELOG, SPEC.md only if it names
./data. tests/run-install-e2e.sh: builds a tarball, serves it andSHA256SUMSover a local HTTP server, runsinstall.shwithWARDIAN_DOWNLOADand a throwawayHOME/prefix, starts the installedwardianfrom an unrelated empty folder, and checks that it uses the platform data folder under thatHOME, seeds the five example apps, and answers/api/status; then checks that a tampered tarball is refused and nothing is installed.
Enforced-By: hexa adr gates (run on demand)#
Gate#
tests/run-install-e2e.sh
References#
- ADR-2610072033 (release basics), ADR-2610071122 (the working folder)
This page is docs/adrs/ADR-2610080915-install-with-one-command.md in the repository. Something wrong or missing? Change that file.