diff --git a/pkgbuilds/tmog-bin/.omarchy/README.md b/pkgbuilds/tmog-bin/.omarchy/README.md new file mode 100644 index 0000000..9c862f3 --- /dev/null +++ b/pkgbuilds/tmog-bin/.omarchy/README.md @@ -0,0 +1,75 @@ +# tmog-bin - repackaging a vendor tarball from a versionless URL + +## Overview + +[TMOG](https://tmog.org/) is a Qt 6 system monitor from Plummers' Software LLC. +There is no source release, no AUR package, and the GitHub repository its +AppStream metadata names (`PlummersSoftwareLLC/TMOG`) is not public, so this +package repackages the vendor's own Linux tarball. + +## Why the tarball and not the AppImage + +Upstream publishes three Linux artifacts at the same version. The tarball is +7.9 MB and links against the system Qt; the AppImage is 55 MB because it carries +its own copy of Qt, which Omarchy already installs for the shell. The `.deb` +holds the same tree as the tarball under Debian's layout. The tarball is the +same binary at a seventh of the download, so that is what this builds from. + +Its layout is already FHS-shaped (`bin/`, `share/applications`, `share/icons`, +`share/metainfo`), so `package()` is a copy rather than a reconstruction. Only +the licence texts move: upstream files them under `share/doc/`, which is +Debian's convention, and on Arch they belong in `share/licenses/`. + +## Before this ships publicly + +The beta licence in `share/doc/taskmanagerog/copyright` says: + +> You may not sell, sublicense, publicly redistribute, or represent the +> software as your own. + +Building this package on pkgs.omarchy.org and serving it to users is public +redistribution, so the package needs Plummers' Software's permission before it +is published, not merely a working build. The same file also describes itself as +"a release-candidate document [that] must be approved by the publisher before +public distribution", so the terms themselves may still move. + +Nothing in the packaging depends on the answer -- it is a question for the +publisher, and it is recorded here so it is not mistaken for settled. + +## The versionless download URL + +Every TMOG release is served from one path: + +```text +https://tmog.org/downloads/TMOG-Task-Manager-Linux-x86_64.tar.gz +``` + +Nothing in it identifies a version, and `downloads/release.json` -- the manifest +the macOS updater verifies -- describes the DMG only. So the Linux side has no +manifest to read a checksum out of, and `.omarchy/upstream.sh` computes one from +the artifact. That download is 7.9 MB and happens only when `/version.txt` +reports something other than the checked-in `pkgver`, so the six-hourly check +normally costs a single small request. + +Two details follow from the path being mutable: + +- **The `?v=-free` query string** in `source=()` is upstream's own + cache key; tmog.org appends it to its Linux download links for the same + reason, so a CDN holding an older object under this path cannot answer for a + new release. +- **The hook checks the tarball's top-level directory**, which upstream names + `TaskManagerOG--linux-x86_64`. It is the only evidence available that + the bytes that arrived are the release `/version.txt` announced. On a mismatch + the hook reports no update and leaves the package alone, which is the right + answer whether the cause is a half-published release or a stale object. + +`sha256sums` is reported under the key `any` rather than `x86_64`: upstream +publishes no aarch64 build, so the package has one plain `source=()` array, and +`any` is `bin/sync-upstream`'s name for the unsuffixed checksum array. + +## Testing + +```bash +bin/sync-upstream tmog-bin +bin/repo build --package tmog-bin +``` diff --git a/pkgbuilds/tmog-bin/.omarchy/package.json b/pkgbuilds/tmog-bin/.omarchy/package.json new file mode 100644 index 0000000..2a9719d --- /dev/null +++ b/pkgbuilds/tmog-bin/.omarchy/package.json @@ -0,0 +1,3 @@ +{ + "source": "local" +} diff --git a/pkgbuilds/tmog-bin/.omarchy/upstream.sh b/pkgbuilds/tmog-bin/.omarchy/upstream.sh new file mode 100755 index 0000000..4635f63 --- /dev/null +++ b/pkgbuilds/tmog-bin/.omarchy/upstream.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# TMOG publishes no manifest for its Linux builds -- release.json describes the +# macOS DMG only -- so the version comes from /version.txt and the checksum has +# to be computed from the artifact itself. That is 8 MB, and only when the +# version has actually moved, so the six-hourly check normally costs one tiny +# request. +# +# The download path carries no version, which makes it worth proving that what +# arrived is what was announced: the tarball's top-level directory is named for +# the release, and a mismatch means the object served is not the one +# /version.txt describes. Reporting no update leaves the checked-in package +# alone and lets the next run try again, which is the right answer whether the +# cause is a half-published release or a stale CDN object. +set -euo pipefail + +BASE_URL="https://tmog.org" + +current=$(grep -m1 '^pkgver=' PKGBUILD | cut -d= -f2- | tr -d "\"'") + +version=$(curl -fsSL "$BASE_URL/version.txt" | tr -d '[:space:]') +if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Unusable version from $BASE_URL/version.txt: '$version'" >&2 + exit 1 +fi + +if [[ $version == "$current" ]]; then + echo '{}' + exit 0 +fi + +tarball=$(mktemp) +trap 'rm -f "$tarball"' EXIT + +curl -fsSL -o "$tarball" \ + "$BASE_URL/downloads/TMOG-Task-Manager-Linux-x86_64.tar.gz?v=${version}-free" + +# Every entry is listed rather than just the first: `head -1` would close the +# pipe under `tar` and take the whole hook down with SIGPIPE, and reading them +# all also catches a tarball that unpacks more than one top-level directory. +expected_dir="TaskManagerOG-${version}-linux-x86_64" +served_dir=$(tar tzf "$tarball" | cut -d/ -f1 | sort -u) +if [[ $served_dir != "$expected_dir" ]]; then + echo "Download holds $served_dir, but /version.txt announced $version; skipping" >&2 + echo '{}' + exit 0 +fi + +# "any" is bin/sync-upstream's name for the unsuffixed sha256sums array, which +# is the one this package has: upstream publishes x86_64 alone, so there is a +# single plain source=() rather than per-architecture arrays. +jq -n \ + --arg pkgver "$version" \ + --arg sha256 "$(sha256sum "$tarball" | cut -d' ' -f1)" \ + '{pkgver: $pkgver, sha256sums: {any: [$sha256]}}' diff --git a/pkgbuilds/tmog-bin/PKGBUILD b/pkgbuilds/tmog-bin/PKGBUILD new file mode 100644 index 0000000..9856cb4 --- /dev/null +++ b/pkgbuilds/tmog-bin/PKGBUILD @@ -0,0 +1,71 @@ +# Maintainer: David Heinemeier Hansson + +# TMOG publishes no source and no AUR package, so this repackages the vendor's +# Linux tarball. That tarball is 8 MB against the system Qt, where the AppImage +# is 55 MB of bundled Qt -- the same binary, minus a second copy of what +# Omarchy already installs. +# +# The download URL carries no version: tmog.org serves every release from the +# same path. .omarchy/upstream.sh rewrites the pkgver and sha256 below when +# /version.txt moves, and checks the tarball's own directory name to be sure +# the mutable URL really served the version it announced. + +pkgname=tmog-bin +pkgver=0.1.1 +pkgrel=1 +pkgdesc="Native system monitor and task manager" +arch=('x86_64') +url="https://tmog.org/" +license=('LicenseRef-proprietary') + +depends=( + 'gcc-libs' + 'glibc' + 'hicolor-icon-theme' + 'qt6-base' + 'qt6-multimedia' + 'qt6-svg' + # Omarchy is a Wayland desktop, so the Wayland platform plugin is what this + # actually runs on; without it Qt falls back to xcb under XWayland. + 'qt6-wayland' + 'systemd-libs' +) + +provides=('tmog') +conflicts=('tmog') + +# Upstream ships a stripped release build and no debug symbols to split out. +options=('!debug' '!strip') + +_srcdir="TaskManagerOG-${pkgver}-linux-x86_64" + +# The query string is upstream's own cache key -- tmog.org appends it to the +# Linux links for the same reason, so a CDN holding an older object under this +# mutable path cannot answer for a new release. +source=("${pkgname}-${pkgver}.tar.gz::${url}downloads/TMOG-Task-Manager-Linux-x86_64.tar.gz?v=${pkgver}-free") +sha256sums=('4d319d3d27f513e83801daeec8eb64cb78ddec1f6483bbe90d57d11e607af39d') + +package() { + cd "${_srcdir}" + + install -Dm755 bin/tmog-task-manager "${pkgdir}/usr/bin/tmog-task-manager" + + install -Dm644 share/applications/com.tmog.taskmanager.desktop \ + "${pkgdir}/usr/share/applications/com.tmog.taskmanager.desktop" + install -Dm644 share/metainfo/com.tmog.taskmanager.metainfo.xml \ + "${pkgdir}/usr/share/metainfo/com.tmog.taskmanager.metainfo.xml" + install -Dm644 share/pixmaps/tmog-task-manager.png \ + "${pkgdir}/usr/share/pixmaps/tmog-task-manager.png" + + local icon + for icon in share/icons/hicolor/*/apps/tmog-task-manager.png; do + install -Dm644 "$icon" "${pkgdir}/usr/${icon}" + done + + # Upstream files its licence texts under share/doc, which is Debian's layout. + # On Arch they belong with the package's licences. + local doc + for doc in share/doc/tmog/* share/doc/taskmanagerog/copyright; do + install -Dm644 "$doc" "${pkgdir}/usr/share/licenses/${pkgname}/${doc##*/}" + done +}