internal/rosa: toolchain abstraction
All checks were successful
Test / Create distribution (push) Successful in 48s
Test / Sandbox (push) Successful in 2m50s
Test / ShareFS (push) Successful in 4m45s
Test / Hpkg (push) Successful in 5m17s
Test / Sandbox (race detector) (push) Successful in 5m24s
Test / Hakurei (push) Successful in 5m38s
Test / Hakurei (race detector) (push) Successful in 7m32s
Test / Flake checks (push) Successful in 1m56s
All checks were successful
Test / Create distribution (push) Successful in 48s
Test / Sandbox (push) Successful in 2m50s
Test / ShareFS (push) Successful in 4m45s
Test / Hpkg (push) Successful in 5m17s
Test / Sandbox (race detector) (push) Successful in 5m24s
Test / Hakurei (push) Successful in 5m38s
Test / Hakurei (race detector) (push) Successful in 7m32s
Test / Flake checks (push) Successful in 1m56s
This provides a clean and easy to use API over toolchains. A toolchain is an opaque set of artifacts and environment fixups. Exported toolchains should be functionally indistinguishable from each other. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -4,6 +4,9 @@ package rosa
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
@@ -48,3 +51,86 @@ func linuxArch() string {
|
|||||||
panic("unsupported target " + runtime.GOARCH)
|
panic("unsupported target " + runtime.GOARCH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toolchain denotes the infrastructure to compile a [pkg.Artifact] on.
|
||||||
|
type Toolchain uintptr
|
||||||
|
|
||||||
|
const (
|
||||||
|
// toolchainBusybox denotes a busybox installation from the busyboxBin
|
||||||
|
// binary distribution. This is for decompressing unsupported formats.
|
||||||
|
toolchainBusybox Toolchain = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// lastIndexFunc is like [strings.LastIndexFunc] but for [slices].
|
||||||
|
func lastIndexFunc[S ~[]E, E any](s S, f func(E) bool) (i int) {
|
||||||
|
if i = slices.IndexFunc(s, f); i < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if i0 := lastIndexFunc[S](s[i+1:], f); i0 >= 0 {
|
||||||
|
i = i0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixupEnviron fixes up PATH, prepends extras and returns the resulting slice.
|
||||||
|
func fixupEnviron(env, extras []string, paths ...string) []string {
|
||||||
|
const pathPrefix = "PATH="
|
||||||
|
pathVal := strings.Join(paths, ":")
|
||||||
|
|
||||||
|
if i := lastIndexFunc(env, func(s string) bool {
|
||||||
|
return strings.HasPrefix(s, pathPrefix)
|
||||||
|
}); i < 0 {
|
||||||
|
env = append(env, pathPrefix+pathVal)
|
||||||
|
} else {
|
||||||
|
if len(env[i]) == len(pathPrefix) {
|
||||||
|
env[i] = pathPrefix + pathVal
|
||||||
|
} else {
|
||||||
|
env[i] += ":" + pathVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(extras, env...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// absCureScript is the absolute pathname [Toolchain.New] places the fixed-up
|
||||||
|
// build script under.
|
||||||
|
var absCureScript = fhs.AbsUsrBin.Append(".cure-script")
|
||||||
|
|
||||||
|
// New returns a [pkg.Artifact] compiled on this toolchain.
|
||||||
|
func (t Toolchain) New(
|
||||||
|
name string,
|
||||||
|
extra []pkg.Artifact,
|
||||||
|
checksum *pkg.Checksum,
|
||||||
|
env []string,
|
||||||
|
script string,
|
||||||
|
|
||||||
|
paths ...pkg.ExecPath,
|
||||||
|
) pkg.Artifact {
|
||||||
|
var (
|
||||||
|
path = AbsSystem.Append("bin", "busybox")
|
||||||
|
args = []string{"hush", absCureScript.String()}
|
||||||
|
support []pkg.Artifact
|
||||||
|
)
|
||||||
|
switch t {
|
||||||
|
case toolchainBusybox:
|
||||||
|
support = slices.Concat([]pkg.Artifact{newBusyboxBin()}, extra)
|
||||||
|
env = fixupEnviron(env, nil, "/system/bin")
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic("unsupported toolchain " + strconv.Itoa(int(t)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkg.NewExec(
|
||||||
|
name, checksum, pkg.ExecTimeoutMax,
|
||||||
|
fhs.AbsRoot, env,
|
||||||
|
path, args,
|
||||||
|
|
||||||
|
slices.Concat([]pkg.ExecPath{pkg.Path(
|
||||||
|
fhs.AbsRoot, true,
|
||||||
|
support...,
|
||||||
|
), pkg.Path(
|
||||||
|
absCureScript, false,
|
||||||
|
pkg.NewFile(".cure-script", []byte("set -e\n"+script)),
|
||||||
|
)}, paths)...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user