30 Commits
Author SHA1 Message Date
cat 88a19aefaa internal/rosa/package/python: 3.14.7 to 3.15.0
Test / Create distribution (push) Successful in 55s
Test / Sandbox (push) Successful in 3m23s
Test / Hakurei (push) Successful in 5m30s
Test / Sandbox (race detector) (push) Successful in 6m17s
Test / Hakurei (race detector) (push) Successful in 7m41s
Test / ShareFS (push) Successful in 8m30s
Test / Flake checks (push) Successful in 1m7s
This has been blocking OpenSSL for months. This currently sits on a release candidate.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-15 18:10:22 +09:00
cat f01776200d internal/rosa/package/openssl: 3.6.2 to 4.0.1
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m59s
Test / Hakurei (push) Successful in 4m50s
Test / Sandbox (race detector) (push) Successful in 6m19s
Test / Hakurei (race detector) (push) Successful in 7m36s
Test / ShareFS (push) Successful in 7m58s
Test / Flake checks (push) Successful in 1m17s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-15 18:09:23 +09:00
cat e58b6eb171 internal/rosa/package: net-tools
Test / Create distribution (push) Successful in 58s
Test / Sandbox (push) Successful in 2m50s
Test / Hakurei (push) Successful in 4m38s
Test / Sandbox (race detector) (push) Successful in 5m48s
Test / Hakurei (race detector) (push) Successful in 6m59s
Test / ShareFS (push) Successful in 7m20s
Test / Flake checks (push) Successful in 1m18s
These are nice to have, but will not be included in the base system.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-15 16:18:44 +09:00
cat 1625aaee80 internal/rosa/package/nss: 3.126 to 3.126.1
Test / Hakurei (push) Successful in 6m50s
Test / Hakurei (race detector) (push) Successful in 9m6s
Test / Sandbox (push) Successful in 4m18s
Test / Sandbox (race detector) (push) Successful in 7m48s
Test / ShareFS (push) Successful in 9m55s
Test / Create distribution (push) Successful in 1m41s
Test / Flake checks (push) Successful in 1m7s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-14 16:19:17 +09:00
cat 203ce6864b internal/rosa/package/go: 1.26.5 to 1.26.6
Test / Hakurei (race detector) (push) Successful in 9m26s
Test / Sandbox (push) Successful in 4m18s
Test / Sandbox (race detector) (push) Successful in 7m51s
Test / ShareFS (push) Successful in 9m42s
Test / Create distribution (push) Successful in 1m25s
Test / Hakurei (push) Successful in 2m54s
Test / Flake checks (push) Successful in 1m7s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-14 16:18:55 +09:00
cat 050051e593 internal/rosa/package/procps: 4.0.6 to 4.0.7
Test / Create distribution (push) Successful in 59s
Test / Sandbox (push) Successful in 3m14s
Test / Hakurei (push) Successful in 5m22s
Test / Sandbox (race detector) (push) Successful in 6m22s
Test / Hakurei (race detector) (push) Successful in 7m48s
Test / ShareFS (push) Successful in 8m11s
Test / Flake checks (push) Successful in 1m16s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-13 20:09:27 +09:00
cat 530b63ca70 internal/rosa/package/harfbuzz: 14.3.0 to 14.3.1
Test / Hakurei (race detector) (push) Successful in 7m54s
Test / Sandbox (push) Successful in 3m9s
Test / Create distribution (push) Successful in 58s
Test / Sandbox (race detector) (push) Successful in 6m25s
Test / ShareFS (push) Successful in 8m3s
Test / Hakurei (push) Successful in 2m50s
Test / Flake checks (push) Successful in 1m14s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-13 20:09:06 +09:00
cat 8821d34b10 internal/pkg: deduplicate unwrapped input errors
Test / Create distribution (push) Successful in 55s
Test / Sandbox (push) Successful in 2m47s
Test / Hakurei (push) Successful in 4m27s
Test / Hakurei (race detector) (push) Successful in 6m58s
Test / Sandbox (race detector) (push) Successful in 5m50s
Test / ShareFS (push) Successful in 7m7s
Test / Flake checks (push) Successful in 1m8s
This avoids repeating errors belonging to multiple instances of the same artifact in different locations in memory.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 22:34:12 +09:00
cat 054a8813d7 internal/rosa/package/qemu: disable broken tests
Test / Sandbox (push) Successful in 3m1s
Test / Hakurei (push) Successful in 4m35s
Test / Sandbox (race detector) (push) Successful in 5m59s
Test / Hakurei (race detector) (push) Successful in 7m1s
Test / ShareFS (push) Successful in 7m28s
Test / Flake checks (push) Successful in 1m9s
Test / Create distribution (push) Successful in 50s
The copy-before-write test was failing on a Haswell machine, although it seems to work pretty reliably on the Zen 3 workstation and RK3588.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 19:01:49 +09:00
cat 1bc16b51a6 cmd/hakurei: terminate specified instance
Test / Create distribution (push) Successful in 59s
Test / Sandbox (push) Successful in 2m55s
Test / Hakurei (push) Successful in 4m56s
Test / Sandbox (race detector) (push) Successful in 6m7s
Test / Hakurei (race detector) (push) Successful in 7m20s
Test / ShareFS (push) Successful in 7m35s
Test / Flake checks (push) Successful in 1m7s
This is theoretically susceptible to the PID race, but such an event is statistically impossible, and not exploitable in the intended use case, regardless.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 18:03:54 +09:00
cat 3718c044c4 internal/rosa/package/qemu: use system meson
Test / Create distribution (push) Successful in 53s
Test / Hakurei (race detector) (push) Successful in 6m56s
Test / Sandbox (push) Successful in 3m1s
Test / Sandbox (race detector) (push) Successful in 5m44s
Test / ShareFS (push) Successful in 7m23s
Test / Hakurei (push) Successful in 3m27s
Test / Flake checks (push) Successful in 1m18s
This also enables meson colour and fixes test suite invocation.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 17:57:57 +09:00
cat 07e92db918 internal/rosa/package/dbus: xdg-dbus-proxy 0.1.7 to 0.1.8
Test / Create distribution (push) Successful in 53s
Test / Hakurei (push) Successful in 6m43s
Test / Hakurei (race detector) (push) Successful in 9m16s
Test / Sandbox (push) Successful in 3m33s
Test / Sandbox (race detector) (push) Successful in 6m56s
Test / ShareFS (push) Successful in 9m15s
Test / Flake checks (push) Successful in 1m9s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 16:29:07 +09:00
cat d2ee7cb551 internal/rosa/package/qemu: 11.0.3 to 11.1.0
Test / Create distribution (push) Successful in 1m6s
Test / Hakurei (push) Successful in 6m21s
Test / Sandbox (push) Successful in 3m31s
Test / ShareFS (push) Successful in 9m30s
Test / Sandbox (race detector) (push) Successful in 7m47s
Test / Hakurei (race detector) (push) Successful in 9m42s
Test / Flake checks (push) Successful in 1m11s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 16:28:47 +09:00
cat 39e757a84d internal/rosa/package/python: wheel 0.47.0 to 0.48.0
Test / Hakurei (race detector) (push) Successful in 10m1s
Test / Sandbox (push) Successful in 3m38s
Test / Hakurei (push) Successful in 2m49s
Test / Sandbox (race detector) (push) Successful in 8m4s
Test / Create distribution (push) Successful in 1m25s
Test / ShareFS (push) Successful in 9m49s
Test / Flake checks (push) Successful in 1m10s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 16:28:18 +09:00
cat a431f16e6f internal/pkg: in-flight error resolution
Test / Hakurei (push) Successful in 4m28s
Test / Sandbox (race detector) (push) Successful in 5m55s
Test / Create distribution (push) Successful in 55s
Test / Sandbox (push) Successful in 2m58s
Test / Hakurei (race detector) (push) Successful in 7m35s
Test / ShareFS (push) Successful in 8m31s
Test / Flake checks (push) Successful in 1m32s
The DCE is a slow and overcomplicated solution to a simple problem. This change replaces the DCE by resolving errors in-flight.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-12 16:21:47 +09:00
cat 1f45d44e7f internal/rosa/package/python: hatchling 1.17.1 to 1.18.0
Test / Hakurei (push) Successful in 8m45s
Test / Create distribution (push) Successful in 1m26s
Test / Hakurei (race detector) (push) Successful in 8m47s
Test / Sandbox (push) Successful in 3m33s
Test / Sandbox (race detector) (push) Successful in 7m9s
Test / ShareFS (push) Successful in 32s
Test / Flake checks (push) Successful in 1m13s
This has gained another dependency, pulling in the fourth python build system we have had to package.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 21:43:19 +09:00
cat 92d01752ab internal/rosa/package/python: poetry-core tomlkit
Test / Hakurei (push) Successful in 6m34s
Test / Sandbox (push) Successful in 4m18s
Test / Create distribution (push) Successful in 1m46s
Test / ShareFS (push) Successful in 34s
Test / Hakurei (race detector) (push) Successful in 46s
Test / Sandbox (race detector) (push) Successful in 41s
Test / Flake checks (push) Successful in 1m11s
This is the fourth python build system required to package meson. Required by tomlkit which is now required by hatchling (yet another build system).

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 21:42:09 +09:00
cat 82bf46d23f internal/rosa/package: replace pkg-config
Test / Hakurei (push) Successful in 5m32s
Test / Sandbox (push) Successful in 3m6s
Test / Create distribution (push) Successful in 1m42s
Test / ShareFS (push) Successful in 31s
Test / Sandbox (race detector) (push) Successful in 39s
Test / Hakurei (race detector) (push) Successful in 43s
Test / Flake checks (push) Successful in 1m12s
This replaces pkg-config with pkgconf for most packages.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 21:27:09 +09:00
cat 2abcb99ea2 internal/rosa/package: pkgconf
Test / Create distribution (push) Successful in 1m2s
Test / Sandbox (push) Successful in 3m2s
Test / Hakurei (push) Successful in 5m48s
Test / Sandbox (race detector) (push) Successful in 6m1s
Test / Hakurei (race detector) (push) Successful in 7m29s
Test / ShareFS (push) Successful in 8m2s
Test / Flake checks (push) Successful in 1m18s
This replaces pkg-config for packages later than meson.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 21:23:11 +09:00
cat 2218efc0cf internal/rosa: improve nil-exec error reporting
Test / Hakurei (push) Successful in 5m54s
Test / Sandbox (race detector) (push) Successful in 6m42s
Test / Hakurei (race detector) (push) Successful in 8m13s
Test / ShareFS (push) Successful in 8m39s
Test / Flake checks (push) Successful in 1m16s
Test / Create distribution (push) Successful in 1m9s
Test / Sandbox (push) Successful in 3m28s
This panics with a more descriptive error instead of relying on the SIGSEGV handler.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 20:40:00 +09:00
cat 30c5525d7b internal/rosa/package/libpsl: 0.23.1 to 0.23.2
Test / Create distribution (push) Successful in 1m0s
Test / Sandbox (push) Successful in 3m1s
Test / Hakurei (push) Successful in 7m29s
Test / Sandbox (race detector) (push) Successful in 5m37s
Test / Hakurei (race detector) (push) Successful in 8m11s
Test / ShareFS (push) Successful in 7m25s
Test / Flake checks (push) Successful in 1m15s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 14:39:44 +09:00
cat bf6d1ada71 internal/rosa/package/libexpat: 2.8.2 to 2.8.3
Test / Hakurei (race detector) (push) Successful in 12m22s
Test / Sandbox (push) Successful in 5m19s
Test / Sandbox (race detector) (push) Successful in 6m24s
Test / ShareFS (push) Successful in 11m20s
Test / Create distribution (push) Successful in 1m31s
Test / Hakurei (push) Successful in 3m15s
Test / Flake checks (push) Successful in 1m31s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 14:39:16 +09:00
cat 16294a35ee internal/rosa/package/googletest: 1.17.0 to 1.18.0
Test / Hakurei (push) Successful in 8m12s
Test / Hakurei (race detector) (push) Successful in 12m47s
Test / Sandbox (push) Successful in 4m57s
Test / ShareFS (push) Successful in 13m48s
Test / Create distribution (push) Successful in 1m38s
Test / Sandbox (race detector) (push) Successful in 2m33s
Test / Flake checks (push) Successful in 1m34s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 14:38:56 +09:00
cat 22756af8fb internal/rosa/package/firmware: 20260622 to 20260810
Test / Flake checks (push) Successful in 1m22s
Test / Hakurei (push) Successful in 10m6s
Test / Sandbox (push) Successful in 5m29s
Test / ShareFS (push) Successful in 13m52s
Test / Create distribution (push) Successful in 1m57s
Test / Sandbox (race detector) (push) Successful in 2m46s
Test / Hakurei (race detector) (push) Successful in 4m41s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 14:38:36 +09:00
cat 739ae4a7cf internal/rosa/package/meson: 1.11.2 to 1.12.0
Test / Flake checks (push) Successful in 1m19s
Test / Hakurei (push) Successful in 10m34s
Test / Sandbox (push) Successful in 5m53s
Test / Sandbox (race detector) (push) Successful in 9m53s
Test / ShareFS (push) Successful in 14m40s
Test / Create distribution (push) Successful in 2m28s
Test / Hakurei (race detector) (push) Successful in 5m3s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 14:38:13 +09:00
cat eec89c4519 internal/rosa/package/kernel: 6.18.43 to 6.18.44
Test / Hakurei (push) Successful in 7m39s
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 1m33s
Test / Sandbox (race detector) (push) Successful in 2m25s
Test / Hakurei (race detector) (push) Successful in 3m44s
Test / ShareFS (push) Successful in 5m36s
Test / Flake checks (push) Successful in 1m13s
Typo fix of rkisp1_ext_param_buffer_version caused world rebuild.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-11 00:08:47 +09:00
cat 7193656b6a internal/rosa: improve helper bindings
Test / Sandbox (race detector) (push) Successful in 5m50s
Test / Hakurei (race detector) (push) Successful in 7m11s
Test / ShareFS (push) Successful in 7m32s
Test / Flake checks (push) Successful in 1m10s
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 2m59s
Test / Hakurei (push) Successful in 4m49s
This uses more intuitive names for some arguments and inverts their default value. Slices and nil-capable strings replace skip arguments.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-10 21:55:47 +09:00
cat 7d86e19c07 internal/rosa/azalea: implement nil identifier
Test / Hakurei (race detector) (push) Successful in 6m59s
Test / Sandbox (push) Successful in 2m55s
Test / Sandbox (race detector) (push) Successful in 5m43s
Test / ShareFS (push) Successful in 7m12s
Test / Create distribution (push) Successful in 59s
Test / Hakurei (push) Successful in 3m4s
Test / Flake checks (push) Successful in 1m24s
This also implements a nil-capable string type.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-10 21:36:21 +09:00
cat f1ffb180bc internal/rosa: optionally block packages from early stages
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m54s
Test / Hakurei (push) Successful in 4m46s
Test / Sandbox (race detector) (push) Successful in 5m49s
Test / Hakurei (race detector) (push) Successful in 7m6s
Test / ShareFS (push) Successful in 7m33s
Test / Flake checks (push) Successful in 1m13s
This helps avoid inadvertently increasing bootstrap input count.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-10 17:50:36 +09:00
cat 7f690145e3 internal/rosa/package/hakurei: 0.4.5 to 0.4.6
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m44s
Test / Hakurei (push) Successful in 4m24s
Test / Sandbox (race detector) (push) Successful in 5m47s
Test / Hakurei (race detector) (push) Successful in 6m54s
Test / ShareFS (push) Successful in 7m14s
Test / Flake checks (push) Successful in 1m7s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-09 21:21:39 +09:00
89 changed files with 938 additions and 580 deletions
+6
View File
@@ -36,6 +36,11 @@ _hakurei_show() {
'files:files:__hakurei_files' 'files:files:__hakurei_files'
} }
_hakurei_kill() {
_alternative \
'instances:domains:__hakurei_instances'
}
__hakurei_files() { __hakurei_files() {
_files -g "*.(json|hakurei)" _files -g "*.(json|hakurei)"
return $? return $?
@@ -60,6 +65,7 @@ __hakurei_instances() {
"run:Load and start container from configuration file" "run:Load and start container from configuration file"
"exec:Configure and start a permissive container" "exec:Configure and start a permissive container"
"show:Show live or local instance configuration" "show:Show live or local instance configuration"
"kill:Terminate an active instance"
"ps:List active instances" "ps:List active instances"
"version:Display version information" "version:Display version information"
"license:Show full license text" "license:Show full license text"
+18
View File
@@ -11,6 +11,7 @@ import (
"os/user" "os/user"
"strconv" "strconv"
"sync" "sync"
"syscall"
"time" "time"
"hakurei.app/check" "hakurei.app/check"
@@ -372,6 +373,23 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
Flag(&flagNoStore, "no-store", command.BoolFlag(false), "Do not attempt to match from active instances") Flag(&flagNoStore, "no-store", command.BoolFlag(false), "Do not attempt to match from active instances")
} }
c.NewCommand("kill", "Terminate an active instance", func(args []string) error {
if len(args) != 1 {
log.Fatal("kill requires 1 argument")
}
var sc hst.Paths
env.CopyPaths().Copy(&sc, new(outcome.Hsu).MustID(nil))
entry := tryIdentifier(msg, args[0], outcome.NewStore(&sc))
if entry == nil {
log.Fatalf("%q does not match any active instance", args[0])
}
if err := syscall.Kill(entry.PID, syscall.SIGTERM); err != nil {
log.Fatalf("cannot terminate %s: %v", entry.ID.String(), err)
}
return errSuccess
})
{ {
var flagShort bool var flagShort bool
c.NewCommand("ps", "List active instances", func(args []string) error { c.NewCommand("ps", "List active instances", func(args []string) error {
+1
View File
@@ -25,6 +25,7 @@ commands:
run Load and start container from configuration file run Load and start container from configuration file
exec Configure and start a permissive container exec Configure and start a permissive container
show Show live or local instance configuration show Show live or local instance configuration
kill Terminate an active instance
ps List active instances ps List active instances
version Display version information version Display version information
license Show full license text license Show full license text
+4
View File
@@ -1196,6 +1196,10 @@ func main() {
if w, ok := err.(interface{ Unwrap() []error }); !ok { if w, ok := err.(interface{ Unwrap() []error }); !ok {
log.Fatal(err) log.Fatal(err)
} else { } else {
if _, ok = w.(pkg.InputError); ok {
log.Fatal(w)
}
errs := w.Unwrap() errs := w.Unwrap()
for i, e := range errs { for i, e := range errs {
if i == len(errs)-1 { if i == len(errs)-1 {
+2 -5
View File
@@ -118,11 +118,8 @@ func TestExec(t *testing.T) {
[]string{"testtool"}, []string{"testtool"},
pkg.MustPath("/proc/nonexistent", false, failingArtifact), pkg.MustPath("/proc/nonexistent", false, failingArtifact),
), nil, nil, pkg.WNew, &pkg.DependencyCureError{ ), nil, nil, pkg.WNew, pkg.InputError{
{ failingArtifact: stub.UniqueError(0xcafe),
A: failingArtifact,
Err: stub.UniqueError(0xcafe),
},
}}, }},
{"invalid paths", pkg.NewExec( {"invalid paths", pkg.NewExec(
+47 -91
View File
@@ -15,10 +15,10 @@ import (
"hash" "hash"
"io" "io"
"io/fs" "io/fs"
"iter"
"maps" "maps"
"math" "math"
"os" "os"
"os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"slices" "slices"
@@ -654,10 +654,10 @@ type pendingArtifactDep struct {
// if curing succeeds. // if curing succeeds.
resP *cureRes resP *cureRes
// Address of result error slice populated during [Cache.Cure], dereferenced // Address of result error map populated during [Cache.Cure], dereferenced
// after acquiring errsMu if curing fails. No additional action is taken, // after acquiring errsMu if curing fails. No additional action is taken,
// [Cache] and its caller are responsible for further error handling. // [Cache] and its caller are responsible for further error handling.
errs *DependencyCureError errs InputError
// Address of mutex synchronising access to errs. // Address of mutex synchronising access to errs.
errsMu *sync.Mutex errsMu *sync.Mutex
@@ -1721,109 +1721,61 @@ retry:
goto retry goto retry
} }
// CureError wraps a non-nil error returned attempting to cure an [Artifact]. // An InputError describes inputs of a [FloodArtifact] which had failed to cure.
type CureError struct { type InputError map[Artifact]error
A Artifact
Err error
}
// Unwrap returns the underlying error. // unwrap returns an iterator over sorted, deduplicated [Artifact] and their
func (e *CureError) Unwrap() error { return e.Err } // corresponding identifier.
func (e InputError) unwrap() iter.Seq2[Artifact, unique.Handle[ID]] {
ir := NewIR()
// Error returns the error message from the underlying Err. type input struct {
func (e *CureError) Error() string { return e.Err.Error() } a Artifact
// A DependencyCureError wraps errors returned while curing dependencies.
type DependencyCureError []*CureError
// unwrapM recursively expands underlying errors into a caller-supplied map.
func (e *DependencyCureError) unwrapM(
ctx context.Context,
ir *IRCache,
me map[unique.Handle[ID]]*CureError,
) {
for _, err := range *e {
if ctx.Err() != nil {
break
}
id := ir.Ident(err.A)
if _, ok := me[id]; ok {
continue
}
if _e, ok := err.Err.(*DependencyCureError); ok {
_e.unwrapM(ctx, ir, me)
continue
}
me[id] = err
}
}
// unwrap recursively expands and deduplicates underlying errors.
func (e *DependencyCureError) unwrap(
ctx context.Context,
ir *IRCache,
) DependencyCureError {
me := make(map[unique.Handle[ID]]*CureError)
e.unwrapM(ctx, ir, me)
type ent struct {
id unique.Handle[ID] id unique.Handle[ID]
err *CureError
} }
errs := make([]*ent, 0, len(me)) p := make([]input, 0, len(e))
for id, err := range me { for a := range e {
errs = append(errs, &ent{id, err}) p = append(p, input{a, ir.Ident(a)})
} }
var identBuf [2]ID var identBuf [2]ID
slices.SortFunc(errs, func(a, b *ent) int { slices.SortFunc(p, func(a, b input) int {
identBuf[0], identBuf[1] = a.id.Value(), b.id.Value() identBuf[0], identBuf[1] = a.id.Value(), b.id.Value()
return slices.Compare(identBuf[0][:], identBuf[1][:]) return slices.Compare(identBuf[0][:], identBuf[1][:])
}) })
p = slices.CompactFunc(p, func(a, b input) bool { return a.id == b.id })
_errs := make(DependencyCureError, len(errs)) return func(yield func(Artifact, unique.Handle[ID]) bool) {
for i, v := range errs { for _, i := range p {
_errs[i] = v.err if !yield(i.a, i.id) {
return
}
}
} }
return _errs
} }
// Unwrap returns a deduplicated slice of underlying errors. // Error returns a user-facing, deterministic text representation of e.
func (e *DependencyCureError) Unwrap() []error { func (e InputError) Error() string {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
errs := e.unwrap(ctx, NewIR())
_errs := make([]error, len(errs))
for i, err := range errs {
_errs[i] = err
}
return _errs
}
// Error returns a user-facing multiline error message.
func (e *DependencyCureError) Error() string {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
ir := NewIR()
errs := e.unwrap(ctx, ir)
if len(errs) == 0 {
return "invalid dependency cure outcome"
}
var buf strings.Builder var buf strings.Builder
buf.WriteString("errors curing dependencies:") buf.WriteString("errors curing inputs:")
for _, err := range errs { for a, id := range e.unwrap() {
buf.WriteString("\n\t" + buf.WriteString("\n\t")
reportName(err.A, ir.Ident(err.A)) + ": " + buf.WriteString(reportName(a, id))
err.Error()) buf.WriteString(": ")
} buf.WriteString(e[a].Error())
if ctx.Err() != nil {
buf.WriteString("\nerror resolution cancelled")
} }
return buf.String() return buf.String()
} }
// Unwrap returns a slice of underlying errors sorted by identifier.
func (e InputError) Unwrap() []error {
errs := make([]error, 0, len(e))
for a := range e.unwrap() {
errs = append(errs, e[a])
}
return errs
}
// enterCure must be called before entering an [Artifact] implementation. // enterCure must be called before entering an [Artifact] implementation.
func (c *Cache) enterCure(a Artifact, curesExempt bool) error { func (c *Cache) enterCure(a Artifact, curesExempt bool) error {
if c.attr.Notify != nil { if c.attr.Notify != nil {
@@ -2023,7 +1975,7 @@ func (c *Cache) cureMany(
wg.Add(len(inputs)) wg.Add(len(inputs))
var mask []bool var mask []bool
res := make([]cureRes, len(inputs)) res := make([]cureRes, len(inputs))
errs := make(DependencyCureError, 0, len(inputs)) errs := make(InputError)
var errsMu sync.Mutex var errsMu sync.Mutex
if shallow { if shallow {
mask = make([]bool, len(inputs)) mask = make([]bool, len(inputs))
@@ -2042,13 +1994,13 @@ func (c *Cache) cureMany(
continue continue
} }
} }
pending := pendingArtifactDep{d, &res[i], &errs, &errsMu, &wg} pending := pendingArtifactDep{d, &res[i], errs, &errsMu, &wg}
go pending.cure(c) go pending.cure(c)
} }
wg.Wait() wg.Wait()
if len(errs) > 0 { if len(errs) > 0 {
return mask, &errs return mask, errs
} }
for i, p := range res { for i, p := range res {
if shallow && mask[i] { if shallow && mask[i] {
@@ -2651,7 +2603,11 @@ func (pending *pendingArtifactDep) cure(c *Cache) {
} }
pending.errsMu.Lock() pending.errsMu.Lock()
*pending.errs = append(*pending.errs, &CureError{pending.a, err}) if errs, ok := err.(InputError); ok {
maps.Copy(pending.errs, errs)
} else {
pending.errs[pending.a] = err
}
pending.errsMu.Unlock() pending.errsMu.Unlock()
} }
+32 -49
View File
@@ -861,14 +861,11 @@ func TestCache(t *testing.T) {
cure: func(f *pkg.FContext) error { cure: func(f *pkg.FContext) error {
panic("attempting to cure impossible artifact") panic("attempting to cure impossible artifact")
}, },
}, nil, nil, pkg.WNew, &pkg.DependencyCureError{ }, nil, nil, pkg.WNew, pkg.InputError{
{ failingFile: struct {
A: failingFile,
Err: struct {
_ []byte _ []byte
stub.UniqueError stub.UniqueError
}{UniqueError: 0xbad}, }{UniqueError: 0xbad},
},
}}, }},
}) })
@@ -1949,7 +1946,7 @@ errors during scrub:
} }
} }
func TestDependencyCureError(t *testing.T) { func TestInputError(t *testing.T) {
t.Parallel() t.Parallel()
makeIdent := func(ident ...byte) pkg.Artifact { makeIdent := func(ident ...byte) pkg.Artifact {
@@ -1962,56 +1959,40 @@ func TestDependencyCureError(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
err pkg.DependencyCureError err pkg.InputError
want string want string
unwrap []error unwrap []error
}{ }{
{"simple", pkg.DependencyCureError{ {"simple", pkg.InputError{
{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)}, makeIdent(0xff, 9): stub.UniqueError(0xbad09),
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)}, makeIdent(0xff, 0): stub.UniqueError(0xbad00),
{A: makeIdent(0xff, 0xf), Err: stub.UniqueError(0xbad0f)}, makeIdent(0xff, 0xf): stub.UniqueError(0xbad0f),
{A: makeIdent(0xff, 1), Err: stub.UniqueError(0xbad01)}, makeIdent(0xff, 1): stub.UniqueError(0xbad01),
}, `errors curing dependencies: }, `errors curing inputs:
_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite _wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite
_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite _wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite
_wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite _wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite
_w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765199 injected by the test suite`, []error{ _w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765199 injected by the test suite`, []error{
&pkg.CureError{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)}, stub.UniqueError(0xbad00),
&pkg.CureError{A: makeIdent(0xff, 1), Err: stub.UniqueError(0xbad01)}, stub.UniqueError(0xbad01),
&pkg.CureError{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)}, stub.UniqueError(0xbad09),
&pkg.CureError{A: makeIdent(0xff, 0xf), Err: stub.UniqueError(0xbad0f)}, stub.UniqueError(0xbad0f),
}}, }},
{"dedup", pkg.DependencyCureError{ {"dedup", pkg.InputError{
{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)}, makeIdent(0xff, 9): stub.UniqueError(0xbad09),
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)}, makeIdent(0xff, 9): stub.UniqueError(0xbad09),
{A: makeIdent(0xff, 0xfd), Err: &pkg.DependencyCureError{ makeIdent(0xff, 9): stub.UniqueError(0xbad09),
{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)}, makeIdent(0xff, 0): stub.UniqueError(0xbad00),
{A: makeIdent(0xff, 0xc), Err: &pkg.DependencyCureError{ makeIdent(0xff, 0): stub.UniqueError(0xbad00),
{A: makeIdent(0xff, 0xf), Err: stub.UniqueError(0xbad0f)}, makeIdent(0xff, 1): stub.UniqueError(0xbad01),
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)}, }, `errors curing inputs:
}},
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)},
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)},
}},
{A: makeIdent(0xff, 0xff), Err: &pkg.DependencyCureError{
{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)},
{A: makeIdent(0xff, 0xc), Err: &pkg.DependencyCureError{
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)},
}},
{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)},
}},
{A: makeIdent(0xff, 0xf), Err: stub.UniqueError(0xbad0f)},
{A: makeIdent(0xff, 1), Err: stub.UniqueError(0xbad01)},
}, `errors curing dependencies:
_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite _wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite
_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite _wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite
_wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite _wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite`, []error{
_w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765199 injected by the test suite`, []error{ stub.UniqueError(0xbad00),
&pkg.CureError{A: makeIdent(0xff, 0), Err: stub.UniqueError(0xbad00)}, stub.UniqueError(0xbad01),
&pkg.CureError{A: makeIdent(0xff, 1), Err: stub.UniqueError(0xbad01)}, stub.UniqueError(0xbad09),
&pkg.CureError{A: makeIdent(0xff, 9), Err: stub.UniqueError(0xbad09)},
&pkg.CureError{A: makeIdent(0xff, 0xf), Err: stub.UniqueError(0xbad0f)},
}}, }},
} }
for _, tc := range testCases { for _, tc := range testCases {
@@ -2055,19 +2036,21 @@ func (a earlyFailureF) Cure(*pkg.FContext) error {
func BenchmarkEarlyDCE(b *testing.B) { func BenchmarkEarlyDCE(b *testing.B) {
msg := message.New(log.New(os.Stderr, "dce: ", 0)) msg := message.New(log.New(os.Stderr, "dce: ", 0))
msg.SwapVerbose(testing.Verbose()) msg.SwapVerbose(testing.Verbose())
for b.Loop() {
b.StopTimer()
c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil) c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
b.StartTimer()
_, _, err = c.Cure(earlyFailureF(8)) _, _, err = c.Cure(earlyFailureF(8))
b.StopTimer()
if !errors.Is(err, stub.UniqueError(0xcafe)) { if !errors.Is(err, stub.UniqueError(0xcafe)) {
b.Fatalf("Cure: error = %v", err) b.Fatalf("Cure: error = %v", err)
} }
c.Close() c.Close()
dce := err.(*pkg.DependencyCureError) b.StartTimer()
for b.Loop() {
dce.Unwrap()
} }
} }
+59 -6
View File
@@ -12,7 +12,7 @@ import (
// Value are types supported by the language. // Value are types supported by the language.
type Value interface { type Value interface {
bool | int64 | string | []string | []int64 | [][2]string bool | int64 | string | []string | []int64 | [][2]string | Nil
} }
type ( type (
@@ -33,6 +33,29 @@ type (
F func(args FArgs) (v any, set bool, err error) F func(args FArgs) (v any, set bool, err error)
V map[unique.Handle[Ident]]any V map[unique.Handle[Ident]]any
} }
// Nil represents an untyped nil.
Nil struct{}
// AString represents an argument string that may be nil.
AString struct {
V string
Nil bool
}
)
// NilError is returned for an invalid nil assignment.
type NilError struct{ reflect.Type }
func (e NilError) Error() string {
return fmt.Sprintf("attempting to assign nil to %s", e.Type)
}
var (
// nilStringV is the [reflect.Value] of an Azalea nil assigned to an [AString].
nilStringV = reflect.ValueOf(AString{Nil: true})
// nilStringT is the [reflect.Type] of nilStringV.
nilStringT = nilStringV.Type()
) )
// Apply applies named arguments and rejects unused arguments. // Apply applies named arguments and rejects unused arguments.
@@ -50,8 +73,8 @@ func (args FArgs) Apply(v map[unique.Handle[Ident]]any) error {
} }
return UndefinedError(arg.K.Value()) return UndefinedError(arg.K.Value())
} }
err := storeE(r, arg.V)
if err != nil { if err := storeE(r, arg.V); err != nil {
return err return err
} }
} }
@@ -115,11 +138,38 @@ func (e TypeError) Is(err error) bool {
} }
// storeE is a convenience function to set the value of a result pointer. // storeE is a convenience function to set the value of a result pointer.
func storeE(rp any, r any) error { func storeE(rp, r any) error {
pv := reflect.ValueOf(rp).Elem() pv := reflect.ValueOf(rp).Elem()
pt := pv.Type()
as := nilStringT.AssignableTo(pt)
if r == (Nil{}) {
switch kind := pt.Kind(); kind {
case reflect.Bool, reflect.String:
return NilError{pt}
default:
if rv, ok := rp.(*any); ok && !reflect.ValueOf(*rv).IsValid() {
*rv = Nil{}
} else if as {
pv.Set(nilStringV)
} else {
pv.SetZero()
}
return nil
}
}
v := reflect.ValueOf(r) v := reflect.ValueOf(r)
pt, vt := pv.Type(), v.Type() if vt := v.Type(); !vt.AssignableTo(pt) {
if !vt.AssignableTo(pt) { if as {
var asv AString
if err := storeE(&asv.V, r); err != nil {
return err
}
pv.Set(reflect.ValueOf(asv))
return nil
}
return TypeError{vt, pt} return TypeError{vt, pt}
} }
pv.Set(v) pv.Set(v)
@@ -226,6 +276,9 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool {
case "false": case "false":
store(rp, false) store(rp, false)
return true return true
case "nil":
store(rp, Nil{})
return true
default: default:
return evaluateAny(d, s, v, rp) return evaluateAny(d, s, v, rp)
} }
+69 -5
View File
@@ -100,15 +100,79 @@ func TestEvaluate(t *testing.T) {
Err: UndefinedError("f"), Err: UndefinedError("f"),
}}, }},
{"error wrap deep", `f { v = nil; }`, makeStackCheck(func( {"error wrap deep", `f { v = nonexistent; }`, makeStackCheck(func(
FArgs, FArgs,
) (any, error) { ) (any, error) {
panic("unreachable") panic("unreachable")
}), "", EvaluationError{ }), "", EvaluationError{
Expr: Ident("nil"), Expr: Ident("nonexistent"),
Err: UndefinedError("nil"), Err: UndefinedError("nonexistent"),
}}, }},
{"nil", `f { v = nil; }`, checkArgs(FArgs{
{K: unique.Make(Ident("v")), V: Nil{}},
}), "\xfd", nil},
{"apply nil string", `f { v = nil; }`, makeStackCheck(func(
args FArgs,
) (v any, err error) {
var s string
err = args.Apply(map[unique.Handle[Ident]]any{
unique.Make(Ident("v")): &s,
})
v = s
return
}), "", EvaluationError{
Expr: Func{
Ident: Ident("f"),
Args: []Arg{
{K: []Ident{"v"}, V: Val{Ident("nil")}},
},
},
Err: NilError{Type: reflect.TypeFor[string]()},
}},
{"apply nil AString", `f { v = nil; }`, makeStackCheck(func(
args FArgs,
) (v any, err error) {
s := AString{}
err = args.Apply(map[unique.Handle[Ident]]any{
unique.Make(Ident("v")): &s,
})
v = s.V
if !s.Nil {
err = fmt.Errorf("got non-nil string %q", s.V)
}
return
}), "", nil},
{"apply AString", `f { v = "\xfd"; }`, makeStackCheck(func(
args FArgs,
) (v any, err error) {
s := AString{}
err = args.Apply(map[unique.Handle[Ident]]any{
unique.Make(Ident("v")): &s,
})
v = s.V
if s.Nil {
err = fmt.Errorf("unexpected nil %q", s.V)
}
return
}), "\xfd", nil},
{"apply nil", `f { v = nil; }`, makeStackCheck(func(
args FArgs,
) (v any, err error) {
s := make([]struct{}, 9)
err = args.Apply(map[unique.Handle[Ident]]any{
unique.Make(Ident("v")): &s,
})
if s != nil {
err = fmt.Errorf("got non-nil value %#v", s)
}
return
}), "", nil},
{"common inputs", `package name { inputs, v = []; }`, nil, "", EvaluationError{ {"common inputs", `package name { inputs, v = []; }`, nil, "", EvaluationError{
Expr: Func{ Expr: Func{
Ident: Ident("name"), Ident: Ident("name"),
@@ -214,8 +278,8 @@ func TestEvaluate(t *testing.T) {
} }
var errEquals bool var errEquals bool
if _, ok := errors.AsType[TypeError](err); ok { if e, ok := errors.AsType[TypeError](err); ok {
errEquals = errors.Is(err, tc.err) errEquals = e.Is(tc.err)
} else { } else {
errEquals = reflect.DeepEqual(err, tc.err) errEquals = reflect.DeepEqual(err, tc.err)
} }
+1 -1
View File
@@ -39,7 +39,7 @@ package acl {
exec = make { exec = make {
// makes assumptions about uid_map/gid_map // makes assumptions about uid_map/gid_map
skipCheck = true; check = nil;
}; };
inputs = [ attr, kernel-headers ]; inputs = [ attr, kernel-headers ];
+3 -3
View File
@@ -15,9 +15,9 @@ package awk {
chmod = true; chmod = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
inPlace = true; chdir = false;
skipConfigure = true; configure = nil;
make = [ "YACC='yacc -d -b awkgram'" ]; make = [ "YACC='yacc -d -b awkgram'" ];
preCheck = "install -vD a.out /system/bin/awk\n"; preCheck = "install -vD a.out /system/bin/awk\n";
install = "install -vD a.out /work/system/bin/awk"; install = "install -vD a.out /work/system/bin/awk";
+1 -1
View File
@@ -12,7 +12,7 @@ package bison {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
check = [ check = [
"TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests { "TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests {
tests = [ tests = [
+1 -1
View File
@@ -19,6 +19,6 @@ package byacc {
chmod = true; chmod = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
}; };
} }
+4 -7
View File
@@ -15,13 +15,10 @@ package bzip2 {
enterSource = true; enterSource = true;
exec = make { exec = make {
skipConfigure = true; chdir = false;
skipCheck = true; configure = nil;
inPlace = true; make = [ "CC=cc" ];
check = nil;
make = [
"CC=cc",
];
install = "make PREFIX=/work/system install"; install = "make PREFIX=/work/system install";
}; };
} }
+1 -1
View File
@@ -27,7 +27,7 @@ package cairo {
// runs the entire test suite in a single meson test // runs the entire test suite in a single meson test
interactiveTest = true; interactiveTest = true;
// only works with specific dependency versions // only works with specific dependency versions
skipTest = true; test = false;
}; };
inputs = [ inputs = [
+1 -1
View File
@@ -20,7 +20,7 @@ package cmake {
chmod = true; chmod = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
configureName = "/usr/src/cmake/bootstrap"; configureName = "/usr/src/cmake/bootstrap";
configure = { configure = {
+1 -1
View File
@@ -19,7 +19,7 @@ package connman {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
dbus, dbus,
iptables, iptables,
+1 -1
View File
@@ -21,7 +21,7 @@ touch \
`; `;
exec = make { exec = make {
inPlace = true; chdir = false;
configureName = "../dist/configure"; configureName = "../dist/configure";
forceAutoconf = true; forceAutoconf = true;
configure = { configure = {
+2 -2
View File
@@ -41,11 +41,11 @@ package xdg-dbus-proxy {
website = "https://github.com/flatpak/xdg-dbus-proxy"; website = "https://github.com/flatpak/xdg-dbus-proxy";
anitya = 58434; anitya = 58434;
version# = "0.1.7"; version# = "0.1.8";
source = remoteGitHub { source = remoteGitHub {
suffix = "flatpak/xdg-dbus-proxy"; suffix = "flatpak/xdg-dbus-proxy";
tag = version; tag = version;
checksum = "UW5Pe-TP-XAaN-kTbxrkOQ7eYdmlAQlr2pdreLtPT0uwdAz-7rzDP8V_8PWuZBup"; checksum = "ygdW0EEvZ-_PJfnFTNoobITmRzqJecTinBsJd_iJQrRvzidwqESCjeNkB55smZ2y";
}; };
exec = meson { exec = meson {
+4 -4
View File
@@ -18,17 +18,17 @@ package elfutils {
]; ];
exec = make { exec = make {
// nonstandard glibc extension
skipCheck = true;
configure = { configure = {
"enable-deterministic-archives"; "enable-deterministic-archives";
}; };
// nonstandard glibc extension
check = nil;
}; };
inputs = [ inputs = [
m4, m4,
pkg-config, pkgconf,
zlib, zlib,
bzip2, bzip2,
+6 -6
View File
@@ -3,12 +3,12 @@ package firmware {
website = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git"; website = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git";
anitya = 141464; anitya = 141464;
version# = "20260622"; version# = "20260810";
source = remoteGitLab { source = remoteGitLab {
domain = "gitlab.com"; domain = "gitlab.com";
suffix = "kernel-firmware/linux-firmware"; suffix = "kernel-firmware/linux-firmware";
ref = version; ref = version;
checksum = "gpytkDM58EVjaUuryOekcekh_rWsfuv3S7LQxopHlNlVGmMsuqNwfug4BjgTgizE"; checksum = "XNUhz9QstaDKNegM3Bl0-TtZzpsvX7-E8WMnDCO7KBhBC6t_TxsdG05-ETdXynry";
}; };
// dedup creates temporary file // dedup creates temporary file
@@ -22,17 +22,17 @@ package firmware {
]; ];
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipConfigure = true; chdir = false;
inPlace = true;
configure = nil;
make = [ make = [
"DESTDIR=/work/system", "DESTDIR=/work/system",
"install-zst", "install-zst",
]; ];
// requires pre-commit // requires pre-commit
skipCheck = true; check = nil;
install = "make " + jobsFlagE + " " + loadFlagE + " DESTDIR=/work/system dedup"; install = "make " + jobsFlagE + " " + loadFlagE + " DESTDIR=/work/system dedup";
}; };
+1 -1
View File
@@ -18,7 +18,7 @@ package fontconfig {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
gettext, gettext,
gperf, gperf,
gzip, gzip,
+1 -1
View File
@@ -22,7 +22,7 @@ package fuse {
postCompile = "python3 -m pytest test/"; postCompile = "python3 -m pytest test/";
// this project uses pytest // this project uses pytest
skipTest = true; test = false;
}; };
inputs = [ inputs = [
+1 -1
View File
@@ -65,7 +65,7 @@ ln -s system/lib /work/
// This toolchain is hacked to pieces, it is not expected to ever work // This toolchain is hacked to pieces, it is not expected to ever work
// well in its current state. That does not matter as long as the // well in its current state. That does not matter as long as the
// toolchain it produces passes its own test suite. // toolchain it produces passes its own test suite.
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
+1 -1
View File
@@ -23,7 +23,7 @@ rm -f /system/bin/httpd
bin = [ "perl" ]; bin = [ "perl" ];
populateUsrBin = true; populateUsrBin = true;
exec = make { exec = make {
inPlace = true; chdir = false;
generate = "make configure"; generate = "make configure";
preMake = ` preMake = `
+9 -9
View File
@@ -19,7 +19,7 @@ chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
}; };
inputs = [ inputs = [
@@ -114,7 +114,7 @@ package libtool {
exec = make { exec = make {
// _Z2a2c: symbol not found // _Z2a2c: symbol not found
skipEarlyStageCheck = true; checkEarly = false;
check = [ check = [
"TESTSUITEFLAGS=" + jobsFlagE, "TESTSUITEFLAGS=" + jobsFlagE,
@@ -142,7 +142,7 @@ package gzip {
exec = make { exec = make {
// dependency loop // dependency loop
skipCheck = true; check = nil;
}; };
} }
@@ -197,7 +197,7 @@ test_disable '#!/bin/sh' tests/cmp
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
}; };
} }
@@ -223,7 +223,7 @@ test_disable '#!/bin/sh' tests/need-filename
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
}; };
} }
@@ -334,7 +334,7 @@ package bash {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
configure = { configure = {
"without-bash-malloc"; "without-bash-malloc";
}; };
@@ -371,7 +371,7 @@ test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
`; `;
exec = make { exec = make {
omitDefaults = true; defaults = false;
configure = { configure = {
"enable-single-binary": "symlinks"; "enable-single-binary": "symlinks";
}; };
@@ -436,7 +436,7 @@ package texinfo {
exec = make { exec = make {
// nonstandard glibc extension // nonstandard glibc extension
skipCheck = true; check = nil;
}; };
inputs = [ perl ]; inputs = [ perl ];
@@ -648,7 +648,7 @@ package mpc {
enterSource = true; enterSource = true;
exec = make { exec = make {
inPlace = true; chdir = false;
generate = "autoreconf -vfi"; generate = "autoreconf -vfi";
}; };
+1 -1
View File
@@ -47,7 +47,7 @@ echo 'int main(){return 0;}' > tests/mini-dtls-fragments.c
bison, bison,
gettext, gettext,
gperf, gperf,
pkg-config, pkgconf,
python, python,
texinfo, texinfo,
-135
View File
@@ -1,135 +0,0 @@
From 06f90ebfa6f3e0a744584513e2786988b26569da Mon Sep 17 00:00:00 2001
From: Damien Neil <dneil@google.com>
Date: Wed, 08 Jul 2026 11:11:48 -0700
Subject: [PATCH] os: properly handle trailing / in Root.MkdirAll
MkdirAll("dir/") should create "dir", not return an error.
Fixes #80308
Change-Id: I75458c30b6cb94be3a3d368f6024caef6a6a6964
---
diff --git a/src/os/root_noopenat.go b/src/os/root_noopenat.go
index 228b580..a84e952 100644
--- a/src/os/root_noopenat.go
+++ b/src/os/root_noopenat.go
@@ -158,6 +158,9 @@
if err := checkPathEscapes(r, name); err == errPathEscapes {
return &PathError{Op: "mkdirat", Path: name, Err: err}
}
+ if name == "" {
+ return &PathError{Op: "mkdirat", Path: name, Err: syscall.ENOENT}
+ }
prefix := r.root.name + string(PathSeparator)
if err := MkdirAll(prefix+name, perm); err != nil {
if pe, ok := err.(*PathError); ok {
diff --git a/src/os/root_openat.go b/src/os/root_openat.go
index d7c9334..92865e4 100644
--- a/src/os/root_openat.go
+++ b/src/os/root_openat.go
@@ -167,6 +167,12 @@
fi, e := r.Stat(fullname)
if e == nil && fi.Mode().IsDir() {
err = nil
+ } else if e == nil {
+ err = syscall.ENOTDIR
+ } else if !IsNotExist(e) {
+ // EPERM, ELOOP, etc.,
+ // probably more useful than EEXIST.
+ err = e
}
}
}
@@ -177,7 +183,12 @@
}
return struct{}{}, &PathError{Op: "mkdirat", Err: err}
}
- _, err := doInRoot(r, fullname, 0, openDirFunc, openLastComponentFunc)
+ flags := uint(doInRootCreatingDirectory)
+ switch runtime.GOOS {
+ case "linux", "windows":
+ flags = doInRootNoHandleTerminalSlash // see rootMkdir
+ }
+ _, err := doInRoot(r, fullname, flags, openDirFunc, openLastComponentFunc)
if err != nil {
if _, ok := err.(*PathError); !ok {
err = &PathError{Op: "mkdirat", Path: fullname, Err: err}
diff --git a/src/os/root_test.go b/src/os/root_test.go
index 5e0acf9..33a2f33 100644
--- a/src/os/root_test.go
+++ b/src/os/root_test.go
@@ -585,6 +585,11 @@
func TestRootMkdirAll(t *testing.T) {
for _, test := range rootTestCases {
+ if test.name == "directory does not exist" {
+ // Test expects error, mkdirall creates the missing directory.
+ // TestRootMultiMkdirAll covers this case better anyway, just skip.
+ continue
+ }
test.run(t, func(t *testing.T, target string, root *os.Root) {
wantError := test.wantError
if test.ltarget != "" {
@@ -593,7 +598,7 @@
wantError = true
}
- err := root.Mkdir(test.open, 0o777)
+ err := root.MkdirAll(test.open, 0o777)
if errEndsTest(t, err, wantError, "root.MkdirAll(%q)", test.open) {
return
}
@@ -3133,6 +3138,52 @@
})
}
+func TestRootMultiMkdirAllShallow(t *testing.T) {
+ runRootMultiTest(t, func(t *testing.T, test *rootMultiTest) (string, error) {
+ return testRootMultiMkdirAll(t, test, test.targetPath)
+ })
+}
+
+func TestRootMultiMkdirAllDeep(t *testing.T) {
+ runRootMultiTest(t, func(t *testing.T, test *rootMultiTest) (string, error) {
+ targetPath := test.targetPath
+ if len(targetPath) > 0 && os.IsPathSeparator(targetPath[len(targetPath)-1]) {
+ targetPath += "a/b/"
+ } else {
+ targetPath += "/a/b"
+ }
+ return testRootMultiMkdirAll(t, test, targetPath)
+ })
+}
+
+func testRootMultiMkdirAll(t *testing.T, test *rootMultiTest, targetPath string) (string, error) {
+ var mkdirAll = os.MkdirAll
+ if test.root != nil {
+ mkdirAll = test.root.MkdirAll
+ }
+
+ test.setOp("MkdirAll(%q, 0o777)", targetPath)
+ gotErr := mkdirAll(targetPath, 0o777)
+
+ switch {
+ case test.root != nil && test.target.lescapes():
+ // "mkdir ../target", or equivalent escaping path.
+ test.wantError(t, gotErr, os.ErrPathEscapes)
+ case test.root != nil && test.target.escapes():
+ // "mkdir ../target", or equivalent escaping path.
+ test.wantError(t, gotErr, errAny)
+ return "", errSkipRootConsistencyCheck
+ case test.root != nil && test.target.kind == testFileSymlink && test.target.target.kind == testFileAbsent && targetPath != test.targetPath:
+ // A minor inconsistency between Root.MkdirAll and os.MkdirAll:
+ // When an intermediate component of the tree being constructed is a
+ // dangling symlink, Root.MkdirAll will follow the symlink and create
+ // its target directory, while os.MkdirAll will fail with an error.
+ return "", errSkipRootConsistencyCheck
+ default:
+ }
+ return "", gotErr
+}
+
func TestRootMultiRename(t *testing.T) {
if runtime.GOOS == "wasip1" {
switch os.Getenv("GOWASIRUNTIME") {
+3 -5
View File
@@ -3,18 +3,16 @@ package go {
website = "https://go.dev"; website = "https://go.dev";
anitya = 1227; anitya = 1227;
version# = "1.26.5"; version# = "1.26.6";
source = remoteTar { source = remoteTar {
url = "https://go.dev/dl/go"+version+".src.tar.gz"; url = "https://go.dev/dl/go"+version+".src.tar.gz";
checksum = "13yt1u_NGOd62LO-WZ8W6CUXodOrEF5CdkiTTiH9E635IHn1luvlXYjsHpBXNFSw"; checksum = "BJQz9rGJ7ElMsZGURH7lw48Hw0x88RwdQJpINMomtgGCMK3AtwGCxDRkLE9REh5r";
compress = gzip; compress = gzip;
}; };
patches = [ patches = [
// https://go.dev/issue/77674 // https://go.dev/issue/77674
"746640.patch", "746640.patch",
// https://go.dev/issue/80308
"799064.patch",
]; ];
env = [ env = [
@@ -27,7 +25,7 @@ package go {
enterSource = true; enterSource = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
mkdir /work/system/ "${TMPDIR}" mkdir /work/system/ "${TMPDIR}"
cp -r . /work/system/go cp -r . /work/system/go
+2 -2
View File
@@ -3,12 +3,12 @@ package googletest {
exclude = true; exclude = true;
anitya = 18290; anitya = 18290;
version# = "1.17.0"; version# = "1.18.0";
output = remoteGitHubRelease { output = remoteGitHubRelease {
suffix = "google/googletest"; suffix = "google/googletest";
tag = "v"+version; tag = "v"+version;
name = "googletest-"+version+".tar.gz"; name = "googletest-"+version+".tar.gz";
checksum = "-1r3ch8vPP8COF7xUH5hyX6bEJ4dN9TQh4IxrmpHr6vaig6mA3DdUpV4cihQ_9dw"; checksum = "ABVPC5sduQR7xfkZQm7UHSmBTaAJcVPRHS_lNMhlL99HU_YffpFmXbwRKeG1ZY8A";
compress = gzip; compress = gzip;
}; };
} }
@@ -2,11 +2,11 @@ package hakurei-source {
description = "hakurei source tree"; description = "hakurei source tree";
exclude = true; exclude = true;
version# = "0.4.5"; version# = "0.4.6";
output = remoteTar { output = remoteTar {
url = "https://git.gensokyo.uk/rosa/hakurei/archive/"+ url = "https://git.gensokyo.uk/rosa/hakurei/archive/"+
"v"+version+".tar.gz"; "v"+version+".tar.gz";
checksum = "5bvbuIRcDIrtijogwqXn3y8h5f3rVS4ZSVhOig6Galfzt3g-O3Ufb-tHL1kQCQWK"; checksum = "2HxvdykuSSymAu-c1WIwQAy3qT4dDm8B--93iL4uomBlBC8wfSWldbvPF1noNkUC";
compress = gzip; compress = gzip;
}; };
} }
@@ -27,16 +27,9 @@ package hakurei {
"CC=clang -O3 -Werror", "CC=clang -O3 -Werror",
]; ];
files = {
"hostname/main.go": "hostname";
};
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
echo 'Building test helper (hostname).'
go build -o /bin/hostname /usr/src/hostname/main.go
mkdir -p /work/system/libexec/hakurei/ mkdir -p /work/system/libexec/hakurei/
echo "Building hakurei for $(go env GOOS)/$(go env GOARCH)." echo "Building hakurei for $(go env GOOS)/$(go env GOARCH)."
@@ -71,7 +64,8 @@ mkdir -p /work/system/bin/
inputs = [ inputs = [
go, go,
pkg-config, pkgconf,
net-tools,
libseccomp, libseccomp,
acl, acl,
@@ -98,16 +92,9 @@ package hakurei-dist {
"CC=clang -O3 -Werror", "CC=clang -O3 -Werror",
]; ];
files = {
"hostname/main.go": "hostname";
};
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
echo 'Building test helper (hostname).'
go build -o /bin/hostname /usr/src/hostname/main.go
NAME=make`; NAME=make`;
check = ` check = `
NAME=all`; NAME=all`;
@@ -118,7 +105,8 @@ DESTDIR=/work "./${NAME}.sh"
inputs = [ inputs = [
go, go,
pkg-config, pkgconf,
net-tools,
libseccomp, libseccomp,
acl, acl,
@@ -146,7 +134,7 @@ package earlyinit {
]; ];
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
echo '# Building earlyinit.' echo '# Building earlyinit.'
go build -trimpath -v -o /work/ -ldflags="-s -w go build -trimpath -v -o /work/ -ldflags="-s -w
-11
View File
@@ -1,11 +0,0 @@
package main
import "os"
func main() {
if name, err := os.Hostname(); err != nil {
panic(err)
} else {
os.Stdout.WriteString(name)
}
}
+2 -2
View File
@@ -3,11 +3,11 @@ package harfbuzz {
website = "https://harfbuzz.github.io"; website = "https://harfbuzz.github.io";
anitya = 1299; anitya = 1299;
version# = "14.3.0"; version# = "14.3.1";
source = remoteGitHub { source = remoteGitHub {
suffix = "harfbuzz/harfbuzz"; suffix = "harfbuzz/harfbuzz";
tag = version; tag = version;
checksum = "C03eSJbyFvrOPXWhlHgwxfqUKyR9xQO_FKzbwQzT7hW9DTUAQIiwvUIf_6cqaKPm"; checksum = "ykVwQNNbvY38Y27VjAfk16SGcEO5NY5A8CFxJCJ8z0ARh5MdLImmONpy-ZSb79Il";
}; };
exec = meson { exec = meson {
+2 -2
View File
@@ -15,9 +15,9 @@ package hwdata {
exec = make { exec = make {
// awk: fatal: cannot open file `hwdata.spec' for reading: No such file or directory // awk: fatal: cannot open file `hwdata.spec' for reading: No such file or directory
inPlace = true; chdir = false;
// lspci: Unknown option 'A' (see "lspci --help") // lspci: Unknown option 'A' (see "lspci --help")
skipCheck = true; check = nil;
}; };
} }
+3 -3
View File
@@ -21,7 +21,7 @@ package iproute2 {
chmod = true; chmod = true;
exec = make { exec = make {
inPlace = true; chdir = false;
// drop default autoconf options // drop default autoconf options
configureName = "./configure"; configureName = "./configure";
configure = { configure = {
@@ -30,11 +30,11 @@ package iproute2 {
}; };
make = [ "CC=cc", "YACC=yacc" ]; make = [ "CC=cc", "YACC=yacc" ];
// wants root // wants root
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
pkg-config, pkgconf,
m4, m4,
byacc, byacc,
flex, flex,
+1 -1
View File
@@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/x86 6.18.43 Kernel Configuration # Linux/x86 6.18.44 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="clang version 22.1.8" CONFIG_CC_VERSION_TEXT="clang version 22.1.8"
CONFIG_GCC_VERSION=0 CONFIG_GCC_VERSION=0
+1 -1
View File
@@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/arm64 6.18.43 Kernel Configuration # Linux/arm64 6.18.44 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="clang version 22.1.8" CONFIG_CC_VERSION_TEXT="clang version 22.1.8"
CONFIG_GCC_VERSION=0 CONFIG_GCC_VERSION=0
+13 -12
View File
@@ -3,11 +3,11 @@ package kernel-source {
website = "https://kernel.org"; website = "https://kernel.org";
exclude = true; exclude = true;
version# = "6.18.43"; version# = "6.18.44";
output = remoteTar { output = remoteTar {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+ url = "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
"snapshot/linux-"+version+".tar.gz"; "snapshot/linux-"+version+".tar.gz";
checksum = "SthN8PgD7oze4syBC54KJoky7JUpAmXJO0Y98an1ZJiqGppnf6N3kmZiZZdvi9dd"; checksum = "yNPGMl3A-EgU6LgD37PAcXIa9iUtP-AmoJuQozfGRSq6Eg1Eq4fdbpKy3iWewU9_";
compress = gzip; compress = gzip;
}; };
} }
@@ -25,8 +25,8 @@ package kernel-headers {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipConfigure = true; configure = nil;
make = [ make = [
"-f /usr/src/kernel-headers/Makefile", "-f /usr/src/kernel-headers/Makefile",
"O=/tmp/kbuild", "O=/tmp/kbuild",
@@ -35,7 +35,7 @@ package kernel-headers {
"INSTALL_HDR_PATH=/work/system", "INSTALL_HDR_PATH=/work/system",
"headers_install", "headers_install",
]; ];
skipCheck = true; check = nil;
install = ` install = `
cat \ cat \
/usr/src/version.h > \ /usr/src/version.h > \
@@ -46,9 +46,9 @@ cat \
checksum = arch { checksum = arch {
default = ""; default = "";
amd64 = "mZZqI0tEpqbr3sQKOFLBeNv-DC7pkHNqPI7JdSSmo40sFCF2XnAMcah1DcUK2HTe"; amd64 = "vN5Ts9yAlHTntcQcNGJSisY5guYsYfvGnQqI1NzTBzvhBMPD432WB3B0KFGYQntA";
arm64 = "e6cD6TsBr1e-zONKtocvbRwmSnxqC_2K7A2KvMcO6lnpt4MXL1gsyx6k-BXqC19Z"; arm64 = "FQtpqCA0tlz17RJP8a5t9YEM_6F9kGPqQ9Z60gFrkVP3v8_P-Vnf5S7wLlxyRlOe";
riscv64 = "cljgtOrTCpyXoQLaKVmnnWPbCWkoXuMIVNjc6YXsy-zgsFzRA-H8yfJ1NojS867z"; riscv64 = "U5yQ9TI5_7diyrCcm2Iqh3XCMl0P60oQGeDMWxt3OQ91zFWPQ5FCH-eoYG9tSTMT";
}; };
inputs = [ rsync ]; inputs = [ rsync ];
} }
@@ -86,11 +86,12 @@ install -Dm0500 \
exclusive = true; exclusive = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipConfigure = true;
configure = nil;
// Build, install, and boot kernel before running kselftest on it. // Build, install, and boot kernel before running kselftest on it.
skipCheck = true; check = nil;
make = [ make = [
"-f /usr/src/kernel/Makefile", "-f /usr/src/kernel/Makefile",
@@ -154,7 +155,7 @@ package gen_init_cpio {
enterSource = true; enterSource = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
mkdir -p /work/system/bin/ mkdir -p /work/system/bin/
cc -o /work/system/bin/gen_init_cpio usr/gen_init_cpio.c cc -o /work/system/bin/gen_init_cpio usr/gen_init_cpio.c
+1 -1
View File
@@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/riscv 6.18.43 Kernel Configuration # Linux/riscv 6.18.44 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="clang version 22.1.8" CONFIG_CC_VERSION_TEXT="clang version 22.1.8"
CONFIG_GCC_VERSION=0 CONFIG_GCC_VERSION=0
+2 -2
View File
@@ -1,5 +1,5 @@
#define LINUX_VERSION_CODE 397866 #define LINUX_VERSION_CODE 397868
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c))) #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
#define LINUX_VERSION_MAJOR 6 #define LINUX_VERSION_MAJOR 6
#define LINUX_VERSION_PATCHLEVEL 18 #define LINUX_VERSION_PATCHLEVEL 18
#define LINUX_VERSION_SUBLEVEL 42 #define LINUX_VERSION_SUBLEVEL 44
+1 -1
View File
@@ -22,7 +22,7 @@ package kmod {
}; };
// makes assumptions about the running kernel // makes assumptions about the running kernel
skipTest = true; test = false;
}; };
inputs = [ inputs = [
+2 -2
View File
@@ -18,8 +18,8 @@ package libaio {
env = [ "PATH=/system/sbin" ]; env = [ "PATH=/system/sbin" ];
bin = [ "bash" ]; bin = [ "bash" ];
exec = make { exec = make {
inPlace = true; chdir = false;
skipConfigure = true; configure = nil;
preCheck = "rm harness/cases/20.t; "+ // flaky preCheck = "rm harness/cases/20.t; "+ // flaky
"CFLAGS='"+ "CFLAGS='"+
"-Wno-unknown-warning-option "+ "-Wno-unknown-warning-option "+
+3 -3
View File
@@ -16,9 +16,9 @@ package libbpf {
chmod = true; chmod = true;
exec = make { exec = make {
inPlace = true; chdir = false;
skipConfigure = true; configure = nil;
skipCheck = true; check = nil;
install = "make DESTDIR=/work LIBSUBDIR=lib install"; install = "make DESTDIR=/work LIBSUBDIR=lib install";
}; };
+4 -12
View File
@@ -23,18 +23,10 @@ package libcap {
bin = [ "bash" ]; bin = [ "bash" ];
exec = make { exec = make {
skipConfigure = true; chdir = false;
inPlace = true; configure = nil;
make = [ "CC=cc", "all" ];
make = [ check = [ "CC=cc", "test" ];
"CC=cc",
"all",
];
check = [
"CC=cc",
"test",
];
}; };
inputs = [ inputs = [
+2 -2
View File
@@ -3,7 +3,7 @@ package libexpat {
website = "https://libexpat.github.io"; website = "https://libexpat.github.io";
anitya = 770; anitya = 770;
version# = "2.8.2"; version# = "2.8.3";
source = remoteGitHubRelease { source = remoteGitHubRelease {
suffix = "libexpat/libexpat"; suffix = "libexpat/libexpat";
tag = "R_"+replace { tag = "R_"+replace {
@@ -12,7 +12,7 @@ package libexpat {
new = "_"; new = "_";
}; };
name = "expat-"+version+".tar.bz2"; name = "expat-"+version+".tar.bz2";
checksum = "98Pdyj5QtO7QRtNFXTWsCNCixQDx701ZGql2B-JIrTDkw49J5WXXUwnS4AdMlM4L"; checksum = "prHQc14YY3Gp6BfflneNcVyRXM-AxFCqiigxrGL9TT1sGhVODvI_9JNR2xnZlZSj";
compress = bzip2; compress = bzip2;
}; };
+3 -3
View File
@@ -3,12 +3,12 @@ package libpsl {
website = "https://rockdaboot.github.io/libpsl"; website = "https://rockdaboot.github.io/libpsl";
anitya = 7305; anitya = 7305;
version# = "0.23.1"; version# = "0.23.2";
source = remoteGitHubRelease { source = remoteGitHubRelease {
suffix = "rockdaboot/libpsl"; suffix = "rockdaboot/libpsl";
tag = version; tag = version;
name = "libpsl-"+version+".tar.gz"; name = "libpsl-"+version+".tar.gz";
checksum = "9wu0JxiNGfY3TuYeCmOq9Xm3faPHole5is_3ZL2KUCh8FyaYwpl7a85SNsz8FmPz"; checksum = "-XIKaQK0QoyzXpwezyvGzDdIBCUTqPyd8jU6axIusrnma-qsYxhLUO1Oycwcelr2";
compress = gzip; compress = gzip;
}; };
@@ -22,7 +22,7 @@ test_disable 'int main(){return 0;}' tests/test-is-public-builtin.c
exec = make {}; exec = make {};
inputs = [ inputs = [
pkg-config, pkgconf,
python, python,
]; ];
} }
+2 -2
View File
@@ -20,7 +20,7 @@ package libtirpc {
exec = make { exec = make {
generate = "sh -e ./bootstrap"; generate = "sh -e ./bootstrap";
configure = { configure = {
"CFLAGS": `"$(pkg-config --cflags libbsd-overlay) ${CFLAGS:-}"`; "CFLAGS": `"$(pkgconf --cflags libbsd-overlay) ${CFLAGS:-}"`;
"disable-gssapi"; "disable-gssapi";
}; };
}; };
@@ -28,7 +28,7 @@ package libtirpc {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
libbsd, libbsd,
kernel-headers, kernel-headers,
+4 -6
View File
@@ -16,13 +16,11 @@ package libucontext {
enterSource = true; enterSource = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipConfigure = true; chdir = false;
inPlace = true;
make = [ configure = nil;
"ARCH=" + linuxArch, make = [ "ARCH=" + linuxArch ];
];
install = "make prefix=/system DESTDIR=/work install"; install = "make prefix=/system DESTDIR=/work install";
}; };
} }
+2 -2
View File
@@ -15,14 +15,14 @@ package libxslt {
generate = "NOCONFIGURE=1 ./autogen.sh"; generate = "NOCONFIGURE=1 ./autogen.sh";
// python libxml2 cyclic dependency // python libxml2 cyclic dependency
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
automake, automake,
libtool, libtool,
python, python,
pkg-config, pkgconf,
libxml2, libxml2,
]; ];
+1 -1
View File
@@ -7,7 +7,7 @@ package lit {
exec = pip { exec = pip {
append = [ "llvm", "utils", "lit" ]; append = [ "llvm", "utils", "lit" ];
// already checked during llvm // already checked during llvm
skipCheck = true; check = nil;
}; };
inputs = [ python-setuptools ]; inputs = [ python-setuptools ];
+2 -2
View File
@@ -56,7 +56,7 @@ message(NOTICE "${LLVM_VERSION_MAJOR}")
"COMPILER_RT_BUILD_PROFILE": "OFF"; "COMPILER_RT_BUILD_PROFILE": "OFF";
"COMPILER_RT_BUILD_XRAY": "OFF"; "COMPILER_RT_BUILD_XRAY": "OFF";
}; };
skipTest = true; test = nil;
postInstall = ` postInstall = `
mkdir -p "/work/system/lib/clang/$LLVM_VERSION_MAJOR/lib/" mkdir -p "/work/system/lib/clang/$LLVM_VERSION_MAJOR/lib/"
ln -s \ ln -s \
@@ -119,7 +119,7 @@ package early-runtimes {
"LLVM_ENABLE_ZSTD": "FORCE_ON"; "LLVM_ENABLE_ZSTD": "FORCE_ON";
"LLVM_ENABLE_LIBXML2": "OFF"; "LLVM_ENABLE_LIBXML2": "OFF";
}; };
skipTest = true; test = nil;
}; };
inputs = [ inputs = [
+4 -14
View File
@@ -17,20 +17,10 @@ package lm_sensors {
bin = [ "perl" ]; bin = [ "perl" ];
populateUsrBin = true; populateUsrBin = true;
exec = make { exec = make {
inPlace = true; chdir = false;
skipConfigure = true; configure = nil;
make = [ "CC=cc", "ETCDIR=/system/etc", "PREFIX=/system" ];
make = [ check = [ "CC=cc", "check" ];
"CC=cc",
"ETCDIR=/system/etc",
"PREFIX=/system",
];
check = [
"CC=cc",
"check",
];
install = "make DESTDIR=/work PREFIX=/system install"; install = "make DESTDIR=/work PREFIX=/system install";
}; };
+2 -2
View File
@@ -20,8 +20,8 @@ package lua {
chmod = true; chmod = true;
exec = make { exec = make {
inPlace = true; chdir = false;
skipConfigure = true; configure = nil;
make = [ "CC='clang -fPIC'", "all" ]; make = [ "CC='clang -fPIC'", "all" ];
check = [ "test" ]; check = [ "test" ];
install = ` install = `
+2 -2
View File
@@ -16,11 +16,11 @@ package lvm2 {
exec = make { exec = make {
// requires root // requires root
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
pkg-config, pkgconf,
libaio, libaio,
kernel-headers, kernel-headers,
+2 -2
View File
@@ -3,11 +3,11 @@ package meson {
website = "https://mesonbuild.com"; website = "https://mesonbuild.com";
anitya = 6472; anitya = 6472;
version# = "1.11.2"; version# = "1.12.0";
source = remoteGitHub { source = remoteGitHub {
suffix = "mesonbuild/meson"; suffix = "mesonbuild/meson";
tag = version; tag = version;
checksum = "9AMilGxTOVqPA2DaGMASyuVs1BeTzgDZ0NH2oSYoRZk846ApvfOBa4cc18XEEK7M"; checksum = "K0hm0h26_6e3-1poYZKwj18IB6bdAtYE-whpROtTCSpVN5GllwSwbXC2xPYcSFAJ";
}; };
patches = [ patches = [
"respect-colour.patch", "respect-colour.patch",
+1 -1
View File
@@ -21,6 +21,6 @@ package musl-fts {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
]; ];
} }
+1 -1
View File
@@ -21,6 +21,6 @@ package musl-obstack {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
]; ];
} }
+5 -11
View File
@@ -23,14 +23,9 @@ package musl-headers {
]; ];
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipCheck = true; make = [ "DESTDIR=/work", "install-headers" ];
check = nil;
make = [
"DESTDIR=/work",
"install-headers",
];
install = "# headers installed during make"; install = "# headers installed during make";
}; };
@@ -53,9 +48,8 @@ package musl {
]; ];
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipCheck = true; check = nil;
postInstall = ` postInstall = `
mkdir -p /work/system/bin mkdir -p /work/system/bin
COMPAT_LINKER_NAME="ld-musl-` + linuxArch + `.so.1" COMPAT_LINKER_NAME="ld-musl-` + linuxArch + `.so.1"
+1 -1
View File
@@ -19,7 +19,7 @@ package ncurses {
}; };
// "tests" are actual demo programs, not a test suite. // "tests" are actual demo programs, not a test suite.
skipCheck = true; check = nil;
postInstall = ` postInstall = `
find /work/system/lib \ find /work/system/lib \
@@ -0,0 +1,115 @@
From 7a8f42fb20013a1493d8cae1c43436f85e656f2d Mon Sep 17 00:00:00 2001
From: Zephkeks <zephyrofficialdiscord@gmail.com>
Date: Tue, 13 May 2025 11:04:17 +0200
Subject: [PATCH] CVE-2025-46836: interface.c: Stack-based Buffer Overflow in
get_name()
Coordinated as GHSA-pfwf-h6m3-63wf
---
lib/interface.c | 63 ++++++++++++++++++++++++++++++-------------------
1 file changed, 39 insertions(+), 24 deletions(-)
diff --git a/lib/interface.c b/lib/interface.c
index 71d4163..a054f12 100644
--- a/lib/interface.c
+++ b/lib/interface.c
@@ -211,32 +211,47 @@ static int if_readconf(void)
}
static const char *get_name(char *name, const char *p)
+/* Safe version — guarantees at most IFNAMSIZ1 bytes are copied
+ and the destination buffer is always NULterminated. */
{
- while (isspace(*p))
- p++;
- while (*p) {
- if (isspace(*p))
- break;
- if (*p == ':') { /* could be an alias */
- const char *dot = p++;
- while (*p && isdigit(*p)) p++;
- if (*p == ':') {
- /* Yes it is, backup and copy it. */
- p = dot;
- *name++ = *p++;
- while (*p && isdigit(*p)) {
- *name++ = *p++;
- }
- } else {
- /* No, it isn't */
- p = dot;
- }
- p++;
- break;
- }
- *name++ = *p++;
+ char *dst = name; /* current write ptr */
+ const char *end = name + IFNAMSIZ - 1; /* last byte we may write */
+
+ /* Skip leading whitespace. */
+ while (isspace((unsigned char)*p))
+ ++p;
+
+ /* Copy until whitespace, end of string, or buffer full. */
+ while (*p && !isspace((unsigned char)*p) && dst < end) {
+ if (*p == ':') { /* possible alias veth0:123: */
+ const char *dot = p; /* remember the colon */
+ ++p;
+ while (*p && isdigit((unsigned char)*p))
+ ++p;
+
+ if (*p == ':') { /* confirmed alias */
+ p = dot; /* rewind and copy it all */
+
+ /* copy the colon */
+ if (dst < end)
+ *dst++ = *p++;
+
+ /* copy the digits */
+ while (*p && isdigit((unsigned char)*p) && dst < end)
+ *dst++ = *p++;
+
+ if (*p == ':') /* consume trailing colon */
+ ++p;
+ } else { /* if so treat as normal */
+ p = dot;
+ }
+ break; /* interface name ends here */
+ }
+
+ *dst++ = *p++; /* ordinary character copy */
}
- *name++ = '\0';
+
+ *dst = '\0'; /* always NULterminate */
return p;
}
From ddb0e375fb9ca95bb69335540b85bbdaa2714348 Mon Sep 17 00:00:00 2001
From: Bernd Eckenfels <net-tools@lina.inka.de>
Date: Sat, 17 May 2025 21:53:23 +0200
Subject: [PATCH] Interface statistic regression after 7a8f42fb2
---
lib/interface.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/interface.c b/lib/interface.c
index a054f12..ca4adf1 100644
--- a/lib/interface.c
+++ b/lib/interface.c
@@ -239,12 +239,11 @@ static const char *get_name(char *name, const char *p)
/* copy the digits */
while (*p && isdigit((unsigned char)*p) && dst < end)
*dst++ = *p++;
-
- if (*p == ':') /* consume trailing colon */
- ++p;
} else { /* if so treat as normal */
p = dot;
}
+ if (*p == ':') /* consume trailing colon */
+ ++p;
break; /* interface name ends here */
}
@@ -0,0 +1,53 @@
From a7926399a04ee8e629a02a2aeb6de1952d42d559 Mon Sep 17 00:00:00 2001
From: Bernd Eckenfels <net-tools@lina.inka.de>
Date: Sat, 17 May 2025 21:11:07 +0200
Subject: [PATCH] ipmaddr.c: Stack-based buffer Overflow in parse_hex()
Coordinated as GHSA-h667-qrp8-gj58.
---
ipmaddr.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/ipmaddr.c b/ipmaddr.c
index 64b7564..623fadd 100644
--- a/ipmaddr.c
+++ b/ipmaddr.c
@@ -91,17 +91,17 @@ static int parse_lla(char *str, char *addr)
return len;
}
-static int parse_hex(char *str, unsigned char *addr)
+static int parse_hex(char *str, unsigned char *dst, size_t dstlen)
{
int len=0;
- while (*str) {
+ while (len < dstlen && *str) {
int tmp;
if (str[1] == 0)
return -1;
if (sscanf(str, "%02x", &tmp) != 1)
return -1;
- addr[len] = tmp;
+ dst[len] = tmp;
len++;
str += 2;
}
@@ -152,7 +152,7 @@ void read_dev_mcast(struct ma_info **result_p)
m.addr.family = AF_PACKET;
- len = parse_hex(hexa, (unsigned char*)&m.addr.data);
+ len = parse_hex(hexa, (unsigned char*)&m.addr.data, sizeof(m.addr.data));
if (len >= 0) {
struct ma_info *ma = xmalloc(sizeof(m));
memcpy(ma, &m, sizeof(m));
@@ -222,7 +222,7 @@ void read_igmp6(struct ma_info **result_p)
m.addr.family = AF_INET6;
- len = parse_hex(hexa, (unsigned char*)&m.addr.data);
+ len = parse_hex(hexa, (unsigned char*)&m.addr.data, sizeof(m.addr.data));
if (len >= 0) {
struct ma_info *ma = xmalloc(sizeof(m));
memcpy(ma, &m, sizeof(m));
@@ -0,0 +1,71 @@
From 84041080a5d4794045b098ced90e0309bcbcff44 Mon Sep 17 00:00:00 2001
From: Zephkeks <zephyrofficialdiscord@gmail.com>
Date: Sat, 17 May 2025 22:11:37 +0200
Subject: [PATCH] proc.c: Stack-based Buffer Overflow in net-tools
(proc_gen_fmt)
Coordinated as GHSA-w7jq-cmw2-cq59.
---
lib/proc.c | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/lib/proc.c b/lib/proc.c
index d51d09f..02aae49 100644
--- a/lib/proc.c
+++ b/lib/proc.c
@@ -17,6 +17,8 @@ char *proc_gen_fmt(const char *name, int more, FILE * fh,...)
char buf[512], format[512] = "";
char *title, *head, *hdr;
va_list ap;
+ size_t format_len = 0;
+ size_t format_size = sizeof(format);
if (!fgets(buf, (sizeof buf) - 1, fh))
return NULL;
@@ -33,14 +35,43 @@ char *proc_gen_fmt(const char *name, int more, FILE * fh,...)
*hdr++ = 0;
if (!strcmp(title, head)) {
- strcat(format, va_arg(ap, char *));
+ const char *arg = va_arg(ap, char *);
+ size_t arg_len = strlen(arg);
+
+ /* Check if we have enough space for format specifier + space */
+ if (format_len + arg_len + 1 >= format_size) {
+ fprintf(stderr, "warning: format buffer overflow in %s\n", name);
+ va_end(ap);
+ return NULL;
+ }
+
+ strcpy(format + format_len, arg);
+ format_len += arg_len;
+
title = va_arg(ap, char *);
if (!title)
break;
} else {
- strcat(format, "%*s"); /* XXX */
+ /* Check if we have enough space for "%*s" */
+ if (format_len + 3 >= format_size) {
+ fprintf(stderr, "warning: format buffer overflow in %s\n", name);
+ va_end(ap);
+ return NULL;
+ }
+
+ strcpy(format + format_len, "%*s");
+ format_len += 3;
}
- strcat(format, " ");
+
+ /* Check if we have space for the trailing space */
+ if (format_len + 1 >= format_size) {
+ fprintf(stderr, "warning: format buffer overflow in %s\n", name);
+ va_end(ap);
+ return NULL;
+ }
+
+ format[format_len++] = ' ';
+ format[format_len] = '\0';
}
va_end(ap);
@@ -0,0 +1,22 @@
From f84cd22a921c25c56a6c194d4825dbd9ceea0e5f Mon Sep 17 00:00:00 2001
From: Bernd <bernd@eckenfels.net>
Date: Sat, 22 Mar 2025 00:17:10 +0100
Subject: [PATCH] Update proc.c; remove redundant null check (CodeQL #3) (#44)
---
lib/proc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/proc.c b/lib/proc.c
index ce85fd1..d51d09f 100644
--- a/lib/proc.c
+++ b/lib/proc.c
@@ -35,7 +35,7 @@ char *proc_gen_fmt(const char *name, int more, FILE * fh,...)
if (!strcmp(title, head)) {
strcat(format, va_arg(ap, char *));
title = va_arg(ap, char *);
- if (!title || !head)
+ if (!title)
break;
} else {
strcat(format, "%*s"); /* XXX */
@@ -0,0 +1,33 @@
package net-tools {
description = "the collection of base networking utilities for Linux";
anitya = 10231;
version# = "2.10";
source = remoteTar {
url = "https://downloads.sourceforge.net/project/net-tools/"+
"net-tools-"+version+".tar.xz";
compress = xz;
checksum = "YLmSUeHOYnhYhjvnisX6MQNkPJRzOIgSZBHRiWmBdzzziWYJVY6hOpM8eWnAZ11N";
};
patches = [
"CVE-2025-46836.patch",
"GHSA-h667-qrp8-gj58.patch",
"f84cd22a921c25c56a6c194d4825dbd9ceea0e5f.patch",
"GHSA-w7jq-cmw2-cq59.patch",
];
enterSource = true;
writable = true;
exec = make {
chdir = false;
configureName = "(set +o pipefail && yes '' | make config)";
check = nil;
};
inputs = [
bash,
kernel-headers,
];
}
+2 -2
View File
@@ -50,7 +50,7 @@ package libnftnl {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
libmnl, libmnl,
kernel-headers, kernel-headers,
@@ -95,7 +95,7 @@ chmod +w /etc/ && ln -s ../usr/src/iptables/etc/ethertypes /etc/
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
bash, bash,
python, python,
+1 -1
View File
@@ -12,7 +12,7 @@ package noto {
enterSource = true; enterSource = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
install = ` install = `
DEST=/work/system/share/fonts/noto DEST=/work/system/share/fonts/noto
for font in $(ls -d fonts/*/); do for font in $(ls -d fonts/*/); do
+7 -8
View File
@@ -17,7 +17,7 @@ package nss {
website = "https://firefox-source-docs.mozilla.org/security/nss/index.html"; website = "https://firefox-source-docs.mozilla.org/security/nss/index.html";
anitya = 2503; anitya = 2503;
version# = "3.126"; version# = "3.126.1";
source = remoteGitHub { source = remoteGitHub {
suffix = "nss-dev/nss"; suffix = "nss-dev/nss";
tag = "NSS_"+join { tag = "NSS_"+join {
@@ -28,7 +28,7 @@ package nss {
}; };
sep = "_"; sep = "_";
}+"_RTM"; }+"_RTM";
checksum = "gzMK4RkCHhgmhe33imV0qzZ8e2_VFAsF5M2db-1jrCWzh6XGijm51P2DIdDO2Dsf"; checksum = "3J7o7P3KlE8Cen4fzHLwvDKA1rrcJ84yBTniJHcIBw59LPT-7Q0NxL2CC4BKGW3F";
}; };
extra = [ nspr ]; extra = [ nspr ];
@@ -38,10 +38,9 @@ package nss {
early = "\nln -s extra/nspr/nspr /usr/src/nspr\nchmod +w ../nspr/\n"; early = "\nln -s extra/nspr/nspr /usr/src/nspr\nchmod +w ../nspr/\n";
exec = make { exec = make {
omitDefaults = true; defaults = false;
skipConfigure = true; chdir = false;
inPlace = true; configure = nil;
make = [ make = [
"CCC=clang++", "CCC=clang++",
"NSDISTMODE=copy", "NSDISTMODE=copy",
@@ -49,7 +48,7 @@ package nss {
"USE_64=1", "USE_64=1",
"nss_build_all", "nss_build_all",
]; ];
skipCheck = true; check = nil;
install = ` install = `
cp -r \ cp -r \
/usr/src/dist/. \ /usr/src/dist/. \
@@ -80,7 +79,7 @@ package nss-cacert {
enterSource = true; enterSource = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
mkdir -p /work/system/etc/ssl/{certs/unbundled,certs/hashed,trust-source} mkdir -p /work/system/etc/ssl/{certs/unbundled,certs/hashed,trust-source}
buildcatrust \ buildcatrust \
+3 -5
View File
@@ -5,14 +5,12 @@ package openssl {
// strange malformed tags treated as pre-releases in Anitya // strange malformed tags treated as pre-releases in Anitya
latest = anityaFallback; latest = anityaFallback;
block = "python"; version# = "4.0.1";
version# = "3.6.2";
source = remoteGitHubRelease { source = remoteGitHubRelease {
suffix = "openssl/openssl"; suffix = "openssl/openssl";
tag = "openssl-"+version; tag = "openssl-"+version;
name = "openssl-"+version+".tar.gz"; name = "openssl-"+version+".tar.gz";
checksum = "jH004dXTiE01Hp0kyShkWXwrSHEksZi4i_3v47D9H9Uz9LQ1aMwF7mrl2Tb4t_XA"; checksum = "8FLTB0bZAKyjpmgO4kU5Og-XuSb2_77fxDfEbpOMPKTnIWxQDo7n8e4UdUuc2YIc";
compress = gzip; compress = gzip;
}; };
@@ -21,7 +19,7 @@ package openssl {
]; ];
exec = make { exec = make {
omitDefaults = true; defaults = false;
configureName = "/usr/src/openssl/Configure"; configureName = "/usr/src/openssl/Configure";
configure = { configure = {
+1 -1
View File
@@ -18,7 +18,7 @@ package pango {
"cairo": "enabled"; "cairo": "enabled";
}; };
// Fontconfig error: Cannot load default config file: File not found: /etc/fonts/fonts.conf // Fontconfig error: Cannot load default config file: File not found: /etc/fonts/fonts.conf
skipTest = true; test = false;
}; };
inputs = [ inputs = [
+3 -3
View File
@@ -28,8 +28,8 @@ disable_test ext/POSIX/t/time.t
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
inPlace = true; chdir = false;
configureName = "./Configure"; configureName = "./Configure";
configure = { configure = {
@@ -70,7 +70,7 @@ package perl-Module-Build {
chmod = true; chmod = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
perl Build.PL --prefix=/system perl Build.PL --prefix=/system
./Build build`; ./Build build`;
+16
View File
@@ -0,0 +1,16 @@
package pkgconf {
description = "package compiler and linker metadata toolkit";
website = "https://github.com/pkgconf/pkgconf";
anitya = 12753;
version# = "3.0.5";
source = remoteGitHub {
suffix = "pkgconf/pkgconf";
tag = "pkgconf-"+version;
checksum = "ZWak6fggXCzZkROSnSrl9twRRV9OJA7Q4DamFKEm094e2vgf_99gCxkmrZP3VFYH";
};
exec = meson {
postInstall = "ln -s pkgconf /work/system/bin/pkg-config";
};
}
+3 -3
View File
@@ -3,12 +3,12 @@ package procps {
website = "https://gitlab.com/procps-ng/procps"; website = "https://gitlab.com/procps-ng/procps";
anitya = 3708; anitya = 3708;
version# = "4.0.6"; version# = "4.0.7";
source = remoteGitLab { source = remoteGitLab {
domain = "gitlab.com"; domain = "gitlab.com";
suffix = "procps-ng/procps"; suffix = "procps-ng/procps";
ref = "v"+version; ref = "v"+version;
checksum = "pl_fZLvDlv6iZTkm8l_tHFpzTDVFGCiSJEs3eu0zAX6u36AV36P_En8K7JPScRWM"; checksum = "h5d0Wd_YyDzeRyduE4YawF0edvyMWA3UBcAXWAMg2fdtHhl5i1r0QeDu1-xAyR8g";
}; };
exec = make { exec = make {
@@ -24,6 +24,6 @@ package procps {
libtool, libtool,
gzip, gzip,
pkg-config, pkgconf,
]; ];
} }
+63 -19
View File
@@ -3,11 +3,14 @@ package python {
website = "https://www.python.org"; website = "https://www.python.org";
anitya = 13254; anitya = 13254;
version# = "3.14.7"; // too many inputs; early variant available
bootstrap = false;
version# = "3.15.0";
source = remoteTar { source = remoteTar {
url = "https://www.python.org/ftp/python/"+version+ url = "https://www.python.org/ftp/python/"+version+
"/Python-"+version+".tgz"; "/Python-"+version+"rc1.tgz";
checksum = "hXLV7_BGEFZvQ04DNIlk5IdoRZd9DkQt4abKhc8rWsLXHTeSboAWTewJ6l0-LxVz"; checksum = "llRZNKCqDOxnAiLU-2bSneXZcssNtdzG9bBgfyfiGchLSbT7gNvls4ekdmMklgKl";
compress = gzip; compress = gzip;
}; };
patches = [ "zipfile-no-default-strict_timestamps.patch" ]; patches = [ "zipfile-no-default-strict_timestamps.patch" ];
@@ -159,7 +162,7 @@ package python-setuptools {
// error: invalid command 'dist_info' // error: invalid command 'dist_info'
buildIsolation = true; buildIsolation = true;
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
runtime = [ python ]; runtime = [ python ];
@@ -170,12 +173,13 @@ package python-wheel {
website = "https://peps.python.org/pep-0427"; website = "https://peps.python.org/pep-0427";
anitya = 11428; anitya = 11428;
version# = "0.47.0"; version# = "0.48.0";
source = remoteGitHub { source = remoteGitHub {
suffix = "pypa/wheel"; suffix = "pypa/wheel";
tag = version; tag = version;
checksum = "HZ-MvkUP8mbbx2YmsRNswj_bbOCIiXckuHqL5Qbvb5NxN5DYfWnqwkGNyS7OrId0"; checksum = "h-UZQHS-NwB3b9YxYpJePR5cbDGZaKxz4bdhYjilWdQXAE46SV7A1CwZKzZcuZFh";
}; };
patches = [ "wheel-test-colour.patch" ];
exec = pip { exec = pip {
install = true; install = true;
@@ -209,7 +213,7 @@ package python-vcs-versioning {
// upstream is monorepo of two packages (setuptools-scm) // upstream is monorepo of two packages (setuptools-scm)
append = [ "vcs-versioning" ]; append = [ "vcs-versioning" ];
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
@@ -243,7 +247,7 @@ package python-setuptools-scm {
// upstream is monorepo of two packages // upstream is monorepo of two packages
append = [ "setuptools-scm" ]; append = [ "setuptools-scm" ];
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
@@ -273,7 +277,7 @@ package python-flit-core {
// upstream has other unused packages with many dependencies // upstream has other unused packages with many dependencies
append = [ "flit_core" ]; append = [ "flit_core" ];
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
runtime = [ python ]; runtime = [ python ];
@@ -293,7 +297,7 @@ package python-packaging {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-flit-core ]; inputs = [ python-flit-core ];
@@ -314,7 +318,7 @@ package python-pathspec {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-flit-core ]; inputs = [ python-flit-core ];
@@ -335,7 +339,7 @@ package python-trove-classifiers {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-setuptools ]; inputs = [ python-setuptools ];
@@ -360,30 +364,68 @@ package python-pluggy {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-setuptools-scm ]; inputs = [ python-setuptools-scm ];
runtime = [ python ]; runtime = [ python ];
} }
package python-poetry-core {
description = "poetry PEP 517 Build Backend & Core Utilities";
website = "https://github.com/python-poetry/poetry-core";
anitya = 71155;
version# = "2.4.1";
source = remoteGitHub {
suffix = "python-poetry/poetry-core";
tag = version;
checksum = "tf9OeSUv9TJwKd48fQIU2uGtZ36GN-PDmPDZzjClozzLjv-rQ5nIbOg9gOXpegiH";
};
exec = pip {
// pytest circular dependency
check = nil;
};
}
package python-tomlkit {
description = "style-preserving TOML library for Python";
website = "https://github.com/python-poetry/tomlkit";
anitya = 19609;
version# = "0.15.1";
source = remoteGitHub {
suffix = "python-poetry/tomlkit";
tag = version;
checksum = "6n8h0Yf-OO0ARildxqyB1mB1EhS7uALtqFJqD7t7G1JSFTTb9RGRWSpCg-vamuu8";
};
exec = pip {
// pytest circular dependency
check = nil;
};
inputs = [ python-poetry-core ];
}
package python-hatchling { package python-hatchling {
description = "the extensible, standards compliant build backend used by Hatch"; description = "the extensible, standards compliant build backend used by Hatch";
website = "https://hatch.pypa.io"; website = "https://hatch.pypa.io";
anitya = 16137; anitya = 16137;
version# = "1.17.1"; version# = "1.18.0";
source = remoteGitHub { source = remoteGitHub {
suffix = "pypa/hatch"; suffix = "pypa/hatch";
tag = "hatch-v"+version; tag = "hatch-v"+version;
checksum = "FK9PkGIkL3wyVFHOKrx9lSRqoevuQ_TFrN-pMqsoFKsh5eim4pfzx7MvL3ioif9o"; checksum = "a_ntndxBlMdqSVW3PkiAY42m-NDgyWJcKLWFIVTB_5PciVeJdYYdbcdF6jsd0U96";
}; };
exec = pip { exec = pip {
// upstream has other unused packages with many dependencies // upstream has other unused packages with many dependencies
append = [ "backend" ]; append = [ "backend" ];
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
@@ -391,6 +433,7 @@ package python-hatchling {
python-pathspec, python-pathspec,
python-trove-classifiers, python-trove-classifiers,
python-pluggy, python-pluggy,
python-tomlkit,
]; ];
runtime = [ runtime = [
@@ -398,6 +441,7 @@ package python-hatchling {
python-pathspec, python-pathspec,
python-trove-classifiers, python-trove-classifiers,
python-pluggy, python-pluggy,
python-tomlkit,
]; ];
} }
@@ -415,7 +459,7 @@ package python-pygments {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-hatchling ]; inputs = [ python-hatchling ];
@@ -440,7 +484,7 @@ package python-iniconfig {
exec = pip { exec = pip {
// pytest circular dependency // pytest circular dependency
skipCheck = true; check = nil;
}; };
inputs = [ python-setuptools-scm ]; inputs = [ python-setuptools-scm ];
@@ -465,7 +509,7 @@ package python-pytest {
exec = pip { exec = pip {
// many dependencies // many dependencies
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
@@ -0,0 +1,21 @@
diff --git a/tests/commands/util.py b/tests/commands/util.py
index 5d139d9..d18d103 100644
--- a/tests/commands/util.py
+++ b/tests/commands/util.py
@@ -2,7 +2,7 @@ from __future__ import annotations
import sys
from io import StringIO
-from os import PathLike
+from os import PathLike, environ
from subprocess import CalledProcessError
from unittest.mock import patch
@@ -10,6 +10,7 @@ import pytest
from wheel._commands import main
+environ["NO_COLOR"] = "1"
def run_command(
command: str, *args: str | PathLike, catch_systemexit: bool = True
@@ -0,0 +1,12 @@
diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write
index 236cb8ac37..0eac14005e 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -279,6 +279,7 @@ read 1048576/1048576 bytes at offset 0
return log
def test_timeout_break_guest(self):
+ return
log = self.do_cbw_timeout('break-guest-write')
# macOS and FreeBSD tend to represent ETIMEDOUT as
# "Operation timed out", when Linux prefer
@@ -0,0 +1,16 @@
diff --git a/tests/qemu-iotests/150 b/tests/qemu-iotests/150
index fab0faa389..d71fb5978d 100755
--- a/tests/qemu-iotests/150
+++ b/tests/qemu-iotests/150
@@ -41,6 +41,11 @@ _supported_fmt raw qcow2
_supported_proto file
_supported_os Linux
+# work directory is never an overlay
+if [ "$(stat -fc '%T' /work/)" = "zfs" ]; then
+ _notrun 'fails on zfs'
+fi
+
img_size=1048576
@@ -0,0 +1,13 @@
diff --git a/configure b/configure
index 6ddfe4b534..1cba33d562 100755
--- a/configure
+++ b/configure
@@ -1946,7 +1946,7 @@ if test "$skip_meson" = no; then
test -n "$gdb_bin" && meson_option_add "-Dgdb=$gdb_bin"
run_meson() {
- NINJA=$ninja $meson setup "$@" "$PWD" "$source_path"
+ NINJA=$ninja CLICOLOR_FORCE=1 $meson setup "$@" "$PWD" "$source_path"
}
eval run_meson $meson_options
if test "$?" -ne 0 ; then
+11 -8
View File
@@ -3,16 +3,22 @@ package qemu {
website = "https://www.qemu.org"; website = "https://www.qemu.org";
anitya = 13607; anitya = 13607;
version# = "11.0.3"; version# = "11.1.0";
source = remoteTar { source = remoteTar {
url = "https://download.qemu.org/qemu-"+version+".tar.bz2"; url = "https://download.qemu.org/qemu-"+version+".tar.bz2";
checksum = "cY1nZe92-WGeOErkkEXU0pDidJxBFgF4JCtUv1IJk0qVUYHw3VSZfVms1NqWfTLq"; checksum = "nOjPiAFhPGVBnM2rYokJhMDUhFM_6ec-B2N-1-LB1wmCiLzF5_ppqSgkNESuoBFu";
compress = bzip2; compress = bzip2;
}; };
patches = [ patches = [
"meson-colour.patch",
"iotests-zfs.patch",
"disable-mcast-test.patch", "disable-mcast-test.patch",
// fails with ipv6 disabled // fails with ipv6 disabled
"disable-netdev-socket.patch", "disable-netdev-socket.patch",
// fails on a slower machine
"copy-before-write-spurious.patch",
]; ];
// configure script uses source as scratch space // configure script uses source as scratch space
@@ -29,10 +35,6 @@ sed -i \
tests/qemu-iotests/[0-9][0-9][0-9]* \ tests/qemu-iotests/[0-9][0-9][0-9]* \
tests/qemu-iotests/tests/copy-before-write \ tests/qemu-iotests/tests/copy-before-write \
tests/qemu-iotests/tests/file-io-error.out tests/qemu-iotests/tests/file-io-error.out
cat << EOF > tests/qemu-iotests/150
#!/bin/sh
_notrun 'appears to spuriously fail on zfs'
EOF
`; `;
exec = make { exec = make {
@@ -56,16 +58,17 @@ EOF
check = [ check = [
"TIMEOUT_MULTIPLIER=5", "TIMEOUT_MULTIPLIER=5",
"check",
]; ];
}; };
inputs = [ inputs = [
bash, bash,
python,
python-setuptools, python-setuptools,
python-wheel, python-wheel,
meson,
ninja, ninja,
pkg-config, pkgconf,
diffutils, diffutils,
openssl, openssl,
+3 -2
View File
@@ -15,7 +15,8 @@ package rsync {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
configure = { configure = {
"disable-openssl"; "disable-openssl";
"disable-xxhash"; "disable-xxhash";
@@ -24,6 +25,6 @@ package rsync {
}; };
// circular dependency // circular dependency
skipCheck = true; check = nil;
}; };
} }
+1 -1
View File
@@ -14,7 +14,7 @@ package spirv-headers {
exec = cmake { exec = cmake {
// upstream has no tests // upstream has no tests
skipTest = true; test = nil;
}; };
} }
+3 -4
View File
@@ -28,10 +28,9 @@ package squashfs-tools {
early = "cd squashfs-tools"; early = "cd squashfs-tools";
exec = make { exec = make {
skipConfigure = true; chdir = false;
inPlace = true; configure = nil;
check = nil;
skipCheck = true;
install = "make INSTALL_PREFIX=/work/system install"; install = "make INSTALL_PREFIX=/work/system install";
}; };
+1 -1
View File
@@ -19,7 +19,7 @@ package tamago {
enterSource = true; enterSource = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = ` build = `
mkdir /work/system/ mkdir /work/system/
cp -r . /work/system/tamago cp -r . /work/system/tamago
+8 -8
View File
@@ -22,10 +22,10 @@ package toybox {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
inPlace = true; chdir = false;
skipConfigure = true;
configure = nil;
preMake = ` preMake = `
LDFLAGS="${LDFLAGS:-''} -static" LDFLAGS="${LDFLAGS:-''} -static"
@@ -50,7 +50,7 @@ sed -i \
"USER=cure", "USER=cure",
"tests", "tests",
]; ];
skipEarlyStageCheck = true; checkEarly = false;
install = "PREFIX=/work/system/bin make install_flat"; install = "PREFIX=/work/system/bin make install_flat";
@@ -80,10 +80,10 @@ package toybox-early {
toyboxEarly = true; toyboxEarly = true;
exec = make { exec = make {
omitDefaults = true; defaults = false;
inPlace = true; chdir = false;
skipConfigure = true;
configure = nil;
preMake = ` preMake = `
LDFLAGS="${LDFLAGS:-''} -static" LDFLAGS="${LDFLAGS:-''} -static"
@@ -115,7 +115,7 @@ CONFIG_DIFF=y
"USER=cure", "USER=cure",
"tests", "tests",
]; ];
skipEarlyStageCheck = true; checkEarly = false;
install = "PREFIX=/work/system/bin make install_flat"; install = "PREFIX=/work/system/bin make install_flat";
+1 -1
View File
@@ -20,7 +20,7 @@ package unzip {
chmod = true; chmod = true;
exec = generic { exec = generic {
inPlace = true; chdir = false;
build = `unix/configure build = `unix/configure
make -f unix/Makefile generic1`; make -f unix/Makefile generic1`;
install = ` install = `
+1 -1
View File
@@ -47,7 +47,7 @@ package util-linux {
// check script claims: // check script claims:
// For development purpose only. // For development purpose only.
// Don't execute on production system! // Don't execute on production system!
skipCheck = true; check = nil;
}; };
inputs = [ inputs = [
+2 -2
View File
@@ -17,14 +17,14 @@ package vim {
enterSource = true; enterSource = true;
exec = make { exec = make {
inPlace = true; chdir = false;
configure = { configure = {
"with-tlib": "ncursesw"; "with-tlib": "ncursesw";
}; };
check = [ "test" ]; check = [ "test" ];
// very expensive // very expensive
skipCheck = true; check = nil;
}; };
inputs = [ ncurses ]; inputs = [ ncurses ];
+20 -20
View File
@@ -34,7 +34,7 @@ package libxtrans {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
]; ];
@@ -59,7 +59,7 @@ package xorgproto {
inputs = [ inputs = [
automake, automake,
pkg-config, pkgconf,
util-macros, util-macros,
]; ];
@@ -121,7 +121,7 @@ package xcb {
inputs = [ inputs = [
python, python,
pkg-config, pkgconf,
xcb-proto, xcb-proto,
libXau, libXau,
@@ -148,7 +148,7 @@ package libxcb-keysyms {
exec = make {}; exec = make {};
inputs = [ inputs = [
pkg-config, pkgconf,
xcb, xcb,
]; ];
@@ -172,7 +172,7 @@ package libxcb-wm {
inputs = [ inputs = [
m4, m4,
pkg-config, pkgconf,
xcb, xcb,
]; ];
@@ -196,7 +196,7 @@ package libxcb-util {
exec = make {}; exec = make {};
inputs = [ inputs = [
pkg-config, pkgconf,
util-macros, util-macros,
xcb, xcb,
@@ -220,7 +220,7 @@ package libxcb-image {
exec = make {}; exec = make {};
inputs = [ inputs = [
pkg-config, pkgconf,
libxcb-util, libxcb-util,
]; ];
@@ -244,7 +244,7 @@ package libxcb-render-util {
exec = make {}; exec = make {};
inputs = [ inputs = [
pkg-config, pkgconf,
util-macros, util-macros,
xcb, xcb,
@@ -278,7 +278,7 @@ package libX11 {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
libxtrans, libxtrans,
@@ -309,7 +309,7 @@ package libXext {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
libX11, libX11,
@@ -338,7 +338,7 @@ package libXfixes {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
xorgproto, xorgproto,
@@ -368,7 +368,7 @@ package libXrender {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
libX11, libX11,
@@ -397,7 +397,7 @@ package libxshmfence {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
xorgproto, xorgproto,
@@ -424,7 +424,7 @@ package libXxf86vm {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
libXext, libXext,
@@ -454,7 +454,7 @@ package libXrandr {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
libXext, libXext,
@@ -488,7 +488,7 @@ package font-util {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
]; ];
@@ -514,7 +514,7 @@ package libfontenc {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
font-util, font-util,
@@ -561,7 +561,7 @@ package xkbcomp {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
byacc, byacc,
util-macros, util-macros,
@@ -591,7 +591,7 @@ package libXfont2 {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
freetype, freetype,
@@ -642,7 +642,7 @@ package libXdmcp {
inputs = [ inputs = [
automake, automake,
libtool, libtool,
pkg-config, pkgconf,
util-macros, util-macros,
xorgproto, xorgproto,
+14
View File
@@ -320,6 +320,8 @@ type PackageAttr struct {
// Whether to replace /usr/bin/ with a symlink to /bin/. // Whether to replace /usr/bin/ with a symlink to /bin/.
PopulateUsrBin bool PopulateUsrBin bool
// Whether this package is disallowed from bootstrap stages.
Std bool
// Hint for an early variant of toybox to be used when available. // Hint for an early variant of toybox to be used when available.
Early bool Early bool
// Whether to omit output colour environment variables. // Whether to omit output colour environment variables.
@@ -375,6 +377,14 @@ func (t Toolchain) Append(a []pkg.Artifact, handles ...ArtifactH) []pkg.Artifact
return a return a
} }
// A BootstrapError describes a package disallowed from bootstrap stages.
type BootstrapError string
func (e BootstrapError) Error() string {
return "package " + strconv.Quote(string(e)) +
" must not be built by bootstrap stages"
}
// New constructs a [pkg.Artifact] via a build system helper. // New constructs a [pkg.Artifact] via a build system helper.
func (t Toolchain) New( func (t Toolchain) New(
name, version string, name, version string,
@@ -387,6 +397,10 @@ func (t Toolchain) New(
attr = new(PackageAttr) attr = new(PackageAttr)
} }
if attr.Std && !t.stage.isStd() {
panic(BootstrapError(name))
}
if name == "" || version == "" { if name == "" || version == "" {
panic("name must be non-empty") panic("name must be non-empty")
} }
+46 -12
View File
@@ -811,14 +811,17 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr GenericHelper var attr GenericHelper
chdir := true
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("inPlace"): &attr.InPlace, k("chdir"): &chdir,
k("build"): &attr.Build, k("build"): &attr.Build,
k("check"): &attr.Check, k("check"): &attr.Check,
k("install"): &attr.Install, k("install"): &attr.Install,
}); err != nil { }); err != nil {
return return
} }
attr.InPlace = !chdir
v = &attr v = &attr
set = true set = true
return return
@@ -828,28 +831,33 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr MakeHelper var attr MakeHelper
defaults, chdir, checkEarly := true, true, true
attr.Configure, attr.Check = []KV{}, []string{}
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("omitDefaults"): &attr.OmitDefaults, k("defaults"): &defaults,
k("generate"): &attr.Generate, k("generate"): &attr.Generate,
k("preMake"): &attr.ScriptMakeEarly, k("preMake"): &attr.ScriptMakeEarly,
k("preCheck"): &attr.ScriptCheckEarly, k("preCheck"): &attr.ScriptCheckEarly,
k("postInstall"): &attr.Script, k("postInstall"): &attr.Script,
k("inPlace"): &attr.InPlace, k("chdir"): &chdir,
k("skipConfigure"): &attr.SkipConfigure,
k("configureName"): &attr.ConfigureName, k("configureName"): &attr.ConfigureName,
k("forceAutoconf"): &attr.ForceAutoconf, k("forceAutoconf"): &attr.ForceAutoconf,
k("configure"): &attr.Configure, k("configure"): &attr.Configure,
k("host"): &attr.Host, k("host"): &attr.Host,
k("build"): &attr.Build, k("build"): &attr.Build,
k("make"): &attr.Make, k("make"): &attr.Make,
k("skipCheck"): &attr.SkipCheck,
k("check"): &attr.Check, k("check"): &attr.Check,
k("install"): &attr.Install, k("install"): &attr.Install,
k("skipEarlyStageCheck"): &attr.SkipCheckEarly, k("checkEarly"): &checkEarly,
}); err != nil { }); err != nil {
return return
} }
attr.OmitDefaults, attr.InPlace = !defaults, !chdir
attr.SkipConfigure = attr.Configure == nil
attr.SkipCheck = attr.Check == nil
attr.SkipCheckEarly = !checkEarly
v = &attr v = &attr
set = true set = true
return return
@@ -859,17 +867,20 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr CMakeHelper var attr CMakeHelper
var test azalea.AString
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("append"): &attr.Append, k("append"): &attr.Append,
k("buildType"): &attr.BuildType, k("buildType"): &attr.BuildType,
k("cache"): &attr.Cache, k("cache"): &attr.Cache,
k("postInstall"): &attr.Script, k("postInstall"): &attr.Script,
k("test"): &attr.Test, k("test"): &test,
k("skipTest"): &attr.SkipTest,
k("make"): &attr.Make, k("make"): &attr.Make,
}); err != nil { }); err != nil {
return return
} }
attr.Test = test.V
attr.SkipTest = test.Nil
v = &attr v = &attr
set = true set = true
return return
@@ -879,18 +890,21 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr MesonHelper var attr MesonHelper
test := true
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("muon"): &attr.Muon, k("muon"): &attr.Muon,
k("preCompile"): &attr.ScriptCompileEarly, k("preCompile"): &attr.ScriptCompileEarly,
k("postCompile"): &attr.ScriptCompiled, k("postCompile"): &attr.ScriptCompiled,
k("postInstall"): &attr.Script, k("postInstall"): &attr.Script,
k("setup"): &attr.Setup, k("setup"): &attr.Setup,
k("skipTest"): &attr.SkipTest, k("test"): &test,
k("skipTests"): &attr.SkipTests, k("skipTests"): &attr.SkipTests,
k("interactiveTest"): &attr.InteractiveTest, k("interactiveTest"): &attr.InteractiveTest,
}); err != nil { }); err != nil {
return return
} }
attr.SkipTest = !test
v = &attr v = &attr
set = true set = true
return return
@@ -900,11 +914,13 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr MakeMakerHelper var attr MakeMakerHelper
doCheck := true
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("skipCheck"): &attr.SkipCheck, k("check"): &doCheck,
}); err != nil { }); err != nil {
return return
} }
attr.SkipCheck = !doCheck
v = &attr v = &attr
set = true set = true
return return
@@ -914,17 +930,20 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs, args azalea.FArgs,
) (v any, set bool, err error) { ) (v any, set bool, err error) {
var attr PipHelper var attr PipHelper
var scriptCheck azalea.AString
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("append"): &attr.Append, k("append"): &attr.Append,
k("buildIsolation"): &attr.BuildIsolation, k("buildIsolation"): &attr.BuildIsolation,
k("enterSource"): &attr.EnterSource, k("enterSource"): &attr.EnterSource,
k("install"): &attr.Install, k("install"): &attr.Install,
k("skipCheck"): &attr.SkipCheck, k("check"): &scriptCheck,
k("check"): &attr.Check,
k("postInstall"): &attr.Script, k("postInstall"): &attr.Script,
}); err != nil { }); err != nil {
return return
} }
attr.Check = scriptCheck.V
attr.SkipCheck = scriptCheck.Nil
v = &attr v = &attr
set = true set = true
return return
@@ -975,6 +994,13 @@ type evalContext struct {
t Toolchain t Toolchain
} }
// HelperError describes a package with nil helper.
type HelperError string
func (e HelperError) Error() string {
return "package " + strconv.Quote(string(e)) + " has no exec helper"
}
// pf implements [azalea.PF]. // pf implements [azalea.PF].
func (ctx *evalContext) pf( func (ctx *evalContext) pf(
name azalea.Ident, name azalea.Ident,
@@ -998,6 +1024,8 @@ func (ctx *evalContext) pf(
overlay string overlay string
inputs, runtimes, extra azalea.Array inputs, runtimes, extra azalea.Array
bootstrap = true
) )
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{ if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("description"): &meta.Description, k("description"): &meta.Description,
@@ -1020,6 +1048,7 @@ func (ctx *evalContext) pf(
k("exclusive"): &attr.Exclusive, k("exclusive"): &attr.Exclusive,
k("toyboxEarly"): &attr.Early, k("toyboxEarly"): &attr.Early,
k("minimal"): &attr.NoToolchain, k("minimal"): &attr.NoToolchain,
k("bootstrap"): &bootstrap,
k("checksum"): &kc, k("checksum"): &kc,
k("output"): &output, k("output"): &output,
@@ -1032,6 +1061,7 @@ func (ctx *evalContext) pf(
}); err != nil { }); err != nil {
return return
} }
attr.Std = !bootstrap
var inputsH, extraH P var inputsH, extraH P
if inputsH, err = toHandles(inputs); err != nil { if inputsH, err = toHandles(inputs); err != nil {
return return
@@ -1149,6 +1179,10 @@ func (ctx *evalContext) pf(
} }
} }
if helper == nil {
panic(HelperError(name))
}
v = cachedArtifact{&meta, ctx.t.New( v = cachedArtifact{&meta, ctx.t.New(
meta.Name, meta.Name,
meta.Version, meta.Version,