Building and Testing¶
Prerequisites¶
The devcontainer in .devcontainer/Containerfile installs everything needed. Outside it you need:
Rust 1.99.0 with
rustfmtandclippy. rust-toolchain.toml pins the version, sorustupinstalls it automatically.Node.js 22 or newer with npm, for the front end and the Tauri CLI.
The Tauri 2 system dependencies for your platform (WebKitGTK 4.1 and friends on Linux, WebView2 on Windows, Xcode command-line tools on macOS).
uv for the documentation site.
libvips (8.18 or newer, with HEIF support), LibRaw (0.22 or newer) and libheif development packages (ADR-0005).
An HEVC decoder plugin for libheif (libde265), needed to read HEIC photos. Many distributions omit it for patent reasons; on Fedora, install
libheif-freeworldfrom RPM Fusion. Check withheif-dec --list-decoders: libde265 must appear under HEIC decoders. On macOS:brew install vips libraw libheifandexport LIBRARY_PATH=$(brew --prefix)/lib.Network access on the first build:
ortdownloads a prebuilt ONNX Runtime for the target fromcdn.pyke.io(checksummed) and caches it in~/.cache/ort.pyke.io. On Linux it bringslibwebgpu_dawn.so, which Cargo copies next to the binaries; they find it there ($ORIGINrun path). There are no prebuilt binaries for Intel macOS.On Windows (Git Bash, with the Visual Studio C++ build tools): run
scripts/setup-windows-libvips.shonce. It downloads the official libvips build for Windows (with LibRaw and libheif, checksum checked) intotarget/libvips-windows, prepares the import libraries the build links and copies the DLLs totarget/windows-runtime. It prints twoexportlines (the linker path andPATH, so tests find the DLLs); run them in the shell you build from.
After cloning, install the front-end dependencies once:
make ui-deps
Note
The devcontainer has no display. The desktop window cannot be opened there; the UI is developed in a browser against the development server (ADR-0010).
Workspace layout¶
Cargo.toml workspace manifest: shared versions, lints
crates/core/ picturesque-core domain, no I/O
crates/app/ picturesque-app use cases and ports
crates/infra/ picturesque-infra adapters (SQLite, decoding, ...)
crates/devserver/ picturesque-devserver development HTTP transport
src-tauri/ picturesque-desktop Tauri 2 shell
ui/ Svelte 5 + TypeScript front end (Vite)
package.json npm workspace root; holds the Tauri CLI
docs/ this site (Sphinx, uv project)
See Components for the layer rules.
Make targets¶
The Makefile is the entry point for everyday tasks.
Target |
What it does |
|---|---|
|
Format Rust code with |
|
Fail if any Rust file is not formatted. |
|
Run |
|
Run unit, integration and doc tests for the whole workspace. |
|
Build every workspace target. |
|
Build Rust API docs; warnings are errors. |
|
Install front-end dependencies from |
|
Front end: |
|
|
|
Run the UI in a browser against the development server (Running the UI in a Browser). Works in the devcontainer. |
|
Playwright end-to-end tests in headless Chromium. |
|
Run the tests (which regenerate the TypeScript API types) and fail
if |
|
Run the desktop app with hot reload ( |
|
Build the desktop app and smoke-test it on Xvfb (Smoke test of the real app). |
|
Build the installers for the current OS; |
|
Remove Rust and documentation build output. |
|
Build, preview or strictly check the documentation (Documentation). |
Lints¶
Lint levels are set once in [workspace.lints] in Cargo.toml.
unsafe_code is denied workspace-wide, and picturesque-core and
picturesque-app forbid it outright. Suppress a lint only on the
narrowest item, with #[expect(..., reason = "...")].
Front end¶
The UI lives in ui/ and is a plain Vite single-page app (no SvelteKit).
Code reaches the backend only through ui/src/lib/api; components never
call Tauri directly, so the same UI runs in a browser against the
development server (Running the UI in a Browser). API types come from
ui/src/lib/api/generated/, generated from Rust
(see Command API).
Front-end commands run from the repository root through the npm workspace:
npm run dev -w ui # Vite dev server on http://127.0.0.1:5173
npm run test -w ui # Vitest
npm run check -w ui # svelte-check
Dependency versions¶
TypeScript stays on 6.0 until
typescript-eslintandsvelte-checksupport TypeScript 7.New dependencies should be releases that are at least two weeks old, unless a newer release fixes a security advisory. With npm:
npm install --before=<date two weeks ago> ....The
@tauri-apps/apiand@tauri-apps/clinpm packages must have the same major and minor version as thetauricrate.
RAW corpus tests¶
Some infrastructure tests run against real camera files from raw.pixls.us (16 cameras, about 630 MB). They are ignored by default. Fetch the corpus once, then run them explicitly:
python3 -I spikes/decoding/scripts/fetch_corpus.py
cargo test -p picturesque-infra -- --ignored
Small fixtures that are committed (for example exif.heic) are
described in crates/infra/tests/fixtures/README.md.