Skip to content

feat(apps): snap backend — plan operations, execution, detection, facade wiring - #21

Merged
hmziqagent merged 8 commits into
masterfrom
feat/snap-backend
Oct 12, 2026
Merged

hmziqagent merged 8 commits into
masterfrom
feat/snap-backend

Conversation

@hmziqagent

Copy link
Copy Markdown
Collaborator

Adds Snap as a backend in toride-apps, end to end except registry routing.

Planner. Operation::SnapInstall { name, channel }, SnapUninstall, and SnapUpdate render snap install [--channel=<track>/<risk>[/branch]], snap remove, and snap refresh. There is no InstallMethod::Snap yet (snapcraft.io source data is a later registry round), so snap operations are constructed at the operation seam — the argv contract is the same as every routed method's.

SnapBackend (backends/snap.rs) executes them through the shared CommandRunner:

  • detect() is a PATH check — no command runs.
  • version() reads the snap <version> client row from snap version.
  • install/remove/refresh follow snapd's real idempotency: the bare exit-0 "already installed" / "not installed" notices are successes; everything else (error: with exit 1, snapd unreachable, unknown snap) surfaces as Error::Command carrying snapd's stderr.
  • list/status/outdated parse snapd's tabwriter tables (two-or-more-space separators, - placeholders). A malformed row is skipped, never fatal to the listing; a non-empty document where nothing parses is treated as unparseable output, not an empty host.

Detection and facade. MultiSourceDetector gains a DetectionSource::Snap probe over the installed listing. AppsBuilder grows a snap slot plus auto-attach, records carry NativeIds::Snap { name } so uninstall and update replay snap remove / snap refresh from the recorded name alone, and status routes snap through the recorded/foreign presence seams, async and sync.

Snap-less hosts. An absent snap binary makes detect() return BinaryNotFound, which the builder skips like any other missing manager — nothing errors, snap installs answer BackendUnavailable, and status never probes the slot.

Tests. Offline suites pin argv, table parsing, and the facade flows (adopt / update / uninstall) against strict FakeRunner fakes with tabwriter-shaped fixtures. tests/live.rs, gated behind TORIDE_APPS_INTEGRATION, exercises detect() and the read-only version / list / per-snap status probes against the real host, branching on whether snap exists — no mutating command anywhere.

Gates: test, fmt, clippy, doc, workspace-check — all pass.

@hmziqagent
hmziqagent merged commit 72e5193 into master Oct 12, 2026
13 checks passed
@hmziqrs
hmziqrs deleted the feat/snap-backend branch October 12, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant