From 4d1fc7bb621976cac13f0091bc4a91dffc722ba4 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sat, 16 May 2026 20:23:29 -0600 Subject: [PATCH] feat(classifypkg): add arch_map/os_map conf keys; use them for ffmpeg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds two new releases.conf keys: arch_map = x64:x86_64 ia32:x86 (upstream:canonical pairs) os_map = win32:windows The generic GitHub classifier now applies these after classify.Filename so packages with non-standard naming don't need a custom classifier. Also adds a .gz (single-file gunzip) branch to package-install.tpl.sh so bare-binary-plus-.gz release patterns are fully handled. Removes the ffmpegdist custom classifier — ffmpeg/releases.conf now uses source = github with arch_map + os_map + version_prefix = b. --- _webi/package-install.tpl.sh | 3 + ffmpeg/releases.conf | 4 +- internal/classifypkg/classifypkg.go | 98 ++++--------------------- internal/installerconf/installerconf.go | 32 ++++++++ 4 files changed, 51 insertions(+), 86 deletions(-) diff --git a/_webi/package-install.tpl.sh b/_webi/package-install.tpl.sh index 9bf0d43..e781ecc 100644 --- a/_webi/package-install.tpl.sh +++ b/_webi/package-install.tpl.sh @@ -226,6 +226,9 @@ __bootstrap_webi() { elif test "$WEBI_EXT" = "git"; then echo " Moving $(t_path "${my_dl_rel}")" mv "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" . + elif test "$WEBI_EXT" = "gz"; then + echo " Inflating $(t_path "${my_dl_rel}")" + gunzip -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE" .gz)" elif test "$WEBI_EXT" = "xz"; then echo " Inflating $(t_path "${my_dl_rel}")" unxz -c "${WEBI_PKG_PATH}/$WEBI_PKG_FILE" > "$(basename "$WEBI_PKG_FILE")" diff --git a/ffmpeg/releases.conf b/ffmpeg/releases.conf index 0d133ea..951ab37 100644 --- a/ffmpeg/releases.conf +++ b/ffmpeg/releases.conf @@ -1,4 +1,6 @@ -source = ffmpegdist +source = github github_releases = eugeneware/ffmpeg-static asset_filter = ffmpeg version_prefix = b +arch_map = x64:x86_64 ia32:x86 arm64:aarch64 arm:armv7 +os_map = win32:windows diff --git a/internal/classifypkg/classifypkg.go b/internal/classifypkg/classifypkg.go index 42a7c6c..a37a770 100644 --- a/internal/classifypkg/classifypkg.go +++ b/internal/classifypkg/classifypkg.go @@ -166,8 +166,6 @@ func classifySource(pkg string, conf *installerconf.Conf, d *rawcache.Dir) ([]st return classifyMariaDBDist(d) case "zigdist": return classifyZigDist(d) - case "ffmpegdist": - return classifyFFmpegDist(d) default: return nil, nil } @@ -428,6 +426,16 @@ func classifyGitHub(pkg string, conf *installerconf.Conf, d *rawcache.Dir) ([]st r := classify.Filename(a.Name) + // Apply conf-level OS/arch overrides for non-standard naming. + osStr := string(r.OS) + if mapped, ok := conf.OSMap[osStr]; ok { + osStr = mapped + } + archStr := string(r.Arch) + if mapped, ok := conf.ArchMap[archStr]; ok { + archStr = mapped + } + // Normalize .tgz → .tar.gz in the display filename. // The download URL still points to the real file. name := a.Name @@ -441,7 +449,7 @@ func classifyGitHub(pkg string, conf *installerconf.Conf, d *rawcache.Dir) ([]st libc = buildmeta.LibcNone } // Windows gnu (MinGW) is self-contained — no runtime deps. - if r.OS == buildmeta.OSWindows && libc == buildmeta.LibcGNU { + if buildmeta.OS(osStr) == buildmeta.OSWindows && libc == buildmeta.LibcGNU { libc = buildmeta.LibcNone } @@ -449,8 +457,8 @@ func classifyGitHub(pkg string, conf *installerconf.Conf, d *rawcache.Dir) ([]st Filename: name, Version: version, Channel: channel, - OS: string(r.OS), - Arch: string(r.Arch), + OS: osStr, + Arch: archStr, Libc: string(libc), Format: string(r.Format), Download: a.BrowserDownloadURL, @@ -466,86 +474,6 @@ func classifyGitHub(pkg string, conf *installerconf.Conf, d *rawcache.Dir) ([]st return assets, nil } -var ffmpegOSMap = map[string]string{ - "linux": "linux", - "darwin": "darwin", - "win32": "windows", -} - -var ffmpegArchMap = map[string]string{ - "x64": "x86_64", - "ia32": "x86", - "arm64": "aarch64", - "arm": "armv7", -} - -// classifyFFmpegDist handles eugeneware/ffmpeg-static releases. -// Upstream uses non-standard names (x64, ia32, win32, arm) and ships both -// bare binaries and .gz-compressed copies. Only bare binaries are kept — -// the install template has no handler for single-file .gz extraction. -func classifyFFmpegDist(d *rawcache.Dir) ([]storage.Asset, error) { - releases, err := ReadAllRaw(d) - if err != nil { - return nil, err - } - - var assets []storage.Asset - for _, data := range releases { - var rel ghRelease - if err := json.Unmarshal(data, &rel); err != nil { - continue - } - if rel.Draft { - continue - } - - version := strings.TrimPrefix(rel.TagName, "b") - - channel := "stable" - if rel.Prerelease { - channel = "beta" - } - - date := "" - if len(rel.PublishedAt) >= 10 { - date = rel.PublishedAt[:10] - } - - for _, a := range rel.Assets { - if strings.Contains(a.Name, ".") { - continue - } - if !strings.HasPrefix(a.Name, "ffmpeg-") { - continue - } - - parts := strings.SplitN(a.Name, "-", 3) - if len(parts) != 3 { - continue - } - - os, osOK := ffmpegOSMap[parts[1]] - arch, archOK := ffmpegArchMap[parts[2]] - if !osOK || !archOK { - continue - } - - assets = append(assets, storage.Asset{ - Filename: a.Name, - Version: version, - Channel: channel, - OS: os, - Arch: arch, - Format: "", - Download: a.BrowserDownloadURL, - Date: date, - }) - } - } - - return assets, nil -} - // classifyServiceman handles serviceman's dual-repo layout: binary releases // from therootcompany/serviceman (≤v0.8.x) and source-only releases from // bnnanet/serviceman (v0.9.x+). Emits binary assets where available, plus diff --git a/internal/installerconf/installerconf.go b/internal/installerconf/installerconf.go index 3b51ff5..923bc9c 100644 --- a/internal/installerconf/installerconf.go +++ b/internal/installerconf/installerconf.go @@ -96,6 +96,16 @@ type Conf struct { // kubectx/kubens) to select only the relevant assets. AssetFilter string + // ArchMap translates non-standard arch strings in asset filenames to + // canonical webi arch names. Format: "upstream:canonical" pairs, + // whitespace-delimited. Example: "x64:x86_64 ia32:x86 arm:armv7" + ArchMap map[string]string + + // OSMap translates non-standard OS strings in asset filenames to + // canonical webi OS names. Format: "upstream:canonical" pairs, + // whitespace-delimited. Example: "win32:windows" + OSMap map[string]string + // Variants documents known build variant names for this package. // Whitespace-delimited. This is a human-readable cue — actual // variant detection logic lives in Go code per-package. @@ -243,6 +253,14 @@ func Read(path string) (*Conf, error) { } c.AssetFilter = raw["asset_filter"] + + if v := raw["arch_map"]; v != "" { + c.ArchMap = parseKVMap(v) + } + if v := raw["os_map"]; v != "" { + c.OSMap = parseKVMap(v) + } + c.OS = raw["os"] c.AliasOf = raw["alias_of"] @@ -269,6 +287,8 @@ func Read(path string) (*Conf, error) { "exclude": true, "asset_exclude": true, "asset_filter": true, + "arch_map": true, + "os_map": true, "os": true, "variants": true, "alias_of": true, @@ -284,3 +304,15 @@ func Read(path string) (*Conf, error) { return c, nil } + +// parseKVMap parses whitespace-delimited "key:value" pairs into a map. +func parseKVMap(s string) map[string]string { + m := make(map[string]string) + for _, pair := range strings.Fields(s) { + k, v, ok := strings.Cut(pair, ":") + if ok { + m[k] = v + } + } + return m +}