concat, concat-bin, concat-git: new packages

Concat (https://github.com/jub0t/Concat) is a Tauri 2 shell around a Rust
video engine, sold as a CapCut replacement. The project is mid-rename: the
binary, the desktop entry, the icons and the .deb asset all still say
WolfCut, so the packages install upstream's paths unchanged and add a
/usr/bin/concat symlink.

Upstream stages a static ffmpeg/ffprobe pair (180 MB) and whisper-cli
inside its bundle so the app runs on a machine with nothing installed.
Both lookups fall back to PATH, so concat-bin drops those two directories
and the source packages set WOLFCUT_SYSTEM_TOOLS=1 - the switch upstream
put in build.rs for exactly this case - leaving ffmpeg and whisper-cpp to
Arch. That is 17 MB installed instead of 225 MB.

!lto is not optional: makepkg's lto puts -flto=auto into CFLAGS, and ring
compiles hand-written assembly through cc, which then comes out as bitcode
and links to nothing.

sherpa-onnx-sys ships no C++ build; its build script downloads a prebuilt
static-lib archive. concat lists that archive as a checksummed source and
points the build script at it, with the version read out of upstream's
Cargo.lock by pkg.sh. concat-git cannot pin it - the version moves with
main - so there the build script fetches it.

Every upstream release is a v<version>-alpha.<n> prerelease published on a
push to main, several a day, and the release list is ordered by creation
rather than by version, so the newest is picked by publication date.

Only concat-git is published for now; concat and concat-bin are held back
with AUR_PUBLISH=false until that cadence has been lived with.
This commit is contained in:
Felitendo committed 2026-08-31 13:56:56 +02:00
1 parent 9b97159b72
commit a9c122584a
10 files changed
+624

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
pkgbase = concat-bin
pkgdesc = Free and open-source CapCut replacement, a Tauri video editor with a Rust engine (upstream binary)
pkgver = 0.2.0alpha.15
pkgrel = 1
url = https://github.com/jub0t/Concat
arch = x86_64
license = MPL-2.0
depends = webkit2gtk-4.1
depends = gtk3
depends = glib2
depends = libsoup3
depends = gdk-pixbuf2
depends = cairo
depends = dbus
depends = glib-networking
depends = alsa-lib
depends = ffmpeg
depends = gcc-libs
depends = glibc
depends = hicolor-icon-theme
optdepends = whisper-cpp: on-device auto-captions and transcription
optdepends = vulkan-icd-loader: Vulkan compositor backend
optdepends = libglvnd: OpenGL compositor backend
provides = concat
conflicts = concat
noextract = concat-bin-0.2.0alpha.15.deb
options = !strip
options = !debug
source = concat-bin-0.2.0alpha.15.deb::https://github.com/jub0t/Concat/releases/download/v0.2.0-alpha.15/WolfCut_0.2.0_amd64.deb
source = LICENSE-0.2.0alpha.15::https://raw.githubusercontent.com/jub0t/Concat/v0.2.0-alpha.15/LICENSE
sha256sums = 1faae2cd2203d3eaeb4b280e1f773e5dbe4be9eb31a485c4b9a9d3fd31e049e4
sha256sums = 66a3107d5ad6a058aab753eaac2047ccb2ed0e39465dd0fe5844da3e300d5172
pkgname = concat-bin
+74
View File
@@ -0,0 +1,74 @@
# Maintainer: Felitendo
# This PKGBUILD is updated automatically:
# https://github.com/Felitendo/PKGBUILDS
pkgname=concat-bin
pkgver=0.2.0alpha.15
pkgrel=1
pkgdesc="Free and open-source CapCut replacement, a Tauri video editor with a Rust engine (upstream binary)"
arch=('x86_64')
url="https://github.com/jub0t/Concat"
license=('MPL-2.0')
# What the binary links against, plus what it reaches for at run time:
# glib-networking is the webview's TLS backend, and the ffmpeg pair is
# spawned by every media operation - see the resources note in package().
# The model downloads carry their own TLS (rustls), so openssl is not needed.
depends=('webkit2gtk-4.1' 'gtk3' 'glib2' 'libsoup3' 'gdk-pixbuf2' 'cairo'
'dbus' 'glib-networking' 'alsa-lib' 'ffmpeg' 'gcc-libs' 'glibc'
'hicolor-icon-theme')
# wgpu picks its backend at run time: Vulkan first, GL as the fallback. Both
# loaders come from the driver stack every desktop already has, so neither is
# a hard dependency of the editor.
optdepends=('whisper-cpp: on-device auto-captions and transcription'
'vulkan-icd-loader: Vulkan compositor backend'
'libglvnd: OpenGL compositor backend')
provides=('concat')
conflicts=('concat')
options=('!strip' '!debug')
# Upstream has no stable release yet. The build workflow publishes a
# v<version>-alpha.<n> prerelease for every green push to main, so /latest is
# empty and the newest versioned release is picked by publication date; see
# pkg.sh. The asset name carries tauri.conf.json's version rather than the
# tag (every alpha of 0.2.0 ships WolfCut_0.2.0_amd64.deb), so it is resolved
# through the GitHub API and synced here along with the checksums.
#
# pkgver drops the hyphens from the tag (v0.2.0-alpha.15 -> 0.2.0alpha.15).
# pacman sorts that older than a later plain 0.2.0 (`vercmp 0.2.0alpha.15
# 0.2.0` is -1, the trailing alphabetic segment loses), so the prereleases
# upgrade to the eventual stable release on their own and no epoch is needed.
_tag="v0.2.0-alpha.15"
_asset="WolfCut_0.2.0_amd64.deb"
source=("${pkgname}-${pkgver}.deb::https://github.com/jub0t/Concat/releases/download/${_tag}/${_asset}"
"LICENSE-${pkgver}::https://raw.githubusercontent.com/jub0t/Concat/${_tag}/LICENSE")
noextract=("${pkgname}-${pkgver}.deb")
sha256sums=('1faae2cd2203d3eaeb4b280e1f773e5dbe4be9eb31a485c4b9a9d3fd31e049e4' '66a3107d5ad6a058aab753eaac2047ccb2ed0e39465dd0fe5844da3e300d5172')
package() {
# /usr/bin/wolfcut-desktop, the desktop entry, the icons and the staged
# resources in /usr/lib/WolfCut - the project is mid-rename, the binary and
# every path it installs still carry the old name.
bsdtar -xOf "$srcdir/${pkgname}-${pkgver}.deb" 'data.tar.*' \
| bsdtar -xpf - -C "$pkgdir" ./usr
# Upstream stages a static ffmpeg/ffprobe pair (180 MB) and whisper-cli
# inside the bundle so the app runs on a machine with nothing installed.
# Both lookups fall back to PATH when the staged copy is missing (desktop
# `use_bundled_ffmpeg`, `transcribe::find_binary`), so the packaged Arch
# copies are used instead of shipping a second ffmpeg. Named explicitly
# rather than dropping the whole resource directory: anything else upstream
# stages there is a resource the app needs, and a rename fails here loudly.
rm -r "$pkgdir/usr/lib/WolfCut/ffmpeg" "$pkgdir/usr/lib/WolfCut/whisper"
rmdir --ignore-fail-on-non-empty "$pkgdir/usr/lib/WolfCut" "$pkgdir/usr/lib"
# Tauri emits the entry with an empty Categories=, which keeps the editor
# out of the application menu. Same categories upstream's Nix build sets.
sed -i 's|^Categories=.*|Categories=AudioVideo;AudioVideoEditing;|' \
"$pkgdir/usr/share/applications/WolfCut.desktop"
# the AUR package is named after the project, the executable after what the
# project used to be called - keep it reachable under both
ln -s wolfcut-desktop "$pkgdir/usr/bin/concat"
install -Dm644 "$srcdir/LICENSE-${pkgver}" \
"$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}
+79
View File
@@ -0,0 +1,79 @@
# concat-bin - Concat (https://github.com/jub0t/Concat), a free and
# open-source CapCut replacement: a Tauri 2 shell around a Rust video engine.
#
# Upstream publishes a Linux .deb per release, so there is no build step
# here: on a new version only pkgver, the asset name and the checksums are
# refreshed and the PKGBUILD repackages the .deb.
#
# The project has no stable release yet. Its build workflow publishes a
# "v<version>-alpha.<n>" prerelease for every green push to main, so /latest
# is empty and every tag is a prerelease - the alphas are what there is to
# package. They arrive several times a day, which is also how often this
# package can move.
#
# The release list is not ordered by version: GitHub sorts it by creation
# time, and upstream's alpha numbering has already run out of step with it
# (v0.2.0-alpha.10 sits between alpha.2 and alpha.1). The newest release is
# therefore picked by publication date rather than by list position.
#
# The asset name carries tauri.conf.json's version, not the tag - every alpha
# of 0.2.0 ships WolfCut_0.2.0_amd64.deb - so it cannot be derived from
# pkgver and is resolved through the API into the _asset variable.
#
# pkgver drops the hyphens from the tag (v0.2.0-alpha.15 -> 0.2.0alpha.15).
# pacman sorts that older than a later plain 0.2.0 (`vercmp 0.2.0alpha.15
# 0.2.0` is -1), so the prereleases upgrade to the eventual stable release on
# their own and no epoch is needed.
# Not on the AUR yet. concat-git goes up first; these two follow once the
# alpha-per-push release cadence has been lived with for a while - upstream
# publishes several a day, and each one is an AUR push (and, for concat, a
# full Rust build in CI). Flip this to true to publish; until then the
# PKGBUILD is still kept current and test-built here.
AUR_PUBLISH=false
UPSTREAM_REPO="jub0t/Concat"
# newest published release whose tag looks like a version
latest_tag() {
gh api "repos/$UPSTREAM_REPO/releases?per_page=100" \
--jq '[.[] | select(.draft | not) | select(.tag_name | test("^v[0-9]"))]
| sort_by(.published_at) | last | .tag_name'
}
tag_to_pkgver() {
sed 's/^v//; s/-//g'
}
latest_version() {
latest_tag | tag_to_pkgver
}
# refresh_checksums <version> <pkgbuild-path>
refresh_checksums() {
local ver="$1" pkgbuild="$2"
local tag asset sha_deb sha_license
tag="$(latest_tag)"
if [[ "$(tag_to_pkgver <<< "$tag")" != "$ver" ]]; then
echo "newest versioned release is $tag, not the requested $ver - try again" >&2
return 1
fi
# e.g. WolfCut_0.2.0_amd64.deb - the version is tauri.conf.json's, not the tag's
asset="$(gh api "repos/$UPSTREAM_REPO/releases/tags/$tag" --jq '.assets[].name' \
| grep -E '_amd64\.deb$')"
[[ "$(wc -l <<< "$asset")" -eq 1 ]] || { echo "expected exactly one amd64 .deb, got: $asset" >&2; return 1; }
sha_deb="$(curl -sfL "https://github.com/$UPSTREAM_REPO/releases/download/$tag/$asset" \
| sha256sum | cut -d' ' -f1)"
# the .deb ships no copyright file, so the license comes from the tag
sha_license="$(curl -sfL "https://raw.githubusercontent.com/$UPSTREAM_REPO/$tag/LICENSE" \
| sha256sum | cut -d' ' -f1)"
sed -i \
-e "s|^_tag=.*|_tag=\"$tag\"|" \
-e "s|^_asset=.*|_asset=\"$asset\"|" \
-e "s|^sha256sums=.*|sha256sums=('$sha_deb' '$sha_license')|" \
"$pkgbuild"
}