From 31dc1f114bc2f329889648850a8d509249a3dc7a Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 11 Mar 2026 13:58:59 -0600 Subject: [PATCH] ref(classify): separate core classifier from legacy backport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move legacy-specific field translations out of the core classifier into LegacyBackport(), called by webicached before writing the JSON cache. Core classifier now outputs canonical values: - Go dist arm → armv6 (correct per GOARM default) - ffmpeg Windows .gz → .gz (correct file extension) LegacyBackport remaps for Node.js compat: - Go dist armv6 → arm (production keeps raw API value) - ffmpeg Windows .gz → exe (production releases.js override) sass armv6→armv7 stays in classifier (Dart Sass genuinely targets ARMv7). --- cmd/webicached/main.go | 2 + internal/classifypkg/classifypkg.go | 55 +++++++++++++++++++++++++--- internal/releases/ffmpeg/variants.go | 29 --------------- 3 files changed, 51 insertions(+), 35 deletions(-) delete mode 100644 internal/releases/ffmpeg/variants.go diff --git a/cmd/webicached/main.go b/cmd/webicached/main.go index 8186eb0..f9b42d5 100644 --- a/cmd/webicached/main.go +++ b/cmd/webicached/main.go @@ -316,6 +316,8 @@ func (wc *WebiCache) refreshPackage(ctx context.Context, pkg pkgConf) error { if err != nil { return fmt.Errorf("classify: %w", err) } + // Legacy backport: translate canonical values to what Node.js expects. + classifypkg.LegacyBackport(name, assets) classifyDur := time.Since(classifyStart) // Step 3: Write to fsstore. diff --git a/internal/classifypkg/classifypkg.go b/internal/classifypkg/classifypkg.go index 65788b8..4a8a88e 100644 --- a/internal/classifypkg/classifypkg.go +++ b/internal/classifypkg/classifypkg.go @@ -22,7 +22,6 @@ import ( "github.com/webinstall/webi-installers/internal/rawcache" "github.com/webinstall/webi-installers/internal/releases/bun" "github.com/webinstall/webi-installers/internal/releases/chromedist" - "github.com/webinstall/webi-installers/internal/releases/ffmpeg" "github.com/webinstall/webi-installers/internal/releases/fish" "github.com/webinstall/webi-installers/internal/releases/gitea" "github.com/webinstall/webi-installers/internal/releases/flutterdist" @@ -151,8 +150,6 @@ func TagVariants(pkg string, assets []storage.Asset) { switch pkg { case "bun": bun.TagVariants(assets) - case "ffmpeg": - ffmpeg.TagVariants(assets) case "fish": fish.TagVariants(assets) case "git": @@ -271,6 +268,54 @@ func ApplyConfig(assets []storage.Asset, conf *installerconf.Conf) []storage.Ass return out } +// LegacyBackport translates canonical classifier output into field values +// the Node.js legacy cache expects. The core classifier uses correct, +// canonical values (armv6, .gz, etc.); this function remaps them for +// backward compatibility with the production resolver. +// +// Call this after Package() when writing to the legacy JSON cache. +// The new Go resolver will use canonical values directly. +func LegacyBackport(pkg string, assets []storage.Asset) { + switch pkg { + case "go": + legacyBackportGo(assets) + case "ffmpeg": + legacyBackportFFmpeg(assets) + } +} + +// legacyBackportGo remaps Go dist's arm classification. +// +// The Go dist API uses bare "arm" (GOARM default = 6). The classifier +// canonicalizes this to "armv6". Production keeps the raw "arm" value +// because normalize.js doesn't run on Go dist assets. The legacy resolver +// expects "arm" for these assets. +func legacyBackportGo(assets []storage.Asset) { + for i := range assets { + if assets[i].Arch == "armv6" { + assets[i].Arch = "arm" + } + } +} + +// legacyBackportFFmpeg remaps Windows gzipped executables. +// +// ffmpeg-static publishes bare executables for Windows. The .gz files +// are gzip-compressed bare executables (not tar archives). Production's +// ffmpeg/releases.js hardcodes rel.ext = 'exe' for Windows assets. +// The legacy resolver needs "exe" to serve these correctly. +func legacyBackportFFmpeg(assets []storage.Asset) { + for i := range assets { + if assets[i].OS != "windows" { + continue + } + switch assets[i].Format { + case ".gz", "": + assets[i].Format = ".exe" + } + } +} + // ReadAllRaw reads all non-directory, non-underscore-prefixed files from // the active generation of a rawcache directory. func ReadAllRaw(d *rawcache.Dir) (map[string][]byte, error) { @@ -883,9 +928,7 @@ func normalizeGoArch(goarch string) string { case "386": return "x86" case "arm": - // Go API uses bare "arm" — keep as-is to match production. - // The resolver handles arm compatibility (armv7→armv6 fallback). - return "arm" + return "armv6" case "ppc64le": return "ppc64le" case "ppc64": diff --git a/internal/releases/ffmpeg/variants.go b/internal/releases/ffmpeg/variants.go deleted file mode 100644 index 8879204..0000000 --- a/internal/releases/ffmpeg/variants.go +++ /dev/null @@ -1,29 +0,0 @@ -// Package ffmpeg provides variant tagging for ffmpeg-static releases. -// -// ffmpeg-static publishes bare executables for Windows. The .gz files -// are gzip-compressed bare executables (not archives). Production -// classifies these as ext "exe". -package ffmpeg - -import ( - "github.com/webinstall/webi-installers/internal/storage" -) - -// TagVariants fixes Windows asset extensions for ffmpeg. -// -// Windows .gz files contain a gzipped bare executable, not a tar archive. -// Production treats these as ext "exe". Bare Windows files (no extension) -// are also executables. -func TagVariants(assets []storage.Asset) { - for i := range assets { - if assets[i].OS != "windows" { - continue - } - switch assets[i].Format { - case ".gz": - assets[i].Format = ".exe" - case "": - assets[i].Format = ".exe" - } - } -}