From bf5cafac18acc725681a32fa01b377d32be203bf Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sat, 16 May 2026 21:23:52 -0600 Subject: [PATCH] feat(ffmpeg): add ffmpegdist classifier for eugeneware/ffmpeg-static Upstream uses non-standard OS/arch names (x64, ia32, win32, arm) and ships both bare binaries and .gz-compressed copies. classifyFFmpegDist maps those to canonical names and keeps only bare binaries. Also adds source-override logic to installerconf so that github_releases + source = ffmpegdist works: GitHub is used for fetching while the custom classifier handles classification. --- ffmpeg/releases.conf | 1 + internal/classifypkg/classifypkg.go | 82 +++++++++++++++++++++++++ internal/installerconf/installerconf.go | 9 +++ 3 files changed, 92 insertions(+) diff --git a/ffmpeg/releases.conf b/ffmpeg/releases.conf index 711a2ea..0d133ea 100644 --- a/ffmpeg/releases.conf +++ b/ffmpeg/releases.conf @@ -1,3 +1,4 @@ +source = ffmpegdist github_releases = eugeneware/ffmpeg-static asset_filter = ffmpeg version_prefix = b diff --git a/internal/classifypkg/classifypkg.go b/internal/classifypkg/classifypkg.go index 646494e..42a7c6c 100644 --- a/internal/classifypkg/classifypkg.go +++ b/internal/classifypkg/classifypkg.go @@ -166,6 +166,8 @@ 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 } @@ -464,6 +466,86 @@ 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 3795c0c..3b51ff5 100644 --- a/internal/installerconf/installerconf.go +++ b/internal/installerconf/installerconf.go @@ -162,6 +162,8 @@ func Read(path string) (*Conf, error) { c := &Conf{} // Infer source from primary key, falling back to explicit "source". + // When both github_releases and source are set, parse the repo ref + // from github_releases but use the explicit source for classification. switch { // GitHub binary releases. case raw["github_releases"] != "": @@ -213,6 +215,13 @@ func Read(path string) (*Conf, error) { default: } + // Explicit "source" overrides the inferred source when both are present. + // This lets packages like ffmpeg use github_releases for fetching but + // a custom classifier for classification. + if raw["source"] != "" && c.Source != "" { + c.Source = raw["source"] + } + // git_url can appear alongside any source type (e.g. github_sources) // to provide a git clone fallback. When it's the only key, it's the // primary source (gittag).