Compare commits
189
Commits
17383ab353
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9803e5be7
|
||
|
|
a28e01b863
|
||
|
|
84ab8daf6a
|
||
|
|
2ca57764a3
|
||
|
|
f189cc25c6
|
||
|
|
fa7e06ebd6
|
||
|
|
142152f6b8
|
||
|
|
b3ac03059f
|
||
|
|
cbd95294ba
|
||
|
|
ace59607f2
|
||
|
|
692c28ad29
|
||
|
|
df04ad592e
|
||
|
|
7737fd03ae
|
||
|
|
476945da23
|
||
|
|
85860c858a
|
||
|
|
60a62ae5f7
|
||
|
|
5313ea627b
|
||
|
|
5352598c68
|
||
|
|
9331a5cbeb
|
||
|
|
9b675c45ff
|
||
|
|
5cf1d70c7b
|
||
|
|
e58b6eb171
|
||
|
|
1625aaee80
|
||
|
|
203ce6864b
|
||
|
|
050051e593
|
||
|
|
530b63ca70
|
||
|
|
8821d34b10
|
||
|
|
054a8813d7
|
||
|
|
1bc16b51a6
|
||
|
|
3718c044c4
|
||
|
|
07e92db918
|
||
|
|
d2ee7cb551
|
||
|
|
39e757a84d
|
||
|
|
a431f16e6f
|
||
|
|
1f45d44e7f
|
||
|
|
92d01752ab
|
||
|
|
82bf46d23f
|
||
|
|
2abcb99ea2
|
||
|
|
2218efc0cf
|
||
|
|
30c5525d7b
|
||
|
|
bf6d1ada71
|
||
|
|
16294a35ee
|
||
|
|
22756af8fb
|
||
|
|
739ae4a7cf
|
||
|
|
eec89c4519
|
||
|
|
7193656b6a
|
||
|
|
7d86e19c07
|
||
|
|
f1ffb180bc
|
||
|
|
7f690145e3
|
||
|
|
c79ae7aed6
|
||
|
|
396ae2ba2a
|
||
|
|
1e85dca9e2
|
||
|
|
d236c9eaf7
|
||
|
|
3c1a6f0793
|
||
|
|
16f84f9499
|
||
|
|
9deed030f0
|
||
|
|
69095e03c9
|
||
|
|
8138b2a3f0
|
||
|
|
308c7d1846
|
||
|
|
807f4ccbeb
|
||
|
|
f1dd3a085b
|
||
|
|
b37c1d8993
|
||
|
|
6a7f124deb
|
||
|
|
a9a32284b6
|
||
|
|
255a1bbf74
|
||
|
|
96cdf4cc07
|
||
|
|
35a55854fd
|
||
|
|
2f057cc72f
|
||
|
|
3356ca3e46
|
||
|
|
ccef0a086a
|
||
|
|
edb694fb41
|
||
|
|
90535adc89
|
||
|
|
6fed6d67bd
|
||
|
|
dcaf67b3d7
|
||
|
|
c7de3d45e3
|
||
|
|
d9bddff160
|
||
|
|
5c6dcce543
|
||
|
|
905a69d2a0
|
||
|
|
e453bc67d0
|
||
|
|
0fa145a1a0
|
||
|
|
b5a65d1255
|
||
|
|
ccdc0fa37e
|
||
|
|
b97518552d
|
||
|
|
67d14dc12c
|
||
|
|
695b1b4845
|
||
|
|
2e5d954f49
|
||
|
|
e6af0c405a
|
||
|
|
599a761b27
|
||
|
|
b7aa91f08f
|
||
|
|
280a736ce3
|
||
|
|
4e41b9bc99
|
||
|
|
153c980a61
|
||
|
|
a2f97f7e0f
|
||
|
|
5e1b4bb0b8
|
||
|
|
e73f9e0626
|
||
|
|
ddd90b780b
|
||
|
|
89c32f5614
|
||
|
|
1567a3e582
|
||
|
|
aa9952cd9e
|
||
|
|
99efc551ad
|
||
|
|
4dbfee0698
|
||
|
|
4e65e41101
|
||
|
|
b8306fe9e2
|
||
|
|
6b246e9036
|
||
|
|
869820ec6d
|
||
|
|
6fb2065a51
|
||
|
|
698fd2d66a
|
||
|
|
4cfbc93aa0
|
||
|
|
feec4b0d22
|
||
|
|
6487b41d92
|
||
|
|
7908fb9583
|
||
|
|
95aa7c205c
|
||
|
|
bd0cc3656f
|
||
|
|
0219240adb
|
||
|
|
aa4a15fc2c
|
||
|
|
0d3efeb456
|
||
|
|
35147f6dfb
|
||
|
|
e5abf51296
|
||
|
|
e26914cd6f
|
||
|
|
b647170d0c
|
||
|
|
5e655a0bf6
|
||
|
|
89eb3d27aa
|
||
|
|
3b7a22ff9b
|
||
|
|
6c2ca507b9
|
||
|
|
1a8212ee02
|
||
|
|
84bb2a5038
|
||
|
|
46b247f911
|
||
|
|
390f3b2dae
|
||
|
|
5d3e47d8e7
|
||
|
|
6f2852547b
|
||
|
|
3cff369368
|
||
|
|
09de939955
|
||
|
|
e0eec632d0
|
||
|
|
67dbb68818
|
||
|
|
0e689d9983
|
||
|
|
21a4067592
|
||
|
|
639766dfca
|
||
|
|
e4f025b9f1
|
||
|
|
1b65c8107c
|
||
|
|
1857ad8763
|
||
|
|
c822ff9aca
|
||
|
|
9df1609660
|
||
|
|
22e9e85a03
|
||
|
|
b79aa3ea1c
|
||
|
|
8d9b14dfe1
|
||
|
|
5770f957e5
|
||
|
|
e7903cf7e2
|
||
|
|
df199a8774
|
||
|
|
d906bc2ee0
|
||
|
|
e0e9910243
|
||
|
|
c8d54cebe9
|
||
|
|
74e7fb7818
|
||
|
|
8366cdd224
|
||
|
|
05f9939077
|
||
|
|
ae30f627dd
|
||
|
|
b4916dd431
|
||
|
|
4cf235675a
|
||
|
|
098943ab46
|
||
|
|
fb3df67ba6
|
||
|
|
b1c882b4de
|
||
|
|
0ed0d8abde
|
||
|
|
51e4426a4f
|
||
|
|
316edeb17b
|
||
|
|
8facae53c7
|
||
|
|
7881bfd027
|
||
|
|
9e9469fe6c
|
||
|
|
b6d90eb8e0
|
||
|
|
879f911fd8
|
||
|
|
1066fc0097
|
||
|
|
3a3d8efb1e
|
||
|
|
cb8c9e4e68
|
||
|
|
1c4a3b72bf
|
||
|
|
fdca05487c
|
||
|
|
89db730bb9
|
||
|
|
5161fc24ec
|
||
|
|
e1f16e7720
|
||
|
|
8e9b3a2ed1
|
||
|
|
fd0a81b304
|
||
|
|
1d6d89a11a
|
||
|
|
6a6fdab92d
|
||
|
|
67c67574e8
|
||
|
|
79be25433b
|
||
|
|
a4d78e8a32
|
||
|
|
ab3c37f75a
|
||
|
|
e6757fe254
|
||
|
|
b0f0d9e060
|
||
|
|
ce58895a0d
|
||
|
|
3c78551b24
|
||
|
|
223e8e56b3
|
@@ -11,7 +11,7 @@
|
|||||||
<a href="https://git.gensokyo.uk/rosa/hakurei/actions"><img src="https://git.gensokyo.uk/rosa/hakurei/actions/workflows/test.yml/badge.svg?branch=staging&style=flat-square" alt="Gitea Workflow Status" /></a>
|
<a href="https://git.gensokyo.uk/rosa/hakurei/actions"><img src="https://git.gensokyo.uk/rosa/hakurei/actions/workflows/test.yml/badge.svg?branch=staging&style=flat-square" alt="Gitea Workflow Status" /></a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://git.gensokyo.uk/rosa/hakurei/releases"><img src="https://img.shields.io/gitea/v/release/rosa/hakurei?gitea_url=https%3A%2F%2Fgit.gensokyo.uk&color=purple" alt="Release" /></a>
|
<a href="https://git.gensokyo.uk/rosa/hakurei/releases"><img src="https://img.shields.io/gitea/v/release/rosa/hakurei?gitea_url=https%3A%2F%2Fgit.gensokyo.uk&color=purple" alt="Release" /></a>
|
||||||
<a href="https://goreportcard.com/report/hakurei.app"><img src="https://goreportcard.com/badge/hakurei.app" alt="Go Report Card" /></a>
|
<a href="https://git.gensokyo.uk/rosa/hakurei/src/branch/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-pink" alt="MIT License" /></a>
|
||||||
<a href="https://hakurei.app"><img src="https://img.shields.io/website?url=https%3A%2F%2Fhakurei.app" alt="Website" /></a>
|
<a href="https://hakurei.app"><img src="https://img.shields.io/website?url=https%3A%2F%2Fhakurei.app" alt="Website" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
v0.4.5
|
v0.4.7
|
||||||
|
|||||||
Vendored
+6
@@ -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"
|
||||||
|
|||||||
Vendored
+3
-3
@@ -57,7 +57,7 @@ func main() {
|
|||||||
verbose := os.Getenv("VERBOSE") != ""
|
verbose := os.Getenv("VERBOSE") != ""
|
||||||
runTests := os.Getenv("HAKUREI_DIST_MAKE") == ""
|
runTests := os.Getenv("HAKUREI_DIST_MAKE") == ""
|
||||||
version = getenv("HAKUREI_VERSION", strings.TrimSpace(version))
|
version = getenv("HAKUREI_VERSION", strings.TrimSpace(version))
|
||||||
prefix := getenv("PREFIX", "/usr")
|
prefix := getenv("PREFIX", "/usr/local")
|
||||||
destdir := getenv("DESTDIR", "dist")
|
destdir := getenv("DESTDIR", "dist")
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
@@ -217,7 +217,7 @@ func main() {
|
|||||||
mustWriteFile("comp/", nil, os.ModeDir|0755)
|
mustWriteFile("comp/", nil, os.ModeDir|0755)
|
||||||
mustWriteFile("comp/_hakurei", comp, 0644)
|
mustWriteFile("comp/_hakurei", comp, 0644)
|
||||||
mustWriteFile("install.sh", []byte(`#!/bin/sh -e
|
mustWriteFile("install.sh", []byte(`#!/bin/sh -e
|
||||||
cd "$(dirname -- "$0")" || exit 1
|
cd "$(dirname -- "$0")"
|
||||||
|
|
||||||
install -vDm0755 "bin/hakurei" "${DESTDIR}`+prefix+`/bin/hakurei"
|
install -vDm0755 "bin/hakurei" "${DESTDIR}`+prefix+`/bin/hakurei"
|
||||||
install -vDm0755 "bin/sharefs" "${DESTDIR}`+prefix+`/bin/sharefs"
|
install -vDm0755 "bin/sharefs" "${DESTDIR}`+prefix+`/bin/sharefs"
|
||||||
@@ -230,7 +230,7 @@ fi
|
|||||||
install -vDm0644 "comp/_hakurei" "${DESTDIR}`+prefix+`/share/zsh/site-functions/_hakurei"
|
install -vDm0644 "comp/_hakurei" "${DESTDIR}`+prefix+`/share/zsh/site-functions/_hakurei"
|
||||||
`), 0755)
|
`), 0755)
|
||||||
|
|
||||||
mustWriteFromPath("README.md", "README.md", 0)
|
mustWriteFromPath("LICENSE", "LICENSE", 0)
|
||||||
mustWriteFile("hsurc.default", []byte("1000 0"), 0400)
|
mustWriteFile("hsurc.default", []byte("1000 0"), 0400)
|
||||||
mustWriteFromPath("bin/hsu", filepath.Join(s, "hsu"), 04511)
|
mustWriteFromPath("bin/hsu", filepath.Join(s, "hsu"), 04511)
|
||||||
for _, name := range []string{
|
for _, name := range []string{
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ func TestHelp(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"main", []string{}, `
|
"main", []string{}, `usage: hakurei [-h | --help] [-v] [--insecure] [--json] <command> [<args>]
|
||||||
Usage: hakurei [-h | --help] [-v] [--insecure] [--json] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
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
|
||||||
@@ -35,10 +35,14 @@ Commands:
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"exec", []string{"exec", "-h"}, `
|
"exec", []string{"exec", "-h"}, `usage: hakurei exec [-h | --help] [--dbus-config <value>]
|
||||||
Usage: hakurei exec [-h | --help] [--dbus-config <value>] [--dbus-system <value>] [--mpris] [--dbus-log] [--id <value>] [-a <int>] [-g <value>] [-d <value>] [-u <value>] [--policy <value>] [--priority <int>] [--private-runtime] [--private-tmpdir] [--wayland] [-X] [--dbus] [--pipewire] [--pulse] COMMAND [OPTIONS]
|
[--dbus-system <value>] [--mpris] [--dbus-log]
|
||||||
|
[--id <value>] [-a <int>] [-g <value>] [-d <value>]
|
||||||
|
[-u <value>] [--policy <value>] [--priority <int>]
|
||||||
|
[--private-runtime] [--private-tmpdir] [--wayland] [-X]
|
||||||
|
[--dbus] [--pipewire] [--pulse] <command> [<args>]
|
||||||
|
|
||||||
Flags:
|
flags:
|
||||||
-X Enable direct connection to X11
|
-X Enable direct connection to X11
|
||||||
-a int
|
-a int
|
||||||
Application identity
|
Application identity
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ func TestEncodeJSON(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{"marshaler", errorJSONMarshaler{},
|
{"marshaler", errorJSONMarshaler{},
|
||||||
`cannot encode json for main.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
|
`cannot encode json for *main.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
|
||||||
{"default", func() {},
|
{"default", func() {},
|
||||||
`cannot write json: json: unsupported type: func()`},
|
`cannot write json: json: unsupported type: func()`},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
@@ -28,6 +29,8 @@ type cache struct {
|
|||||||
idle bool
|
idle bool
|
||||||
// Unset [pkg.CSuppressInit].
|
// Unset [pkg.CSuppressInit].
|
||||||
verboseInit bool
|
verboseInit bool
|
||||||
|
// Whether to enable output colours.
|
||||||
|
color bool
|
||||||
// Unset [pkg.CExternShallow].
|
// Unset [pkg.CExternShallow].
|
||||||
deep bool
|
deep bool
|
||||||
// Loaded artifact of [rosa.QEMU].
|
// Loaded artifact of [rosa.QEMU].
|
||||||
@@ -36,18 +39,32 @@ type cache struct {
|
|||||||
base, mirror string
|
base, mirror string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeTitle sets title of the terminal connected to [message.Msg].
|
||||||
|
func writeTitle(msg message.Msg, s string) {
|
||||||
|
msg.Suspend()
|
||||||
|
w := msg.GetLogger().Writer()
|
||||||
|
_, _ = w.Write([]byte("\x1b]0;" + s + "\a"))
|
||||||
|
msg.Resume()
|
||||||
|
}
|
||||||
|
|
||||||
// open opens the underlying [pkg.Cache].
|
// open opens the underlying [pkg.Cache].
|
||||||
func (cache *cache) open() (err error) {
|
func (cache *cache) open() (err error) {
|
||||||
if cache.c != nil {
|
if cache.c != nil {
|
||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hostname string
|
||||||
|
if hostname, err = os.Hostname(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var base *check.Absolute
|
var base *check.Absolute
|
||||||
if cache.base, err = filepath.Abs(cache.base); err != nil {
|
if cache.base, err = filepath.Abs(cache.base); err != nil {
|
||||||
return
|
return
|
||||||
} else if base, err = check.NewAbs(cache.base); err != nil {
|
} else if base, err = check.NewAbs(cache.base); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var notify chan bool
|
||||||
|
|
||||||
if cache.idle {
|
if cache.idle {
|
||||||
cache.attr.Flags |= pkg.CSchedIdle
|
cache.attr.Flags |= pkg.CSchedIdle
|
||||||
@@ -61,6 +78,11 @@ func (cache *cache) open() (err error) {
|
|||||||
if !cache.deep {
|
if !cache.deep {
|
||||||
cache.attr.Flags |= pkg.CExternShallow
|
cache.attr.Flags |= pkg.CExternShallow
|
||||||
}
|
}
|
||||||
|
if cache.color {
|
||||||
|
cache.attr.Flags |= pkg.CColourOutput
|
||||||
|
notify = make(chan bool, 1<<12)
|
||||||
|
cache.attr.Notify = notify
|
||||||
|
}
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
defer close(done)
|
defer close(done)
|
||||||
@@ -104,6 +126,33 @@ func (cache *cache) open() (err error) {
|
|||||||
cache.c.SetExternal(r)
|
cache.c.SetExternal(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cache.attr.Notify != nil {
|
||||||
|
cache.msg.Suspend()
|
||||||
|
_, _ = cache.msg.GetLogger().Writer().Write([]byte("\x1b[22;0t"))
|
||||||
|
cache.msg.Resume()
|
||||||
|
|
||||||
|
prefix := hostname + ": mbf "
|
||||||
|
go func() {
|
||||||
|
var n, nc uint64
|
||||||
|
for enter := range notify {
|
||||||
|
if enter {
|
||||||
|
nc++
|
||||||
|
} else {
|
||||||
|
nc--
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
|
||||||
|
if nc == 0 {
|
||||||
|
writeTitle(cache.msg, prefix[:len(prefix)-1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
writeTitle(cache.msg, prefix+
|
||||||
|
"("+strconv.FormatUint(nc, 10)+
|
||||||
|
" running, "+strconv.FormatUint(n, 10)+" complete)")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if cache.qemu != nil {
|
if cache.qemu != nil {
|
||||||
var pathname *check.Absolute
|
var pathname *check.Absolute
|
||||||
pathname, _, err = cache.c.Cure(cache.qemu)
|
pathname, _, err = cache.c.Cure(cache.qemu)
|
||||||
@@ -124,6 +173,11 @@ func (cache *cache) open() (err error) {
|
|||||||
func (cache *cache) Close() {
|
func (cache *cache) Close() {
|
||||||
if cache.c != nil {
|
if cache.c != nil {
|
||||||
cache.c.Close()
|
cache.c.Close()
|
||||||
|
if cache.attr.Notify != nil {
|
||||||
|
cache.msg.Suspend()
|
||||||
|
_, _ = cache.msg.GetLogger().Writer().Write([]byte("\x1b[23;0t"))
|
||||||
|
cache.msg.Resume()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func TestNoReply(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<-done
|
<-done
|
||||||
wantIdent := pkg.MustDecode("fiZf-ZY_Yq6qxJNrHbMiIPYCsGkUiKCRsZrcSELXTqZWtCnESlHmzV5ThhWWGGYG")
|
wantIdent := pkg.MustDecode("bpVsJ69hdKPBntMh_u777g7-quFNVmMlBJQOlM_thiQa9JnOFLAbe5OlR4zNjZ32")
|
||||||
if gotIdent := c.Ident(a).Value(); gotIdent != wantIdent {
|
if gotIdent := c.Ident(a).Value(); gotIdent != wantIdent {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"cureFromIR: %s, want %s",
|
"cureFromIR: %s, want %s",
|
||||||
@@ -124,7 +124,7 @@ func TestDaemon(t *testing.T) {
|
|||||||
cancel()
|
cancel()
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
const want = "fiZf-ZY_Yq6qxJNrHbMiIPYCsGkUiKCRsZrcSELXTqZWtCnESlHmzV5ThhWWGGYG"
|
const want = "bpVsJ69hdKPBntMh_u777g7-quFNVmMlBJQOlM_thiQa9JnOFLAbe5OlR4zNjZ32"
|
||||||
if got := filepath.Base(p.String()); got != want {
|
if got := filepath.Base(p.String()); got != want {
|
||||||
t.Errorf("cureRemote: %s, want %s", got, want)
|
t.Errorf("cureRemote: %s, want %s", got, want)
|
||||||
}
|
}
|
||||||
@@ -132,8 +132,8 @@ func TestDaemon(t *testing.T) {
|
|||||||
wantLog := []string{
|
wantLog := []string{
|
||||||
"",
|
"",
|
||||||
"daemon: aborting all pending cures",
|
"daemon: aborting all pending cures",
|
||||||
"daemon: attempting to cancel invalid artifact kQm9fmnCmXST1-MMmxzcau2oKZCXXrlZydo4PkeV5hO_2PKfeC8t98hrbV_ZZx_j",
|
"daemon: attempting to cancel invalid artifact 58Vy_5beLZCvZX__KzRKyIE6vATleaZP1ZBxbqoWnekz9aZ1zkxNgcIUFI5V1_Jf",
|
||||||
"daemon: fulfilled artifact fiZf-ZY_Yq6qxJNrHbMiIPYCsGkUiKCRsZrcSELXTqZWtCnESlHmzV5ThhWWGGYG",
|
"daemon: fulfilled artifact " + want,
|
||||||
}
|
}
|
||||||
gotLog := strings.Split(buf.String(), "\n")
|
gotLog := strings.Split(buf.String(), "\n")
|
||||||
slices.Sort(gotLog)
|
slices.Sort(gotLog)
|
||||||
|
|||||||
+76
-36
@@ -92,6 +92,11 @@ func main() {
|
|||||||
|
|
||||||
var cm cache
|
var cm cache
|
||||||
defer func() { cm.Close() }()
|
defer func() { cm.Close() }()
|
||||||
|
if cm.color = ext.Isatty(syscall.Stderr) &&
|
||||||
|
os.Getenv("NO_COLOR") == "" &&
|
||||||
|
os.Getenv("TERM") != "dumb"; cm.color {
|
||||||
|
log.SetPrefix("\x1b[2mmbf: \x1b[0m")
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flagQuiet bool
|
flagQuiet bool
|
||||||
@@ -210,6 +215,10 @@ func main() {
|
|||||||
&cm.attr.Jobs,
|
&cm.attr.Jobs,
|
||||||
"jobs", command.IntFlag(0),
|
"jobs", command.IntFlag(0),
|
||||||
"Preferred number of jobs to run, when applicable",
|
"Preferred number of jobs to run, when applicable",
|
||||||
|
).Flag(
|
||||||
|
&cm.attr.Load,
|
||||||
|
"load-average", command.IntFlag(0),
|
||||||
|
"Preferred load average number, when applicable",
|
||||||
).Flag(
|
).Flag(
|
||||||
&cm.base,
|
&cm.base,
|
||||||
"d", command.StringFlag("$MBF_CACHE_DIR"),
|
"d", command.StringFlag("$MBF_CACHE_DIR"),
|
||||||
@@ -274,7 +283,7 @@ func main() {
|
|||||||
if _, err := io.Copy(h, os.Stdin); err != nil {
|
if _, err := io.Copy(h, os.Stdin); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println(pkg.Encode(pkg.Checksum(h.Sum(nil))))
|
fmt.Println(pkg.Encode(pkg.Checksum(h.Sum(nil))))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -611,27 +620,10 @@ func main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
var (
|
|
||||||
flagGentoo string
|
|
||||||
flagChecksum string
|
|
||||||
)
|
|
||||||
c.NewCommand(
|
c.NewCommand(
|
||||||
"stage3",
|
"stage4",
|
||||||
"Check for toolchain 3-stage non-determinism",
|
"Check for toolchain 3-stage non-determinism",
|
||||||
func(args []string) (err error) {
|
func(args []string) (err error) {
|
||||||
s := rosa.Std
|
|
||||||
if flagGentoo != "" {
|
|
||||||
s -= 3 // magic number to discourage misuse
|
|
||||||
|
|
||||||
var checksum pkg.Checksum
|
|
||||||
if len(flagChecksum) != 0 {
|
|
||||||
if err = pkg.Decode(&checksum, flagChecksum); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rosa.Native().SetGentooStage3(flagGentoo, checksum)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pathname *check.Absolute
|
pathname *check.Absolute
|
||||||
checksum [2]unique.Handle[pkg.Checksum]
|
checksum [2]unique.Handle[pkg.Checksum]
|
||||||
@@ -639,7 +631,7 @@ func main() {
|
|||||||
|
|
||||||
_llvm := rosa.H("llvm")
|
_llvm := rosa.H("llvm")
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(s - 2).Load(_llvm)
|
_, llvm := rosa.Native().New(rosa.Std - 2).Load(_llvm)
|
||||||
pathname, _, err = cache.Cure(llvm)
|
pathname, _, err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -648,22 +640,32 @@ func main() {
|
|||||||
log.Println("stage1:", pathname)
|
log.Println("stage1:", pathname)
|
||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(s - 1).Load(_llvm)
|
_, llvm := rosa.Native().New(rosa.Std - 1).Load(_llvm)
|
||||||
pathname, checksum[0], err = cache.Cure(llvm)
|
pathname, _, err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Println("stage2:", pathname)
|
log.Println("stage2:", pathname)
|
||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(s).Load(_llvm)
|
_, llvm := rosa.Native().New(rosa.Std).Load(_llvm)
|
||||||
pathname, checksum[1], err = cache.Cure(llvm)
|
pathname, checksum[0], err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Println("stage3:", pathname)
|
log.Println("stage3:", pathname)
|
||||||
|
|
||||||
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
|
_, llvm := rosa.Native().New(rosa.Stage3).Load(_llvm)
|
||||||
|
pathname, checksum[1], err = cache.Cure(llvm)
|
||||||
|
return
|
||||||
|
}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("stage4:", pathname)
|
||||||
|
|
||||||
if checksum[0] != checksum[1] {
|
if checksum[0] != checksum[1] {
|
||||||
err = &pkg.ChecksumMismatchError{
|
err = &pkg.ChecksumMismatchError{
|
||||||
Got: checksum[0].Value(),
|
Got: checksum[0].Value(),
|
||||||
@@ -671,23 +673,34 @@ func main() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println(
|
log.Println(
|
||||||
"stage2 is identical to stage3",
|
"stage3 is identical to stage4",
|
||||||
"("+pkg.Encode(checksum[0].Value())+")",
|
"("+pkg.Encode(checksum[0].Value())+")",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
).Flag(
|
|
||||||
&flagGentoo,
|
|
||||||
"gentoo", command.StringFlag(""),
|
|
||||||
"Bootstrap from a Gentoo stage3 tarball",
|
|
||||||
).Flag(
|
|
||||||
&flagChecksum,
|
|
||||||
"checksum", command.StringFlag(""),
|
|
||||||
"Checksum of Gentoo stage3 tarball",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.NewCommand(
|
||||||
|
"all",
|
||||||
|
command.UsageInternal,
|
||||||
|
func([]string) error {
|
||||||
|
all := rosa.Native().CollectAll()
|
||||||
|
a := make(pkg.Collect, len(all))
|
||||||
|
for i, h := range all {
|
||||||
|
_, a[i] = rosa.Native().Std().Load(h)
|
||||||
|
}
|
||||||
|
return cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
|
_, _, err = cache.Cure(&a)
|
||||||
|
if pkg.IsCollected(err) {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
var (
|
var (
|
||||||
flagDump string
|
flagDump string
|
||||||
@@ -701,6 +714,9 @@ func main() {
|
|||||||
|
|
||||||
flagBoot bool
|
flagBoot bool
|
||||||
flagStd bool
|
flagStd bool
|
||||||
|
|
||||||
|
flagGentoo string
|
||||||
|
flagChecksum string
|
||||||
)
|
)
|
||||||
c.NewCommand(
|
c.NewCommand(
|
||||||
"cure",
|
"cure",
|
||||||
@@ -717,6 +733,18 @@ func main() {
|
|||||||
t -= 1
|
t -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flagGentoo != "" {
|
||||||
|
var checksum pkg.Checksum
|
||||||
|
if len(flagChecksum) != 0 {
|
||||||
|
if err := pkg.Decode(&checksum, flagChecksum); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rosa.Native().SetGentooStage3(flagGentoo, checksum)
|
||||||
|
|
||||||
|
t -= 3 // magic number to discourage misuse
|
||||||
|
}
|
||||||
|
|
||||||
_, a := rosa.Native().New(t).Load(rosa.ArtifactH(unique.Make(args[0])))
|
_, a := rosa.Native().New(t).Load(rosa.ArtifactH(unique.Make(args[0])))
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return fmt.Errorf("unknown artifact %q", args[0])
|
return fmt.Errorf("unknown artifact %q", args[0])
|
||||||
@@ -736,7 +764,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println(pathname)
|
fmt.Println(pathname)
|
||||||
|
|
||||||
if flagExport != "" {
|
if flagExport != "" {
|
||||||
msg.Verbosef("exporting %s to %s...", args[0], flagExport)
|
msg.Verbosef("exporting %s to %s...", args[0], flagExport)
|
||||||
@@ -785,7 +813,7 @@ func main() {
|
|||||||
ctx,
|
ctx,
|
||||||
a,
|
a,
|
||||||
"", true, os.Stdin, os.Stdout, os.Stderr,
|
"", true, os.Stdin, os.Stdout, os.Stderr,
|
||||||
rosa.AbsSystem.Append("bin", "mksh"),
|
rosa.AbsSystem.Append("bin", "sh"),
|
||||||
"sh",
|
"sh",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -797,7 +825,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
pathname, err := cureRemote(ctx, &addr, a, flags)
|
pathname, err := cureRemote(ctx, &addr, a, flags)
|
||||||
if !flagNoReply && err == nil {
|
if !flagNoReply && err == nil {
|
||||||
log.Println(pathname)
|
fmt.Println(pathname)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
@@ -895,6 +923,14 @@ func main() {
|
|||||||
&flagRebuild,
|
&flagRebuild,
|
||||||
"rebuild", command.BoolFlag(false),
|
"rebuild", command.BoolFlag(false),
|
||||||
"Always enter the artifact implementation",
|
"Always enter the artifact implementation",
|
||||||
|
).Flag(
|
||||||
|
&flagGentoo,
|
||||||
|
"gentoo", command.StringFlag(""),
|
||||||
|
"Bootstrap from a Gentoo stage3 tarball",
|
||||||
|
).Flag(
|
||||||
|
&flagChecksum,
|
||||||
|
"checksum", command.StringFlag(""),
|
||||||
|
"Checksum of Gentoo stage3 tarball",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,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 {
|
||||||
|
|||||||
+3
-2
@@ -13,6 +13,7 @@ func New(output io.Writer, logf LogFunc, name string, early HandlerFunc) Command
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newNode initialises a subcommand tree and returns its address.
|
||||||
func newNode(output io.Writer, logf LogFunc, name, usage string) *node {
|
func newNode(output io.Writer, logf LogFunc, name, usage string) *node {
|
||||||
n := &node{
|
n := &node{
|
||||||
name: name, usage: usage,
|
name: name, usage: usage,
|
||||||
@@ -22,8 +23,8 @@ func newNode(output io.Writer, logf LogFunc, name, usage string) *node {
|
|||||||
n.set.SetOutput(output)
|
n.set.SetOutput(output)
|
||||||
n.set.Usage = func() {
|
n.set.Usage = func() {
|
||||||
_ = n.writeHelp()
|
_ = n.writeHelp()
|
||||||
if n.suffix.Len() > 0 {
|
if len(n.suffix) > 0 {
|
||||||
_, _ = fmt.Fprintln(output, "Flags:")
|
_, _ = fmt.Fprintln(output, "flags:")
|
||||||
n.set.PrintDefaults()
|
n.set.PrintDefaults()
|
||||||
_, _ = fmt.Fprintln(output)
|
_, _ = fmt.Fprintln(output)
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-4
@@ -18,8 +18,14 @@ func TestBuild(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("direct zero length", func(t *testing.T) {
|
t.Run("direct zero length", func(t *testing.T) {
|
||||||
wantPanic := "invalid subcommand"
|
wantPanic := "invalid subcommand"
|
||||||
t.Run("zero length name", func(t *testing.T) { defer checkRecover(t, "Command", wantPanic); c.Command("", "usage", stubHandler) })
|
t.Run("zero length name", func(t *testing.T) {
|
||||||
t.Run("zero length usage", func(t *testing.T) { defer checkRecover(t, "Command", wantPanic); c.Command("name", "", stubHandler) })
|
defer checkRecover(t, "Command", wantPanic)
|
||||||
|
c.Command("", "usage", stubHandler)
|
||||||
|
})
|
||||||
|
t.Run("zero length usage", func(t *testing.T) {
|
||||||
|
defer checkRecover(t, "Command", wantPanic)
|
||||||
|
c.Command("name", "", stubHandler)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("direct adopt unique names", func(t *testing.T) {
|
t.Run("direct adopt unique names", func(t *testing.T) {
|
||||||
@@ -34,8 +40,14 @@ func TestBuild(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("zero length", func(t *testing.T) {
|
t.Run("zero length", func(t *testing.T) {
|
||||||
wantPanic := "invalid subcommand tree"
|
wantPanic := "invalid subcommand tree"
|
||||||
t.Run("zero length name", func(t *testing.T) { defer checkRecover(t, "New", wantPanic); c.New("", "usage") })
|
t.Run("zero length name", func(t *testing.T) {
|
||||||
t.Run("zero length usage", func(t *testing.T) { defer checkRecover(t, "New", wantPanic); c.New("name", "") })
|
defer checkRecover(t, "New", wantPanic)
|
||||||
|
c.New("", "usage")
|
||||||
|
})
|
||||||
|
t.Run("zero length usage", func(t *testing.T) {
|
||||||
|
defer checkRecover(t, "New", wantPanic)
|
||||||
|
c.New("name", "")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("direct adopt unique names", func(t *testing.T) {
|
t.Run("direct adopt unique names", func(t *testing.T) {
|
||||||
|
|||||||
+26
-6
@@ -6,36 +6,43 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UsageInternal causes the command to be hidden from help text when set as the usage string.
|
// UsageInternal is a special usage string that hides the command from the
|
||||||
const UsageInternal = "internal"
|
// generated help message.
|
||||||
|
const UsageInternal = "\x00"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// HandlerFunc is called when matching a directly handled subcommand tree.
|
// HandlerFunc is called when matching a directly handled subcommand tree.
|
||||||
HandlerFunc = func(args []string) error
|
HandlerFunc = func(args []string) error
|
||||||
|
|
||||||
// LogFunc is the function signature of a printf function.
|
// LogFunc is the function signature of a printf function. The zero value
|
||||||
|
// implies [log.Printf].
|
||||||
LogFunc = func(format string, a ...any)
|
LogFunc = func(format string, a ...any)
|
||||||
|
|
||||||
// FlagDefiner is a deferred flag definer value, usually encapsulating the default value.
|
// FlagDefiner is a deferred flag definer value, usually encapsulating the
|
||||||
|
// default value.
|
||||||
FlagDefiner interface {
|
FlagDefiner interface {
|
||||||
// Define defines the flag in set.
|
// Define defines the flag in set.
|
||||||
Define(b *strings.Builder, set *flag.FlagSet, p any, name, usage string)
|
Define(b *strings.Builder, set *flag.FlagSet, p any, name, usage string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Flag is satisfied by command objects capable of receiving flags.
|
||||||
Flag[T any] interface {
|
Flag[T any] interface {
|
||||||
// Flag defines a generic flag type in Node's flag set.
|
// Flag defines a generic flag type in Node's flag set.
|
||||||
Flag(p any, name string, value FlagDefiner, usage string) T
|
Flag(p any, name string, value FlagDefiner, usage string) T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Command is the root of a command tree.
|
||||||
Command interface {
|
Command interface {
|
||||||
Parse(arguments []string) error
|
Parse(arguments []string) error
|
||||||
|
|
||||||
// MustParse determines exit outcomes for Parse errors
|
// MustParse determines exit outcomes for Parse errors and calls
|
||||||
// and calls handleError if [HandlerFunc] returns a non-nil error.
|
// handleError if [HandlerFunc] returns a non-nil error.
|
||||||
MustParse(arguments []string, handleError func(error))
|
MustParse(arguments []string, handleError func(error))
|
||||||
|
|
||||||
baseNode[Command]
|
baseNode[Command]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Node is a subcommand under a [Command].
|
||||||
Node baseNode[Node]
|
Node baseNode[Node]
|
||||||
|
|
||||||
baseNode[T any] interface {
|
baseNode[T any] interface {
|
||||||
@@ -53,3 +60,16 @@ type (
|
|||||||
Flag[T]
|
Flag[T]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// rootNode satisfies baseNode for [Command].
|
||||||
|
type rootNode struct{ *node }
|
||||||
|
|
||||||
|
func (r rootNode) Command(name, usage string, f HandlerFunc) Command {
|
||||||
|
r.node.Command(name, usage, f)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r rootNode) Flag(p any, name string, value FlagDefiner, usage string) Command {
|
||||||
|
r.node.Flag(p, name, value, usage)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|||||||
+7
-1
@@ -16,7 +16,13 @@ func (e FlagError) Is(target error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) Flag(p any, name string, value FlagDefiner, usage string) Node {
|
func (n *node) Flag(p any, name string, value FlagDefiner, usage string) Node {
|
||||||
value.Define(&n.suffix, n.set, p, name, usage)
|
var buf strings.Builder
|
||||||
|
value.Define(&buf, n.set, p, name, usage)
|
||||||
|
s := buf.String()
|
||||||
|
if len(s) > 0 && s[0] == ' ' {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
n.suffix = append(n.suffix, s)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-3
@@ -1,6 +1,7 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -13,14 +14,31 @@ var ErrHelp = errors.New("help requested")
|
|||||||
func (n *node) PrintHelp() { _ = n.writeHelp() }
|
func (n *node) PrintHelp() { _ = n.writeHelp() }
|
||||||
|
|
||||||
func (n *node) writeHelp() error {
|
func (n *node) writeHelp() error {
|
||||||
|
prefix := strings.Join(append(n.prefix, n.name), " ")
|
||||||
|
var buf strings.Builder
|
||||||
|
offset := 7 + len(prefix)
|
||||||
|
line := offset + 14
|
||||||
|
w := bytes.Repeat([]byte{' '}, offset+1)
|
||||||
|
w[0] = '\n'
|
||||||
|
|
||||||
|
for _, flag := range n.suffix {
|
||||||
|
line += len(flag) + 1
|
||||||
|
if line >= 80 {
|
||||||
|
line = offset + len(flag) + 1
|
||||||
|
buf.Write(w)
|
||||||
|
}
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
buf.WriteString(flag)
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(n.out,
|
if _, err := fmt.Fprintf(n.out,
|
||||||
"\nUsage:\t%s [-h | --help]%s COMMAND [OPTIONS]\n",
|
"usage: %s [-h | --help]%s <command> [<args>]\n",
|
||||||
strings.Join(append(n.prefix, n.name), " "), &n.suffix,
|
prefix, &buf,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if n.child != nil {
|
if n.child != nil {
|
||||||
if _, err := fmt.Fprint(n.out, "\nCommands:\n"); err != nil {
|
if _, err := fmt.Fprint(n.out, "\ncommands:\n"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -3,9 +3,9 @@ package command
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A node represents a command.
|
||||||
type node struct {
|
type node struct {
|
||||||
child, next *node
|
child, next *node
|
||||||
name, usage string
|
name, usage string
|
||||||
@@ -13,13 +13,16 @@ type node struct {
|
|||||||
out io.Writer
|
out io.Writer
|
||||||
logf LogFunc
|
logf LogFunc
|
||||||
|
|
||||||
|
// Names of commands preceding node.
|
||||||
prefix []string
|
prefix []string
|
||||||
suffix strings.Builder
|
// Short user-facing representations of flags received by node.
|
||||||
|
suffix []string
|
||||||
|
|
||||||
f HandlerFunc
|
f HandlerFunc
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adopt adds v as the last child of n.
|
||||||
func (n *node) adopt(v *node) bool {
|
func (n *node) adopt(v *node) bool {
|
||||||
if n.child != nil {
|
if n.child != nil {
|
||||||
return n.child.append(v)
|
return n.child.append(v)
|
||||||
@@ -28,6 +31,7 @@ func (n *node) adopt(v *node) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append adds v as the last sibling of n.
|
||||||
func (n *node) append(v *node) bool {
|
func (n *node) append(v *node) bool {
|
||||||
if n.name == v.name {
|
if n.name == v.name {
|
||||||
return false
|
return false
|
||||||
|
|||||||
+18
-22
@@ -70,7 +70,7 @@ func TestParse(t *testing.T) {
|
|||||||
"d=0 out of order string flag",
|
"d=0 out of order string flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"string", "--string", "64d3b4b7b21788585845060e2199a78f"},
|
[]string{"string", "--string", "64d3b4b7b21788585845060e2199a78f"},
|
||||||
"flag provided but not defined: -string\n\nUsage:\ttest string [-h | --help] COMMAND [OPTIONS]\n\n", "",
|
"flag provided but not defined: -string\nusage: test string [-h | --help] <command> [<args>]\n\n", "",
|
||||||
errors.New("flag provided but not defined: -string"),
|
errors.New("flag provided but not defined: -string"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ func TestParse(t *testing.T) {
|
|||||||
"d=1 empty sub help",
|
"d=1 empty sub help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"empty", "-h"},
|
[]string{"empty", "-h"},
|
||||||
"\nUsage:\ttest empty [-h | --help] COMMAND [OPTIONS]\n\n", "", flag.ErrHelp,
|
"usage: test empty [-h | --help] <command> [<args>]\n\n", "", flag.ErrHelp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"d=1 no match",
|
"d=1 no match",
|
||||||
@@ -151,10 +151,10 @@ func TestParse(t *testing.T) {
|
|||||||
"d=0 help",
|
"d=0 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{},
|
[]string{},
|
||||||
`
|
`usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>]
|
||||||
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
|
[--repeat <value>] <command> [<args>]
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
error return an error
|
error return an error
|
||||||
print wraps Fprint
|
print wraps Fprint
|
||||||
string print string passed by flag
|
string print string passed by flag
|
||||||
@@ -171,10 +171,10 @@ Commands:
|
|||||||
"d=0 help flag",
|
"d=0 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"-h"},
|
[]string{"-h"},
|
||||||
`
|
`usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>]
|
||||||
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
|
[--repeat <value>] <command> [<args>]
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
error return an error
|
error return an error
|
||||||
print wraps Fprint
|
print wraps Fprint
|
||||||
string print string passed by flag
|
string print string passed by flag
|
||||||
@@ -185,7 +185,7 @@ Commands:
|
|||||||
succeed this command succeeds
|
succeed this command succeeds
|
||||||
deep top level of command tree with various levels
|
deep top level of command tree with various levels
|
||||||
|
|
||||||
Flags:
|
flags:
|
||||||
-fail
|
-fail
|
||||||
fail early
|
fail early
|
||||||
-int int
|
-int int
|
||||||
@@ -203,10 +203,9 @@ Flags:
|
|||||||
"d=1 help",
|
"d=1 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"join"},
|
[]string{"join"},
|
||||||
`
|
`usage: test join [-h | --help] <command> [<args>]
|
||||||
Usage: test join [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
out write result to wout
|
out write result to wout
|
||||||
log log result to wlog
|
log log result to wlog
|
||||||
|
|
||||||
@@ -216,10 +215,9 @@ Commands:
|
|||||||
"d=1 help flag",
|
"d=1 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"join", "-h"},
|
[]string{"join", "-h"},
|
||||||
`
|
`usage: test join [-h | --help] <command> [<args>]
|
||||||
Usage: test join [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
out write result to wout
|
out write result to wout
|
||||||
log log result to wlog
|
log log result to wlog
|
||||||
|
|
||||||
@@ -230,10 +228,9 @@ Commands:
|
|||||||
"d=2 help",
|
"d=2 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"deep", "d=2"},
|
[]string{"deep", "d=2"},
|
||||||
`
|
`usage: test deep d=2 [-h | --help] <command> [<args>]
|
||||||
Usage: test deep d=2 [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
d=3 relative third level
|
d=3 relative third level
|
||||||
|
|
||||||
`, "", command.ErrHelp,
|
`, "", command.ErrHelp,
|
||||||
@@ -242,10 +239,9 @@ Commands:
|
|||||||
"d=2 help flag",
|
"d=2 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"deep", "d=2", "-h"},
|
[]string{"deep", "d=2", "-h"},
|
||||||
`
|
`usage: test deep d=2 [-h | --help] <command> [<args>]
|
||||||
Usage: test deep d=2 [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
d=3 relative third level
|
d=3 relative third level
|
||||||
|
|
||||||
`, "", flag.ErrHelp,
|
`, "", flag.ErrHelp,
|
||||||
@@ -261,7 +257,7 @@ Commands:
|
|||||||
t.Errorf("Parse: error = %v; wantErr %v", err, tc.wantErr)
|
t.Errorf("Parse: error = %v; wantErr %v", err, tc.wantErr)
|
||||||
}
|
}
|
||||||
if got := wout.String(); got != tc.want {
|
if got := wout.String(); got != tc.want {
|
||||||
t.Errorf("Parse: %s want %s", got, tc.want)
|
t.Errorf("Parse:\n%s\nwant\n%s", got, tc.want)
|
||||||
}
|
}
|
||||||
if gotLog := wlog.String(); gotLog != tc.wantLog {
|
if gotLog := wlog.String(); gotLog != tc.wantLog {
|
||||||
t.Errorf("Parse: log = %s wantLog %s", gotLog, tc.wantLog)
|
t.Errorf("Parse: log = %s wantLog %s", gotLog, tc.wantLog)
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
// the top level node wants [Command] returned for its builder methods
|
|
||||||
type rootNode struct{ *node }
|
|
||||||
|
|
||||||
func (r rootNode) Command(name, usage string, f HandlerFunc) Command {
|
|
||||||
r.node.Command(name, usage, f)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r rootNode) Flag(p any, name string, value FlagDefiner, usage string) Command {
|
|
||||||
r.node.Flag(p, name, value, usage)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
@@ -202,7 +202,7 @@ func TestArchiveArtifact(t *testing.T) {
|
|||||||
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/uevent": {Mode: 0600, Data: []byte("add")},
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/uevent": {Mode: 0600, Data: []byte("add")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/3oYyAbRJ_we7AgWo1BRcRcnxXFk3mAQ0Qui2nGQMi8GIJNJQtvUC6P2IeoA5mbjD": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F")},
|
"identifier/-zXKfphyWM2Ko7VMVURaEMSuixNokFSe0xFbnwR2RtRtvMrcPGWalV0LIn45PXTY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
|||||||
+12
-3
@@ -73,7 +73,10 @@ func (c *Cache) Clean(dry, inputs bool, keep ...Artifact) (
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.msg.Verbosef("arranging for destruction of %s...", name)
|
c.msg.Verbosef(
|
||||||
|
"arranging for destruction of %s%s%s...",
|
||||||
|
c.sgrIdent, name, c.sgrRes,
|
||||||
|
)
|
||||||
idents = append(idents, identPair{id, name})
|
idents = append(idents, identPair{id, name})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +105,10 @@ func (c *Cache) Clean(dry, inputs bool, keep ...Artifact) (
|
|||||||
if err = c.parent.Err(); err != nil {
|
if err = c.parent.Err(); err != nil {
|
||||||
return destroyedIdents, destroyedChecksums, err
|
return destroyedIdents, destroyedChecksums, err
|
||||||
}
|
}
|
||||||
c.msg.Verbosef("destroying checksum %s...", name)
|
c.msg.Verbosef(
|
||||||
|
"destroying checksum %s%s%s...",
|
||||||
|
c.sgrIdent, name, c.sgrRes,
|
||||||
|
)
|
||||||
if !dry {
|
if !dry {
|
||||||
if err = errors.Join(removeAll(c.base.Append(
|
if err = errors.Join(removeAll(c.base.Append(
|
||||||
dirChecksum,
|
dirChecksum,
|
||||||
@@ -130,7 +136,10 @@ func (c *Cache) Clean(dry, inputs bool, keep ...Artifact) (
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.msg.Verbosef("destroying substitute %s...", name)
|
c.msg.Verbosef(
|
||||||
|
"destroying substitute %s%s%s...",
|
||||||
|
c.sgrIdent, name, c.sgrRes,
|
||||||
|
)
|
||||||
if !dry {
|
if !dry {
|
||||||
if err = os.Remove(c.base.Append(
|
if err = os.Remove(c.base.Append(
|
||||||
dirStatus,
|
dirStatus,
|
||||||
|
|||||||
+11
-11
@@ -48,7 +48,7 @@ func TestClean(t *testing.T) {
|
|||||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400},
|
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/pPRjw2XYgjB5k8dYedwxTBMgHh4_v2JM_G2Vd-skQbAGOOgPsl3CGSUbEF7om_MO": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
"identifier/h6qx7m0vsyhO6oLEJgY2rKa1c6RZuIZ4QXxZSh__NZJ9VU0MIj5bFB-KuaPcsfpE": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
|
||||||
"lock": {Mode: 0644},
|
"lock": {Mode: 0644},
|
||||||
"variant": {Mode: 0400},
|
"variant": {Mode: 0400},
|
||||||
@@ -69,7 +69,7 @@ func TestClean(t *testing.T) {
|
|||||||
"checksum/KgZ-FjbGuU-XP2QEHInpgv-2Zn0cTH5NqFMgTU0XrSdKmSwyC-3baVs1BMCP5spk": {Mode: 0400, Data: []byte("\xfd")},
|
"checksum/KgZ-FjbGuU-XP2QEHInpgv-2Zn0cTH5NqFMgTU0XrSdKmSwyC-3baVs1BMCP5spk": {Mode: 0400, Data: []byte("\xfd")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/FMwSBYw22KqM8jZryfY2ChHXpLuVDdWYyNOYdHvIVYk8ujY6UnGRm5brr2sTTfpD": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/KgZ-FjbGuU-XP2QEHInpgv-2Zn0cTH5NqFMgTU0XrSdKmSwyC-3baVs1BMCP5spk")},
|
"identifier/tkrOYhQfTRaArk4nNYNjTmHQUmuJMVIoDeAKIQBm3I4uuMimBKXKMIY2gGZqwQg4": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/KgZ-FjbGuU-XP2QEHInpgv-2Zn0cTH5NqFMgTU0XrSdKmSwyC-3baVs1BMCP5spk")},
|
||||||
|
|
||||||
"lock": {Mode: 0644},
|
"lock": {Mode: 0644},
|
||||||
"variant": {Mode: 0400},
|
"variant": {Mode: 0400},
|
||||||
@@ -122,16 +122,16 @@ func TestClean(t *testing.T) {
|
|||||||
"checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE/result": {Mode: 0444},
|
"checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE/result": {Mode: 0444},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/Ef8KX6s_rS_nLgze0rj90zKyrGAvOnzyU0DL7nrYQWEG_f4a9pmUKI6HBEMD8AE8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv")},
|
"identifier/KpxTUsUfGbsX6C6HU2j9cd9He3_tt2o2m2MgH4m0zial8lmoqSWY-Gc3KrS0k-UK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv")},
|
||||||
"identifier/xoIGLemzLF227e-w_AJcf_1Sgqh2gs3KFgqvOIWUQE-9P_y2vHBMBytL4GRGQqTb": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"identifier/xxQ43VMIS1WHMSEFnUdBNd6pulbtgiTorP_mtJpEsZENYhGBiDEL6Y2D8yqn0Sra": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
|
|
||||||
"lock": {Mode: 0644},
|
"lock": {Mode: 0644},
|
||||||
"variant": {Mode: 0400},
|
"variant": {Mode: 0400},
|
||||||
"status": {Mode: fs.ModeDir | 0700},
|
"status": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/4bjS-QjGcSV4nth-W6Vg3-wolKmKgiq4Ld2oRIWcOfy6Wi41XXLAWPoo8FcDx6BH": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"substitute/dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
"substitute/dzO8FEY9lu4hwRT6BfRZOX-uYGsC_5XH4jEJ7sJyThcmG9J_w1ArOAaUCGfL8wAM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"substitute/td1tf1kb3z8iUFg2k1xlHeTTEz3xR4e77WSWdv2JhjmZyY6iuvodhdT8BblDOi0E": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
|
|
||||||
"fault": {Mode: fs.ModeDir | 0700},
|
"fault": {Mode: fs.ModeDir | 0700},
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
@@ -199,18 +199,18 @@ func TestClean(t *testing.T) {
|
|||||||
"checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv": {Mode: 0400, Data: []byte("kept")},
|
"checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv": {Mode: 0400, Data: []byte("kept")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/Ef8KX6s_rS_nLgze0rj90zKyrGAvOnzyU0DL7nrYQWEG_f4a9pmUKI6HBEMD8AE8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv")},
|
"identifier/KpxTUsUfGbsX6C6HU2j9cd9He3_tt2o2m2MgH4m0zial8lmoqSWY-Gc3KrS0k-UK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/H-eSiCo227-xdqyNl2R-5G3eqXPtbb8XegAB70I5OQb2majeZXJoCxTq9wJy5qqv")},
|
||||||
"identifier/xoIGLemzLF227e-w_AJcf_1Sgqh2gs3KFgqvOIWUQE-9P_y2vHBMBytL4GRGQqTb": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CyDnDvF-LaeGPcSW70tPosNCoclByWkTjznUUF1DcgzlIwkN9yzz1ZFME1TlPj6W")},
|
"identifier/xxQ43VMIS1WHMSEFnUdBNd6pulbtgiTorP_mtJpEsZENYhGBiDEL6Y2D8yqn0Sra": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CyDnDvF-LaeGPcSW70tPosNCoclByWkTjznUUF1DcgzlIwkN9yzz1ZFME1TlPj6W")},
|
||||||
|
|
||||||
"lock": {Mode: 0644},
|
"lock": {Mode: 0644},
|
||||||
"variant": {Mode: 0400},
|
"variant": {Mode: 0400},
|
||||||
|
|
||||||
"status": {Mode: fs.ModeDir | 0700},
|
"status": {Mode: fs.ModeDir | 0700},
|
||||||
"status/4bjS-QjGcSV4nth-W6Vg3-wolKmKgiq4Ld2oRIWcOfy6Wi41XXLAWPoo8FcDx6BH": {Mode: 0400, Data: []byte(statusHeader + "kept")},
|
"status/xxQ43VMIS1WHMSEFnUdBNd6pulbtgiTorP_mtJpEsZENYhGBiDEL6Y2D8yqn0Sra": {Mode: 0400, Data: []byte(statusHeader + "kept")},
|
||||||
"status/xoIGLemzLF227e-w_AJcf_1Sgqh2gs3KFgqvOIWUQE-9P_y2vHBMBytL4GRGQqTb": {Mode: 0400, Data: []byte(statusHeader + "kept")},
|
"status/td1tf1kb3z8iUFg2k1xlHeTTEz3xR4e77WSWdv2JhjmZyY6iuvodhdT8BblDOi0E": {Mode: 0400, Data: []byte(statusHeader + "kept")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/4bjS-QjGcSV4nth-W6Vg3-wolKmKgiq4Ld2oRIWcOfy6Wi41XXLAWPoo8FcDx6BH": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CyDnDvF-LaeGPcSW70tPosNCoclByWkTjznUUF1DcgzlIwkN9yzz1ZFME1TlPj6W")},
|
"substitute/td1tf1kb3z8iUFg2k1xlHeTTEz3xR4e77WSWdv2JhjmZyY6iuvodhdT8BblDOi0E": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CyDnDvF-LaeGPcSW70tPosNCoclByWkTjznUUF1DcgzlIwkN9yzz1ZFME1TlPj6W")},
|
||||||
|
|
||||||
"fault": {Mode: fs.ModeDir | 0700},
|
"fault": {Mode: fs.ModeDir | 0700},
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"hakurei.app/internal/xz"
|
||||||
|
"hakurei.app/internal/zstd"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -13,6 +16,10 @@ const (
|
|||||||
Gzip = iota
|
Gzip = iota
|
||||||
// Bzip2 denotes a stream compressed via [bzip2].
|
// Bzip2 denotes a stream compressed via [bzip2].
|
||||||
Bzip2
|
Bzip2
|
||||||
|
// Zstd denotes a stream compressed via [zstd].
|
||||||
|
Zstd
|
||||||
|
// XZ denotes a stream compressed via [xz].
|
||||||
|
XZ
|
||||||
)
|
)
|
||||||
|
|
||||||
// A decompressArtifact is a [FileArtifact] decompressing a backing
|
// A decompressArtifact is a [FileArtifact] decompressing a backing
|
||||||
@@ -91,6 +98,9 @@ func (c compoundCloser) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsExecutable returns false.
|
||||||
|
func (*decompressArtifact) IsExecutable() bool { return false }
|
||||||
|
|
||||||
// Cure returns a decompressor [io.ReadCloser].
|
// Cure returns a decompressor [io.ReadCloser].
|
||||||
func (a *decompressArtifact) Cure(r *RContext) (io.ReadCloser, error) {
|
func (a *decompressArtifact) Cure(r *RContext) (io.ReadCloser, error) {
|
||||||
sr, err := r.Open(a.f)
|
sr, err := r.Open(a.f)
|
||||||
@@ -114,6 +124,23 @@ func (a *decompressArtifact) Cure(r *RContext) (io.ReadCloser, error) {
|
|||||||
io.Closer
|
io.Closer
|
||||||
}{bzip2.NewReader(br), br}, nil
|
}{bzip2.NewReader(br), br}, nil
|
||||||
|
|
||||||
|
case Zstd:
|
||||||
|
return struct {
|
||||||
|
io.Reader
|
||||||
|
io.Closer
|
||||||
|
}{zstd.NewReader(br), br}, nil
|
||||||
|
|
||||||
|
case XZ:
|
||||||
|
var _dr io.Reader
|
||||||
|
if _dr, err = xz.NewReader(br, 0); err != nil {
|
||||||
|
_ = br.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return struct {
|
||||||
|
io.Reader
|
||||||
|
io.Closer
|
||||||
|
}{_dr, br}, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, os.ErrInvalid
|
return nil, os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ func TestDecompress(t *testing.T) {
|
|||||||
return (pkg.Checksum)(h.Sum(nil))
|
return (pkg.Checksum)(h.Sum(nil))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
gh := pkg.NewDecompress(pkg.NewHTTPGet(
|
||||||
|
&client,
|
||||||
|
"file:///testdata",
|
||||||
|
testdataChecksum,
|
||||||
|
), pkg.Gzip)
|
||||||
|
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"decompress", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"decompress", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
@@ -48,11 +54,7 @@ func TestDecompress(t *testing.T) {
|
|||||||
Want: pkg.Checksum{0xfd},
|
Want: pkg.Checksum{0xfd},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"gzip", pkg.NewDecompress(pkg.NewHTTPGet(
|
{"gzip", gh, ignorePathname, expectsChecksum(sha512.Sum384([]byte{0})), pkg.WNew, nil},
|
||||||
&client,
|
|
||||||
"file:///testdata",
|
|
||||||
testdataChecksum,
|
|
||||||
), pkg.Gzip), ignorePathname, expectsChecksum(sha512.Sum384([]byte{0})), pkg.WNew, nil},
|
|
||||||
})
|
})
|
||||||
}, expectsFS{
|
}, expectsFS{
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
@@ -61,7 +63,7 @@ func TestDecompress(t *testing.T) {
|
|||||||
"checksum/" + pkg.Encode(sha512.Sum384([]byte{0})): {Mode: 0400, Data: []byte{0}},
|
"checksum/" + pkg.Encode(sha512.Sum384([]byte{0})): {Mode: 0400, Data: []byte{0}},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/QpjkahDrz7pz-tv0eAGNXR6x9NAtTjWCK5Hr7G1cIZj9rT7bLYJWUQeLD4wamAlF": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
"identifier/" + pkg.Encode(pkg.NewIR().Ident(gh).Value()): {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
|||||||
+15
-4
@@ -444,7 +444,7 @@ func scanVerbose(
|
|||||||
msg message.Msg,
|
msg message.Msg,
|
||||||
cancel context.CancelFunc,
|
cancel context.CancelFunc,
|
||||||
done chan<- struct{},
|
done chan<- struct{},
|
||||||
prefix string,
|
prefix, suffix string,
|
||||||
r io.Reader,
|
r io.Reader,
|
||||||
) {
|
) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
@@ -454,7 +454,7 @@ func scanVerbose(
|
|||||||
bufio.MaxScanTokenSize<<12,
|
bufio.MaxScanTokenSize<<12,
|
||||||
)
|
)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
msg.Verbose(prefix, s.Text())
|
msg.Verbose(prefix, s.Text()+suffix)
|
||||||
}
|
}
|
||||||
if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) {
|
if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) {
|
||||||
cancel()
|
cancel()
|
||||||
@@ -728,14 +728,25 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
|
|||||||
|
|
||||||
brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr)
|
brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr)
|
||||||
stdoutDone, stderrDone := make(chan struct{}), make(chan struct{})
|
stdoutDone, stderrDone := make(chan struct{}), make(chan struct{})
|
||||||
|
|
||||||
|
var suffix, prefixO, prefixE string
|
||||||
|
if f.cache.attr.Flags&CColourOutput != 0 {
|
||||||
|
suffix = "\x1b[0m"
|
||||||
|
prefixO = "\x1b[1;37m(" + a.name + ")\x1b[0m"
|
||||||
|
prefixE = "\x1b[1;97m(" + a.name + ")\x1b[0m"
|
||||||
|
} else {
|
||||||
|
prefixO = "(" + a.name + ":1)"
|
||||||
|
prefixE = "(" + a.name + ":2)"
|
||||||
|
}
|
||||||
|
|
||||||
go scanVerbose(
|
go scanVerbose(
|
||||||
msg, cancel, stdoutDone,
|
msg, cancel, stdoutDone,
|
||||||
"("+a.name+":1)",
|
prefixO, suffix,
|
||||||
io.TeeReader(brStdout, status),
|
io.TeeReader(brStdout, status),
|
||||||
)
|
)
|
||||||
go scanVerbose(
|
go scanVerbose(
|
||||||
msg, cancel, stderrDone,
|
msg, cancel, stderrDone,
|
||||||
"("+a.name+":2)",
|
prefixE, suffix,
|
||||||
io.TeeReader(brStderr, status),
|
io.TeeReader(brStderr, status),
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
+13
-16
@@ -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(
|
||||||
@@ -183,11 +180,11 @@ func TestExec(t *testing.T) {
|
|||||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/QwS7SmiatdqryQYgESdGw7Yw2PcpNf0vNfpvUA0t92BTlKiUjfCrXyMW17G2X77X": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
"identifier/" + expected.Offline: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.Offline: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
"identifier/" + expected.OfflineS: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.OfflineS: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/_OHzj_xdmfpaWfFN-_D9JpGpPlIjh84873E3Ui9xwv9PPPIt0BlzvH-cnPNeRsTl": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -242,7 +239,7 @@ func TestExec(t *testing.T) {
|
|||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/" + expected.Net: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")},
|
"identifier/" + expected.Net: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")},
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -284,7 +281,7 @@ func TestExec(t *testing.T) {
|
|||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/" + expected.OvlRoot: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.OvlRoot: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -331,7 +328,7 @@ func TestExec(t *testing.T) {
|
|||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/" + expected.Work: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.Work: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -403,9 +400,9 @@ func TestExec(t *testing.T) {
|
|||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
"identifier/B-kc5iJMx8GtlCua4dz6BiJHnDAOUfPjgpbKq4e-QEn0_CZkSYs3fOA1ve06qMs2": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK")},
|
"identifier/2uIvmnqtzAx4Ed4PWV8xjZCWeJCwfE2IcCc0evM-Nd8mDUlgSU6nLtPLcpPUcMlG": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK")},
|
||||||
"identifier/" + expected.Layers: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.Layers: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -452,8 +449,8 @@ func TestExec(t *testing.T) {
|
|||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/kvJIqZo5DKFOxC2ZQ-8_nPaQzEAz9cIm3p6guO-uLqm-xaiPu7oRkSnsu411jd_U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/Vzj9qaSVBtNyBQv_PW6uojFOWTwraHoaC0C6xdaGG1q_HTvSh4KLVxRcEQU1jd2Y": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/" + expected.Promote: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
"identifier/" + expected.Promote: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
@@ -519,9 +516,9 @@ func TestExec(t *testing.T) {
|
|||||||
"checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3/check": {Mode: 0400, Data: []byte("binfmt")},
|
"checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3/check": {Mode: 0400, Data: []byte("binfmt")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/6VQTJ1lI5BmVuI1YFYJ8ClO3MRORvTTrcWFDcUU-l5Ga8EofxCxGlSTYN-u8dKj_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3")},
|
"identifier/c-HodmoEG0f_WGdst9aN-duLMH7QDDXOUi7UcyArXMeM1fc9lYKKQlTCW8ktaK8X": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3")},
|
||||||
"identifier/_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV")},
|
"identifier/_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV")},
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/MEaM1v6MLRQ60JQOOKbfDzfJOdC3L8i30IgOpYbQdX68enwF0FN-P36_M4RX_0Vd": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type fileArtifact []byte
|
|||||||
|
|
||||||
var _ KnownChecksum = new(fileArtifact)
|
var _ KnownChecksum = new(fileArtifact)
|
||||||
var _ CuresExempt = new(fileArtifact)
|
var _ CuresExempt = new(fileArtifact)
|
||||||
|
var _ RevisionArtifact = new(fileArtifact)
|
||||||
|
|
||||||
// fileArtifactNamed embeds fileArtifact alongside a caller-supplied name.
|
// fileArtifactNamed embeds fileArtifact alongside a caller-supplied name.
|
||||||
type fileArtifactNamed struct {
|
type fileArtifactNamed struct {
|
||||||
@@ -76,6 +77,20 @@ func (a *fileArtifact) Checksum() Checksum {
|
|||||||
return Checksum(h.Sum(nil))
|
return Checksum(h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Revision satisfies [RevisionArtifact] for incompatible IsExecutable behaviour.
|
||||||
|
func (*fileArtifact) Revision() uint64 { return 0 }
|
||||||
|
|
||||||
|
// IsExecutable returns whether the contents begin with shebang or the ELF
|
||||||
|
// magic number.
|
||||||
|
func (a *fileArtifact) IsExecutable() bool {
|
||||||
|
return a != nil &&
|
||||||
|
(bytes.HasPrefix(
|
||||||
|
*a, []byte{'#', '!'},
|
||||||
|
) || bytes.HasPrefix(
|
||||||
|
*a, []byte{0x7f, 'E', 'L', 'F'},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
// Cure returns the caller-supplied data.
|
// Cure returns the caller-supplied data.
|
||||||
func (a *fileArtifact) Cure(*RContext) (io.ReadCloser, error) {
|
func (a *fileArtifact) Cure(*RContext) (io.ReadCloser, error) {
|
||||||
return io.NopCloser(bytes.NewReader(*a)), nil
|
return io.NopCloser(bytes.NewReader(*a)), nil
|
||||||
|
|||||||
@@ -12,22 +12,41 @@ func TestFile(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
want := expectsFile{0}
|
want := expectsFile{0}
|
||||||
|
const ident = "N7M6W8-e55Wky_1q1a6qRKFVDw1S5XtPdB4HE2YZObG8OFum8HittyJgZUG5Ru2u"
|
||||||
|
wantShebang := expectsFile("#!/bin/sh\n")
|
||||||
|
const identShebang = "oKTGZb_TRtJf5G1iGGj4SOx1WUbI6YhmsUeEsCNvmK9tZYRwdwQf-DLFUxRPx5qm"
|
||||||
|
wantELF := expectsFile("\x7fELF\xde\xad\xbe\xef")
|
||||||
|
const identELF = "LjeHmIJgD1SiXIH8ewpGRed2_LU84NLapstnOAa_0hxLd8YY7x4KM0aApsj-RwCh"
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"file", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"file", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"short", pkg.NewFile("null", []byte{0}), base.Append(
|
{"short", pkg.NewFile("null", want), base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi",
|
ident,
|
||||||
), want, pkg.WNew, nil},
|
), want, pkg.WNew, nil},
|
||||||
|
|
||||||
|
{"shebang", pkg.NewFile("shebang", wantShebang), base.Append(
|
||||||
|
"identifier",
|
||||||
|
identShebang,
|
||||||
|
), wantShebang, pkg.WNew, nil},
|
||||||
|
|
||||||
|
{"elf", pkg.NewFile("ELF", wantELF), base.Append(
|
||||||
|
"identifier",
|
||||||
|
identELF,
|
||||||
|
), wantELF, pkg.WNew, nil},
|
||||||
})
|
})
|
||||||
}, expectsFS{
|
}, expectsFS{
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
"checksum/" + pkg.Encode(want.hash()): {Mode: 0400, Data: []byte{0}},
|
"checksum/" + pkg.Encode(want.hash()): {Mode: 0400, Data: want},
|
||||||
|
"checksum/" + pkg.Encode(wantShebang.hash()): {Mode: 0500, Data: wantShebang},
|
||||||
|
"checksum/" + pkg.Encode(wantELF.hash()): {Mode: 0500, Data: wantELF},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
"identifier/" + ident: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + pkg.Encode(want.hash()))},
|
||||||
|
"identifier/" + identShebang: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + pkg.Encode(wantShebang.hash()))},
|
||||||
|
"identifier/" + identELF: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + pkg.Encode(wantELF.hash()))},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package expected
|
package expected
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Offline = "q5ktDTq0miP-VvB2blxqXQeaRXCUWgP_KbC18KNtUDtyoaI_h5mHmGuPMArVEBDs"
|
Offline = "IKmVhALejtYA3JhN1PCfjKF-Dio1XVcOeMWDHhfSHCbb4iBNhGjFy2UspZveZvb8"
|
||||||
OfflineS = "IY91PCtOpCYy21AaIK0c9f8-Z6fb2_2ewoHWkt4dxoLf0GOrWqS8yAGFLV84b1Dw"
|
OfflineS = "6ZubjSyCnz4-TKgQZi_BbY-JUwsStYCtD_f-BTDOOotfEbqkm47W20AazHRaLviz"
|
||||||
OvlRoot = "NacZGXwuRkTvcHaG08a22ujJ8qCWN0RSoFlRSR5FSt0ZcBbJ28FRvkYsHEtX7G8i"
|
OvlRoot = "Yox7WpG8B_OqIXWF4HWFZkUfsEl7DGzpFyZM0qtd9T8nQ-7SAkEUurlAe6_DJ6Iu"
|
||||||
Layers = "WBJDrATtX6rIE5yAu8ePX3WmDF0Tt9kFiue0m3cRnyRoVx1my8a67fh3CAW486oP"
|
Layers = "aAwfxDB-efVo379FNl178jK7HEKU3LEjHbZdaVVjk7GnXGZGEANNsXnB3SCUxM9A"
|
||||||
Net = "CmYtj2sNB3LHtqiDuck_Lz3MjLLIiwyP8N4NDitQ1Icvv__LVP9p8tm-sHeQaKKp"
|
Net = "IU3GwU2jTBd7HjotvFo2wsDWBQGVGpamwiSKdc2G1EnhM-ZaacxAuK6q0wbTVxra"
|
||||||
Promote = "TX3eCloaQFkV-SZIH6Jg6E5WKH--rcXY1P0jnZKmLFKWrNqnOzd4G9eIBh6i5ywN"
|
Promote = "rOjetGHzT_jPErrBR24IAZKDj8Q9dLLqxFQqloMgjsULss0VXDI--n6LxuMBHvmZ"
|
||||||
Work = "OuNiLSC68pZhAOr1YQ4WbV1tzASA0nxLEBcK7lO7MqxDY_j8dmP_C612RTuF23Lu"
|
Work = "7f9XDeREfvJIjCe0qesND0s0tasExAIcc-OH33-eq9tsrQPUXhJp4KEkpsYH4hCD"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package expected
|
package expected
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Offline = "WapqyoPxbWSnq07dWHt71mHaJXq99pAjJfFlELlJljSiZMhTFqqlzU1_mN86shSj"
|
Offline = "MTgCSzwPrzGigp9phvDPRwUTNGLm1KM2EsEtbz-l2cNieqjaGtnzm65CDXlSxXrl"
|
||||||
OfflineS = "ibQZHcdXgNQ1OiMX1FrburBbGPVvKEHvPilbQCkm_0oV0BQCHomyyTbYNrFMGIwl"
|
OfflineS = "p89bQg7_jR4nwaSbpEd08ne1jHOEw7Wlnlyv5FHq7ba1Kml3HSBZwEKRzu0gCqEb"
|
||||||
OvlRoot = "V9anFOiRvjGfAeBhLl14AL8TKdWZyD0WTPYe4fS9mOBw8iW5Lmarvt6TG6MV8uWm"
|
OvlRoot = "9ifwO6MAaV9kTqRR2O5PJzm8XhfXbr50mFLWyEHQm8OHHcJtAEUgXZzJYoZt9YVV"
|
||||||
Layers = "tKx7JNRoSBdK_7MdzI-nwTNV2wmiPzwYdcd17oLmXKL_iLmUzUiA79qTqdrTasrv"
|
Layers = "INuGActFPwJtS7mAR9Bkt7FD4yoHlXHSJ9CaSAQJrpkUBL_k815Cs_jvRfxy5-a7"
|
||||||
Net = "aXyDLzBCJ9XltXZIfetEVsEkrqHfcXuD5XE_FcUnYbN3emwL55N6P8LlHzNfGnM5"
|
Net = "kJvy24uk4ePvHoxSKf4vMOhR4NxLbmyWlA9bTS7d3z3fE9WF1Tvpao9g-QuYU4vm"
|
||||||
Promote = "3k4V16n96Lq04gjFSKmm4sFjyQ883FFBNXgTy9s_DjeTwxT3pg_iacEh8yMb_S4m"
|
Promote = "lYqyYrfjPawIbld5Qz0NbKvd_bmI3nJC1eEnlIQWzsjWE9uA1HuKPAaClnDeyG6L"
|
||||||
Work = "6Q49MhFWRE3Ne6MycwAotgl1GtoU5WCHqJNWG2byYZCY-zX-IxPrWiKk7bKkNzhE"
|
Work = "V6k4FqOBMRCmHiqchs5-joVGZ_MhNWZyXm3gdbU0S7S5eMze7G4SwYMTf66ojKQL"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package expected
|
package expected
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Offline = "Z6yXE5gOJScL3srmnVMWgCXccDiUNZ5snSrf6RkXuU1_U0rX_kGVwsfHUgNG_awd"
|
Offline = "LlieSHVDe1lnKvfI8t4oGRg_2hPxwyy1drmaqc-EKCOENuS9C2YHrp2VY5pSyhbg"
|
||||||
OfflineS = "zN16xv6LKRJRipUJwupyxg2rZcvf-qpsMn_qCxUmgxlTSuNwYI70ZEb7dHW5k0gO"
|
OfflineS = "qccjM8oYjUuEYPKFFzAxDFVzMerSUKUZc18NdVQoiPWf-70XOsNK8NaUQqjTgTAD"
|
||||||
OvlRoot = "zYXJHFRLuxvUhuisZEXgGgVvdQd6piMfp5jmtT6jdVjvC2gICXquOq-UTwlrSD5I"
|
OvlRoot = "lpV2bb_KGYFHPiOn-jtGop8K_ew0y1p3BezRp0ebM93_a-T9J-vkqGD5uokda1aN"
|
||||||
Layers = "_F8EDazHbcLeT0sVSQXRN_kn9IjduqJcDYgzXpsT-hpKU4EBcZ0PISN2zchpqMbm"
|
Layers = "sM3DJm210CHPGHkAquIbrXhspB81FpVC60ApQrvJGD5El2i7cSONj7LWf7EWqKpT"
|
||||||
Net = "CA_FAaSIYJgapBEHV40doxpH23PdUEy_6s1TZc7wfSPN0XYqwGpMceXXDSabGveO"
|
Net = "JihQUwsVETRYjb2-yIXLYZ6WVsaFebwl8btSYAsNQ2QapS5MZVaI-dYwrVoySycR"
|
||||||
Promote = "_3LPrLp--4h9k4GsNNApu9hHtAafq-GUhfU6d4hJKBDKT3bz_szOsvkXxc5sK53d"
|
Promote = "lGqwR4W2OjylSVitMQP1lc6wApOBkbMjsmIqkxQbfEZ3DHEQBbJr84ErW6Xb54zo"
|
||||||
Work = "FEgHeiCD_WT4wsfB-9kDH5n6cRWCEYtJmXdKZgmUUukAOoXumH_hLlosXREC-tqq"
|
Work = "aZgtyv6aMtoHFkHAaJr6nLaA7N_SHjShgWPyQ5UdzaIqYSiVqvCrZqSokGTCcTii"
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-5
@@ -278,10 +278,11 @@ func (ic *irCache) encode(
|
|||||||
return *a == *b
|
return *a == *b
|
||||||
})
|
})
|
||||||
|
|
||||||
// kind uint64 | deps_sz uint64
|
// kind uint64 | rev uint64 | deps_sz uint64
|
||||||
var buf [wordSize * 2]byte
|
var buf [wordSize * 3]byte
|
||||||
binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
|
binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
|
||||||
binary.LittleEndian.PutUint64(buf[wordSize:], uint64(len(idents)))
|
binary.LittleEndian.PutUint64(buf[wordSize:], GetRevision(a))
|
||||||
|
binary.LittleEndian.PutUint64(buf[wordSize*2:], uint64(len(idents)))
|
||||||
if _, err = w.Write(buf[:]); err != nil {
|
if _, err = w.Write(buf[:]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -740,6 +741,15 @@ func (ir *IRReader) ReadString() string {
|
|||||||
return unsafe.String(unsafe.SliceData(p), len(p))
|
return unsafe.String(unsafe.SliceData(p), len(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A RevisionError describes the first [Artifact] in an IR stream claiming a
|
||||||
|
// revision not supported by the registered implementation.
|
||||||
|
type RevisionError [2]uint64
|
||||||
|
|
||||||
|
func (e RevisionError) Error() string {
|
||||||
|
return "claimed revision " + strconv.FormatUint(e[0], 10) +
|
||||||
|
" differs from implementation value " + strconv.FormatUint(e[1], 10)
|
||||||
|
}
|
||||||
|
|
||||||
// decode decodes the next [Artifact] in the IR stream and returns any buffer
|
// decode decodes the next [Artifact] in the IR stream and returns any buffer
|
||||||
// originating from [Cache] before returning. decode returns [io.EOF] if and
|
// originating from [Cache] before returning. decode returns [io.EOF] if and
|
||||||
// only if the underlying [io.Reader] is already read to EOF.
|
// only if the underlying [io.Reader] is already read to EOF.
|
||||||
@@ -772,6 +782,9 @@ func (d *IRDecoder) decode() (a Artifact, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir.mustRead(ir.buf[:])
|
||||||
|
rev := binary.LittleEndian.Uint64(ir.buf[:])
|
||||||
|
|
||||||
defer ir.putAll()
|
defer ir.putAll()
|
||||||
ir.mustRead(ir.buf[:])
|
ir.mustRead(ir.buf[:])
|
||||||
sz := binary.LittleEndian.Uint64(ir.buf[:])
|
sz := binary.LittleEndian.Uint64(ir.buf[:])
|
||||||
@@ -792,6 +805,10 @@ func (d *IRDecoder) decode() (a Artifact, err error) {
|
|||||||
err = syscall.ENOTRECOVERABLE
|
err = syscall.ENOTRECOVERABLE
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if _rev := GetRevision(a); _rev != rev {
|
||||||
|
err = RevisionError{rev, _rev}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ir.count != -1 {
|
if ir.count != -1 {
|
||||||
err = ErrRemainingIR
|
err = ErrRemainingIR
|
||||||
@@ -806,8 +823,8 @@ func (d *IRDecoder) decode() (a Artifact, err error) {
|
|||||||
d.ident[id] = a
|
d.ident[id] = a
|
||||||
} else {
|
} else {
|
||||||
d.c.msg.Verbosef(
|
d.c.msg.Verbosef(
|
||||||
"artifact %s appeared more than once in IR stream",
|
"artifact %s%s%s appeared more than once in IR stream",
|
||||||
Encode(id.Value()),
|
d.c.sgrIdent, Encode(id.Value()), d.c.sgrRes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,3 +135,36 @@ func TestIRRoundtrip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
checkWithCache(t, testCasesCache)
|
checkWithCache(t, testCasesCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRevision(t *testing.T) {
|
||||||
|
checkWithCache(t, []cacheTestCase{{"revision", 0, nil,
|
||||||
|
func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
|
a := pkg.NewFile("", nil)
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := c.EncodeAll(&buf, a); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := c.NewDecoder(
|
||||||
|
bytes.NewReader(buf.Bytes()),
|
||||||
|
).Decode(); err != nil {
|
||||||
|
t.Fatalf("Decode: error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p := buf.Bytes()
|
||||||
|
p[8] = 0xfd
|
||||||
|
wantErr := pkg.RevisionError{0xfd, 0}
|
||||||
|
if _, err := c.NewDecoder(
|
||||||
|
bytes.NewReader(p),
|
||||||
|
).Decode(); !reflect.DeepEqual(err, wantErr) {
|
||||||
|
t.Fatalf("Decode: error = %v, want %v", err, wantErr)
|
||||||
|
}
|
||||||
|
}, expectsFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
},
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ func (e ResponseStatusError) Error() string {
|
|||||||
return "the requested URL returned non-OK status: " + http.StatusText(int(e))
|
return "the requested URL returned non-OK status: " + http.StatusText(int(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsExecutable returns false.
|
||||||
|
func (*httpArtifact) IsExecutable() bool { return false }
|
||||||
|
|
||||||
// Cure sends the http request and returns the resulting response body reader
|
// Cure sends the http request and returns the resulting response body reader
|
||||||
// wrapped to perform checksum validation. It is valid but not encouraged to
|
// wrapped to perform checksum validation. It is valid but not encouraged to
|
||||||
// close the resulting [io.ReadCloser] before it is read to EOF, as that causes
|
// close the resulting [io.ReadCloser] before it is read to EOF, as that causes
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func TestHTTPGet(t *testing.T) {
|
|||||||
)
|
)
|
||||||
wantPathname := base.Append(
|
wantPathname := base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"oM-2pUlk-mOxK1t3aMWZer69UdOQlAXiAgMrpZ1476VoOqpYVP1aGFS9_HYy-D8_",
|
"COBRUwkxpIvZWJggpRxn7HVXiw6epXZOex8jGRJKpowpwukV7GRBY_LBvOJNQHue",
|
||||||
)
|
)
|
||||||
if pathname, checksum, err := c.Cure(f); err != nil {
|
if pathname, checksum, err := c.Cure(f); err != nil {
|
||||||
t.Fatalf("Cure: error = %v", err)
|
t.Fatalf("Cure: error = %v", err)
|
||||||
@@ -158,7 +158,7 @@ func TestHTTPGet(t *testing.T) {
|
|||||||
"checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU": {Mode: 0400, Data: []byte("\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69")},
|
"checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU": {Mode: 0400, Data: []byte("\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/oM-2pUlk-mOxK1t3aMWZer69UdOQlAXiAgMrpZ1476VoOqpYVP1aGFS9_HYy-D8_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")},
|
"identifier/COBRUwkxpIvZWJggpRxn7HVXiw6epXZOex8jGRJKpowpwukV7GRBY_LBvOJNQHue": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
|||||||
+166
-111
@@ -15,9 +15,10 @@ import (
|
|||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"iter"
|
||||||
"maps"
|
"maps"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -477,6 +478,8 @@ type KnownIdent interface {
|
|||||||
// [Artifact]. This value must be known ahead of time and guaranteed to be
|
// [Artifact]. This value must be known ahead of time and guaranteed to be
|
||||||
// unique without having obtained the full contents of the [Artifact].
|
// unique without having obtained the full contents of the [Artifact].
|
||||||
ID() ID
|
ID() ID
|
||||||
|
|
||||||
|
Artifact
|
||||||
}
|
}
|
||||||
|
|
||||||
// KnownChecksum is optionally implemented by [Artifact] for an artifact with
|
// KnownChecksum is optionally implemented by [Artifact] for an artifact with
|
||||||
@@ -488,6 +491,8 @@ type KnownChecksum interface {
|
|||||||
//
|
//
|
||||||
// Result must remain identical across multiple invocations.
|
// Result must remain identical across multiple invocations.
|
||||||
Checksum() Checksum
|
Checksum() Checksum
|
||||||
|
|
||||||
|
Artifact
|
||||||
}
|
}
|
||||||
|
|
||||||
// CuresExempt is optionally implemented for an artifact exempt to the
|
// CuresExempt is optionally implemented for an artifact exempt to the
|
||||||
@@ -505,6 +510,12 @@ type CuresExempt interface {
|
|||||||
// FileArtifact does not support fine-grained cancellation. Its context is
|
// FileArtifact does not support fine-grained cancellation. Its context is
|
||||||
// inherited from the first [TrivialArtifact] or [FloodArtifact] that opens it.
|
// inherited from the first [TrivialArtifact] or [FloodArtifact] that opens it.
|
||||||
type FileArtifact interface {
|
type FileArtifact interface {
|
||||||
|
// IsExecutable returns whether the resulting filesystem entry should be made
|
||||||
|
// executable, if the [FileArtifact] is cured to the on-disk cache.
|
||||||
|
//
|
||||||
|
// Result must remain identical across multiple invocations.
|
||||||
|
IsExecutable() bool
|
||||||
|
|
||||||
// Cure returns [io.ReadCloser] of the full contents of [FileArtifact]. If
|
// Cure returns [io.ReadCloser] of the full contents of [FileArtifact]. If
|
||||||
// [FileArtifact] implements [KnownChecksum], Cure is responsible for
|
// [FileArtifact] implements [KnownChecksum], Cure is responsible for
|
||||||
// validating any data it produces and must return [ChecksumMismatchError]
|
// validating any data it produces and must return [ChecksumMismatchError]
|
||||||
@@ -514,12 +525,35 @@ type FileArtifact interface {
|
|||||||
//
|
//
|
||||||
// Callers are responsible for closing the resulting [io.ReadCloser].
|
// Callers are responsible for closing the resulting [io.ReadCloser].
|
||||||
//
|
//
|
||||||
// Result must remain identical across multiple invocations.
|
// The resulting [io.ReadCloser] across multiple invocations must have
|
||||||
|
// identical behaviour.
|
||||||
Cure(r *RContext) (io.ReadCloser, error)
|
Cure(r *RContext) (io.ReadCloser, error)
|
||||||
|
|
||||||
Artifact
|
Artifact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RevisionArtifact is optionally implemented by an artifact that had undergone
|
||||||
|
// internal changes affecting its behaviour while retaining its IR structure.
|
||||||
|
type RevisionArtifact interface {
|
||||||
|
// Revision returns the revision number of [Artifact]. This value is always
|
||||||
|
// represented in the IR. An IR stream produced from the same [Kind] with
|
||||||
|
// differing revision is rejected.
|
||||||
|
//
|
||||||
|
// Result must remain identical across multiple invocations.
|
||||||
|
Revision() uint64
|
||||||
|
|
||||||
|
Artifact
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRevision returns the revision number of an [Artifact].
|
||||||
|
func GetRevision(a Artifact) (revision uint64) {
|
||||||
|
revision = math.MaxUint64
|
||||||
|
if r, ok := a.(RevisionArtifact); ok {
|
||||||
|
revision = r.Revision()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// reportName returns a string describing [Artifact] presented to the user.
|
// reportName returns a string describing [Artifact] presented to the user.
|
||||||
func reportName(a Artifact, id unique.Handle[ID]) string {
|
func reportName(a Artifact, id unique.Handle[ID]) string {
|
||||||
r := Encode(id.Value())
|
r := Encode(id.Value())
|
||||||
@@ -620,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
|
||||||
|
|
||||||
@@ -687,6 +721,9 @@ const (
|
|||||||
// CExternShallow arranges for only non-flood inputs to be fetched when
|
// CExternShallow arranges for only non-flood inputs to be fetched when
|
||||||
// curing an [Artifact] available via the external cache.
|
// curing an [Artifact] available via the external cache.
|
||||||
CExternShallow
|
CExternShallow
|
||||||
|
|
||||||
|
// CColourOutput enables output colouring via ANSI control sequences.
|
||||||
|
CColourOutput
|
||||||
)
|
)
|
||||||
|
|
||||||
// toplevel holds [context.WithCancel] over caller-supplied context, where all
|
// toplevel holds [context.WithCancel] over caller-supplied context, where all
|
||||||
@@ -742,6 +779,8 @@ type Cache struct {
|
|||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
// Reports new cures and passed to [Artifact].
|
// Reports new cures and passed to [Artifact].
|
||||||
msg message.Msg
|
msg message.Msg
|
||||||
|
// Select graphics rendition sequences, populated by Open.
|
||||||
|
sgrRes, sgrIdent, sgrWarn, sgrErr string
|
||||||
|
|
||||||
// Directory where all [Cache] related files are placed.
|
// Directory where all [Cache] related files are placed.
|
||||||
base *check.Absolute
|
base *check.Absolute
|
||||||
@@ -1098,7 +1137,10 @@ func (c *Cache) Scrub(checks int) error {
|
|||||||
} else if !ce.check(ent, want) {
|
} else if !ce.check(ent, want) {
|
||||||
wg.Go(func() { condemn(ent) })
|
wg.Go(func() { condemn(ent) })
|
||||||
} else {
|
} else {
|
||||||
c.msg.Verbosef("%s is consistent", ent.Name())
|
c.msg.Verbosef(
|
||||||
|
"%s%s%s is consistent",
|
||||||
|
c.sgrIdent, ent.Name(), c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
p.Put(want)
|
p.Put(want)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
@@ -1474,10 +1516,10 @@ func (c *Cache) openFile(
|
|||||||
id := c.Ident(f)
|
id := c.Ident(f)
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
rn := reportName(f, id)
|
rn := reportName(f, id)
|
||||||
c.msg.Verbosef("curing %s in memory...", rn)
|
c.msg.Verbosef("curing %s%s%s in memory...", c.sgrIdent, rn, c.sgrRes)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.msg.Verbosef("opened %s for reading", rn)
|
c.msg.Verbosef("opened %s%s%s for reading", c.sgrIdent, rn, c.sgrRes)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@@ -1679,111 +1721,67 @@ 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
|
||||||
|
id unique.Handle[ID]
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
}
|
p := make([]input, 0, len(e))
|
||||||
|
for a := range e {
|
||||||
// unwrap recursively expands and deduplicates underlying errors.
|
p = append(p, input{a, ir.Ident(a)})
|
||||||
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]
|
|
||||||
err *CureError
|
|
||||||
}
|
|
||||||
errs := make([]*ent, 0, len(me))
|
|
||||||
for id, err := range me {
|
|
||||||
errs = append(errs, &ent{id, err})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
c.attr.Notify <- true
|
||||||
|
}
|
||||||
|
|
||||||
if a.IsExclusive() {
|
if a.IsExclusive() {
|
||||||
c.exclMu.Lock()
|
c.exclMu.Lock()
|
||||||
}
|
}
|
||||||
@@ -1806,6 +1804,10 @@ func (c *Cache) enterCure(a Artifact, curesExempt bool) error {
|
|||||||
|
|
||||||
// exitCure must be called after exiting an [Artifact] implementation.
|
// exitCure must be called after exiting an [Artifact] implementation.
|
||||||
func (c *Cache) exitCure(a Artifact, curesExempt bool) {
|
func (c *Cache) exitCure(a Artifact, curesExempt bool) {
|
||||||
|
if c.attr.Notify != nil {
|
||||||
|
c.attr.Notify <- false
|
||||||
|
}
|
||||||
|
|
||||||
if a.IsExclusive() {
|
if a.IsExclusive() {
|
||||||
c.exclMu.Unlock()
|
c.exclMu.Unlock()
|
||||||
}
|
}
|
||||||
@@ -1856,7 +1858,10 @@ func (mr *measuredReader) Close() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
mr.c.msg.Verbosef("missed %d bytes on measured reader", n)
|
mr.c.msg.Verbosef(
|
||||||
|
"%smissed %d bytes on measured reader%s",
|
||||||
|
mr.c.sgrWarn, n, mr.c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mr.r.Close(); err != nil {
|
if err = mr.r.Close(); err != nil {
|
||||||
@@ -1970,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))
|
||||||
@@ -1989,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] {
|
||||||
@@ -2117,8 +2122,9 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
)
|
)
|
||||||
if errors.Is(err, os.ErrExist) {
|
if errors.Is(err, os.ErrExist) {
|
||||||
c.msg.Verbosef(
|
c.msg.Verbosef(
|
||||||
"creating alternative over %s for artifact %s",
|
"creating alternative over %s%s%s for artifact %s%s%s",
|
||||||
Encode(substitute.Value()), ids,
|
c.sgrIdent, Encode(substitute.Value()), c.sgrRes,
|
||||||
|
c.sgrIdent, ids, c.sgrRes,
|
||||||
)
|
)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
@@ -2161,15 +2167,18 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
whence = WNew
|
whence = WNew
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
rn := reportName(a, id)
|
rn := reportName(a, id)
|
||||||
c.msg.Verbosef("curing %s...", rn)
|
c.msg.Verbosef("curing %s%s%s...", c.sgrIdent, rn, c.sgrRes)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if checksums != "" {
|
if checksums != "" {
|
||||||
c.msg.Verbosef("cured %s checksum %s", rn, checksums)
|
c.msg.Verbosef(
|
||||||
|
"cured %s%s%s checksum %s%s%s",
|
||||||
|
c.sgrIdent, rn, c.sgrRes,
|
||||||
|
c.sgrIdent, checksums, c.sgrRes)
|
||||||
} else {
|
} else {
|
||||||
c.msg.Verbosef("cured %s", rn)
|
c.msg.Verbosef("cured %s%s%s", c.sgrIdent, rn, c.sgrRes)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@@ -2185,12 +2194,17 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
perm := os.FileMode(0400)
|
||||||
|
if f.IsExecutable() {
|
||||||
|
perm = 0500
|
||||||
|
}
|
||||||
|
|
||||||
work := c.base.Append(dirWork, ids)
|
work := c.base.Append(dirWork, ids)
|
||||||
var w *os.File
|
var w *os.File
|
||||||
if w, err = os.OpenFile(
|
if w, err = os.OpenFile(
|
||||||
work.String(),
|
work.String(),
|
||||||
os.O_CREATE|os.O_EXCL|os.O_WRONLY,
|
os.O_CREATE|os.O_EXCL|os.O_WRONLY,
|
||||||
0400,
|
perm,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2259,7 +2273,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
c.exitCure(a, curesExempt)
|
c.exitCure(a, curesExempt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("cure file %s: %v", reportName(f, id), err)
|
c.msg.Verbosef(
|
||||||
|
"cure file %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(f, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2306,7 +2324,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
c.exitCure(a, curesExempt)
|
c.exitCure(a, curesExempt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("cure trivial %s: %v", reportName(ca, id), err)
|
c.msg.Verbosef(
|
||||||
|
"cure trivial %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(ca, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2316,7 +2338,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
var externChecksum unique.Handle[Checksum]
|
var externChecksum unique.Handle[Checksum]
|
||||||
if externChecksum, err = c.tryExtern(ctx, id); err != nil {
|
if externChecksum, err = c.tryExtern(ctx, id); err != nil {
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("extern %s: %v", reportName(ca, id), err)
|
c.msg.Verbosef(
|
||||||
|
"extern %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(ca, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2356,8 +2382,8 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
if sum == zeroChecksum {
|
if sum == zeroChecksum {
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef(
|
c.msg.Verbosef(
|
||||||
"input %s not available",
|
"input %s%s%s not available",
|
||||||
reportName(d, did),
|
c.sgrIdent, reportName(d, did), c.sgrRes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
err = HangingInputError(did)
|
err = HangingInputError(did)
|
||||||
@@ -2421,7 +2447,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
if checksum != zeroChecksum && externChecksum != checksum {
|
if checksum != zeroChecksum && externChecksum != checksum {
|
||||||
err = &ChecksumMismatchError{externChecksum.Value(), checksum.Value()}
|
err = &ChecksumMismatchError{externChecksum.Value(), checksum.Value()}
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("extern %s: %v", reportName(ca, id), err)
|
c.msg.Verbosef(
|
||||||
|
"extern %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(ca, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2470,7 +2500,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("cure %s: %v", reportName(ca, id), err)
|
c.msg.Verbosef(
|
||||||
|
"cure %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(ca, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2521,7 +2555,11 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
|
|||||||
Want: checksum.Value(),
|
Want: checksum.Value(),
|
||||||
}
|
}
|
||||||
if c.msg.IsVerbose() {
|
if c.msg.IsVerbose() {
|
||||||
c.msg.Verbosef("validate %s: %v", reportName(a, id), err)
|
c.msg.Verbosef(
|
||||||
|
"validate %s%s%s: %s%v%s",
|
||||||
|
c.sgrIdent, reportName(a, id), c.sgrRes,
|
||||||
|
c.sgrErr, err, c.sgrRes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2565,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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2663,6 +2705,10 @@ func (c *Cache) Close() {
|
|||||||
c.wg.Wait()
|
c.wg.Wait()
|
||||||
close(c.cures)
|
close(c.cures)
|
||||||
c.unlock()
|
c.unlock()
|
||||||
|
|
||||||
|
if c.attr.Notify != nil {
|
||||||
|
close(c.attr.Notify)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsupportedVariantError describes an on-disk cache with an extension variant
|
// UnsupportedVariantError describes an on-disk cache with an extension variant
|
||||||
@@ -2690,6 +2736,8 @@ type CacheAttr struct {
|
|||||||
Jobs int
|
Jobs int
|
||||||
// Preferred loadavg target, when applicable.
|
// Preferred loadavg target, when applicable.
|
||||||
Load int
|
Load int
|
||||||
|
// Optional cure entry and exit notification.
|
||||||
|
Notify chan<- bool
|
||||||
|
|
||||||
// Omit the [lockedfile] lock.
|
// Omit the [lockedfile] lock.
|
||||||
skipLock bool
|
skipLock bool
|
||||||
@@ -2856,6 +2904,13 @@ func Open(
|
|||||||
return nil, UnsupportedVariantError(s)
|
return nil, UnsupportedVariantError(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.Flags&CColourOutput != 0 {
|
||||||
|
c.sgrRes = "\x1b[0m"
|
||||||
|
c.sgrIdent = "\x1b[1m"
|
||||||
|
c.sgrWarn = "\x1b[35m"
|
||||||
|
c.sgrErr = "\x1b[1;31m"
|
||||||
|
}
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+78
-93
@@ -170,6 +170,8 @@ type stubFile struct {
|
|||||||
stubArtifact
|
stubArtifact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*stubFile) IsExecutable() bool { return false }
|
||||||
|
|
||||||
func (a *stubFile) Cure(*pkg.RContext) (io.ReadCloser, error) {
|
func (a *stubFile) Cure(*pkg.RContext) (io.ReadCloser, error) {
|
||||||
return io.NopCloser(bytes.NewReader(a.data)), a.err
|
return io.NopCloser(bytes.NewReader(a.data)), a.err
|
||||||
}
|
}
|
||||||
@@ -330,7 +332,7 @@ func TestIdent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
}, unique.Make[pkg.ID](pkg.MustDecode(
|
}, unique.Make[pkg.ID](pkg.MustDecode(
|
||||||
"97Y85QewssfPbNIN9cyNhzD4e6dLHcDTU8rb2c34k-aCrZfBNXFUc0duPiLFFcw_",
|
"fkmge-H56Ph2LzNNbEUjTypes8LfOxrF_CEXg07kq6ho_nbTNvzQde9-bjB7gyB_",
|
||||||
))},
|
))},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,7 +830,7 @@ func TestCache(t *testing.T) {
|
|||||||
kind: pkg.KindExec,
|
kind: pkg.KindExec,
|
||||||
params: []byte("artifact overridden to be incomplete"),
|
params: []byte("artifact overridden to be incomplete"),
|
||||||
}}, nil, nil, pkg.WNew, pkg.InvalidArtifactError(pkg.MustDecode(
|
}}, nil, nil, pkg.WNew, pkg.InvalidArtifactError(pkg.MustDecode(
|
||||||
"E__uZ1sLIvb84vzSm5Uezb03RogsiaeTt1nfIVv8TKnnf4LqwtSi-smdHhlkZrUJ",
|
"poVrv3zNINbHd-WUJihwgWQwJpbHURFHfpY7Zux-ztto_bQhhS5PdpbNMjdkXv-V",
|
||||||
))},
|
))},
|
||||||
|
|
||||||
{"error passthrough", newStubFile(
|
{"error passthrough", newStubFile(
|
||||||
@@ -859,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,
|
_ []byte
|
||||||
Err: struct {
|
stub.UniqueError
|
||||||
_ []byte
|
}{UniqueError: 0xbad},
|
||||||
stub.UniqueError
|
|
||||||
}{UniqueError: 0xbad},
|
|
||||||
},
|
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1121,7 +1120,7 @@ func TestCache(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, base.Append(
|
}, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"xMDWovje7OfyIaDy_2VnjpKxRqSOQ_LoeD946t-3WsS2V2SeMJ7nDGrNfpa4Pbc-",
|
"gIH5eti07nBAhVti3ZTn8EIGOBCZWWvNpxg5CmCZlDzIC4mBdomPmQLeEpf1IQg9",
|
||||||
), want, pkg.WNew, nil},
|
), want, pkg.WNew, nil},
|
||||||
|
|
||||||
{"substitutable", &stubArtifactF{
|
{"substitutable", &stubArtifactF{
|
||||||
@@ -1140,7 +1139,7 @@ func TestCache(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, base.Append(
|
}, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"k2ilgG5KQ9NXnMoT2oB6NdwOnSPRn_H24oXQc4l6qOYIxIG9XfuEczeyrR8UEv_f",
|
"VGjpp7NVw3OYLpgOQumfM0KcJgY3suz6torykUczcg4bGT24ySkPn5hy-4dNqqkR",
|
||||||
), want, pkg.WSubstitute, nil},
|
), want, pkg.WSubstitute, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1169,7 +1168,7 @@ func TestCache(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, base.Append(
|
}, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"_EmV5nsYZ2UWHgRmLDMU8i-rJWDx-kv5_1pFrzQI7vMMCM5mAXivO8UZtVfOqMR_",
|
"zeZ4JEZ0atAKl6Am67cBID6-KR18nZGgeYfU4qTuYaWhQC4eAn0dyTXdIBH9Bos8",
|
||||||
), want, pkg.WSubstitute, nil},
|
), want, pkg.WSubstitute, nil},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1194,15 +1193,15 @@ func TestCache(t *testing.T) {
|
|||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
"identifier/_EmV5nsYZ2UWHgRmLDMU8i-rJWDx-kv5_1pFrzQI7vMMCM5mAXivO8UZtVfOqMR_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"identifier/zeZ4JEZ0atAKl6Am67cBID6-KR18nZGgeYfU4qTuYaWhQC4eAn0dyTXdIBH9Bos8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
"identifier/___9_QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
"identifier/___9_QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
||||||
"identifier/_wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
"identifier/_wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
||||||
"identifier/_woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
"identifier/_woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
|
||||||
"identifier/k2ilgG5KQ9NXnMoT2oB6NdwOnSPRn_H24oXQc4l6qOYIxIG9XfuEczeyrR8UEv_f": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"identifier/VGjpp7NVw3OYLpgOQumfM0KcJgY3suz6torykUczcg4bGT24ySkPn5hy-4dNqqkR": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
"identifier/xMDWovje7OfyIaDy_2VnjpKxRqSOQ_LoeD946t-3WsS2V2SeMJ7nDGrNfpa4Pbc-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"identifier/gIH5eti07nBAhVti3ZTn8EIGOBCZWWvNpxg5CmCZlDzIC4mBdomPmQLeEpf1IQg9": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/OyBGorh72Z9kVw35JUa8FbqDbpR4DqT-MX1jic0uKN5PdYmUBiAF38BRsIRnBigf": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
"substitute/nWPg893oqn_YNN8kgfZrs_LVLwP90e0mKxqU8UwoazQh-yBPwhoviD7of6YALx-M": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
}},
|
}},
|
||||||
@@ -1510,18 +1509,18 @@ func TestCache(t *testing.T) {
|
|||||||
"checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV": {Mode: 0400, Data: []byte("destroyed")},
|
"checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV": {Mode: 0400, Data: []byte("destroyed")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/0Jmc-vGnNDlXTD3jxy-4DGxHW-2-2LtLZ9SXaJtDIqu4uyHfDwDbghNBQ2aYRpab": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"identifier/CLyyxJWn1yUGFs_0KnJ4ZSU2hH4-elvGFRB36x14LrNrKBJPxvORhL9O4Rc7oeYU": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
|
||||||
"identifier/L-A8SK4ZX631eyealbJVH08u5pAVEf2NMk8RmLlxl7BVADkU4hNjWD6pi5H7uL1F": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
|
"identifier/arv8a6z4i0x6pUb5Z2T-3iE4ETvyZj-uReHGKsS7uiBgMgKNEOzTGG3LIZb8vp0L": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
|
||||||
"identifier/VbVV2dFVosCriHnG9t5vwfW4lbHvzOkV2eYwpGpPJZOgNBc0g1wZAhbdKEweLqmW": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"identifier/heRgWhNJmhm898V68kw0ta76t4rP1o29tYW_TrdyBWXGfo37K3QWA7Z-JkLXAwcn": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
"identifier/aSMwvPAwdsIF9e1spuLyRNEc8aTFA4HRVasoNqGjxdm1laSMs2h2teGsoSzLp_pR": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
|
"identifier/q-VoVBI3IjcWTqwIokpi3y05CP113CHgHslc-XWnhOvDULwzVc3q9Y5xOCm_YyLZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
|
|
||||||
"status": {Mode: fs.ModeDir | 0700},
|
"status": {Mode: fs.ModeDir | 0700},
|
||||||
"status/0Jmc-vGnNDlXTD3jxy-4DGxHW-2-2LtLZ9SXaJtDIqu4uyHfDwDbghNBQ2aYRpab": {Mode: fs.ModeSymlink | 0777, Data: []byte("dzO8FEY9lu4hwRT6BfRZOX-uYGsC_5XH4jEJ7sJyThcmG9J_w1ArOAaUCGfL8wAM")},
|
"status/q-VoVBI3IjcWTqwIokpi3y05CP113CHgHslc-XWnhOvDULwzVc3q9Y5xOCm_YyLZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x")},
|
||||||
"status/VbVV2dFVosCriHnG9t5vwfW4lbHvzOkV2eYwpGpPJZOgNBc0g1wZAhbdKEweLqmW": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
|
"status/heRgWhNJmhm898V68kw0ta76t4rP1o29tYW_TrdyBWXGfo37K3QWA7Z-JkLXAwcn": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
|
||||||
"status/dzO8FEY9lu4hwRT6BfRZOX-uYGsC_5XH4jEJ7sJyThcmG9J_w1ArOAaUCGfL8wAM": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
|
"status/dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/dzO8FEY9lu4hwRT6BfRZOX-uYGsC_5XH4jEJ7sJyThcmG9J_w1ArOAaUCGfL8wAM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
"substitute/dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
}},
|
}},
|
||||||
@@ -1613,17 +1612,17 @@ func TestCache(t *testing.T) {
|
|||||||
"checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
|
"checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/4HqRo4uTwRQjfy3d2cujMoDC_pC4iv20h4a7NYlx0UdbVuky18o5iK78TFEfPX2U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/k8yyhlBV3JpYzzywAnrRWkfp2TmgIDNC6FqMFwrrR2x0C3unBLveDNKgigOjG9MM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/7AZcJm58ghFyTVf_v2baSntgpsxkP5el7ti9dC77C29n8YTEqQW9jRW92KGNdYnz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/Xys8hPpJsKirZmTTuT7SwQ6661TCp_ZRu8iUjPPD7pC5E3ll7xw4zhNlZ2PVcz_-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
"identifier/c4aCI00C-ZVyo_FQDQLl1OYK4U_kjzxwrLdFDiXMHnbMcZXCkXo_nxUWauScZ_4V": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/8sInO_dhPW9kweit7jVuH_vtMkRxlZT7XE4_yEKPZmpGkgVxkmxz0OpXgbMsH6ET": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/cNoG77frXGRCJa7fUi1INKUEQg7L4qrX5acsSv-wqZdGZT7dQwM93rD3at6kSFFF": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
"identifier/ofaXbB5gIza_7W4Rzo5XDe_8FwlCPKWn3TBcmGgFAkkTWMl5GXGmOzX89Jd2Mk2A": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
"identifier/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
|
|
||||||
"status": {Mode: fs.ModeDir | 0700},
|
"status": {Mode: fs.ModeDir | 0700},
|
||||||
"status/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: 0400, Data: []byte("\x00")},
|
"status/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: 0400, Data: []byte("\x00")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/qOYrxy9ztKeOA96Os811_0Ox5sd8FBOxis6psJAnRJL5MLazFMaqmd4g7t7k1OHk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"substitute/socGRnhdsJlJ4Z01ZwHFZdLzFH0rWvoaJrylcUKtvhBdGsE7VoYl-vdUuvfK8B4I": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
}},
|
}},
|
||||||
@@ -1756,20 +1755,20 @@ func TestCache(t *testing.T) {
|
|||||||
"checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
|
"checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/4HqRo4uTwRQjfy3d2cujMoDC_pC4iv20h4a7NYlx0UdbVuky18o5iK78TFEfPX2U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/3fYJjSiWhklt7TK9MPVLGk5_8AIU8ostTcFPXULJf_qeAVG6pmC-Cqqu4ZhEXRxn": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
"identifier/7AZcJm58ghFyTVf_v2baSntgpsxkP5el7ti9dC77C29n8YTEqQW9jRW92KGNdYnz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
"identifier/RJbTOOIlqsEkAxGlTIsbp4mHPO0Q2IlwU7Gh_FIaTxnhgxUjAQPXXgPyP2GJWX2A": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/8sInO_dhPW9kweit7jVuH_vtMkRxlZT7XE4_yEKPZmpGkgVxkmxz0OpXgbMsH6ET": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/c4aCI00C-ZVyo_FQDQLl1OYK4U_kjzxwrLdFDiXMHnbMcZXCkXo_nxUWauScZ_4V": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"identifier/Xys8hPpJsKirZmTTuT7SwQ6661TCp_ZRu8iUjPPD7pC5E3ll7xw4zhNlZ2PVcz_-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
"identifier/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/k8yyhlBV3JpYzzywAnrRWkfp2TmgIDNC6FqMFwrrR2x0C3unBLveDNKgigOjG9MM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"identifier/lqjQtzpJ6asInpsdxqNYVjTkRHK-gW0eUCqNCCk1KhZTuKwKAc5Z0H7tS-GWfRlg": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"identifier/mXlNz_v77nW7jstn_rJn4RL7dCQlkakM0y-HjO6tkDubtzaj-wCmW1hIr2Gk64_O": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
|
|
||||||
"status": {Mode: fs.ModeDir | 0700},
|
"status": {Mode: fs.ModeDir | 0700},
|
||||||
"status/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: 0400, Data: []byte("\x00")},
|
"status/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: 0400, Data: []byte("\x00")},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
"substitute/qOYrxy9ztKeOA96Os811_0Ox5sd8FBOxis6psJAnRJL5MLazFMaqmd4g7t7k1OHk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
"substitute/socGRnhdsJlJ4Z01ZwHFZdLzFH0rWvoaJrylcUKtvhBdGsE7VoYl-vdUuvfK8B4I": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
"substitute/vLTXKbImP9XTTSi7P3PIuqy5L5UgX4dFQm2traX4X_pCDvg9GDraX1LmaUpgLu4w": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"substitute/MccYezQ4pshkeBV4w_aAEIwvZdKHL3OAgAkR3ouZ43EF94Ur1HBHaN7njPfJAj50": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
"substitute/yn1xEs5uSnu5EFLtkvjFSQ0C_fv50hU_w2wfDH_WBEzQhUiPJfyS3Eegy6YSclYN": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
"substitute/VV5W0_DiA1iylaqbKFThp1ZpV_y1ccVS1XyqDnDaXoHQ-EEyPI4XFrQHcHOF2hWG": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
}},
|
}},
|
||||||
@@ -1947,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 {
|
||||||
@@ -1960,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 {
|
||||||
@@ -2053,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())
|
||||||
c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
_, _, err = c.Cure(earlyFailureF(8))
|
|
||||||
if !errors.Is(err, stub.UniqueError(0xcafe)) {
|
|
||||||
b.Fatalf("Cure: error = %v", err)
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
dce := err.(*pkg.DependencyCureError)
|
|
||||||
|
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
dce.Unwrap()
|
b.StopTimer()
|
||||||
|
c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
_, _, err = c.Cure(earlyFailureF(8))
|
||||||
|
b.StopTimer()
|
||||||
|
if !errors.Is(err, stub.UniqueError(0xcafe)) {
|
||||||
|
b.Fatalf("Cure: error = %v", err)
|
||||||
|
}
|
||||||
|
c.Close()
|
||||||
|
b.StartTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,13 @@ func (a *tarArtifact) Cure(t *TContext) (err error) {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case tar.TypeChar:
|
||||||
|
t.GetMessage().Verbosef(
|
||||||
|
"%sskipping character device %d, %d %q%s",
|
||||||
|
t.cache.sgrWarn, header.Devmajor, header.Devminor, header.Name, t.cache.sgrRes,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
case tar.TypeXGlobalHeader:
|
case tar.TypeXGlobalHeader:
|
||||||
continue // ignore
|
continue // ignore
|
||||||
|
|
||||||
|
|||||||
+10
-29
@@ -3,7 +3,6 @@ package pkg_test
|
|||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"errors"
|
"errors"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
@@ -80,8 +79,8 @@ func TestTar(t *testing.T) {
|
|||||||
"checksum/" + wantEncode + "/work": {Mode: fs.ModeDir | 0500},
|
"checksum/" + wantEncode + "/work": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/T68YqeEW5moiwVe4J0wPvjERgyMUd4k_cKKxTcQx6AXqZaQAuuryu-Iv-qxDV6-T": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
"identifier/snWp53xxNdx6cV5KSJqzyVWzLlTsFd8udOisIu8Rgxly09mGcxufYCoQ5CQrHDyZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
||||||
"identifier/WbWIIUGl6bqDBsjU-UB69JqOWLjG5waiUJBUBGeeRp3V7FBbwaBe3sG1qm7DlPSk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
"identifier/v9DUj2R4YK_3ae0m9VuUYI-HJysDDCENu1k10thxioycRzFH1Qejw5bBGukm4IdL": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -104,8 +103,8 @@ func TestTar(t *testing.T) {
|
|||||||
"checksum/" + wantExpandEncode + "/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
"checksum/" + wantExpandEncode + "/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
"identifier/WbWIIUGl6bqDBsjU-UB69JqOWLjG5waiUJBUBGeeRp3V7FBbwaBe3sG1qm7DlPSk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
"identifier/1SuvgGltcsgqps9tWqjULG8RCdpx_6KVWXdsMd5xPKvdtysOxqpE-3bLu4j0WpGk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
||||||
"identifier/e3BECw_x_vDyTvj2P48MJVgwpgALeXQ90Ye2Y8gr6SwIPtMup6SR2LVcCTDRGpVi": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
"identifier/snWp53xxNdx6cV5KSJqzyVWzLlTsFd8udOisIu8Rgxly09mGcxufYCoQ5CQrHDyZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
||||||
|
|
||||||
"substitute": {Mode: fs.ModeDir | 0700},
|
"substitute": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
@@ -132,16 +131,7 @@ func checkTarHTTP(
|
|||||||
if err := w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
t.Fatalf("Close: error = %v", err)
|
t.Fatalf("Close: error = %v", err)
|
||||||
}
|
}
|
||||||
|
testdata = buf.String()
|
||||||
var zbuf bytes.Buffer
|
|
||||||
gw := gzip.NewWriter(&zbuf)
|
|
||||||
if _, err := gw.Write(buf.Bytes()); err != nil {
|
|
||||||
t.Fatalf("Write: error = %v", err)
|
|
||||||
}
|
|
||||||
if err := gw.Close(); err != nil {
|
|
||||||
t.Fatalf("Close: error = %v", err)
|
|
||||||
}
|
|
||||||
testdata = zbuf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testdataChecksum := func() pkg.Checksum {
|
testdataChecksum := func() pkg.Checksum {
|
||||||
@@ -208,28 +198,19 @@ func checkTarHTTP(
|
|||||||
defer newDestroyArtifactFunc(&tarDirType)(t, base, c)
|
defer newDestroyArtifactFunc(&tarDirType)(t, base, c)
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"file", pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
|
{"file", pkg.NewTar(pkg.NewHTTPGet(
|
||||||
&client,
|
&client,
|
||||||
"file:///testdata",
|
"file:///testdata",
|
||||||
testdataChecksum,
|
testdataChecksum,
|
||||||
), pkg.Gzip)), ignorePathname, want, pkg.WNew, nil},
|
|
||||||
|
|
||||||
{"directory", pkg.NewTar(pkg.NewDecompress(
|
|
||||||
&tarDir,
|
|
||||||
pkg.Gzip,
|
|
||||||
)), ignorePathname, want, pkg.WNew, nil},
|
)), ignorePathname, want, pkg.WNew, nil},
|
||||||
|
|
||||||
{"multiple entries", pkg.NewTar(pkg.NewDecompress(
|
{"directory", pkg.NewTar(&tarDir), ignorePathname, want, pkg.WNew, nil},
|
||||||
&tarDirMulti,
|
|
||||||
pkg.Gzip,
|
{"multiple entries", pkg.NewTar(&tarDirMulti), nil, nil, pkg.WNew, errors.New(
|
||||||
)), nil, nil, pkg.WNew, errors.New(
|
|
||||||
"input directory does not contain a single regular file",
|
"input directory does not contain a single regular file",
|
||||||
)},
|
)},
|
||||||
|
|
||||||
{"bad type", pkg.NewTar(pkg.NewDecompress(
|
{"bad type", pkg.NewTar(&tarDirType), nil, nil, pkg.WNew, errors.New(
|
||||||
&tarDirType,
|
|
||||||
pkg.Gzip,
|
|
||||||
)), nil, nil, pkg.WNew, errors.New(
|
|
||||||
"input directory does not contain a single regular file",
|
"input directory does not contain a single regular file",
|
||||||
)},
|
)},
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func TestDispatch(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}, true, []string{`{"kind":"fatal","message":"rejecting coldboot loop","error":"unique error 51966 injected by the test suite"}
|
}, true, []string{`{"kind":"fatal","message":"rejecting coldboot loop","error":"unique error 51966 injected by the test suite"}
|
||||||
`, `{"kind":"inconsistent","message":"processed inconsistent uevent","error":{"fault":1,"event":{"action":"add","devpath":"\u0000","env":{"V":"\ufffd"},"seqnum":2,"subsystem":""},"object":{"state":1,"devpath":"\u0000","subsystem":"","env":{"V":"\ufffd"}}}}
|
`, `{"kind":"inconsistent","message":"processed inconsistent uevent","error":{"fault":1,"event":{"action":"add","devpath":"\u0000","env":{"V":"` + "\ufffd" + `"},"seqnum":2,"subsystem":""},"object":{"state":1,"devpath":"\u0000","subsystem":"","env":{"V":"` + "\ufffd" + `"}}}}
|
||||||
`}, `dispatch: rejecting coldboot loop: unique error 51966 injected by the test suite
|
`}, `dispatch: rejecting coldboot loop: unique error 51966 injected by the test suite
|
||||||
dispatch: processed inconsistent uevent: duplicate add event on devpath "\x00"
|
dispatch: processed inconsistent uevent: duplicate add event on devpath "\x00"
|
||||||
`, nil},
|
`, nil},
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func skipGNUTests(tests ...int64) string {
|
|||||||
buf.WriteString(strconv.Itoa(int(n - 1)))
|
buf.WriteString(strconv.Itoa(int(n - 1)))
|
||||||
buf.WriteString(" ")
|
buf.WriteString(" ")
|
||||||
}
|
}
|
||||||
if i == len(tests)-1 || tests[i+1] != n+1 {
|
if i == len(tests)-1 || (tests[i+1] != n+1 && tests[i+1] != n+2) {
|
||||||
buf.WriteString(strconv.Itoa(int(n + 1)))
|
buf.WriteString(strconv.Itoa(int(n + 1)))
|
||||||
buf.WriteString("-")
|
buf.WriteString("-")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ func TestSkipGNUTests(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{[]int64{764}, "1-763 765-"},
|
{[]int64{764}, "1-763 765-"},
|
||||||
{[]int64{764, 0xcafe, 37, 9}, "1-8 10-36 38-763 765-51965 51967-"},
|
{[]int64{764, 0xcafe, 37, 9}, "1-8 10-36 38-763 765-51965 51967-"},
|
||||||
|
{[]int64{168, 170, 623, 764}, "1-167 169 171-622 624-763 765-"},
|
||||||
{[]int64{1, 2, 0xbed}, "3-3052 3054-"},
|
{[]int64{1, 2, 0xbed}, "3-3052 3054-"},
|
||||||
{[]int64{3, 4}, "1-2 5-"},
|
{[]int64{3, 4}, "1-2 5-"},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"hakurei.app/fhs"
|
|
||||||
"hakurei.app/internal/pkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
// busyboxBin is a busybox binary distribution installed under bin/busybox.
|
|
||||||
type busyboxBin struct {
|
|
||||||
// Underlying busybox binary.
|
|
||||||
bin pkg.FileArtifact
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind returns the hardcoded [pkg.Kind] value.
|
|
||||||
func (a busyboxBin) Kind() pkg.Kind { return kindBusyboxBin }
|
|
||||||
|
|
||||||
// Params is a noop.
|
|
||||||
func (a busyboxBin) Params(*pkg.IContext) {}
|
|
||||||
|
|
||||||
// IsExclusive returns false: Cure performs a trivial filesystem write.
|
|
||||||
func (busyboxBin) IsExclusive() bool { return false }
|
|
||||||
|
|
||||||
// Inputs returns the underlying busybox [pkg.FileArtifact].
|
|
||||||
func (a busyboxBin) Inputs() []pkg.Artifact {
|
|
||||||
return []pkg.Artifact{a.bin}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
pkg.Register(kindBusyboxBin, func(r *pkg.IRReader) pkg.Artifact {
|
|
||||||
a := busyboxBin{r.Next().(pkg.FileArtifact)}
|
|
||||||
if _, ok := r.Finalise(); ok {
|
|
||||||
panic(pkg.ErrUnexpectedChecksum)
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the reporting name of the underlying file prefixed with expand.
|
|
||||||
func (a busyboxBin) String() string {
|
|
||||||
return "expand-" + a.bin.(fmt.Stringer).String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cure installs the underlying busybox [pkg.File] to bin/busybox.
|
|
||||||
func (a busyboxBin) Cure(t *pkg.TContext) (err error) {
|
|
||||||
var r io.ReadCloser
|
|
||||||
if r, err = t.Open(a.bin); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
closeErr := r.Close()
|
|
||||||
if err == nil {
|
|
||||||
err = closeErr
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
binDir := t.GetWorkDir().Append("bin")
|
|
||||||
if err = os.MkdirAll(binDir.String(), 0700); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var w *os.File
|
|
||||||
if w, err = os.OpenFile(
|
|
||||||
binDir.Append("busybox").String(),
|
|
||||||
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
|
|
||||||
0500,
|
|
||||||
); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
closeErr := w.Close()
|
|
||||||
if err == nil {
|
|
||||||
err = closeErr
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
_, err = io.Copy(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBusyboxBin returns a [pkg.Artifact] containing a busybox installation from
|
|
||||||
// the https://busybox.net/downloads/binaries/ binary release.
|
|
||||||
func (s *S) newBusyboxBin() pkg.Artifact {
|
|
||||||
var version, url, checksum string
|
|
||||||
switch s.arch {
|
|
||||||
case "amd64":
|
|
||||||
version = "1.35.0"
|
|
||||||
url = "https://busybox.net/downloads/binaries/" +
|
|
||||||
version + "-" + s.linuxArch() + "-linux-musl/busybox"
|
|
||||||
checksum = "L7OBIsPu9enNHn7FqpBT1kOg_mCLNmetSeNMA3i4Y60Z5jTgnlX3qX3zcQtLx5AB"
|
|
||||||
case "arm64":
|
|
||||||
version = "1.31.0"
|
|
||||||
url = "https://busybox.net/downloads/binaries/" +
|
|
||||||
version + "-defconfig-multiarch-musl/busybox-armv8l"
|
|
||||||
checksum = "npJjBO7iwhjW6Kx2aXeSxf8kXhVgTCDChOZTTsI8ZfFfa3tbsklxRiidZQdrVERg"
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("unsupported target " + s.arch)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkg.NewExec(
|
|
||||||
"busybox-bin-"+version, s.arch, nil, pkg.ExecTimeoutMax, false, false,
|
|
||||||
fhs.AbsRoot, []string{
|
|
||||||
"PATH=/system/bin",
|
|
||||||
},
|
|
||||||
AbsSystem.Append("bin", "busybox"),
|
|
||||||
[]string{"hush", "-c", "" +
|
|
||||||
"busybox mkdir -p /work/system/bin/ && " +
|
|
||||||
"busybox cp /system/bin/busybox /work/system/bin/ && " +
|
|
||||||
"busybox --install -s /work/system/bin/"},
|
|
||||||
pkg.Path(AbsSystem, true, busyboxBin{pkg.NewHTTPGet(
|
|
||||||
&http.Client{Transport: &http.Transport{
|
|
||||||
// busybox website is really slow to respond
|
|
||||||
TLSHandshakeTimeout: 2 * time.Minute,
|
|
||||||
}}, url,
|
|
||||||
mustDecode(checksum),
|
|
||||||
)}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -35,7 +35,7 @@ type CMakeHelper struct {
|
|||||||
var _ Helper = new(CMakeHelper)
|
var _ Helper = new(CMakeHelper)
|
||||||
|
|
||||||
// extra returns the cmake handle alongside either ninja or make.
|
// extra returns the cmake handle alongside either ninja or make.
|
||||||
func (attr *CMakeHelper) extra(int) P {
|
func (attr *CMakeHelper) extra() P {
|
||||||
if attr != nil && attr.Make {
|
if attr != nil && attr.Make {
|
||||||
return P{_cmake, _make}
|
return P{_cmake, _make}
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,7 @@ func (attr *CMakeHelper) script(t Toolchain, name string) string {
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
cmake -G ` + generate + ` \
|
cmake -G ` + generate + ` \
|
||||||
|
-Wno-author -Wno-unused-cli \
|
||||||
-DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
-DCMAKE_C_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||||
-DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
-DCMAKE_CXX_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||||
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ func init() {
|
|||||||
a := cureEtc{}
|
a := cureEtc{}
|
||||||
if r.ReadUint32() == 0 {
|
if r.ReadUint32() == 0 {
|
||||||
a.minimal = true
|
a.minimal = true
|
||||||
|
} else {
|
||||||
|
r.Next()
|
||||||
}
|
}
|
||||||
if _, ok := r.Finalise(); ok {
|
if _, ok := r.Finalise(); ok {
|
||||||
panic(pkg.ErrUnexpectedChecksum)
|
panic(pkg.ErrUnexpectedChecksum)
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package rosa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"hakurei.app/internal/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// gentooOverlay are symlinks on top of a Gentoo LLVM stage3 tarball for
|
||||||
|
// compatibility with the Rosa OS stage0 distribution.
|
||||||
|
type gentooOverlay struct{ stage3 pkg.Artifact }
|
||||||
|
|
||||||
|
// Kind returns the hardcoded [pkg.Kind] value.
|
||||||
|
func (a gentooOverlay) Kind() pkg.Kind { return kindGentooOverlay }
|
||||||
|
|
||||||
|
// Params is a noop.
|
||||||
|
func (a gentooOverlay) Params(*pkg.IContext) {}
|
||||||
|
|
||||||
|
// IsExclusive returns false: Cure performs a trivial filesystem write.
|
||||||
|
func (gentooOverlay) IsExclusive() bool { return false }
|
||||||
|
|
||||||
|
// Inputs returns the underlying Gentoo stage3.
|
||||||
|
func (a gentooOverlay) Inputs() []pkg.Artifact {
|
||||||
|
return []pkg.Artifact{a.stage3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
pkg.Register(kindGentooOverlay, func(r *pkg.IRReader) pkg.Artifact {
|
||||||
|
a := gentooOverlay{r.Next()}
|
||||||
|
if _, ok := r.Finalise(); ok {
|
||||||
|
panic(pkg.ErrUnexpectedChecksum)
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a hardcoded name.
|
||||||
|
func (a gentooOverlay) String() string { return "gentoo-overlay" }
|
||||||
|
|
||||||
|
// Revision returns a hardcoded value incremented on layout changes.
|
||||||
|
func (a gentooOverlay) Revision() uint64 { return 0 }
|
||||||
|
|
||||||
|
// Cure installs the overlay.
|
||||||
|
func (a gentooOverlay) Cure(f *pkg.FContext) (err error) {
|
||||||
|
pathname, _ := f.GetArtifact(a.stage3)
|
||||||
|
var stage3 *os.Root
|
||||||
|
if stage3, err = os.OpenRoot(pathname.String()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
closeErr := stage3.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fsys := stage3.FS()
|
||||||
|
|
||||||
|
system := f.GetWorkDir().Append("system")
|
||||||
|
bin := system.Append("bin")
|
||||||
|
if err = os.MkdirAll(bin.String(), 0700); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
linknames := []string{
|
||||||
|
"../../bin/sh",
|
||||||
|
}
|
||||||
|
|
||||||
|
var dents []os.DirEntry
|
||||||
|
|
||||||
|
const llvm = "usr/lib/llvm"
|
||||||
|
dents, err = fs.ReadDir(fsys, llvm)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(dents) != 1 {
|
||||||
|
return errors.New("stage3 /" + llvm + " contains more than one entry")
|
||||||
|
}
|
||||||
|
|
||||||
|
llvmBin := filepath.Join(llvm, dents[0].Name(), "bin")
|
||||||
|
dents, err = fs.ReadDir(fsys, llvmBin)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, dent := range dents {
|
||||||
|
linknames = append(linknames, filepath.Join(
|
||||||
|
"../..",
|
||||||
|
llvmBin,
|
||||||
|
dent.Name(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, linkname := range linknames {
|
||||||
|
if err = os.Symlink(
|
||||||
|
linkname,
|
||||||
|
bin.Append(filepath.Base(linkname)).String(),
|
||||||
|
); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
+14
-7
@@ -20,19 +20,26 @@ func (t Toolchain) NewViaGit(
|
|||||||
return t.New(strings.TrimSuffix(
|
return t.New(strings.TrimSuffix(
|
||||||
path.Base(url),
|
path.Base(url),
|
||||||
".git",
|
".git",
|
||||||
)+"-src-"+path.Base(rev), THostNet, t.Append(nil,
|
)+"-src", path.Base(rev), nil, &PackageAttr{
|
||||||
_nssCACert,
|
KnownChecksum: &checksum,
|
||||||
_git,
|
|
||||||
), &checksum, nil, `
|
HostNet: true,
|
||||||
|
Paths: []pkg.ExecPath{resolvconf()},
|
||||||
|
}, &GenericHelper{
|
||||||
|
Build: `
|
||||||
git \
|
git \
|
||||||
-c advice.detachedHead=false \
|
-c advice.detachedHead=false \
|
||||||
clone \
|
clone \
|
||||||
--depth=1 \
|
--depth=1 \
|
||||||
--revision=`+rev+` \
|
--revision=` + rev + ` \
|
||||||
--shallow-submodules \
|
--shallow-submodules \
|
||||||
--recurse-submodules \
|
--recurse-submodules \
|
||||||
`+url+` \
|
` + url + ` \
|
||||||
/work
|
/work
|
||||||
rm -rf /work/.git
|
rm -rf /work/.git
|
||||||
`, resolvconf())
|
`,
|
||||||
|
},
|
||||||
|
_nssCACert,
|
||||||
|
_git,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-28
@@ -13,7 +13,7 @@ func (t Toolchain) newGo(
|
|||||||
script string,
|
script string,
|
||||||
boot ...pkg.Artifact,
|
boot ...pkg.Artifact,
|
||||||
) pkg.Artifact {
|
) pkg.Artifact {
|
||||||
return t.NewPackage("go", version, newTar(
|
return t.New("go", version, newTar(
|
||||||
"https://go.dev/dl/go"+version+".src.tar.gz",
|
"https://go.dev/dl/go"+version+".src.tar.gz",
|
||||||
checksum,
|
checksum,
|
||||||
pkg.Gzip,
|
pkg.Gzip,
|
||||||
@@ -56,16 +56,15 @@ ln -s \
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
const (
|
const (
|
||||||
version = "1.26.4"
|
version = "1.25.14"
|
||||||
checksum = "fpqJlxa41wKRtbnviYNLk9VxgcL-5oIEDxsriF8svU6kNwQW70oRRA9gTz_ImVoB"
|
checksum = "QKYjKzziCmD1eboU__Oi8VjqbPjaHrHAI9ceWyF3D9ORm7cPHN8muZuiGsoLKjCJ"
|
||||||
)
|
)
|
||||||
meta := Metadata{
|
meta := Metadata{
|
||||||
Name: "go",
|
Name: "go-bootstrap",
|
||||||
Description: "the Go programming language toolchain",
|
Description: "the Go programming language toolchain (bootstrap)",
|
||||||
Website: "https://go.dev",
|
Website: "https://go.dev",
|
||||||
Version: version,
|
Version: version,
|
||||||
|
Exclude: true,
|
||||||
ID: 1227,
|
|
||||||
}
|
}
|
||||||
native.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) {
|
native.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) {
|
||||||
var (
|
var (
|
||||||
@@ -76,7 +75,7 @@ func init() {
|
|||||||
)
|
)
|
||||||
switch t.arch {
|
switch t.arch {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
bootstrapEarly = []pkg.Artifact{t.NewPackage("go", "1.4-bootstrap", newTar(
|
bootstrapEarly = []pkg.Artifact{t.New("go", "1.4-bootstrap", newTar(
|
||||||
"https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz",
|
"https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz",
|
||||||
"8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23",
|
"8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23",
|
||||||
pkg.Gzip,
|
pkg.Gzip,
|
||||||
@@ -152,8 +151,8 @@ sed -i \
|
|||||||
)
|
)
|
||||||
|
|
||||||
go125 := t.newGo(
|
go125 := t.newGo(
|
||||||
"1.25.11",
|
version,
|
||||||
"cnqAQ8wpVZXcM6nHAfSqFkIW4L3H73ALB9rBfKUBbfgg4_pOF3I9zOZARgYQ6MR2",
|
checksum,
|
||||||
[]string{"CGO_ENABLED=0"}, `
|
[]string{"CGO_ENABLED=0"}, `
|
||||||
sed -i \
|
sed -i \
|
||||||
's,/lib/ld-musl-`+t.linuxArch()+`.so.1,/system/bin/linker,' \
|
's,/lib/ld-musl-`+t.linuxArch()+`.so.1,/system/bin/linker,' \
|
||||||
@@ -165,23 +164,6 @@ rm \
|
|||||||
`, go123,
|
`, go123,
|
||||||
)
|
)
|
||||||
|
|
||||||
return &meta, t.newGo(
|
return &meta, go125
|
||||||
version,
|
|
||||||
checksum,
|
|
||||||
finalEnv, `
|
|
||||||
sed -i \
|
|
||||||
's,/lib/ld-musl-`+t.linuxArch()+`.so.1,/system/bin/linker,' \
|
|
||||||
cmd/link/internal/`+t.arch+`/obj.go
|
|
||||||
sed -i \
|
|
||||||
's/cpu.X86.HasAVX512VBMI/& \&\& cpu.X86.HasPOPCNT/' \
|
|
||||||
internal/runtime/gc/scan/scan_amd64.go
|
|
||||||
|
|
||||||
rm \
|
|
||||||
os/root_unix_test.go \
|
|
||||||
cmd/cgo/internal/testsanitizers/tsan_test.go \
|
|
||||||
cmd/cgo/internal/testsanitizers/cshared_test.go
|
|
||||||
`, go125,
|
|
||||||
)
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-176
@@ -1,27 +1,25 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/fs"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_llvmSource = H("llvm-project")
|
_llvmSource = H("llvm-project")
|
||||||
_muslHeaders = H("musl-headers")
|
_muslHeaders = H("musl-headers")
|
||||||
_earlyCompilerRT = H("early-compiler-rt")
|
_earlyRuntimes = H("early-runtimes")
|
||||||
_earlyRuntimes = H("early-runtimes")
|
_musl = H("musl")
|
||||||
_musl = H("musl")
|
|
||||||
|
|
||||||
_bash = H("bash")
|
_bash = H("bash")
|
||||||
_gawk = H("gawk")
|
_awk = H("awk")
|
||||||
_coreutils = H("coreutils")
|
_pythonEarly = H("python-early")
|
||||||
_diffutils = H("diffutils")
|
_coreutils = H("coreutils")
|
||||||
_findutils = H("findutils")
|
_diffutils = H("diffutils")
|
||||||
|
_findutils = H("findutils")
|
||||||
|
|
||||||
_zlib = H("zlib")
|
_zlib = H("zlib")
|
||||||
_zstd = H("zstd")
|
_zstd = H("zstd")
|
||||||
@@ -50,165 +48,6 @@ func litArgs(verbose bool, skipChecks ...string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var llvmPatches []KV
|
|
||||||
for _, name := range [...]string{
|
|
||||||
"increase-stack-size-unconditional",
|
|
||||||
"add-rosa-vendor",
|
|
||||||
"xfail-broken-tests",
|
|
||||||
"path-system-include",
|
|
||||||
"path-system-libraries",
|
|
||||||
} {
|
|
||||||
p, err := fs.ReadFile(nativeB, "package/llvm/"+name+".patch")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
llvmPatches = append(llvmPatches, KV{
|
|
||||||
name,
|
|
||||||
unsafe.String(unsafe.SliceData(p), len(p)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
native.MustRegister("early-compiler-rt", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
|
||||||
meta := Metadata{
|
|
||||||
Name: "early-compiler-rt",
|
|
||||||
Description: "early LLVM runtime: compiler-rt",
|
|
||||||
|
|
||||||
Dependencies: P{_musl},
|
|
||||||
}
|
|
||||||
_meta, source := t.MustLoad(_llvmSource)
|
|
||||||
meta.Version = _meta.Version
|
|
||||||
major, _, _ := strings.Cut(meta.Version, ".")
|
|
||||||
return &meta, t.NewPackage("early-compiler-rt", meta.Version, source, &PackageAttr{
|
|
||||||
Flag: TExclusive,
|
|
||||||
}, &CMakeHelper{
|
|
||||||
Append: []string{"compiler-rt"},
|
|
||||||
|
|
||||||
Cache: []KV{
|
|
||||||
{"ENABLE_LINKER_BUILD_ID", "ON"},
|
|
||||||
|
|
||||||
// libc++ not yet available
|
|
||||||
{"CMAKE_CXX_COMPILER_TARGET", ""},
|
|
||||||
|
|
||||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_ENABLE_RTTI", "ON"},
|
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_LINK_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
|
|
||||||
|
|
||||||
{"COMPILER_RT_BUILD_BUILTINS", "ON"},
|
|
||||||
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"},
|
|
||||||
{"COMPILER_RT_USE_BUILTINS_LIBRARY", "ON"},
|
|
||||||
{"COMPILER_RT_SANITIZERS_TO_BUILD", "asan"},
|
|
||||||
{"COMPILER_RT_BUILD_GWP_ASAN", "OFF"},
|
|
||||||
|
|
||||||
// does not work without libunwind
|
|
||||||
{"COMPILER_RT_BUILD_CTX_PROFILE", "OFF"},
|
|
||||||
{"COMPILER_RT_BUILD_LIBFUZZER", "OFF"},
|
|
||||||
{"COMPILER_RT_BUILD_MEMPROF", "OFF"},
|
|
||||||
{"COMPILER_RT_BUILD_PROFILE", "OFF"},
|
|
||||||
{"COMPILER_RT_BUILD_XRAY", "OFF"},
|
|
||||||
},
|
|
||||||
SkipTest: true,
|
|
||||||
Script: `
|
|
||||||
mkdir -p "/work/system/lib/clang/` + major + `/lib/"
|
|
||||||
ln -s \
|
|
||||||
"../../../${ROSA_TRIPLE}" \
|
|
||||||
"/work/system/lib/clang/` + major + `/lib/"
|
|
||||||
|
|
||||||
ln -s \
|
|
||||||
"clang_rt.crtbegin-` + t.linuxArch() + `.o" \
|
|
||||||
"/work/system/lib/${ROSA_TRIPLE}/crtbeginS.o"
|
|
||||||
ln -s \
|
|
||||||
"clang_rt.crtend-` + t.linuxArch() + `.o" \
|
|
||||||
"/work/system/lib/${ROSA_TRIPLE}/crtendS.o"
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
_python,
|
|
||||||
|
|
||||||
_muslHeaders,
|
|
||||||
_kernelHeaders,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
native.MustRegister("early-runtimes", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
|
||||||
meta := Metadata{
|
|
||||||
Name: "early-runtimes",
|
|
||||||
Description: "early LLVM runtimes: libunwind, libcxx, libcxxabi",
|
|
||||||
|
|
||||||
Dependencies: P{
|
|
||||||
_earlyCompilerRT,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_meta, source := t.MustLoad(_llvmSource)
|
|
||||||
meta.Version = _meta.Version
|
|
||||||
|
|
||||||
return &meta, t.NewPackage("early-runtimes", meta.Version, source, &PackageAttr{
|
|
||||||
Flag: TExclusive,
|
|
||||||
}, &CMakeHelper{
|
|
||||||
Append: []string{"runtimes"},
|
|
||||||
|
|
||||||
Cache: []KV{
|
|
||||||
{"ENABLE_LINKER_BUILD_ID", "ON"},
|
|
||||||
|
|
||||||
// libc++ not yet available
|
|
||||||
{"CMAKE_CXX_COMPILER_WORKS", "ON"},
|
|
||||||
|
|
||||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_ENABLE_RTTI", "ON"},
|
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_LINK_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_ENABLE_RUNTIMES", "'libunwind;libcxx;libcxxabi'"},
|
|
||||||
|
|
||||||
{"LIBUNWIND_ENABLE_ASSERTIONS", "OFF"},
|
|
||||||
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
|
||||||
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXX_CXX_ABI", "libcxxabi"},
|
|
||||||
{"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"},
|
|
||||||
{"LIBCXX_HARDENING_MODE", "fast"},
|
|
||||||
{"LIBCXX_HAS_ATOMIC_LIB", "OFF"},
|
|
||||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
|
||||||
{"LIBCXXABI_ENABLE_STATIC_UNWINDER", "OFF"},
|
|
||||||
{"LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL", "OFF"},
|
|
||||||
|
|
||||||
{"LLVM_ENABLE_ZLIB", "FORCE_ON"},
|
|
||||||
{"LLVM_ENABLE_ZSTD", "FORCE_ON"},
|
|
||||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
|
||||||
},
|
|
||||||
SkipTest: true,
|
|
||||||
},
|
|
||||||
_python,
|
|
||||||
|
|
||||||
_zlib,
|
|
||||||
_zstd,
|
|
||||||
_earlyCompilerRT,
|
|
||||||
_kernelHeaders,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const (
|
|
||||||
version = "22.1.8"
|
|
||||||
checksum = "_QzoDE0W6cv0vfIWeLPDvqG_vKhz6IGWl1nqUUvhlKWiRzf5dMGqeC3tyS2XgI6j"
|
|
||||||
)
|
|
||||||
|
|
||||||
native.MustRegister("llvm-project", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
|
||||||
meta := Metadata{
|
|
||||||
Name: "llvm-project",
|
|
||||||
Description: "LLVM monorepo with Rosa OS patches",
|
|
||||||
Version: version,
|
|
||||||
|
|
||||||
ID: 1830,
|
|
||||||
}
|
|
||||||
return &meta, t.NewPatchedSource("llvm-"+version, newFromGitHub(
|
|
||||||
"llvm/llvm-project",
|
|
||||||
"llvmorg-"+version,
|
|
||||||
checksum,
|
|
||||||
), true, llvmPatches...)
|
|
||||||
})
|
|
||||||
|
|
||||||
native.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
native.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
||||||
meta := Metadata{
|
meta := Metadata{
|
||||||
Name: "llvm",
|
Name: "llvm",
|
||||||
@@ -244,9 +83,11 @@ ln -s \
|
|||||||
{"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"},
|
{"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"},
|
||||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
||||||
{"LIBCXX_HARDENING_MODE", "fast"},
|
{"LIBCXX_HARDENING_MODE", "fast"},
|
||||||
|
{"LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY", "ON"},
|
||||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
||||||
{"LIBCXXABI_ENABLE_STATIC_UNWINDER", "OFF"},
|
{"LIBCXXABI_ENABLE_STATIC_UNWINDER", "ON"},
|
||||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
||||||
|
{"LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY", "ON"},
|
||||||
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
||||||
{"LLVM_INSTALL_UTILS", "ON"},
|
{"LLVM_INSTALL_UTILS", "ON"},
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
||||||
@@ -299,6 +140,10 @@ ln -s \
|
|||||||
"CodeGen/PowerPC/ppc-tmmintrin.c",
|
"CodeGen/PowerPC/ppc-tmmintrin.c",
|
||||||
"CodeGen/PowerPC/ppc-smmintrin.c",
|
"CodeGen/PowerPC/ppc-smmintrin.c",
|
||||||
"CodeGenCUDA/amdgpu-alias-undef-symbols.cu",
|
"CodeGenCUDA/amdgpu-alias-undef-symbols.cu",
|
||||||
|
// clang: deadlocks with LIBCXXABI_ENABLE_STATIC_UNWINDER
|
||||||
|
"global-value-regex",
|
||||||
|
"global-hex-value-regex",
|
||||||
|
"check-globals",
|
||||||
// cxx: fails on musl
|
// cxx: fails on musl
|
||||||
"close.dont-get-rid-of-buffer",
|
"close.dont-get-rid-of-buffer",
|
||||||
"re/re.traits",
|
"re/re.traits",
|
||||||
@@ -339,8 +184,8 @@ ln -s \
|
|||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &meta, t.NewPackage("llvm", meta.Version, source, &PackageAttr{
|
return &meta, t.New("llvm", meta.Version, source, &PackageAttr{
|
||||||
Flag: TExclusive,
|
Exclusive: true,
|
||||||
Bin: []string{
|
Bin: []string{
|
||||||
"chmod",
|
"chmod",
|
||||||
"mkdir",
|
"mkdir",
|
||||||
@@ -348,6 +193,10 @@ ln -s \
|
|||||||
"tr",
|
"tr",
|
||||||
"awk",
|
"awk",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ScriptEarly: `
|
||||||
|
rm -f /system/bin/clang++.cfg
|
||||||
|
`,
|
||||||
}, &CMakeHelper{
|
}, &CMakeHelper{
|
||||||
Append: []string{"llvm"},
|
Append: []string{"llvm"},
|
||||||
|
|
||||||
@@ -357,6 +206,10 @@ ln -s ld.lld /work/system/bin/ld
|
|||||||
ln -s clang /work/system/bin/cc
|
ln -s clang /work/system/bin/cc
|
||||||
ln -s clang /work/system/bin/cpp
|
ln -s clang /work/system/bin/cpp
|
||||||
ln -s clang++ /work/system/bin/c++
|
ln -s clang++ /work/system/bin/c++
|
||||||
|
cat << EOF > /work/system/bin/clang++.cfg
|
||||||
|
-static-libstdc++
|
||||||
|
-Wl,--exclude-libs,libunwind.a:libc++.a:libc++experimental.a:libc++abi.a
|
||||||
|
EOF
|
||||||
`,
|
`,
|
||||||
|
|
||||||
// LLVM_LINK_LLVM_DYLIB causes llvm test suite to leak system
|
// LLVM_LINK_LLVM_DYLIB causes llvm test suite to leak system
|
||||||
@@ -367,11 +220,11 @@ ln -s clang++ /work/system/bin/c++
|
|||||||
|
|
||||||
Test: "ninja " + jobsFlagE + " " + loadFlagE + " check-all",
|
Test: "ninja " + jobsFlagE + " " + loadFlagE + " check-all",
|
||||||
},
|
},
|
||||||
_python,
|
_pythonEarly,
|
||||||
_perl,
|
_perl,
|
||||||
_diffutils,
|
_diffutils,
|
||||||
_bash,
|
_bash,
|
||||||
_gawk,
|
_awk,
|
||||||
_coreutils,
|
_coreutils,
|
||||||
_findutils,
|
_findutils,
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestLLVMInputs(t *testing.T) {
|
func TestLLVMInputs(t *testing.T) {
|
||||||
const wantInputCount = 553
|
const wantInputCount = 470
|
||||||
|
|
||||||
_, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm"))
|
_, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm"))
|
||||||
var n int
|
var n int
|
||||||
|
|||||||
@@ -52,15 +52,16 @@ type MakeHelper struct {
|
|||||||
var _ Helper = new(MakeHelper)
|
var _ Helper = new(MakeHelper)
|
||||||
|
|
||||||
// extra returns make and other optional dependencies.
|
// extra returns make and other optional dependencies.
|
||||||
func (attr *MakeHelper) extra(flag int) P {
|
func (attr *MakeHelper) extra() P {
|
||||||
extra := P{_make}
|
if attr == nil || !attr.OmitDefaults {
|
||||||
if (attr == nil || !attr.OmitDefaults) && flag&TEarly == 0 {
|
return P{
|
||||||
extra = append(extra,
|
_make,
|
||||||
_gawk,
|
|
||||||
|
_awk,
|
||||||
_coreutils,
|
_coreutils,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return extra
|
return P{_make}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wantsChmod returns whether the build system needs to be generated.
|
// wantsChmod returns whether the build system needs to be generated.
|
||||||
@@ -172,6 +173,7 @@ make \
|
|||||||
scriptMake += attr.ScriptCheckEarly + `make \
|
scriptMake += attr.ScriptCheckEarly + `make \
|
||||||
` + jobsFlagE + ` \
|
` + jobsFlagE + ` \
|
||||||
` + loadFlagE + ` \
|
` + loadFlagE + ` \
|
||||||
|
AM_COLOR_TESTS=always \
|
||||||
`
|
`
|
||||||
if len(attr.Check) > 0 {
|
if len(attr.Check) > 0 {
|
||||||
scriptMake += strings.Join(attr.Check, " \\\n\t")
|
scriptMake += strings.Join(attr.Check, " \\\n\t")
|
||||||
|
|||||||
+45
-16
@@ -5,10 +5,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _meson = H("meson")
|
var (
|
||||||
|
_muon = H("muon")
|
||||||
|
_meson = H("meson")
|
||||||
|
)
|
||||||
|
|
||||||
// MesonHelper builds and tests a meson project.
|
// MesonHelper builds and tests a meson project.
|
||||||
type MesonHelper struct {
|
type MesonHelper struct {
|
||||||
|
// Use muon instead of meson.
|
||||||
|
Muon bool
|
||||||
|
|
||||||
// Runs after setup.
|
// Runs after setup.
|
||||||
ScriptCompileEarly string
|
ScriptCompileEarly string
|
||||||
// Runs after compile.
|
// Runs after compile.
|
||||||
@@ -29,7 +35,12 @@ type MesonHelper struct {
|
|||||||
var _ Helper = new(MesonHelper)
|
var _ Helper = new(MesonHelper)
|
||||||
|
|
||||||
// extra returns hardcoded meson runtime dependencies.
|
// extra returns hardcoded meson runtime dependencies.
|
||||||
func (*MesonHelper) extra(int) P { return P{_meson} }
|
func (attr *MesonHelper) extra() P {
|
||||||
|
if !attr.isPython() {
|
||||||
|
return P{_muon}
|
||||||
|
}
|
||||||
|
return P{_meson}
|
||||||
|
}
|
||||||
|
|
||||||
// wantsChmod returns false.
|
// wantsChmod returns false.
|
||||||
func (*MesonHelper) wantsChmod() bool { return false }
|
func (*MesonHelper) wantsChmod() bool { return false }
|
||||||
@@ -43,6 +54,12 @@ func (*MesonHelper) scriptEarly() string { return "" }
|
|||||||
// wantsDir requests a new directory in TMPDIR.
|
// wantsDir requests a new directory in TMPDIR.
|
||||||
func (*MesonHelper) wantsDir() (string, bool) { return `"$(mktemp -d)"`, false }
|
func (*MesonHelper) wantsDir() (string, bool) { return `"$(mktemp -d)"`, false }
|
||||||
|
|
||||||
|
// isPython returns whether the legacy python implementation is used.
|
||||||
|
func (attr *MesonHelper) isPython() bool {
|
||||||
|
return attr == nil ||
|
||||||
|
!attr.Muon || len(attr.SkipTests) != 0 || attr.InteractiveTest
|
||||||
|
}
|
||||||
|
|
||||||
// script generates the cure script.
|
// script generates the cure script.
|
||||||
func (attr *MesonHelper) script(t Toolchain, name string) string {
|
func (attr *MesonHelper) script(t Toolchain, name string) string {
|
||||||
if attr == nil {
|
if attr == nil {
|
||||||
@@ -54,12 +71,28 @@ func (attr *MesonHelper) script(t Toolchain, name string) string {
|
|||||||
scriptCompiled = "\n" + scriptCompiled
|
scriptCompiled = "\n" + scriptCompiled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
python := attr.isPython()
|
||||||
|
muon := "muon"
|
||||||
|
compile := " samu " + jobsFlagE
|
||||||
|
destdir := "-d"
|
||||||
|
if python {
|
||||||
|
muon = "meson"
|
||||||
|
compile = " compile " + jobsFlagE + " " + loadFlagE
|
||||||
|
destdir = "--destdir"
|
||||||
|
}
|
||||||
|
|
||||||
var scriptTest string
|
var scriptTest string
|
||||||
if !attr.SkipTest && t.opts&OptSkipCheck == 0 {
|
if !attr.SkipTest && t.opts&OptSkipCheck == 0 {
|
||||||
scriptTest = `
|
scriptTest = `
|
||||||
meson test \
|
` + muon + ` test \
|
||||||
-t 10 \
|
` + jobsFlagE + ` \
|
||||||
|
-t 10`
|
||||||
|
if python {
|
||||||
|
scriptTest += ` \
|
||||||
--print-errorlogs`
|
--print-errorlogs`
|
||||||
|
} else {
|
||||||
|
scriptTest += " -Rv"
|
||||||
|
}
|
||||||
if attr.InteractiveTest {
|
if attr.InteractiveTest {
|
||||||
scriptTest += ` \
|
scriptTest += ` \
|
||||||
--interactive`
|
--interactive`
|
||||||
@@ -70,29 +103,25 @@ meson test \
|
|||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
cd "$(mktemp -d)"
|
` + muon + ` setup \
|
||||||
meson setup \
|
|
||||||
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
||||||
for _, v := range append([]KV{
|
for _, v := range append([]KV{
|
||||||
{"wrap-mode", "nofallback"},
|
{"wrap_mode", "nofallback"},
|
||||||
{"prefix", "/system"},
|
{"prefix", "/system"},
|
||||||
{"buildtype", "release"},
|
{"buildtype", "release"},
|
||||||
}, attr.Setup...) {
|
}, attr.Setup...) {
|
||||||
s := "-" + v[0]
|
s := v[0]
|
||||||
if len(v[0]) > 0 && v[0][0] != 'D' {
|
|
||||||
s = "-" + s
|
|
||||||
}
|
|
||||||
if v[1] != "" {
|
if v[1] != "" {
|
||||||
s += "=" + v[1]
|
s = "-D" + s + "=" + v[1]
|
||||||
}
|
}
|
||||||
if !yield(s) {
|
if !yield(s) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}), " \\\n\t") + ` \
|
}), " \\\n\t") + ` \
|
||||||
. '/usr/src/` + name + `'
|
'/usr/src/` + name + `'
|
||||||
meson compile` + scriptCompiled + scriptTest + `
|
` + muon + compile + scriptCompiled + scriptTest + `
|
||||||
meson install \
|
` + muon + ` install \
|
||||||
--destdir=/work
|
` + destdir + ` /work
|
||||||
` + attr.Script
|
` + attr.Script
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ];
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package awk {
|
||||||
|
description = "one true awk";
|
||||||
|
website = "https://github.com/onetrueawk/awk";
|
||||||
|
anitya = 16171;
|
||||||
|
|
||||||
|
version# = "20260426";
|
||||||
|
source = remoteGitHub {
|
||||||
|
suffix = "onetrueawk/awk";
|
||||||
|
tag = version;
|
||||||
|
checksum = "ewAvWLEHajhm7cA7v4DsKVk1c11niCLKIE5Q-8W_sxv1XXsbZlcOuWn1KOBYMxjo";
|
||||||
|
};
|
||||||
|
|
||||||
|
enterSource = true;
|
||||||
|
writable = true;
|
||||||
|
chmod = true;
|
||||||
|
|
||||||
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
|
chdir = false;
|
||||||
|
configure = nil;
|
||||||
|
make = [ "YACC='yacc -d -b awkgram'" ];
|
||||||
|
preCheck = "install -vD a.out /system/bin/awk\n";
|
||||||
|
install = "install -vD a.out /work/system/bin/awk";
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
m4,
|
||||||
|
byacc,
|
||||||
|
diffutils,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -5,15 +5,19 @@ package bison {
|
|||||||
|
|
||||||
version# = "3.8.2";
|
version# = "3.8.2";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/bison/bison-"+version+".tar.gz";
|
||||||
checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y";
|
checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toyboxEarly = true;
|
||||||
exec = make {
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
check = [
|
check = [
|
||||||
"TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests {
|
"TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests {
|
||||||
tests = [
|
tests = [
|
||||||
|
// GNU-isms not implemented in toybox
|
||||||
|
168, 170, 623,
|
||||||
// clang miscompiles (SIGILL)
|
// clang miscompiles (SIGILL)
|
||||||
764,
|
764,
|
||||||
];
|
];
|
||||||
@@ -22,9 +26,5 @@ package bison {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
inputs = [
|
inputs = [ m4 ];
|
||||||
m4,
|
|
||||||
diffutils,
|
|
||||||
sed,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package byacc {
|
||||||
|
description = "Berkeley Yacc";
|
||||||
|
website = "https://invisible-island.net/byacc";
|
||||||
|
anitya = 233;
|
||||||
|
|
||||||
|
version# = "20260126";
|
||||||
|
source = remoteTar {
|
||||||
|
url = "https://invisible-island.net/archives/byacc/"+
|
||||||
|
"byacc-"+version+".tgz";
|
||||||
|
compress = gzip;
|
||||||
|
checksum = "3IXzewZmFUW3hkFKBuweR0hUSftlI2zE0lBZf16I8oK3mFEyj51FzVv1wvA12uoC";
|
||||||
|
};
|
||||||
|
|
||||||
|
// awk dependency loop
|
||||||
|
toyboxEarly = true;
|
||||||
|
|
||||||
|
// test suite assumes writable source
|
||||||
|
writable = true;
|
||||||
|
chmod = true;
|
||||||
|
|
||||||
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,25 +13,25 @@ package cairo {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Ddwrite": "enabled";
|
"dwrite": "enabled";
|
||||||
"Dfontconfig": "enabled";
|
"fontconfig": "enabled";
|
||||||
"Dfreetype": "enabled";
|
"freetype": "enabled";
|
||||||
|
|
||||||
"Dpng": "enabled";
|
"png": "enabled";
|
||||||
"Dtee": "enabled";
|
"tee": "enabled";
|
||||||
"Dxcb": "enabled";
|
"xcb": "enabled";
|
||||||
"Dxlib": "disabled";
|
"xlib": "disabled";
|
||||||
"Dxlib-xcb": "disabled";
|
"xlib-xcb": "disabled";
|
||||||
"Dzlib": "enabled";
|
"zlib": "enabled";
|
||||||
};
|
};
|
||||||
// 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 = [
|
||||||
gawk,
|
awk,
|
||||||
|
|
||||||
zlib,
|
zlib,
|
||||||
libpng,
|
libpng,
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
diff --git a/Tests/BootstrapTest.cmake b/Tests/BootstrapTest.cmake
|
|
||||||
index 137de78bc1..b4da52e664 100644
|
|
||||||
--- a/Tests/BootstrapTest.cmake
|
|
||||||
+++ b/Tests/BootstrapTest.cmake
|
|
||||||
@@ -9,7 +9,7 @@ if(NOT nproc EQUAL 0)
|
|
||||||
endif()
|
|
||||||
message(STATUS "running bootstrap: ${bootstrap} ${ninja_arg} ${parallel_arg}")
|
|
||||||
execute_process(
|
|
||||||
- COMMAND ${bootstrap} ${ninja_arg} ${parallel_arg}
|
|
||||||
+ COMMAND ${bootstrap} ${ninja_arg} ${parallel_arg} -- -DCMAKE_USE_OPENSSL=OFF
|
|
||||||
WORKING_DIRECTORY "${bin_dir}"
|
|
||||||
RESULT_VARIABLE result
|
|
||||||
)
|
|
||||||
@@ -3,18 +3,15 @@ package cmake {
|
|||||||
website = "https://cmake.org";
|
website = "https://cmake.org";
|
||||||
anitya = 306;
|
anitya = 306;
|
||||||
|
|
||||||
version# = "4.3.4";
|
version# = "4.4.2";
|
||||||
source = remoteGitHubRelease {
|
source = remoteGitHubRelease {
|
||||||
suffix = "Kitware/CMake";
|
suffix = "Kitware/CMake";
|
||||||
tag = "v"+version;
|
tag = "v"+version;
|
||||||
name = "cmake-"+version+".tar.gz";
|
name = "cmake-"+version+".tar.gz";
|
||||||
checksum = "6A50pqarKDXKOCv7ffKMvWJWmNTVp_ep8KoaWwNdg-RYQRddgKbxayHveTo6jZ_7";
|
checksum = "IWlqJqJCZ6f-z-7Ft1U4ycvCX4riuihKale5NKWusiHemBgC3m5gCecrzikXoL7S";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
patches = [
|
patches = [ "disable-broken-tests-musl.patch" ];
|
||||||
"bootstrap-test-no-openssl.patch",
|
|
||||||
"disable-broken-tests-musl.patch",
|
|
||||||
];
|
|
||||||
|
|
||||||
// test suite expects writable source tree
|
// test suite expects writable source tree
|
||||||
writable = true;
|
writable = true;
|
||||||
@@ -23,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 = {
|
||||||
@@ -32,6 +29,7 @@ package cmake {
|
|||||||
"--";
|
"--";
|
||||||
"-DCMAKE_USE_OPENSSL": "OFF";
|
"-DCMAKE_USE_OPENSSL": "OFF";
|
||||||
"-DCMake_TEST_NO_NETWORK": "ON";
|
"-DCMake_TEST_NO_NETWORK": "ON";
|
||||||
|
"-DCMake_TEST_BOOTSTRAP": "OFF";
|
||||||
};
|
};
|
||||||
|
|
||||||
check = [
|
check = [
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package connman {
|
|||||||
inputs = [
|
inputs = [
|
||||||
automake,
|
automake,
|
||||||
libtool,
|
libtool,
|
||||||
pkg-config,
|
pkgconf,
|
||||||
|
|
||||||
dbus,
|
dbus,
|
||||||
iptables,
|
iptables,
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package cryptsetup {
|
||||||
|
description = "open-source disk encryption";
|
||||||
|
website = "https://gitlab.com/cryptsetup/cryptsetup";
|
||||||
|
anitya = 13709;
|
||||||
|
|
||||||
|
version# = "2.8.7";
|
||||||
|
source = remoteGitLab {
|
||||||
|
domain = "gitlab.com";
|
||||||
|
suffix = "cryptsetup/cryptsetup";
|
||||||
|
ref = "v"+version;
|
||||||
|
checksum = "eDi_UaMtwhIzqpsdcA91aVb56zCYDrsDzeMWfWXAnPbuvn2bEgeH5dFs7mouHz8V";
|
||||||
|
};
|
||||||
|
|
||||||
|
bin = [ "bash" ];
|
||||||
|
exec = meson {
|
||||||
|
setup = {
|
||||||
|
"asciidoc": "disabled";
|
||||||
|
"ssh-token": "false";
|
||||||
|
"blkid": "false";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
bash,
|
||||||
|
gettext,
|
||||||
|
coreutils,
|
||||||
|
|
||||||
|
popt,
|
||||||
|
lvm2,
|
||||||
|
json-c,
|
||||||
|
e2fsprogs,
|
||||||
|
argp-standalone,
|
||||||
|
kernel-headers,
|
||||||
|
];
|
||||||
|
|
||||||
|
runtime = [
|
||||||
|
popt,
|
||||||
|
lvm2,
|
||||||
|
json-c,
|
||||||
|
e2fsprogs,
|
||||||
|
openssl,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ package dbus {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Depoll": "enabled";
|
"epoll": "enabled";
|
||||||
"Dinotify": "enabled";
|
"inotify": "enabled";
|
||||||
"Dx11_autolaunch": "disabled";
|
"x11_autolaunch": "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,16 +41,16 @@ 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 {
|
||||||
setup = {
|
setup = {
|
||||||
"Dman": "disabled";
|
"man": "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package dtc {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Dyaml": "disabled";
|
"yaml": "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package e2fsprogs {
|
||||||
|
description = "ext2/3/4 filesystem userspace utilities";
|
||||||
|
website = "http://e2fsprogs.sourceforge.net";
|
||||||
|
anitya = 646;
|
||||||
|
|
||||||
|
version# = "1.47.4";
|
||||||
|
source = remoteTar {
|
||||||
|
url = "https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git"+
|
||||||
|
"/snapshot/e2fsprogs-"+version+".tar.gz";
|
||||||
|
compress = gzip;
|
||||||
|
checksum = "gdnAEVjncIciqG-ZhFfYVv4wbBbCHBmPPYwRxltIfOTqdYH5L3ri8wk75YIVlgN0";
|
||||||
|
};
|
||||||
|
|
||||||
|
exec = make {
|
||||||
|
configure = {
|
||||||
|
"enable-elf-shlibs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
perl,
|
||||||
|
gzip,
|
||||||
|
bzip2,
|
||||||
|
diffutils,
|
||||||
|
|
||||||
|
kernel-headers,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ package fcft {
|
|||||||
|
|
||||||
version# = "3.3.3";
|
version# = "3.3.3";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://codeberg.org/dnkl/fcft/archive/"+version+".tar.gz";
|
url = "https://codeberg.org/dnkl/fcft/releases/download/"+version+
|
||||||
checksum = "bMj8OmqtoANRKZWbjHk4WfP09AxJYRbWGqUsm1gRJ_dOFg6gooNbgkDu597PLfz2";
|
"/fcft-"+version+".tar.gz";
|
||||||
|
checksum = "pryAJA-d1OpY8KXbGFEHum9Wm6ME9XkPx9EM_OQ_ZEpOUpQnqlkzIq-cwS1ziMPk";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package fontconfig {
|
|||||||
website = "https://www.freedesktop.org/wiki/Software/fontconfig";
|
website = "https://www.freedesktop.org/wiki/Software/fontconfig";
|
||||||
anitya = 827;
|
anitya = 827;
|
||||||
|
|
||||||
version# = "2.18.1";
|
version# = "2.18.3";
|
||||||
source = remoteGitLab {
|
source = remoteGitLab {
|
||||||
domain = "gitlab.freedesktop.org";
|
domain = "gitlab.freedesktop.org";
|
||||||
suffix = "fontconfig/fontconfig";
|
suffix = "fontconfig/fontconfig";
|
||||||
ref = version;
|
ref = version;
|
||||||
checksum = "S3FJfh-PeZ2_YgNrUqL0H2G4Wf_ilj5HpIGV2oURnkK672AQHpWk526bNtRHwyJt";
|
checksum = "ZZzmt8fYh-3jKJ6vHXUDbeAWM2ilRusWxdynLt3Z4E_CQQ8cCwzpuAWACXmr9qHI";
|
||||||
};
|
};
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
@@ -18,7 +18,7 @@ package fontconfig {
|
|||||||
inputs = [
|
inputs = [
|
||||||
automake,
|
automake,
|
||||||
libtool,
|
libtool,
|
||||||
pkg-config,
|
pkgconf,
|
||||||
gettext,
|
gettext,
|
||||||
gperf,
|
gperf,
|
||||||
gzip,
|
gzip,
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ package foot {
|
|||||||
|
|
||||||
version# = "1.27.0";
|
version# = "1.27.0";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://codeberg.org/dnkl/foot/archive/"+version+".tar.gz";
|
url = "https://codeberg.org/dnkl/foot/releases/download/"+version+
|
||||||
checksum = "E2XIPRD8t-WBBJUebIwChFT8K_85diwdalssUNwnuZBIynPa7rlXro5WCe9v3UlK";
|
"/foot-"+version+".tar.gz";
|
||||||
|
checksum = "22rG3rMuQI8Ae2XTcZgOJ-6AbF7Taex8XpgvD6Fyg1Mn5Va67FfUcK3tRaq61TFg";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ package fribidi {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Ddocs": "false";
|
"docs": "false";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ package fuse {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Ddefault_library": "both";
|
"default_library": "both";
|
||||||
"Dtests": "true";
|
"tests": "true";
|
||||||
"Duseroot": "false";
|
"useroot": "false";
|
||||||
"Dinitscriptdir": "/system/etc";
|
"initscriptdir": "/system/etc";
|
||||||
};
|
};
|
||||||
|
|
||||||
postCompile = "python3 -m pytest test/";
|
postCompile = "python3 -m pytest test/";
|
||||||
// this project uses pytest
|
// this project uses pytest
|
||||||
skipTest = true;
|
test = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
diff --git a/test/Makefile.am b/test/Makefile.am
|
||||||
|
index 88e15ef1f..bfc279fcb 100644
|
||||||
|
--- a/test/Makefile.am
|
||||||
|
+++ b/test/Makefile.am
|
||||||
|
@@ -1726,7 +1726,7 @@ LOCALE_CHARSET_TESTS = \
|
||||||
|
SHLIB_TESTS = \
|
||||||
|
apiterm filefuncs fnmatch fork fork2 fts functab4 functab5 \
|
||||||
|
getfile indirectbuiltin2 inplace1 inplace2 inplace2bcomp inplace3 \
|
||||||
|
- inplace3bcomp ordchr ordchr2 readall readdir readdir_retest \
|
||||||
|
+ inplace3bcomp ordchr ordchr2 readall readdir_retest \
|
||||||
|
readdir_test readfile readfile2 revout revtwoway rwarray \
|
||||||
|
testext time
|
||||||
|
|
||||||
|
diff --git a/test/Makefile.in b/test/Makefile.in
|
||||||
|
index 2d4eeaa5a..7930af8d5 100644
|
||||||
|
--- a/test/Makefile.in
|
||||||
|
+++ b/test/Makefile.in
|
||||||
|
@@ -1986,7 +1986,7 @@ LOCALE_CHARSET_TESTS = \
|
||||||
|
SHLIB_TESTS = \
|
||||||
|
apiterm filefuncs fnmatch fork fork2 fts functab4 functab5 \
|
||||||
|
getfile indirectbuiltin2 inplace1 inplace2 inplace2bcomp inplace3 \
|
||||||
|
- inplace3bcomp ordchr ordchr2 readall readdir readdir_retest \
|
||||||
|
+ inplace3bcomp ordchr ordchr2 readall readdir_retest \
|
||||||
|
readdir_test readfile readfile2 revout revtwoway rwarray \
|
||||||
|
testext time
|
||||||
|
|
||||||
|
diff --git a/test/clos1way6.ok b/test/clos1way6.ok
|
||||||
|
index 5768617d3..be4d73e79 100644
|
||||||
|
--- a/test/clos1way6.ok
|
||||||
|
+++ b/test/clos1way6.ok
|
||||||
|
@@ -1,3 +1,3 @@
|
||||||
|
gawk: clos1way6.awk:5: warning: fflush: cannot flush: two-way pipe `cat - 1>&2; sleep 2' has closed write end
|
||||||
|
-test1
|
||||||
|
Bad file descriptor
|
||||||
|
+test1
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
diff --git a/test/testext-mpfr.ok b/test/testext-mpfr.ok
|
||||||
|
index 6a5f98147..adf8685e2 100644
|
||||||
|
--- a/test/testext-mpfr.ok
|
||||||
|
+++ b/test/testext-mpfr.ok
|
||||||
|
@@ -21,7 +21,7 @@ var_test: sym_update of ARGC failed - correctly
|
||||||
|
var_test: sym_update("testvar") succeeded
|
||||||
|
var_test() returned 1, test_var = 42
|
||||||
|
|
||||||
|
-test_errno() returned 1, ERRNO = No child processes
|
||||||
|
+test_errno() returned 1, ERRNO = No child process
|
||||||
|
|
||||||
|
fubar = 9
|
||||||
|
rumpus = -5
|
||||||
|
diff --git a/test/testext.ok b/test/testext.ok
|
||||||
|
index 3e0c1328c..11d150fe3 100644
|
||||||
|
--- a/test/testext.ok
|
||||||
|
+++ b/test/testext.ok
|
||||||
|
@@ -21,7 +21,7 @@ var_test: sym_update of ARGC failed - correctly
|
||||||
|
var_test: sym_update("testvar") succeeded
|
||||||
|
var_test() returned 1, test_var = 42
|
||||||
|
|
||||||
|
-test_errno() returned 1, ERRNO = No child processes
|
||||||
|
+test_errno() returned 1, ERRNO = No child process
|
||||||
|
|
||||||
|
fubar = 9
|
||||||
|
rumpus = -5
|
||||||
|
diff --git a/vms/vmstest.com b/vms/vmstest.com
|
||||||
|
index a042764b1..c47984e38 100644
|
||||||
|
--- a/vms/vmstest.com
|
||||||
|
+++ b/vms/vmstest.com
|
||||||
|
@@ -917,7 +917,7 @@ $ set noOn
|
||||||
|
$ AWKLIBPATH_dir
|
||||||
|
$ gawk -f _'test'.awk >_'test'.tmp 2>&1
|
||||||
|
$ if .not. $status then call exit_code '$status' _'test'.tmp
|
||||||
|
-$ gawk "{gsub(""no children"",""No child processes"")}1" -
|
||||||
|
+$ gawk "{gsub(""no children"",""No child process"")}1" -
|
||||||
|
_'test'.tmp >_'test'.tmp1
|
||||||
|
$ rm sys$disk:[]_'test'.tmp;*
|
||||||
|
$ mv sys$disk:[]_'test'.tmp1 sys$disk:[]_'test'.tmp
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package gawk {
|
||||||
|
description = "an implementation of awk with GNU extensions";
|
||||||
|
website = "https://www.gnu.org/software/gawk";
|
||||||
|
anitya = 868;
|
||||||
|
|
||||||
|
block = "regressions introduced in 5.4.1, "+
|
||||||
|
"does not even pass its own test suite";
|
||||||
|
|
||||||
|
version# = "5.4.0";
|
||||||
|
source = remoteTar {
|
||||||
|
url = "https://mirrors.kernel.org/gnu/gawk/gawk-"+version+".tar.gz";
|
||||||
|
checksum = "m0RkIolC-PI7EY5q8pcx5Y-0twlIW0Yp3wXXmV-QaHorSdf8BhZ7kW9F8iWomz0C";
|
||||||
|
compress = gzip;
|
||||||
|
};
|
||||||
|
patches = [
|
||||||
|
"musl-errno.patch",
|
||||||
|
"broken-tests.patch",
|
||||||
|
];
|
||||||
|
|
||||||
|
exec = make {};
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
diffutils,
|
||||||
|
util-linux,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -3,10 +3,10 @@ package binutils {
|
|||||||
website = "https://www.gnu.org/software/binutils";
|
website = "https://www.gnu.org/software/binutils";
|
||||||
anitya = 7981;
|
anitya = 7981;
|
||||||
|
|
||||||
version# = "2.46.1";
|
version# = "2.47";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2";
|
url = "https://mirrors.kernel.org/gnu/binutils/binutils-"+version+".tar.bz2";
|
||||||
checksum = "ihCVohBxX-URAR-YFDdVrL3inLYsEVX8KbbQmcbHaShHgqqmtsvUue1h3LXSjW-d";
|
checksum = "VjbMg5KtZ6VSeNc77Z5p8RKg9eZ56g29ViKbbsF3tcFhZu0Yurg0nZt7UwB577LM";
|
||||||
compress = bzip2;
|
compress = bzip2;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -20,11 +20,11 @@ package gcc {
|
|||||||
website = "https://www.gnu.org/software/gcc";
|
website = "https://www.gnu.org/software/gcc";
|
||||||
anitya = 6502;
|
anitya = 6502;
|
||||||
|
|
||||||
version# = "16.1.0";
|
version# = "16.2.0";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
|
url = "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
|
||||||
"gcc-"+version+"/gcc-"+version+".tar.gz";
|
"gcc-"+version+"/gcc-"+version+".tar.gz";
|
||||||
checksum = "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K";
|
checksum = "yWDNSrcKa6yA5ucD4G-a5nCN99yPA8cRlxKgQlaaT-jM4pWYR6e1EvI2qbjUqXWZ";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
patches = [
|
patches = [
|
||||||
@@ -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 = [
|
||||||
@@ -82,6 +82,7 @@ ln -s system/lib /work/
|
|||||||
|
|
||||||
mpc,
|
mpc,
|
||||||
zlib,
|
zlib,
|
||||||
|
zstd,
|
||||||
libucontext,
|
libucontext,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = `
|
||||||
@@ -60,6 +60,9 @@ disable_test t1451-fsck-buffer
|
|||||||
disable_test t4104-apply-boundary
|
disable_test t4104-apply-boundary
|
||||||
disable_test t4200-rerere
|
disable_test t4200-rerere
|
||||||
disable_test t5515-fetch-merge-logic
|
disable_test t5515-fetch-merge-logic
|
||||||
|
disable_test t4124-apply-ws-rule
|
||||||
|
disable_test t3404-rebase-interactive
|
||||||
|
disable_test t7527-builtin-fsmonitor
|
||||||
`;
|
`;
|
||||||
|
|
||||||
check = [
|
check = [
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package glib {
|
|||||||
website = "https://developer.gnome.org/glib";
|
website = "https://developer.gnome.org/glib";
|
||||||
anitya = 10024;
|
anitya = 10024;
|
||||||
|
|
||||||
version# = "2.89.1";
|
version# = "2.89.3";
|
||||||
source = remoteGit {
|
source = remoteGit {
|
||||||
url = "https://gitlab.gnome.org/GNOME/glib.git";
|
url = "https://gitlab.gnome.org/GNOME/glib.git";
|
||||||
tag = version;
|
tag = version;
|
||||||
checksum = "9_6Eew2KIwa1AHopjU7CqC13_nur5FPJMu-iGUd7sD_1gAM1pa_HVUuAtqExJoYU";
|
checksum = "eM9KrXwhwKiZferwrILKmDeq-IGnSjr0EKqV90EEVl0Ee82QVcyVSf2LDMROHcOF";
|
||||||
};
|
};
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
@@ -17,7 +17,7 @@ package glib {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Ddefault_library": "both";
|
"default_library": "both";
|
||||||
};
|
};
|
||||||
// fails with ipv6 disabled
|
// fails with ipv6 disabled
|
||||||
skipTests = [ "gio" ];
|
skipTests = [ "gio" ];
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package glslang {
|
package glslang {
|
||||||
description = "reference front end for GLSL/ESSL";
|
description = "reference front end for GLSL/ESSL";
|
||||||
website = "https://github.com/KhronosGroup/glslang";
|
website = "https://github.com/KhronosGroup/glslang";
|
||||||
anitya = 205796;
|
anitya = 334917;
|
||||||
|
|
||||||
version# = "16.3.0";
|
version# = "1.4.357.0";
|
||||||
source = remoteGitHub {
|
source = remoteGitHub {
|
||||||
suffix = "KhronosGroup/glslang";
|
suffix = "KhronosGroup/glslang";
|
||||||
tag = version;
|
tag = "vulkan-sdk-"+version;
|
||||||
checksum = "xyqDf8k3-D0_BXHGi0uLgMglnJ05Rf3j73QgbDs3sGtKNdBIQhY8JfqX1NcNoJQN";
|
checksum = "7Zq12xtSd5z_aEEeYCnsWR5WvcEGVlTsRaV6MqkmY1a3iNIrRbX_rrg-taI3wMe6";
|
||||||
};
|
};
|
||||||
|
|
||||||
// test suite writes to source
|
// test suite writes to source
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package m4 {
|
|||||||
|
|
||||||
version# = "1.4.21";
|
version# = "1.4.21";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2";
|
url = "https://mirrors.kernel.org/gnu/m4/m4-"+version+".tar.bz2";
|
||||||
checksum = "pPa6YOo722Jw80l1OsH1tnUaklnPFjFT-bxGw5iAVrZTm1P8FQaWao_NXop46-pm";
|
checksum = "pPa6YOo722Jw80l1OsH1tnUaklnPFjFT-bxGw5iAVrZTm1P8FQaWao_NXop46-pm";
|
||||||
compress = bzip2;
|
compress = bzip2;
|
||||||
};
|
};
|
||||||
@@ -17,7 +17,10 @@ package m4 {
|
|||||||
chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
|
chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exec = make {};
|
toyboxEarly = true;
|
||||||
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
|
};
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
diffutils,
|
diffutils,
|
||||||
@@ -33,7 +36,7 @@ package autoconf {
|
|||||||
|
|
||||||
version# = "2.73";
|
version# = "2.73";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/autoconf/autoconf-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/autoconf/autoconf-"+version+".tar.gz";
|
||||||
checksum = "yGabDTeOfaCUB0JX-h3REYLYzMzvpDwFmFFzHNR7QilChCUNE4hR6q7nma4viDYg";
|
checksum = "yGabDTeOfaCUB0JX-h3REYLYzMzvpDwFmFFzHNR7QilChCUNE4hR6q7nma4viDYg";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -68,7 +71,7 @@ package automake {
|
|||||||
|
|
||||||
version# = "1.18.1";
|
version# = "1.18.1";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/automake/automake-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/automake/automake-"+version+".tar.gz";
|
||||||
checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG";
|
checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -102,16 +105,16 @@ package libtool {
|
|||||||
website = "https://www.gnu.org/software/libtool";
|
website = "https://www.gnu.org/software/libtool";
|
||||||
anitya = 1741;
|
anitya = 1741;
|
||||||
|
|
||||||
version# = "2.5.4";
|
version# = "2.6.2";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/libtool/libtool-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/libtool/libtool-"+version+".tar.gz";
|
||||||
checksum = "pa6LSrQggh8mSJHQfwGjysAApmZlGJt8wif2cCLzqAAa2jpsTY0jZ-6stS3BWZ2Q";
|
checksum = "roFqdjyoGjpK7CWWLJJrTS56LuOQcIdq6Tgr4yplacSwirFHoaiDe6CojIWYinWe";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
// _Z2a2c: symbol not found
|
// _Z2a2c: symbol not found
|
||||||
skipEarlyStageCheck = true;
|
checkEarly = false;
|
||||||
|
|
||||||
check = [
|
check = [
|
||||||
"TESTSUITEFLAGS=" + jobsFlagE,
|
"TESTSUITEFLAGS=" + jobsFlagE,
|
||||||
@@ -132,14 +135,14 @@ package gzip {
|
|||||||
|
|
||||||
version# = "1.14";
|
version# = "1.14";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/gzip/gzip-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/gzip/gzip-"+version+".tar.gz";
|
||||||
checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q";
|
checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
// dependency loop
|
// dependency loop
|
||||||
skipCheck = true;
|
check = nil;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +153,7 @@ package sed {
|
|||||||
|
|
||||||
version# = "4.10";
|
version# = "4.10";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/sed/sed-"+version+".tar.gz";
|
||||||
checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51";
|
checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -178,7 +181,7 @@ package diffutils {
|
|||||||
|
|
||||||
version# = "3.12";
|
version# = "3.12";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/diffutils/diffutils-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/diffutils/diffutils-"+version+".tar.gz";
|
||||||
checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44";
|
checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -193,7 +196,9 @@ test_disable '#!/bin/sh' tests/cmp
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
toyboxEarly = true;
|
toyboxEarly = true;
|
||||||
exec = make {};
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
package patch {
|
package patch {
|
||||||
@@ -203,7 +208,7 @@ package patch {
|
|||||||
|
|
||||||
version# = "2.8";
|
version# = "2.8";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/patch/patch-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/patch/patch-"+version+".tar.gz";
|
||||||
checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR";
|
checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -216,26 +221,9 @@ test_disable '#!/bin/sh' tests/ed-style
|
|||||||
test_disable '#!/bin/sh' tests/need-filename
|
test_disable '#!/bin/sh' tests/need-filename
|
||||||
`;
|
`;
|
||||||
|
|
||||||
toyboxEarly = true;
|
|
||||||
exec = make {};
|
|
||||||
}
|
|
||||||
|
|
||||||
package gawk {
|
|
||||||
description = "an implementation of awk with GNU extensions";
|
|
||||||
website = "https://www.gnu.org/software/gawk";
|
|
||||||
anitya = 868;
|
|
||||||
|
|
||||||
version# = "5.4.0";
|
|
||||||
source = remoteTar {
|
|
||||||
url = "https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz";
|
|
||||||
checksum = "m0RkIolC-PI7EY5q8pcx5Y-0twlIW0Yp3wXXmV-QaHorSdf8BhZ7kW9F8iWomz0C";
|
|
||||||
compress = gzip;
|
|
||||||
};
|
|
||||||
|
|
||||||
toyboxEarly = true;
|
toyboxEarly = true;
|
||||||
exec = make {
|
exec = make {
|
||||||
// dependency loop
|
defaults = false;
|
||||||
skipCheck = true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +234,7 @@ package grep {
|
|||||||
|
|
||||||
version# = "3.12";
|
version# = "3.12";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/grep/grep-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/grep/grep-"+version+".tar.gz";
|
||||||
checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1";
|
checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -271,7 +259,7 @@ package gettext {
|
|||||||
|
|
||||||
version# = "1.0";
|
version# = "1.0";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/gettext/gettext-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/gettext/gettext-"+version+".tar.gz";
|
||||||
checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC";
|
checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -309,14 +297,18 @@ package findutils {
|
|||||||
website = "https://www.gnu.org/software/findutils";
|
website = "https://www.gnu.org/software/findutils";
|
||||||
anitya = 812;
|
anitya = 812;
|
||||||
|
|
||||||
version# = "4.10.0";
|
version# = "4.11.0";
|
||||||
source = remoteFile {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/findutils/findutils-"+version+".tar.xz";
|
url = "https://mirrors.kernel.org/gnu/findutils/findutils-"+version+".tar.xz";
|
||||||
checksum = "ZXABdNBQXL7QjTygynRRTdXYWxQKZ0Wn5eMd3NUnxR0xaS0u0VfcKoTlbo50zxv6";
|
compress = xz;
|
||||||
|
checksum = "X-qsv9aUoBL583q-4iZcBI3_7Ufd3fSIqFmNLXWdEpUihlRfMpGGyAUt8SAvDKae";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
writable = true;
|
||||||
|
chmod = true;
|
||||||
early = `
|
early = `
|
||||||
echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh
|
echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh
|
||||||
|
echo 'int main(){return 0;}' > gnulib-tests/test-fstatat.c
|
||||||
echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
|
echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -324,7 +316,6 @@ echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
|
|||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
diffutils,
|
diffutils,
|
||||||
xz,
|
|
||||||
sed,
|
sed,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -336,13 +327,14 @@ package bash {
|
|||||||
|
|
||||||
version# = "5.3";
|
version# = "5.3";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/bash/bash-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/bash/bash-"+version+".tar.gz";
|
||||||
checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq";
|
checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
toyboxEarly = true;
|
toyboxEarly = true;
|
||||||
exec = make {
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
configure = {
|
configure = {
|
||||||
"without-bash-malloc";
|
"without-bash-malloc";
|
||||||
};
|
};
|
||||||
@@ -357,7 +349,7 @@ package coreutils {
|
|||||||
|
|
||||||
version# = "9.11";
|
version# = "9.11";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/coreutils/coreutils-"+version+".tar.gz";
|
||||||
checksum = "t8UMed5wpFEoC56aa42_yidfOAaRGzOfj7MRtQkkqgGbpXiskNA8bd-EmVSQkZie";
|
checksum = "t8UMed5wpFEoC56aa42_yidfOAaRGzOfj7MRtQkkqgGbpXiskNA8bd-EmVSQkZie";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -379,6 +371,7 @@ test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
|
defaults = false;
|
||||||
configure = {
|
configure = {
|
||||||
"enable-single-binary": "symlinks";
|
"enable-single-binary": "symlinks";
|
||||||
};
|
};
|
||||||
@@ -399,7 +392,7 @@ package tar {
|
|||||||
|
|
||||||
version# = "1.35";
|
version# = "1.35";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/tar/tar-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/tar/tar-"+version+".tar.gz";
|
||||||
checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA";
|
checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -436,21 +429,21 @@ package texinfo {
|
|||||||
|
|
||||||
version# = "7.3";
|
version# = "7.3";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/texinfo/texinfo-"+version+".tar.gz";
|
||||||
checksum = "RRmC8Xwdof7JuZJeWGAQ_GeASIHAuJFQMbNONXBz5InooKIQGmqmWRjGNGEr5n4-";
|
checksum = "RRmC8Xwdof7JuZJeWGAQ_GeASIHAuJFQMbNONXBz5InooKIQGmqmWRjGNGEr5n4-";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
// nonstandard glibc extension
|
// nonstandard glibc extension
|
||||||
skipCheck = true;
|
check = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
inputs = [ perl ];
|
inputs = [ perl ];
|
||||||
|
|
||||||
runtime = [
|
runtime = [
|
||||||
perl,
|
perl,
|
||||||
gawk,
|
awk,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +454,7 @@ package gperf {
|
|||||||
|
|
||||||
version# = "3.3";
|
version# = "3.3";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gperf/gperf-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/gperf/gperf-"+version+".tar.gz";
|
||||||
checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7";
|
checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -478,7 +471,7 @@ package bc {
|
|||||||
|
|
||||||
version# = "1.08.2";
|
version# = "1.08.2";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/bc/bc-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/bc/bc-"+version+".tar.gz";
|
||||||
checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy";
|
checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -501,7 +494,7 @@ package libiconv {
|
|||||||
|
|
||||||
version# = "1.19";
|
version# = "1.19";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/libiconv/libiconv-"+version+".tar.gz";
|
||||||
checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x";
|
checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -514,10 +507,10 @@ package parallel {
|
|||||||
website = "https://www.gnu.org/software/parallel";
|
website = "https://www.gnu.org/software/parallel";
|
||||||
anitya = 5448;
|
anitya = 5448;
|
||||||
|
|
||||||
version# = "20260622";
|
version# = "20260722";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2";
|
url = "https://mirrors.kernel.org/gnu/parallel/parallel-"+version+".tar.bz2";
|
||||||
checksum = "pEkZ_J18AvKCMoPfxEprC0Smw7zP6qXASmC1uFf_HVD_jc95H06LvzGi40-mtCUo";
|
checksum = "liG9pBSRqUPqDuRXmnJPoVh-G53lDKkkO8GGabSxQnSho4b9BD0EaJDdScgVhnwj";
|
||||||
compress = bzip2;
|
compress = bzip2;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -539,7 +532,7 @@ package libunistring {
|
|||||||
|
|
||||||
version# = "1.4.2";
|
version# = "1.4.2";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/libunistring/libunistring-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/libunistring/libunistring-"+version+".tar.gz";
|
||||||
checksum = "iW9BbfLoVlXjWoLTZ4AekQSu4cFBnLcZ4W8OHWbv0AhJNgD3j65_zqaLMzFKylg2";
|
checksum = "iW9BbfLoVlXjWoLTZ4AekQSu4cFBnLcZ4W8OHWbv0AhJNgD3j65_zqaLMzFKylg2";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -566,7 +559,7 @@ package libtasn1 {
|
|||||||
|
|
||||||
version# = "4.21.0";
|
version# = "4.21.0";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/libtasn1/libtasn1-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/libtasn1/libtasn1-"+version+".tar.gz";
|
||||||
checksum = "9DYI3UYbfYLy8JsKUcY6f0irskbfL0fHZA91Q-JEOA3kiUwpodyjemRsYRjUpjuq";
|
checksum = "9DYI3UYbfYLy8JsKUcY6f0irskbfL0fHZA91Q-JEOA3kiUwpodyjemRsYRjUpjuq";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -581,7 +574,7 @@ package readline {
|
|||||||
|
|
||||||
version# = "8.3";
|
version# = "8.3";
|
||||||
source = remoteTar {
|
source = remoteTar {
|
||||||
url = "https://ftpmirror.gnu.org/gnu/readline/readline-"+version+".tar.gz";
|
url = "https://mirrors.kernel.org/gnu/readline/readline-"+version+".tar.gz";
|
||||||
checksum = "r-lcGRJq_MvvBpOq47Z2Y1OI2iqrmtcqhTLVXR0xWo37ZpC2uT_md7gKq5o_qTMV";
|
checksum = "r-lcGRJq_MvvBpOq47Z2Y1OI2iqrmtcqhTLVXR0xWo37ZpC2uT_md7gKq5o_qTMV";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
@@ -655,7 +648,7 @@ package mpc {
|
|||||||
enterSource = true;
|
enterSource = true;
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
inPlace = true;
|
chdir = false;
|
||||||
generate = "autoreconf -vfi";
|
generate = "autoreconf -vfi";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package go {
|
||||||
|
description = "the Go programming language toolchain";
|
||||||
|
website = "https://go.dev";
|
||||||
|
anitya = 1227;
|
||||||
|
|
||||||
|
version# = "1.27.0";
|
||||||
|
source = remoteTar {
|
||||||
|
url = "https://go.dev/dl/go"+version+".src.tar.gz";
|
||||||
|
checksum = "Ookl2vP6KMfJuxaxX6nXZ1gnL43wZPl5GjpVsrI7IJiB4b3xr1PbnbYIOJ8v5jzG";
|
||||||
|
compress = gzip;
|
||||||
|
};
|
||||||
|
|
||||||
|
env = [
|
||||||
|
"CC=cc",
|
||||||
|
"GOCACHE=/tmp/gocache",
|
||||||
|
"GOROOT_BOOTSTRAP=/system/go",
|
||||||
|
"TMPDIR=/dev/shm/go",
|
||||||
|
];
|
||||||
|
|
||||||
|
enterSource = true;
|
||||||
|
|
||||||
|
exec = generic {
|
||||||
|
chdir = false;
|
||||||
|
build = `
|
||||||
|
mkdir /work/system/ "${TMPDIR}"
|
||||||
|
cp -r . /work/system/go
|
||||||
|
cd /work/system/go/src/
|
||||||
|
chmod -R +w ..
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
's,/lib/ld-musl-`+linuxArch+`.so.1,/system/bin/linker,' \
|
||||||
|
cmd/link/internal/`+arch+`/obj.go
|
||||||
|
|
||||||
|
rm \
|
||||||
|
os/root_unix_test.go \
|
||||||
|
runtime/crash_cgo_test.go \
|
||||||
|
cmd/cgo/internal/testsanitizers/tsan_test.go \
|
||||||
|
cmd/cgo/internal/testsanitizers/cshared_test.go
|
||||||
|
|
||||||
|
set +u
|
||||||
|
. ./make.bash "$@" --no-banner
|
||||||
|
set -u
|
||||||
|
`;
|
||||||
|
check = "bash run.bash --no-rebuild\n";
|
||||||
|
install = `
|
||||||
|
../bin/go tool dist banner # print build info
|
||||||
|
|
||||||
|
mkdir /work/system/bin
|
||||||
|
ln -s \
|
||||||
|
../go/bin/go \
|
||||||
|
../go/bin/gofmt \
|
||||||
|
/work/system/bin
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = [ bash, go-bootstrap ];
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if name, err := os.Hostname(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
os.Stdout.WriteString(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,19 +3,19 @@ package harfbuzz {
|
|||||||
website = "https://harfbuzz.github.io";
|
website = "https://harfbuzz.github.io";
|
||||||
anitya = 1299;
|
anitya = 1299;
|
||||||
|
|
||||||
version# = "14.2.1";
|
version# = "14.3.1";
|
||||||
source = remoteGitHub {
|
source = remoteGitHub {
|
||||||
suffix = "harfbuzz/harfbuzz";
|
suffix = "harfbuzz/harfbuzz";
|
||||||
tag = version;
|
tag = version;
|
||||||
checksum = "gWl1fS1nXSH9Z9GpJSrh6w7Iv6AOjZbDL_4JZAZTiTYSyLCfxIFuCRLjYmqT2nbt";
|
checksum = "ykVwQNNbvY38Y27VjAfk16SGcEO5NY5A8CFxJCJ8z0ARh5MdLImmONpy-ZSb79Il";
|
||||||
};
|
};
|
||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Dcairo": "enabled";
|
"cairo": "enabled";
|
||||||
"Dpng": "enabled";
|
"png": "enabled";
|
||||||
"Dzlib": "enabled";
|
"zlib": "enabled";
|
||||||
"Dfreetype": "enabled";
|
"freetype": "enabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package hwdata {
|
|||||||
website = "https://github.com/vcrhonek/hwdata";
|
website = "https://github.com/vcrhonek/hwdata";
|
||||||
anitya = 5387;
|
anitya = 5387;
|
||||||
|
|
||||||
version# = "0.409";
|
version# = "0.410";
|
||||||
source = remoteGitHub {
|
source = remoteGitHub {
|
||||||
suffix = "vcrhonek/hwdata";
|
suffix = "vcrhonek/hwdata";
|
||||||
tag = "v"+version;
|
tag = "v"+version;
|
||||||
checksum = "p2qr1_Y9dpjMNnK8OPNcuHSNwZldwb6mtiJ9Nd5HgU8z3L9fixLthnixywU8dd65";
|
checksum = "w1fbTz8NR7C6SYOupqTyNZGJHa_cDRAsGs4guZ3LddqlmawgEP_CWFw9-OYFKJ1q";
|
||||||
};
|
};
|
||||||
|
|
||||||
writable = true;
|
writable = true;
|
||||||
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,22 +21,22 @@ 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 = {
|
||||||
"prefix": "/system";
|
"prefix": "/system";
|
||||||
"color": "auto";
|
"color": "auto";
|
||||||
};
|
};
|
||||||
make = [ "CC=cc" ];
|
make = [ "CC=cc", "YACC=yacc" ];
|
||||||
// wants root
|
// wants root
|
||||||
skipCheck = true;
|
check = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
pkg-config,
|
pkgconf,
|
||||||
m4,
|
m4,
|
||||||
bison,
|
byacc,
|
||||||
flex,
|
flex,
|
||||||
|
|
||||||
libbpf,
|
libbpf,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/x86 6.18.38 Kernel Configuration
|
# Linux/x86 6.18.45 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
|
||||||
@@ -424,12 +424,12 @@ CONFIG_X86_DEBUGCTLMSR=y
|
|||||||
CONFIG_IA32_FEAT_CTL=y
|
CONFIG_IA32_FEAT_CTL=y
|
||||||
CONFIG_X86_VMX_FEATURE_NAMES=y
|
CONFIG_X86_VMX_FEATURE_NAMES=y
|
||||||
# CONFIG_PROCESSOR_SELECT is not set
|
# CONFIG_PROCESSOR_SELECT is not set
|
||||||
CONFIG_BROADCAST_TLB_FLUSH=y
|
|
||||||
CONFIG_CPU_SUP_INTEL=y
|
CONFIG_CPU_SUP_INTEL=y
|
||||||
CONFIG_CPU_SUP_AMD=y
|
CONFIG_CPU_SUP_AMD=y
|
||||||
CONFIG_CPU_SUP_HYGON=y
|
CONFIG_CPU_SUP_HYGON=y
|
||||||
CONFIG_CPU_SUP_CENTAUR=y
|
CONFIG_CPU_SUP_CENTAUR=y
|
||||||
CONFIG_CPU_SUP_ZHAOXIN=y
|
CONFIG_CPU_SUP_ZHAOXIN=y
|
||||||
|
CONFIG_BROADCAST_TLB_FLUSH=y
|
||||||
CONFIG_HPET_TIMER=y
|
CONFIG_HPET_TIMER=y
|
||||||
CONFIG_HPET_EMULATE_RTC=y
|
CONFIG_HPET_EMULATE_RTC=y
|
||||||
CONFIG_DMI=y
|
CONFIG_DMI=y
|
||||||
@@ -7311,6 +7311,7 @@ CONFIG_AGP_INTEL=m
|
|||||||
CONFIG_AGP_SIS=m
|
CONFIG_AGP_SIS=m
|
||||||
CONFIG_AGP_VIA=m
|
CONFIG_AGP_VIA=m
|
||||||
CONFIG_INTEL_GTT=m
|
CONFIG_INTEL_GTT=m
|
||||||
|
CONFIG_GPU_BUDDY=y
|
||||||
CONFIG_DRM=m
|
CONFIG_DRM=m
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/arm64 6.18.38 Kernel Configuration
|
# Linux/arm64 6.18.45 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
|
||||||
@@ -7986,6 +7986,7 @@ CONFIG_HT16K33=m
|
|||||||
CONFIG_MAX6959=m
|
CONFIG_MAX6959=m
|
||||||
CONFIG_SEG_LED_GPIO=m
|
CONFIG_SEG_LED_GPIO=m
|
||||||
CONFIG_PANEL=m
|
CONFIG_PANEL=m
|
||||||
|
CONFIG_GPU_BUDDY=y
|
||||||
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
|
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
|
||||||
CONFIG_TEGRA_HOST1X=m
|
CONFIG_TEGRA_HOST1X=m
|
||||||
CONFIG_TEGRA_HOST1X_FIREWALL=y
|
CONFIG_TEGRA_HOST1X_FIREWALL=y
|
||||||
@@ -14215,7 +14216,6 @@ CONFIG_CRYPTO_SM4_ARM64_CE_GCM=m
|
|||||||
CONFIG_CRYPTO_HW=y
|
CONFIG_CRYPTO_HW=y
|
||||||
CONFIG_CRYPTO_DEV_ALLWINNER=y
|
CONFIG_CRYPTO_DEV_ALLWINNER=y
|
||||||
CONFIG_CRYPTO_DEV_SUN4I_SS=m
|
CONFIG_CRYPTO_DEV_SUN4I_SS=m
|
||||||
# CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set
|
|
||||||
# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set
|
# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set
|
||||||
CONFIG_CRYPTO_DEV_SUN8I_CE=m
|
CONFIG_CRYPTO_DEV_SUN8I_CE=m
|
||||||
# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set
|
# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package kernel-source {
|
|||||||
website = "https://kernel.org";
|
website = "https://kernel.org";
|
||||||
exclude = true;
|
exclude = true;
|
||||||
|
|
||||||
version# = "6.18.38";
|
version# = "6.18.45";
|
||||||
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 = "y_c897Efibj3TxgJQfpfTOWHTEoBPqu-XLwl2c40THwfgiNAop3qusrGvQkThXtI";
|
checksum = "yI15OXBcDSWVnozq7ilLiiKMbn2xGIuZWa73luYAjcHK12e8R9n_n_am43hnhNAZ";
|
||||||
compress = gzip;
|
compress = gzip;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,8 @@ package kernel-headers {
|
|||||||
toyboxEarly = true;
|
toyboxEarly = true;
|
||||||
|
|
||||||
exec = make {
|
exec = make {
|
||||||
skipConfigure = true;
|
defaults = false;
|
||||||
|
configure = nil;
|
||||||
make = [
|
make = [
|
||||||
"-f /usr/src/kernel-headers/Makefile",
|
"-f /usr/src/kernel-headers/Makefile",
|
||||||
"O=/tmp/kbuild",
|
"O=/tmp/kbuild",
|
||||||
@@ -34,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 > \
|
||||||
@@ -45,9 +46,9 @@ cat \
|
|||||||
checksum = arch {
|
checksum = arch {
|
||||||
default = "";
|
default = "";
|
||||||
|
|
||||||
amd64 = "UscduTw49AOk4CL6gLS6yORPFiHO79h1kFZKXKDaUI9j0x5CySi7P2Ywf29gYBsM";
|
amd64 = "vN5Ts9yAlHTntcQcNGJSisY5guYsYfvGnQqI1NzTBzvhBMPD432WB3B0KFGYQntA";
|
||||||
arm64 = "FM5-YFUbkOiux1KMxU29pecCoq6kPUfSL_4JlfqRHe4ZxIiT1AELGt7liD6df3-K";
|
arm64 = "FQtpqCA0tlz17RJP8a5t9YEM_6F9kGPqQ9Z60gFrkVP3v8_P-Vnf5S7wLlxyRlOe";
|
||||||
riscv64 = "Z1jR7S3nnGYOJtOR3sOMznfmkD_TirHP7-f3tVcgkVzWzHvMXS7ElHLT1NExqcqa";
|
riscv64 = "U5yQ9TI5_7diyrCcm2Iqh3XCMl0P60oQGeDMWxt3OQ91zFWPQ5FCH-eoYG9tSTMT";
|
||||||
};
|
};
|
||||||
inputs = [ rsync ];
|
inputs = [ rsync ];
|
||||||
}
|
}
|
||||||
@@ -85,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",
|
||||||
@@ -132,7 +134,7 @@ rm -v "/work/system/lib/modules/$(make -f /usr/src/kernel/Makefile kernelversion
|
|||||||
perl,
|
perl,
|
||||||
bc,
|
bc,
|
||||||
sed,
|
sed,
|
||||||
gawk,
|
awk,
|
||||||
coreutils,
|
coreutils,
|
||||||
diffutils,
|
diffutils,
|
||||||
bash,
|
bash,
|
||||||
@@ -153,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,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/riscv 6.18.38 Kernel Configuration
|
# Linux/riscv 6.18.45 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
|
||||||
@@ -6897,6 +6897,7 @@ CONFIG_HT16K33=m
|
|||||||
CONFIG_MAX6959=m
|
CONFIG_MAX6959=m
|
||||||
CONFIG_SEG_LED_GPIO=m
|
CONFIG_SEG_LED_GPIO=m
|
||||||
CONFIG_PANEL=m
|
CONFIG_PANEL=m
|
||||||
|
CONFIG_GPU_BUDDY=y
|
||||||
CONFIG_DRM=m
|
CONFIG_DRM=m
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -11358,7 +11359,6 @@ CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
|
|||||||
CONFIG_CRYPTO_HW=y
|
CONFIG_CRYPTO_HW=y
|
||||||
CONFIG_CRYPTO_DEV_ALLWINNER=y
|
CONFIG_CRYPTO_DEV_ALLWINNER=y
|
||||||
CONFIG_CRYPTO_DEV_SUN4I_SS=m
|
CONFIG_CRYPTO_DEV_SUN4I_SS=m
|
||||||
# CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set
|
|
||||||
# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set
|
# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set
|
||||||
CONFIG_CRYPTO_DEV_SUN8I_CE=m
|
CONFIG_CRYPTO_DEV_SUN8I_CE=m
|
||||||
# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set
|
# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define LINUX_VERSION_CODE 397861
|
#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 37
|
#define LINUX_VERSION_SUBLEVEL 44
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ package kmod {
|
|||||||
|
|
||||||
exec = meson {
|
exec = meson {
|
||||||
setup = {
|
setup = {
|
||||||
"Dmoduledir": "/system/lib/modules";
|
"moduledir": "/system/lib/modules";
|
||||||
"Dsysconfdir": "/system/etc";
|
"sysconfdir": "/system/etc";
|
||||||
"Dbashcompletiondir": "no";
|
"bashcompletiondir": "no";
|
||||||
"Dfishcompletiondir": "no";
|
"fishcompletiondir": "no";
|
||||||
"Dxz": "disabled";
|
"xz": "disabled";
|
||||||
"Dmanpages": "false";
|
"manpages": "false";
|
||||||
};
|
};
|
||||||
|
|
||||||
// makes assumptions about the running kernel
|
// makes assumptions about the running kernel
|
||||||
skipTest = true;
|
test = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package libaio {
|
||||||
|
description = "kernel asynchronous I/O (AIO) support";
|
||||||
|
website = "https://lse.sourceforge.net/io/aio.html";
|
||||||
|
anitya = 1557;
|
||||||
|
|
||||||
|
version# = "0.3.113";
|
||||||
|
source = remoteTar {
|
||||||
|
url = "https://pagure.io/libaio/archive/libaio-"+version+
|
||||||
|
"/libaio-libaio-"+version+".tar.gz";
|
||||||
|
compress = gzip;
|
||||||
|
checksum = "vUATfur4I3D742vjRhiGMLYDCm-blbsymb3JTUiM3RV5HIEWi0wDBiPqh7jJpMWd";
|
||||||
|
};
|
||||||
|
|
||||||
|
enterSource = true;
|
||||||
|
writable = true;
|
||||||
|
chmod = true;
|
||||||
|
|
||||||
|
env = [ "PATH=/system/sbin" ];
|
||||||
|
bin = [ "bash" ];
|
||||||
|
exec = make {
|
||||||
|
chdir = false;
|
||||||
|
configure = nil;
|
||||||
|
preCheck = "rm harness/cases/20.t; "+ // flaky
|
||||||
|
"CFLAGS='"+
|
||||||
|
"-Wno-unknown-warning-option "+
|
||||||
|
"-Wno-gnu-designator "+
|
||||||
|
"-Wno-#warnings' ";
|
||||||
|
check = [ "partcheck" ];
|
||||||
|
install = "make prefix=/work/system install";
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
bash,
|
||||||
|
e2fsprogs,
|
||||||
|
kernel-headers,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -60,4 +60,5 @@ list(APPEND CTEST_CUSTOM_TESTS_IGNORE
|
|||||||
"libarchive_test_read_format_tar_filename"
|
"libarchive_test_read_format_tar_filename"
|
||||||
"libarchive_test_read_format_ustar_filename"
|
"libarchive_test_read_format_ustar_filename"
|
||||||
"libarchive_test_read_append_wrong_filter"
|
"libarchive_test_read_append_wrong_filter"
|
||||||
|
"libarchive_test_read_format_zip_ppmd8_aes256_streaming"
|
||||||
)
|
)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user