diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1f86442 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "contrib/homebrew"] + path = contrib/homebrew + url = https://tildeforge.dev/beefcarver/homebrew diff --git a/aur/README.md b/aur/README.md deleted file mode 100644 index b095b30..0000000 --- a/aur/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# AUR packaging for beefy-player - -An AUR repository holds exactly two tracked files, `PKGBUILD` and `.SRCINFO`. -This directory is the staging area for both; the rest of the project is -irrelevant to the AUR. - -## Build it locally - -```bash -cd aur -makepkg -si # build, run the test suite, install -``` - -`makepkg -o && makepkg -e` skips the download/checksum phase, and -`extra-x86_64-build` (devtools) builds in a clean chroot. The package builds -with `base-devel` plus the `makedepends`/`checkdepends` listed in the -`PKGBUILD`; every dependency comes from the official repositories, none from -the AUR. - -## Publish to the AUR - -```bash -git clone ssh://aur@aur.archlinux.org/beefy-player.git /tmp/aur-beefy-player -cp PKGBUILD .SRCINFO /tmp/aur-beefy-player/ -cd /tmp/aur-beefy-player -git add PKGBUILD .SRCINFO -git commit -m "Initial import: beefy-player 1.2.2-1" -git push -``` - -## Releasing a new version - -1. Set `pkgver` in `PKGBUILD` and `pyproject.toml`, and reset `pkgrel=1`. -2. Point `_commit` at the commit carrying that version: - - ```bash - git rev-parse HEAD # or the tag, once one exists - ``` - -3. Refresh the checksum: - - ```bash - curl -fsSL "https://tildeforge.dev/beefcarver/beefy-player/archive/$_commit.tar.gz" | sha256sum - ``` - -4. Regenerate the metadata (on Arch, or inside a chroot): - - ```bash - makepkg --printsrcinfo > .SRCINFO - ``` - -5. Push to the AUR with the conventional commit message: - - ```bash - git commit -am "upgpkg: beefy-player -" - ``` - -## Why the source is a commit archive - -Upstream publishes no tags or releases, so the checksum in `sha256sums` -belongs to the archive of a specific commit rather than of a `v$pkgver` tag. -Forge archives of a commit are deterministic, so the checksum stays stable. -Once `v$pkgver` is tagged, replace the `source` line with - -```bash -source=("$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz") -``` - -## Packaging notes - -- The wheel is built with `hatchling`; `theme.tcss` is force-included by - `pyproject.toml`, so it ends up in `site-packages/beefy_player/`. -- `check()` runs the real test suite. It is offline by design (station - catalogues are fixtures and `mpv`/`parec` are faked), which makes it safe in - a build chroot with no network. -- `mpv`, `ffmpeg`, `libpulse` (`parec`/`pactl`) and `tmux` are `optdepends`, - not `depends`: the player degrades gracefully without them and says so in - the UI. Users who want sound need `mpv` (or `ffmpeg` for `ffplay`) and, for - the output-synced spectrum, `libpulse`. -- `license=('WTFPL')` is an SPDX identifier shipped by Arch's `licenses` - package. diff --git a/aur/.SRCINFO b/contrib/aur/.SRCINFO similarity index 100% rename from aur/.SRCINFO rename to contrib/aur/.SRCINFO diff --git a/aur/PKGBUILD b/contrib/aur/PKGBUILD similarity index 100% rename from aur/PKGBUILD rename to contrib/aur/PKGBUILD diff --git a/contrib/homebrew b/contrib/homebrew new file mode 160000 index 0000000..ad6fcc5 --- /dev/null +++ b/contrib/homebrew @@ -0,0 +1 @@ +Subproject commit ad6fcc5732623dddfb55d17765ddbf0b743096b5 diff --git a/homebrew/Formula/b/beefy-player.rb b/homebrew/Formula/b/beefy-player.rb deleted file mode 100644 index c74d86c..0000000 --- a/homebrew/Formula/b/beefy-player.rb +++ /dev/null @@ -1,51 +0,0 @@ -class BeefyPlayer < Formula - include Language::Python::Virtualenv - - desc "Terminal player for internet radio with a live spectrum analyser" - homepage "https://tildeforge.dev/beefcarver/beefy-player" - url "https://tildeforge.dev/beefcarver/beefy-player/releases/download/v1.2.2/beefy-player-1.2.2.tar.gz" - sha256 "0000000000000000000000000000000000000000000000000000000000000000" # TODO: release asset - license "WTFPL" - head "https://tildeforge.dev/beefcarver/beefy-player.git", branch: "main" - - depends_on "python@3.14" - - # numpy and pillow are large native builds. Depending on Homebrew's own - # formulae (which have bottles) keeps them out of the app's virtualenv build; - # the venv sees them through system site-packages. - depends_on "numpy" - depends_on "pillow" - - # Runtime tools the app shells out to: mpv for audio, ffmpeg for the stream - # decode fallback of the spectrum analyser. Both are optional at runtime -- - # the UI degrades gracefully -- but a radio player without them is not much fun. - depends_on "ffmpeg" - depends_on "mpv" - - # Tells `brew update-python-resources` what to resolve: numpy/pillow come from - # the formulae above, and dbus-next is marker-gated to Linux upstream so it - # has to be requested explicitly for the Linux side of the tap. - pypi_packages exclude_packages: "numpy,pillow", extra_packages: "dbus-next" - - def install - # system_site_packages is the default, so the excluded numpy/pillow from the - # formulae are importable from the virtualenv. - virtualenv_install_with_resources - end - - def caveats - <<~EOS - The spectrum analyser follows what you hear. On macOS 14.2+ grant your - terminal permission under System Settings > Privacy & Security > System - Audio Recording, otherwise it falls back to decoding the stream. - - Inside tmux, install `tmux` for image passthrough. - EOS - end - - test do - assert_match version.to_s, shell_output("#{bin}/beefy-player --version") - # --offline keeps the test hermetic: cached or bundled stations only. - assert_match(/^# /, shell_output("#{bin}/beefy-player --offline --list")) - end -end diff --git a/homebrew/README.md b/homebrew/README.md deleted file mode 100644 index ffac788..0000000 --- a/homebrew/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# Homebrew packaging for beefy-player - -A Homebrew **tap** is just a second git repository that Homebrew clones next to -homebrew/core. There is no central submission, no review and no binary host: -`brew` reads the Ruby formula from the tap, downloads the pinned source tarball -and installs it on the user's machine. - -This directory is the staging area for the tap repository, which lives at -**https://tildeforge.dev/beefcarver/homebrew-tap** (repo name `homebrew-tap`, so -the tap name is `beefcarver/tap`). - -Because Homebrew's one-argument `brew tap` assumes GitHub, a Forgejo tap has to -be tapped with its URL, and Homebrew 6+ also wants an explicit trust. - -## Install (user side) - -```bash -brew tap beefcarver/tap https://tildeforge.dev/beefcarver/homebrew-tap -brew trust --formula beefcarver/tap/beefy-player -brew install beefcarver/tap/beefy-player -``` - -`brew update` refreshes the tap from then on; `brew upgrade` picks up new -versions like any core formula. If the tap is mirrored to GitHub later, -`brew install beefcarver/tap/beefy-player` becomes a one-liner, because that -form auto-taps from GitHub and trusts only the formula it installs. - -## Publishing the tap (maintainer side) - -### 1. One tag per release, with a release asset - -The formula pins a stable URL plus a SHA-256, so it needs an immutable tarball. -Do **not** point it at Forgejo's `/archive/v$VERSION.tar.gz` URL: those archives -are generated on demand and are not guaranteed byte-stable. Attach a tarball to -the release instead (Forgejo serves it at `/releases/download//`): - -```bash -VERSION=$(uv run python -c 'import beefy_player; print(beefy_player.__version__)') -git archive --format=tar.gz --prefix="beefy-player-$VERSION/" \ - -o "beefy-player-$VERSION.tar.gz" "v$VERSION" -sha256sum "beefy-player-$VERSION.tar.gz" -``` - -Create the tag on the mirror (`git push tildeforge "v$VERSION"`), upload the -tarball to the `v$VERSION` release, then paste the URL and checksum into -`Formula/b/beefy-player.rb`. - -### 2. Resolve the Python resources - -Every Python dependency (and its recursive dependencies) that is not provided by -another formula must be declared as a `resource` so Homebrew installs with -dependency resolution disabled. Never write these by hand: - -```bash -brew tap beefcarver/tap /path/to/homebrew-tap # local clone, or the URL -brew update-python-resources --print-only beefcarver/tap/beefy-player -brew update-python-resources beefcarver/tap/beefy-player -``` - -`pypi_packages exclude_packages: "numpy,pillow"` keeps the two native builds out -of the resource list — they come from the `numpy`/`pillow` formulae, which ship -bottles, and the virtualenv picks them up through system site-packages. -`extra_packages: "dbus-next"` makes sure the Linux-only dependency is recorded -even though the resolver runs on macOS. - -In a third-party tap, `--ignore-errors` records anything that cannot be resolved -and leaves a `RESOURCE-ERROR` comment; the official taps do not allow that, a -personal one does. - -### 3. Build, test and audit locally - -```bash -brew install --build-from-source beefcarver/tap/beefy-player -brew test beefcarver/tap/beefy-player -brew audit --strict beefcarver/tap/beefy-player -brew style beefcarver/tap/beefy-player -``` - -The formula's `test do` block runs `--version` and `--offline --list`, so it -needs no network and no audio device. - -### 4. Push - -```bash -git add Formula/b/beefy-player.rb && git commit -m 'beefy-player 1.2.2' && git push -``` - -## Version bumps - -For each release: tag, upload the tarball, update `url`/`sha256`, rerun -`brew update-python-resources` (only needed when the dependency set or pins -changed), install from source, test, push. `brew bump-formula-pr` only works -against GitHub-hosted taps, so on Forgejo the bump is a `sed` plus a re-test. - -Optional `livecheck` support, so `brew livecheck --tap beefcarver/tap` can spot -new tags: - -```ruby -livecheck do - url "https://tildeforge.dev/beefcarver/beefy-player/tags" - regex(/^v?(\d+(?:\.\d+)+)$/i) -end -``` - -## Bottles (optional) - -Without a `bottle do` block users build from source — for this app that means -filling a virtualenv with pure-Python resources while `numpy`, `pillow`, `mpv` -and `ffmpeg` arrive as bottles, so it is quick. Prebuilt bottles need Homebrew's -GitHub Actions workflows, which cannot run on Forgejo; skip them unless the tap -is also mirrored to GitHub. - -## Why a tap and not homebrew-core - -homebrew-core requires a tagged, immutable source URL and enough notability to -be accepted at all (roughly 75+ stars / 30+ forks, or coverage that makes a -project notable). A tap has none of those constraints, which is why upstream -taps are the normal route for a project this size. The formula here follows -core's conventions, so it could be submitted there later unchanged if the -project qualifies.