Debian Package Tracker
Register | Log in
Subscribe

moraine

snapshot backup over SSH/rsync and rclone (CLI + GTK desktop app)

Choose email to subscribe with

general
  • source: moraine (main)
  • version: 0.2.2-1
  • maintainer: Jonaz Thern (DMD)
  • arch: any
  • std-ver: 4.7.4
  • VCS: Git (Browse, QA)
versions [more versions can be listed by madison] [old versions available from snapshot.debian.org]
[pool directory]
  • testing: 0.2.2-1
  • unstable: 0.2.2-1
versioned links
  • 0.2.2-1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
binaries
  • moraine
action needed
29 new commits since last upload, is it time to release? normal
vcswatch reports that this package seems to have new commits in its VCS but has not yet updated debian/changelog. You should consider updating the Debian changelog and uploading this new version into the archive.

Here are the relevant commit logs:
commit 1ad8c869279ae9eba311b64f1288ae722c18de4d
Author: TheJonaz <44526342+TheJonaz@users.noreply.github.com>
Date:   Sat Aug 8 20:15:42 2026 +0200

    macOS installer, OpenBSD/NetBSD ports, and a native arm64 AppImage (#7)
    
    * recommend: extend the suggestion manifest to the BSDs
    
    The curated MANIFEST was #[cfg(target_os = "linux")], so FreeBSD, OpenBSD and
    NetBSD — all of which have (or will have) ports — fell through to the empty
    fallback: `moraine recommend` built, installed and shipped, then answered
    "nothing to suggest". A BSD desktop is the same XDG layout, the same ~/.config,
    the same Firefox/Thunderbird dot-directories, so it is one manifest, not four.
    
    A typo in a target_os string still compiles, so a new test asserts the manifest
    is non-empty on whatever platform it runs — a ports/pkgsrc builder's `make test`
    now checks its own platform.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * packaging: OpenBSD ports + NetBSD pkgsrc recipes, generated off-BSD
    
    Both trees build Rust offline from a per-crate list plus a checksum file in a
    tree- and OS-specific encoding, normally produced on the target OS. Everything
    they compute is a property of bytes on crates.io, so bsd-distinfo.py does it
    here: it reads the crate list from the Cargo.lock inside the *tagged tarball*
    (never the working tree, which drifts after a release) and verifies every
    downloaded .crate against the SHA-256 Cargo.lock already records before taking
    any other digest — a wrong file cannot reach the output.
    
    Both recipes are CLI-only: OpenBSD's WANTLIB for a CLI is correct by
    construction, whereas a GTK4 WANTLIB needs a real OpenBSD build; NetBSD follows
    for symmetry (adding the GUI later is one buildlink3 include).
    
    check-crate-lists.py now covers both lists, and bump-recipes.sh skips them in
    its blanket version sed — their distinfo carries a per-crate hash, so a sed
    would rewrite a crate sitting at the old version and leave every hash stale;
    they are regenerated instead.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * packaging: universal macOS installer (.pkg) for the CLI
    
    build-pkg.sh produces moraine-<version>-macos-universal.pkg: a standard installer
    that drops the moraine CLI into /usr/local/bin (plus man page and docs). The
    binary is universal — arm64 + x86_64 lipo'd together — so one package covers
    Apple Silicon and Intel, and the script fails loudly if the result is not
    actually fat.
    
    A .pkg, not a .dmg: the macOS build is CLI-only (bundling GTK4 into a .app is
    separate work), and a disk image holding a bare executable teaches the user
    nothing about where it goes. Built --features keyring (native Keychain, no extra
    runtime dep) so `password = "keyring:"` works out of the box, which the plain
    --no-default-features tarball does not — a deliberate, documented difference.
    
    Unsigned: proper signing needs the 99 USD/yr Apple Developer Program plus two
    certificates. README.md documents the three ways past Gatekeeper meanwhile.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * appimage: build the aarch64 AppImage natively too
    
    linuxdeploy bundles the host's GTK, so an AppImage's architecture is whatever
    machine builds it — there is no cross-compiling this. GitHub's ubuntu-24.04-arm
    runners are free for public repos and are the same 24.04 base, so the glibc 2.39
    floor (forced by GTK >= 4.10 / features = ["v4_10"]) applies to aarch64
    unchanged. Raspberry Pi / ARM-server desktops get the GUI as one portable file,
    matching what x86_64 already ships.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * ci: build the macOS installer + native arm64 AppImage on release
    
    Adds a macos-pkg job (universal .pkg via packaging/macos/build-pkg.sh, smoke-
    tested with `installer` + `--version` + `man -w`) and turns the appimage job
    into a matrix over ubuntu-24.04 and ubuntu-24.04-arm, so both AppImage
    architectures are built natively and their arch is asserted before upload.
    
    Also fixes a latent gap: the checksums job hashes whatever is attached when it
    runs, so every asset-uploading job must be in its `needs`. macos-pkg was
    missing, which would have raced the .pkg out of SHA256SUMS on a real release.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * ci: push-triggered test-build for the two off-workstation artifacts
    
    The macOS .pkg and the aarch64 AppImage are the only release artifacts that
    cannot be produced on the Linux workstation, so they had never actually been
    built. This branch-scoped workflow builds just those two (as workflow
    artifacts, no Release, no recipe bump, main untouched) to prove the recipes
    before they reach a real tag. Push-triggered because a workflow_dispatch is
    only exposed once the file lives on the default branch. Remove before merging.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * macos: make optional signing safe under set -u on bash 3.2
    
    `productbuild "${sign[@]}"` with an empty `sign` array aborts with
    "sign[@]: unbound variable" on macOS's /bin/bash (3.2), where expanding an
    empty array under `set -u` is an error rather than the empty string newer bash
    produces. This broke every unsigned build — i.e. the default path in CI — after
    the universal binary and pkgbuild had already succeeded. Use the portable
    ${sign[@]+"${sign[@]}"} idiom. Caught by the test-build CI run.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * appimage: fix the aarch64 arch assertion in the smoke test
    
    `file -b` prints the arch token twice for the aarch64 binary — once in the ELF
    header ("ARM aarch64") and once in the interpreter path
    ("ld-linux-aarch64.so.1") — so `grep -o` returned two lines and the
    string-equality check against a single "aarch64" always failed. Assert the
    expected token is present (grep -qw) instead. This was latent in release.yml
    too: the aarch64 AppImage had never been built, so its leg had never run.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    * ci: drop the throwaway test-build workflow
    
    It did its job: the macOS .pkg and the aarch64 AppImage built green (run
    31211710777) and the two release-breakers it surfaced are fixed. The real jobs
    live in release.yml, so this branch-scoped harness is no longer needed.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

commit 10d03e816bd3f48c62d3accb38f0f4aea908f9e3
Author: TheJonaz <44526342+TheJonaz@users.noreply.github.com>
Date:   Wed Aug 5 22:27:29 2026 +0200

    ci: stop vendor apt repositories from failing our builds (#6)
    
    The lint job on 4d74fc6 died at "Install GTK" with exit 100, on a commit that
    changed a .gitignore, a README, a nuspec and a Python script — nothing a Rust
    build can see. `apt-get update` had returned 403 for
    packages.microsoft.com/repos/azure-cli and .../ubuntu/24.04/prod, both
    configured by the runner image, neither of any use to a job installing
    libgtk-4-dev from Ubuntu's archive.
    
    That is the whole failure mode: apt-get update exits non-zero if *any*
    configured source fails, so an outage at a vendor we do not depend on takes down
    a build that would otherwise be green. Re-running fixed it, which is exactly what
    makes it worth fixing properly — a red main that clears on retry teaches the
    habit of retrying, and the next real breakage gets the same shrug.
    
    The five apt steps across three workflows now go through a composite action that
    drops those sources first. It selects them by what they point at rather than by
    filename, because the filenames move between image versions: anything not
    mentioning ubuntu.com goes. That keeps archive.ubuntu.com, azure.archive on the
    x86 images and ports.ubuntu.com on the arm64 runner flatpak-aarch64.yml uses,
    and removes the Microsoft and Google entries.
    
    Should a future image name Ubuntu's own archive something that does not match,
    the failure is a loud "Unable to locate package", not a silent skip.
    
    Verified: the selection logic was run against a directory holding the three
    vendor lists plus both Ubuntu layouts (deb822 azure.archive and ports) — the
    three go, both Ubuntu sources stay. All four YAML files parse, and no apt-get
    call site is left unconverted. ci.yml's own run on this PR exercises the action
    for real; release.yml and flatpak-aarch64.yml do not run on pull requests, so
    their two call sites are checked by inspection only.
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 4d74fc639f085e25287adb786898c894bf223d8e
Author: TheJonaz <44526342+TheJonaz@users.noreply.github.com>
Date:   Wed Aug 5 22:05:09 2026 +0200

    chocolatey: build the package on Linux, and pin an icon (#5)
    
    The recipe has been complete since 0.1.x and never submitted, for a practical
    reason: `choco pack` runs on Windows only, and the only machine here is a Mint
    host. That made the last roadmap channel depend on borrowing a Windows box.
    
    It does not have to. A .nupkg is an OPC container — a zip holding the nuspec,
    the payload, and three bookkeeping parts (`[Content_Types].xml`, `_rels/.rels`
    and a `.psmdcp` core-properties part) that NuGet clients require. build-nupkg.py
    writes those directly, so the package builds anywhere Python does. Its structure
    was compared part by part against a real package from nuget.org; the part names,
    relationship types and content-type defaults match. The output is reproducible —
    identical sha256 across rebuilds — so what was pushed stays checkable later.
    
    This is safe here specifically because the payload is a downloader script rather
    than compiled artefacts: nothing about the build host can end up in the package.
    A Windows host is still the only way to *test* `choco install`, which is also
    what Chocolatey's own verifier does on submission.
    
    Pushing needs no choco either: the endpoint is a plain NuGet PUT with the API
    key in X-NuGet-ApiKey, which curl does. Both routes are in the README.
    
    Verified against the actual v0.2.2 release rather than assumed: the Windows zip
    contains moraine-windows-x86_64/moraine.exe, matching what the shim comment in
    chocolateyinstall.ps1 claims, and the SHA-256 pinned there matches both
    SHA256SUMS and the downloaded file.
    
    Also adds <iconUrl>, whose absence moderators flag. It points at jsDelivr rather
    than raw.githubusercontent, which Chocolatey asks for, and is pinned to the
    release tag so the icon cannot change under an already-approved package. That
    pin is now in the per-release checklist, along with the two fields that were
    already there; the push example in the README still said 0.1.19.
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 005cb75a488f9d0fc14c63e15c13caaf26126443
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Wed Aug 5 13:54:56 2026 +0200

    packaging: fail the release bump when the vendored crate lists are stale
    
    FreeBSD, Gentoo and Flatpak build offline from a hand-maintained list of every
    crates.io dependency. Nothing regenerates those lists, and bump-recipes.sh only
    printed a reminder at the very end that they had been left alone — after the
    commit, and easy to scroll past. A list that is missing a crate then fails
    solely on the distributions that build offline, long after the release, in a
    place the author has no reason to look.
    
    check-crate-lists.py parses all three formats — FreeBSD's `name-version`,
    Gentoo's `name@version`, Flatpak's crates.io URLs — and compares them against a
    Cargo.lock. bump-recipes.sh now runs it against the Cargo.lock taken from the
    *released tarball it already downloads*, not the working tree: the recipes are
    about to point at that tag, and the working tree is usually ahead of it.
    
    The check runs before anything is written, so a mismatch stops the bump outright
    rather than leaving the recipes half-edited. --skip-crate-check overrides it.
    
    Calibrated before being enforced: against v0.2.2's Cargo.lock all three lists
    match exactly — 157 crates.io dependencies, none missing, none stale — so strict
    equality is the right rule and will not cry wolf. Only `registry+` sources are
    compared; the root package and any path/git dependency is never vendored.
    
    Against main it reports 50 missing from each, which is the keyring work merged
    in f774f02. Worth noting the number: `cargo tree` on Linux shows 27 new crates,
    but Cargo.lock carries every platform's, so apple-native-keyring-store and
    windows-native-keyring-store and their transitive dependencies count too. Judging
    this by eye was never going to work.
    
    The lists are deliberately NOT regenerated here. The recipes still pin v0.2.2,
    whose Cargo.lock has none of these crates, so today's lists are correct for what
    they build; regenerating now would break the offline builds. That belongs to the
    next release bump — which is precisely what this check will insist on.
    
    Verified end to end against a copy of packaging/: a matching list lets the bump
    run, a single removed crate aborts it with the crate name and the regeneration
    command, no file is touched before the abort, and --skip-crate-check gets past
    it.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 920af2585258a7c1f705ac5abc41c4ec88c64ec8
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Tue Aug 4 23:00:35 2026 +0200

    ci: allow running the workflow on demand
    
    f774f02 reached main without any CI run: the squash-merge API call errored
    after updating the ref, so no push event was dispatched and
    `actions/runs?head_sha=f774f02c` returns zero. The tree was covered by the
    pull_request run on the identical commit, but there was no way to give main
    its own run short of pushing an empty commit.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit ea227a20e13eea310d604f4f11f7fa153e636986
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Tue Aug 4 22:56:06 2026 +0200

    snap: make it a classic CLI snap, and build it without snapd
    
    The recipe had never been built. Doing so turned up that its central claim was
    wrong: it declared `confinement: strict` and told users the `home`,
    `removable-media` and `ssh-keys` interfaces covered "the common case (back up
    your home + external drives)". They do not. The `home` interface grants
    "access to non-hidden files in the home directory" — snapd's rule is literally
    `owner @{HOME}/[^s.]** rwkl` — so every top-level dotfile is excluded. Six of
    the eleven locations `moraine recommend` offers on Linux are exactly those:
    ~/.config, ~/.mozilla, ~/.thunderbird, ~/.gitconfig, ~/.ssh, ~/.gnupg. The five
    that would have worked are re-downloadable media; the six that would not are
    the configuration and keys a backup exists for.
    
    `personal-files` cannot close the gap — it declares named paths and needs a
    store request per path, while the set here is whatever the user chooses — and
    scheduling writes to crontab, which strict confinement also denies. So the snap
    is now classic, with the reasoning in the yaml rather than in a README nobody
    reads at install time.
    
    Classic in turn rules out the GUI: the `gnome` extension only exists for strict
    confinement, so a GTK app under classic means bundling GTK 4 and patching rpath
    by hand. The desktop is already covered by the Flatpak, the AppImage and the
    .deb, so the snap ships the CLI alone — like the Homebrew and Scoop channels.
    
    Two things the first real build exposed. A classic snap runs with the host's
    environment and does *not* get $SNAP/usr/bin prepended the way a strict one
    does, so without an explicit PATH the bundled rsync/ssh/rclone would be dead
    weight and a host without rclone would simply fail. And the metadata linter
    wanted title/license/contact/issues/source-code/website, all of which the store
    listing needs anyway.
    
    build-in-docker.sh + Dockerfile.build make this buildable on a host that has no
    snapd and cannot get it — Linux Mint ships /etc/apt/preferences.d/nosnap.pref,
    and snapd wants systemd, which a container has not got. The image unsquashes
    snapcraft, core24 and snapd into the absolute /snap/<name>/current paths their
    binaries are linked against and runs `snapcraft --destructive-mode` in place.
    The build tree is deliberately a mktemp outside the repository: snapcraft
    copies all of `source:` into parts/<part>/src, so a build directory inside the
    repo copies the repo into itself until the disk fills. --local stages tracked
    files only, since `target/` alone is 5 GB snapcraft would copy for nothing.
    
    Verified by building and unpacking the snap, not only by packing it: classic
    confinement in meta/snap.yaml, `moraine --version` runs from the payload, and a
    real backup to a local rclone target produces a timestamped snapshot that
    `moraine list` reads back — using the bundled rclone, rsync 3.2.7 and OpenSSH
    9.6p1. Note that Ubuntu 24.04's rclone is v1.60.1 (2022); everything Moraine
    calls predates it, but the ceiling is documented in the README.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit f774f02c8891313b963f4ebc9e3275107fb6c61b
Author: TheJonaz <44526342+TheJonaz@users.noreply.github.com>
Date:   Tue Aug 4 22:27:02 2026 +0200

    secrets: let a target's secrets live outside moraine.toml (#1)
    
    The config holds FTP passwords, SSH key passphrases and crypt_password — the
    key that decrypts the destination — in plaintext. Mode 0600 stops other users
    reading it, but not the ways secrets actually escape: a backup that happens to
    cover the home directory, a config pasted into a bug report, a repo commit.
    
    Each secret field now records *where* the secret is rather than necessarily
    being it: "hunter2" keeps it in the file as before, "env:VAR" reads an
    environment variable, "keyring:" reads the OS keyring, and "literal:..." covers
    a secret that would otherwise be read as one of those prefixes. The TOML keys
    are unchanged, so every 0.2.x config keeps working untouched and a config this
    build saves is still readable by an older one — pinned by a test in both
    directions, because the GUI writes the file back.
    
    Resolving is deliberately fallible and loud. Previously an unavailable secret
    could only be the empty string; with an external store that means handing
    rclone an empty passphrase and writing an *unencrypted* snapshot to a
    destination the user believes is encrypted. askpass_env and env_for return
    Result for that reason, and a build without keyring support refuses to run
    rather than silently degrading. The fields were renamed to *_spec behind
    #[serde(rename)] so the compiler enumerated all 30 read sites instead of
    leaving one to fail silently.
    
    Three ways to move a secret: `moraine secrets migrate` for a whole config,
    `moraine secrets set` for one, and a Move to keyring button under each secret
    field in the GUI. All of them write to the keyring and read it back before
    repointing the config — the config is the only copy, so a keyring that accepts
    a write it cannot return would otherwise destroy the secret. `moraine secrets
    check` reports where each secret comes from without printing any, and
    `moraine verify` runs it before connecting; the message names cron explicitly,
    since a keyring that works in a desktop session usually is not reachable from
    a schedule.
    
    The GUI writes the account into the field (keyring:nas/password) instead of
    letting it be derived from the target name. Names are editable per keystroke
    there, and a derived account would stop resolving the moment a target was
    renamed — surfacing only at the next scheduled backup.
    
    Settings -> Export config now resolves secrets before encrypting, or the export
    would be a set of pointers meaning nothing on another machine. The plaintext
    goes to gpg on stdin and never touches disk; the passphrase goes in a 0600 file
    in the per-user tmpfs and is removed immediately, including when gpg fails.
    Import puts the secrets back in the keyring, falling back to leaving them in
    the config — and saying so — if it is unreachable.
    
    `gui` implies `keyring`: a machine running a GTK app has the desktop session a
    Secret Service needs, while --no-default-features stays clean for servers and
    cron. That adds 27 crates to the GUI packages, all pure Rust — the zbus store
    shares the one ksni already pulls in, so no libdbus — but the OBS tarball needs
    re-vendoring and the FreeBSD port's CARGO_CRATES an update.
    
    Also fixes a secret with leading or trailing whitespace being trimmed, which
    turns a working config into an authentication failure that looks exactly like a
    wrong password.
    
    Verified against a real Secret Service, not just in tests: a local rclone
    target with crypt_password = "keyring:" backs up with filenames and contents
    encrypted on disk, and list/check read it back. Removing the keyring entry
    stops the run with an actionable error and leaves the destination untouched.
    Clicking the GUI button through to `moraine secrets check` reading the result
    caught a bug no type check could — the refresh clearing the entry fired the
    changed handler, which wrote the empty string over the pointer just before
    saving, so the secret reached the keyring but the config lost its way back to
    it. Renaming the target afterwards still resolves. Clippy is clean and the
    tests pass across all five feature combinations; two integration tests touch
    the real keyring and are #[ignore]d so CI never does.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 015dd3cdd877e98895ebebaf564182f0cd2ddfb6
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Mon Aug 3 19:12:41 2026 +0200

    alpine: use the maintainer= variable and shorten pkgdesc
    
    Both from Hoang Nguyen's review on aports MR !106248. The pkgdesc loses its
    "(CLI + GTK desktop app)" tail — users can work that out — and the
    # Maintainer:/# Contributor: comments become the maintainer= variable aports
    is migrating to (alpine/tsc#109; abuild never parsed # Contributor at all).
    packaging/alpine/ tracks what is on the MR, so it moves with it.
    
    Verified in an Alpine edge container before pushing: apkbuild-lint clean,
    abuild -r builds moraine and moraine-doc in 4m16s. The MR pipeline is now
    green on all nine Alpine architectures, riscv64 included.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 09bbdeedc111a703d3f74dfe274f6ea503fc2b18
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Mon Aug 3 14:57:22 2026 +0200

    appimage: build it in CI and ship it through the CDN
    
    The recipe existed but had never been built. Doing so turned up that its own
    advice was impossible: it says to build on Ubuntu 22.04 for portability, but
    moraine builds gtk4-rs with features = ["v4_10"] and 22.04 ships GTK 4.6.
    24.04 is the oldest base that can work, which fixes the glibc floor at 2.39 —
    Ubuntu 24.04+, Debian 13+, Fedora 40+ and the rolling distros. Older systems
    keep the Flatpak (own runtime, no floor) and the .deb, so nothing is lost, but
    the CI job must stay pinned to ubuntu-24.04: moving it to ubuntu-latest would
    silently raise the floor and drop working distros.
    
    The job smoke-tests what it built — extracts the AppImage, runs the bundled
    CLI, and requires AppRun to reach "Failed to open display". That is the line
    between a complete bundle and one that dies on a loader error at a user's
    machine. Verified by hand on Ubuntu 24.04 (glibc 2.39) and Arch (2.43); the
    GUI renders under Xvfb with its icons and assets resolved out of the bundle.
    
    checksums gains appimage in `needs`: it downloads the whole release and hashes
    it, so a job finishing later is silently absent from SHA256SUMS.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 68a716655e622cff32d75d8c09711fd4f4430dc7
Author: Jonaz Thern <44526342+TheJonaz@users.noreply.github.com>
Date:   Mon Aug 3 14:37:49 2026 +0200

    gentoo: publish from our own overlay, and make the GUI optional
    
    GURU is an official Gentoo project and is bound by Gentoo's AI policy,
    which forbids AI-assisted contributions — so neither GURU nor ::gentoo can
    take this ebuild. It ships from TheJonaz/moraine-overlay instead, added
    with `eselect repository add`. packaging/gentoo/ stays the source of truth;
    the overlay gets a copy per release.
    
    The ebuild gains +gui: gui-libs/gtk:4 is a hard dependency only with
    USE=gui, and the desktop entry, icons and runtime assets install only then.
    USE=-gui pulls 5 packages instead of 152 and installs the CLI alone, which
    is what a backup tool on a headless server wants. cargo_src_configure does
    NOT add --no-default-features on its own (it maps myfeatures to --features
    and forwards "$@"), so the CLI-only path passes it explicitly — the comment
    claiming otherwise, and that myfeatures=( gui ) had dropped the tray icon,
    was wrong.
    
    Verified in a stage3 container against the published overlay: eselect
    repository add + emaint sync + emerge installs and runs 0.2.2, and pkgcheck
    scan is clean — confirmed meaningful by scanning a deliberately broken copy
    alongside, which reports three findings.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit ef095aeca051a31981ae4a32716d2d647e4a151c
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 20:50:54 2026 +0200

    flatpak(aarch64): install elfutils explicitly
    
    flatpak-builder only *recommends* elfutils, so --no-install-recommends
    left the runner without eu-strip. The job compiled rsync in full and then
    died on the debuginfo step of the very first module.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit da456603b628e8db39de700eee595c8af7b2e7ca
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 20:47:41 2026 +0200

    flatpak: build aarch64 too
    
    The rclone module fetched the linux-amd64 zip unconditionally, so an
    aarch64 build would have installed an x86-64 binary. The build succeeds
    either way — every rclone backend would just die with "Exec format error"
    the first time a user ran one. Gate the two archives with only-arches.
    (The amd64 checksum already matched rclone's published SHA256SUMS; the
    arm64 one is taken from the same file.)
    
    aarch64 is built by a new workflow on ubuntu-24.04-arm — GitHub's ARM
    runners are free for public repos and release.yml already uses them, and
    emulating a Rust release build on the x86-64 workstation is measured in
    hours. It cannot push to the CDN (the firewall drops runner IPs, which is
    why every other channel is pull-based), so it attaches a single-file
    bundle to the release; flatpak-release.sh imports it next to the x86_64
    build. The job installs the bundle and asserts uname -m before uploading,
    because a wrong-arch bundle installs cleanly and only fails in use.
    
    x86_64 rebuilt after the change: identical output, rclone still x86-64.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit edc9a5c96cd26d12d9e3e00b26e1461323d3d96c
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 20:30:57 2026 +0200

    style: apply rustfmt
    
    CI's `cargo fmt --all --check` was failing on code from the recommender
    and arch-aware-update commits. Those sat unpushed for a while, so CI only
    ran on them once the whole batch went up.
    
    No behaviour change: rustfmt output only, clippy and the 41 tests pass.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 842478b1e5bdbec1b4781fd7854450548e92f9f3
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 20:25:09 2026 +0200

    gui: say in the feedback dialog that the IP address is stored
    
    The form records the submitter's IP so abuse can be traced. That is a
    deliberate choice, but it was not stated anywhere the sender could see it.
    Say it in the dialog, next to the other things the report attaches.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 916f20ba80bf9c2353c943e6e31cd4a75316a6d5
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 20:15:01 2026 +0200

    flatpak: fix the stale commit pin, the stale crate list and the tray
    
    The manifest could not build. Three things had gone stale since the
    Flathub attempt in July:
    
    - `commit:` pinned 47e5b6f — that is **v0.1.19** — under `tag: v0.2.2`.
      flatpak-builder checks the tag against the commit and fails, which is
      the only reason this was ever noticed.
    - cargo-sources.json was missing 44 crates: the whole ksni/zbus/async
      stack the `tray` feature pulled in after the file was generated. The
      build is `cargo --offline`, so it would have failed on the first
      missing crate.
    - the tray was compiled in (it is a default feature) but had no D-Bus
      access, so it could never have appeared inside the sandbox. Grant
      --talk-name=org.kde.StatusNotifierWatcher. ksni's own well-known name
      cannot be granted — flatpak only accepts a `.*` wildcard after a dot —
      so it falls back to its unique bus name, which the spec allows.
    
    Also take the metainfo from next to the manifest instead of from the git
    checkout. The release entry for X.Y.Z is written after X.Y.Z is tagged,
    so the copy inside the tag is always one release behind: the app reported
    0.2.1 to software centres while shipping 0.2.2.
    
    Built and installed from https://cdn.thern.io/flatpak with signature
    verification on; the CLI, GUI, and the bundled rsync/ssh/rclone all run.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit a113b8ce96985d8bd431f684fe6fc8710ca7bd98
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sun Aug 2 19:39:30 2026 +0200

    alpine: apply the aports review — cargo-auditable, arch=all, install -t
    
    Hoang Nguyen's review of aports!106248 raised four points:
    
    - arch was pinned to "x86_64 aarch64" for no technical reason; it was
      carried over from the arches our CI publishes binaries for. Alpine
      builds from source, and rust, cargo-auditable and gtk4.0 (4.22.4, well
      past the 4.10 the GUI needs) are present on all nine arches, so use
      arch="all" and let the builders narrow it if 32-bit ever OOMs.
    - build with cargo-auditable, as the other Rust aports do. That pulls in
      the rest of the idiom from community/ripgrep: fetch the crates in
      prepare() and build with --frozen, so the build needs no network and
      the aport does not have to set options="net".
    - drop --release from check() (aports work item 18294).
    - collapse the repeated install calls onto -t. The icons keep an explicit
      destination since they are renamed, but they fold into a loop.
    
    Built with abuild -r on Alpine 3.24.1 x86_64: builds clean, tests pass,
    and the packaged file list is byte-for-byte what it was before.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 42973f4278444c749817896489ab7d957f16ac1b
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 31 08:58:36 2026 +0200

    gentoo: fix the stale crate list and the dropped tray feature
    
    CRATES had the same staleness the FreeBSD port's CARGO_CRATES did: generated
    before the ksni/zbus tray work landed, so it listed 113 of the 157 crates in
    Cargo.lock and omitted ksni, zbus*, zvariant*, the async-* stack, rustix,
    tempfile and uuid. The build would have failed at unpack with
    
        error: no matching package named `ksni` found
    
    Regenerated with `pycargoebuild -i`, which also recomputes the dependent-crate
    LICENSE set from crate metadata rather than the hand-guessed list that was
    there. That tool needs the marker comment `# Dependent crate licenses` above
    LICENSE+=, so add it.
    
    Separately, `myfeatures=( gui )` was silently shipping a GUI with no tray icon.
    cargo.eclass appends --no-default-features as soon as myfeatures is non-empty,
    and the crate's default is ["gui", "tray"], so Gentoo alone would have dropped
    the StatusNotifierItem — with no build error to reveal it. Now ( gui tray ).
    
    Also install the 48px and 64px hicolor icons, which the AUR and Alpine recipes
    already ship and this one did not.
    
    Verified in a Gentoo stage3 container: full emerge of all 152 packages exits 0,
    `moraine --version` runs, and `strings` on the installed moraine-gui confirms
    the StatusNotifier code is compiled in.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 2a7f07d3fb0b3f4c46037cfb88aa3615ce1ccd42
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 31 08:58:23 2026 +0200

    alpine: ready the aport for submission to testing/
    
    Three changes aports requires of a new aport. A `# Contributor:` line
    alongside `# Maintainer:`; `url` pointing at the homepage rather than the
    GitHub repo, with the tarball URL spelled out in `source` instead of being
    interpolated from `url`; and `arch="x86_64 aarch64"`, since gtk4.0-dev, rust
    and cargo all exist on aarch64 in v3.24 and moraine already ships aarch64
    builds.
    
    Build-verified in an Alpine 3.24.1 VM: `abuild -r` clean in 4m07s, 37/37 tests
    pass, `apkbuild-lint` silent, and the GUI links against musl and GTK 4.22.4
    with nothing unresolved. Submitted as testing/moraine.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit bc8f3956e337ab1d7701cc3269dd3f17a5b43251
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Mon Jul 27 20:26:03 2026 +0200

    aur: allow aarch64
    
    makepkg builds from source and nothing in the package is architecture-specific,
    so Arch Linux ARM users (Raspberry Pi and friends) can build it too. The
    x86_64-only arch line was refusing them for no reason.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit d7bd92f56afd0999411de8e2aef1377e46a3f605
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Mon Jul 27 18:49:10 2026 +0200

    gui: offer updates for the running CPU architecture, and ship arm64 builds
    
    The in-app updater picked its download by OS only: every Linux branch spelled
    x86_64/amd64, and pick_asset() fell back to `-linux-x86_64.tar.gz`
    unconditionally. On arm64 — a Raspberry Pi, an ARM server — that offered a
    binary the machine cannot execute.
    
    Asset names now carry the running architecture, with the spelling each format
    uses (dpkg says arm64 where rpm/pacman/tarballs say aarch64), and an
    architecture with no published build resolves to None so the caller reports
    "no downloadable build for this platform" instead. Same fix for an Intel Mac,
    which was being offered the Apple-silicon tarball.
    
    Release CI gains a native linux/arm64 job on GitHub's free ARM runner, so
    aarch64 users get a tarball and a .deb rather than having to compile; the .deb
    name is now driven by the matrix instead of a hardcoded amd64.
    
    The matching half is split into match_asset() so the tests don't shell out to
    dpkg/rpm/pacman — probing those took 86s per run.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit 2650e7c4499fa361dfc100f560878c9f7549498a
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Mon Jul 27 00:42:14 2026 +0200

    freebsd: fix the stale crate list, add distinfo, build-verify the port
    
    CARGO_CRATES had been generated before the ksni/zbus tray work landed, so it
    was missing 44 crates (ksni, zbus*, zvariant*, the async-* stack, rustix,
    tempfile, uuid, …). The port failed at configure with
    
        error: no matching package named `ksni` found
    
    because the vendored cargo-crates directory didn't contain them. Regenerated
    with `make cargo-crates`: 113 -> 156 crates. Same staleness the Flatpak
    cargo-sources.json had.
    
    Also check in `distinfo` (hashes for the tarball + all 156 crates) so the port
    is submittable as-is, reflow pkg-descr under 80 columns (portlint), and write
    up the two traps that cost the most time: match the ports tree to your pkg set
    (quarterly branch, else lang/rust gets built from source) and regenerate both
    generated lists on a version bump.
    
    Verified on FreeBSD 15.1-RELEASE: make install succeeds from a clean tree,
    check-plist reports no issues, and both binaries run (moraine 0.2.2).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit 130918febf5836b5b5d9ed67667f8f3f4d227df8
Merge: bdb6375 8da5e9f
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 24 21:56:51 2026 +0200

    Merge branch 'feature/recommender-gui'

commit bdb6375126ed3b370f99f342101e65e930e57470
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 24 21:56:34 2026 +0200

    docs: refresh the README screenshot to the current UI, size down the logo
    
    The README screenshot was still the v0.1.0 shot from the initial commit (4
    tabs, old layout). Replace it with a current v0.2.2 capture (6 tabs, themed
    UI). Also constrain the header logo to a fixed 80px width via an <img> tag —
    as bare markdown the icon rendered oversized.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit 8da5e9f138fab556525992f9b47261f3c9b3cb5e
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 24 16:51:35 2026 +0200

    gui: "What should I back up?" — wire the OS-aware recommender into the app
    
    The recommender (moraine::recommend) was CLI-only. Add a "✨ Suggest sources"
    button to the Quick Backup targets panel that opens a dialog: it scans this
    machine (recommend::scan), lists the found locations grouped by category with a
    checkbox each, flags credential-bearing paths as "sensitive" with an encryption
    note, and turns the ticked picks into a ready-made target (recommend::
    suggested_target) with sensible excludes — leaving host/dest as placeholders to
    fill in. Verified end to end in the running GTK app.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit d25f312db39a0368e1f636cf1c492c87b7d5d0d3
Merge: acdbff5 5d92576
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Fri Jul 24 16:43:34 2026 +0200

    Merge branch 'feature/recommender' into feature/recommender-gui

commit acdbff52d5fe813cdca1f02c09796dee951ab780
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Wed Jul 22 20:04:36 2026 +0200

    gui: drop a redundant borrow in a format! argument
    
    clippy::useless_borrows_in_formatting, new in Rust 1.97, has been failing
    CI since the ad-hoc-backups commit — seven releases with a red build. The
    code was always correct; the lint just wants the borrow gone.

commit 8e0cefbaf282b37104e34ef23b136138317eabae
Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Wed Jul 22 13:46:16 2026 +0000

    packaging: bump downstream recipes to v0.2.2

commit f16cbe55e96bb53696bb57379e03a61e41c97b85
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Wed Jul 22 15:42:26 2026 +0200

    debian: changelog 0.2.2-1 — the single initial-release entry now matches the release
    
    The 0.2.2 upload to mentors is built from this entry; keeping it in git is
    what prevents the packaging from drifting away from the repository again.

commit 5d925762431f6e8170691cf5838cb99da1781559
Author: Jonaz Thern <jonaz.thern@gmail.com>
Date:   Sat Jul 18 16:16:40 2026 +0200

    recommend: OS-aware "what should I back up?" helper
    
    Add `moraine recommend`: scans the machine for a curated, OS-specific set
    of important locations (documents, media, app settings, dev keys, mail)
    and prints them grouped, flagging credential-bearing paths as [sensitive]
    with a nudge to enable crypt_password. Emits a ready-to-paste [[target]]
    with sane default excludes; --write appends it to the config (preserving
    existing comments, owner-only, refusing duplicate names).
    
    Paths are `~`-relative templates so the same string drives both the
    existence check and the runtime source (no %APPDATA%/$XDG syntax moraine
    wouldn't expand). Manifest is a small per-OS table, easy to extend.
    
    Phase 1 of the feature (CLI + engine); GUI wizard to follow.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Created: 2026-08-09 Last update: 2026-08-13 20:02
AppStream hints: 1 warning for moraine normal
AppStream found metadata issues for packages:
  • moraine: 1 warning
You should get rid of them to provide more metadata about this software.
Created: 2026-08-10 Last update: 2026-08-10 04:30
news
[rss feed]
  • [2026-08-13] moraine 0.2.2-1 MIGRATED to testing (Debian testing watch)
  • [2026-08-09] Accepted moraine 0.2.2-1 (source amd64) into unstable (Debian FTP Masters) (signed by: Simon Quigley)
bugs [bug history graph]
  • all: 0
links
  • homepage
  • lintian
  • buildd: logs, reproducibility, cross
  • popcon
  • browse source code
  • other distros
  • debian patches
ubuntu Ubuntu logo [Information about Ubuntu for Debian Developers]
  • version: 0.2.2-1

Debian Package Tracker — Copyright 2013-2025 The Distro Tracker Developers
Report problems to the tracker.debian.org pseudo-package in the Debian BTS.
Documentation — Bugs — Git Repository — Contributing