Files
Duy /zuey/andGitHub 425cecb9a3 feat(packages): Phase 2b — apk update flow + pkg-helper v2 protocol (#900) (#7)
* feat(packages): add apk update flow + pkg-helper v2 protocol

- APK update checker/executor via helper IPC (runtime detection, upgrade scan via apk list --upgradable)
- BREAKING: pkg-helper v2 protocol (5 actions: check_apk/check_pip/check_npm/exec_apk/exec_pip, code/data fields, renewable 10min deadline, apkMutex, 1MB scanner)
- Edition gating: SupportsApk + IsAlpineRuntime double-gate (Standard/Full only)
- Backend 3-branch wiring: alpine/apt/yum routes + update_registry, dep_installer helpers
- i18n: 5 apk keys (EN/VI/ZH catalogs)
- Frontend: source pill Alpine badge, APK in updates-list/summary-bar/update-all modal
- E2E tests: apk_e2e build tag covering checker/executor/helper protocol
- Docs: packages-apk.md, security/changelog updates
- Plans + reports under plans/260417-1500-packages-update-phase2b-apk-pkghelper/ + plans/reports/

* docs(packages): journal Phase 2b apk + pkg-helper v2
2026-05-11 15:41:27 +07:00

42 lines
1.3 KiB
Go

package skills
import (
"os"
"sync"
)
// isAlpineOnce ensures the stat call happens at most once per process lifetime.
var (
isAlpineOnce sync.Once
isAlpineVal bool
)
// IsAlpineRuntime reports whether the current process is running on Alpine
// Linux. Detection: presence of /etc/alpine-release (Alpine-specific file;
// not present on Debian, Ubuntu, RHEL, macOS, or Windows).
//
// The result is cached for the lifetime of the process; safe for concurrent use.
// Used by packages update wiring to gate apk checker/executor registration.
// Call overrideAlpineRuntime in tests to bypass the stat call.
func IsAlpineRuntime() bool {
isAlpineOnce.Do(func() {
_, err := os.Stat("/etc/alpine-release")
isAlpineVal = err == nil
})
return isAlpineVal
}
// overrideAlpineRuntime resets the once guard and sets a fixed result.
// ONLY for use in tests — not exported. Tests that need to control the
// Alpine detection result must call this before exercising any code that
// calls IsAlpineRuntime().
func overrideAlpineRuntime(val bool) {
isAlpineOnce = sync.Once{}
isAlpineVal = val
isAlpineOnce.Do(func() {
// Already set via isAlpineVal; Do body records the value.
// Reassign inside Do to guarantee the once-cached value is val.
isAlpineVal = val
})
}