aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-06-04 18:37:07 +0900
committerOphestra <cat@gensokyo.uk>2026-06-04 18:54:43 +0900
commitdb69dcf0be0c1be4e3187027fa4199538013e76d (patch)
tree78513e0ec30c375af15270852d551f326c7f663f
parent76c1fb84c87ba12a22b64f7c471a92603365837f (diff)
internal/pkg: remove tar built-in decompressor
This is replaced by decompressArtifact and is no longer necessary. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/pkg/compress.go2
-rw-r--r--internal/pkg/ir_test.go34
-rw-r--r--internal/pkg/tar.go79
-rw-r--r--internal/pkg/tar_test.go80
-rw-r--r--internal/rosa/builtins.go15
-rw-r--r--internal/rosa/etc.go2
-rw-r--r--internal/rosa/go.go4
-rw-r--r--internal/rosa/llvm_test.go2
-rw-r--r--internal/rosa/state.go24
9 files changed, 78 insertions, 164 deletions
diff --git a/internal/pkg/compress.go b/internal/pkg/compress.go
index 310fe065..a683c816 100644
--- a/internal/pkg/compress.go
+++ b/internal/pkg/compress.go
@@ -36,7 +36,7 @@ type decompressArtifactNamed struct {
var _ fmt.Stringer = new(decompressArtifactNamed)
// NewDecompress returns a [FileArtifact] decompressing the supplied [Artifact].
-func NewDecompress(a Artifact, compress uint32) Artifact {
+func NewDecompress(a Artifact, compress uint32) FileArtifact {
da := decompressArtifact{a, compress}
if s, ok := a.(fmt.Stringer); ok {
if name := s.String(); name != "" {
diff --git a/internal/pkg/ir_test.go b/internal/pkg/ir_test.go
index d49d2c56..0cb4a6ef 100644
--- a/internal/pkg/ir_test.go
+++ b/internal/pkg/ir_test.go
@@ -27,16 +27,14 @@ func TestIRRoundtrip(t *testing.T) {
pkg.Checksum(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
)},
- {"http get tar", pkg.NewHTTPGetTar(
+ {"http get tar", pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
nil, "file:///testdata",
pkg.Checksum(bytes.Repeat([]byte{0xff}, len(pkg.Checksum{}))),
- pkg.TarBzip2,
- )},
- {"http get tar unaligned", pkg.NewHTTPGetTar(
+ ), pkg.Bzip2))},
+ {"http get tar unaligned", pkg.NewTar(pkg.NewHTTPGet(
nil, "https://hakurei.app",
pkg.Checksum(bytes.Repeat([]byte{0xfe}, len(pkg.Checksum{}))),
- pkg.TarUncompressed,
- )},
+ ))},
{"exec offline", pkg.NewExec(
"exec-offline", "", nil, 0, false, false,
@@ -47,15 +45,13 @@ func TestIRRoundtrip(t *testing.T) {
pkg.MustPath("/file", false, pkg.NewFile("file", []byte(
"stub file",
- ))), pkg.MustPath("/.hakurei", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/.hakurei", false, pkg.NewTar(pkg.NewHTTPGet(
nil, "file:///hakurei.tar",
pkg.Checksum(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
- pkg.TarUncompressed,
- )), pkg.MustPath("/opt", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/opt", false, pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
nil, "file:///testtool.tar.gz",
pkg.Checksum(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
- pkg.TarGzip,
- )),
+ ), pkg.Gzip))),
)},
{"exec net", pkg.NewExec(
@@ -69,15 +65,13 @@ func TestIRRoundtrip(t *testing.T) {
pkg.MustPath("/file", false, pkg.NewFile("file", []byte(
"stub file",
- ))), pkg.MustPath("/.hakurei", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/.hakurei", false, pkg.NewTar(pkg.NewHTTPGet(
nil, "file:///hakurei.tar",
pkg.Checksum(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
- pkg.TarUncompressed,
- )), pkg.MustPath("/opt", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/opt", false, pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
nil, "file:///testtool.tar.gz",
pkg.Checksum(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
- pkg.TarGzip,
- )),
+ ), pkg.Gzip))),
)},
{"exec measured", pkg.NewExec(
@@ -91,15 +85,13 @@ func TestIRRoundtrip(t *testing.T) {
pkg.MustPath("/file", false, pkg.NewFile("file", []byte(
"stub file",
- ))), pkg.MustPath("/.hakurei", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/.hakurei", false, pkg.NewTar(pkg.NewHTTPGet(
nil, "file:///hakurei.tar",
pkg.Checksum(bytes.Repeat([]byte{0xfd}, len(pkg.Checksum{}))),
- pkg.TarUncompressed,
- )), pkg.MustPath("/opt", false, pkg.NewHTTPGetTar(
+ ))), pkg.MustPath("/opt", false, pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
nil, "file:///testtool.tar.gz",
pkg.Checksum(bytes.Repeat([]byte{0xfd}, len(pkg.Checksum{}))),
- pkg.TarGzip,
- )),
+ ), pkg.Gzip))),
)},
{"file anonymous", pkg.NewFile("", []byte{0})},
diff --git a/internal/pkg/tar.go b/internal/pkg/tar.go
index 1c558d52..0b40e103 100644
--- a/internal/pkg/tar.go
+++ b/internal/pkg/tar.go
@@ -2,32 +2,18 @@ package pkg
import (
"archive/tar"
- "compress/bzip2"
- "compress/gzip"
"errors"
"fmt"
"io"
"io/fs"
- "net/http"
"os"
"path/filepath"
)
-const (
- // TarUncompressed denotes an uncompressed tarball.
- TarUncompressed = iota
- // TarGzip denotes a tarball compressed via [gzip].
- TarGzip
- // TarBzip2 denotes a tarball compressed via [bzip2].
- TarBzip2
-)
-
// A tarArtifact is an [Artifact] unpacking a tarball backed by a [FileArtifact].
type tarArtifact struct {
// Caller-supplied backing tarball.
f Artifact
- // Compression on top of the tarball.
- compression uint32
}
// tarArtifactNamed embeds tarArtifact for a [fmt.Stringer] tarball.
@@ -42,10 +28,10 @@ var _ fmt.Stringer = new(tarArtifactNamed)
// String returns the name of the underlying [Artifact] suffixed with unpack.
func (a *tarArtifactNamed) String() string { return a.name + "-unpack" }
-// NewTar returns a new [Artifact] backed by the supplied [Artifact] and
-// compression method. The source [Artifact] must be a [FileArtifact].
-func NewTar(a Artifact, compression uint32) Artifact {
- ta := tarArtifact{a, compression}
+// NewTar returns a new [Artifact] unpacking the tar stream produced by the
+// backing [Artifact]. The source [Artifact] must be a [FileArtifact].
+func NewTar(a Artifact) Artifact {
+ ta := tarArtifact{a}
if s, ok := a.(fmt.Stringer); ok {
if name := s.String(); name != "" {
return &tarArtifactNamed{ta, name}
@@ -54,25 +40,15 @@ func NewTar(a Artifact, compression uint32) Artifact {
return &ta
}
-// NewHTTPGetTar is abbreviation for NewHTTPGet passed to NewTar.
-func NewHTTPGetTar(
- hc *http.Client,
- url string,
- checksum Checksum,
- compression uint32,
-) Artifact {
- return NewTar(NewHTTPGet(hc, url, checksum), compression)
-}
-
// Kind returns the hardcoded [Kind] constant.
func (a *tarArtifact) Kind() Kind { return KindTar }
-// Params writes compression encoded in little endian.
-func (a *tarArtifact) Params(ctx *IContext) { ctx.WriteUint32(a.compression) }
+// Params is a noop.
+func (a *tarArtifact) Params(*IContext) {}
func init() {
register(KindTar, func(r *IRReader) Artifact {
- a := NewTar(r.Next(), r.ReadUint32())
+ a := NewTar(r.Next())
if _, ok := r.Finalise(); ok {
panic(ErrUnexpectedChecksum)
}
@@ -98,42 +74,17 @@ func (e DisallowedTypeflagError) Error() string {
// Cure cures the [Artifact], producing a directory located at work.
func (a *tarArtifact) Cure(t *TContext) (err error) {
- var tr io.ReadCloser
- if tr, err = t.Open(a.f); err != nil {
+ var r io.ReadCloser
+ if r, err = t.Open(a.f); err != nil {
return
}
- defer func(f io.ReadCloser) {
- if err == nil {
- err = tr.Close()
- }
-
- closeErr := f.Close()
+ defer func() {
+ closeErr := r.Close()
if err == nil {
err = closeErr
}
- }(tr)
- br := t.cache.getReader(tr)
- defer t.cache.putReader(br)
- tr = io.NopCloser(br)
-
- switch a.compression {
- case TarUncompressed:
- break
-
- case TarGzip:
- if tr, err = gzip.NewReader(tr); err != nil {
- return
- }
- break
-
- case TarBzip2:
- tr = io.NopCloser(bzip2.NewReader(tr))
- break
-
- default:
- return os.ErrInvalid
- }
+ }()
type dirTargetPerm struct {
path string
@@ -156,8 +107,8 @@ func (a *tarArtifact) Cure(t *TContext) (err error) {
}()
var header *tar.Header
- r := tar.NewReader(tr)
- for header, err = r.Next(); err == nil; header, err = r.Next() {
+ tr := tar.NewReader(r)
+ for header, err = tr.Next(); err == nil; header, err = tr.Next() {
typeflag := header.Typeflag
if typeflag == 0 {
if len(header.Name) > 0 && header.Name[len(header.Name)-1] == '/' {
@@ -183,7 +134,7 @@ func (a *tarArtifact) Cure(t *TContext) (err error) {
); err != nil {
return
}
- if _, err = io.Copy(f, r); err != nil {
+ if _, err = io.Copy(f, tr); err != nil {
_ = f.Close()
return
} else if err = f.Close(); err != nil {
diff --git a/internal/pkg/tar_test.go b/internal/pkg/tar_test.go
index c7f8fca5..29ddcdad 100644
--- a/internal/pkg/tar_test.go
+++ b/internal/pkg/tar_test.go
@@ -80,8 +80,8 @@ func TestTar(t *testing.T) {
"checksum/" + wantEncode + "/work": {Mode: fs.ModeDir | 0500},
"identifier": {Mode: fs.ModeDir | 0700},
- "identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
- "identifier/rg7F1D5hwv6o4xctjD5zDq4i5MD0mArTsUIWfhUbik8xC6Bsyt3mjXXOm3goojTz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
+ "identifier/T68YqeEW5moiwVe4J0wPvjERgyMUd4k_cKKxTcQx6AXqZaQAuuryu-Iv-qxDV6-T": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
+ "identifier/WbWIIUGl6bqDBsjU-UB69JqOWLjG5waiUJBUBGeeRp3V7FBbwaBe3sG1qm7DlPSk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
"substitute": {Mode: fs.ModeDir | 0700},
@@ -104,8 +104,8 @@ func TestTar(t *testing.T) {
"checksum/" + wantExpandEncode + "/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
"identifier": {Mode: fs.ModeDir | 0700},
- "identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
- "identifier/_v1blm2h-_KA-dVaawdpLas6MjHc6rbhhFS8JWwx8iJxZGUu8EBbRrhr5AaZ9PJL": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
+ "identifier/WbWIIUGl6bqDBsjU-UB69JqOWLjG5waiUJBUBGeeRp3V7FBbwaBe3sG1qm7DlPSk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
+ "identifier/e3BECw_x_vDyTvj2P48MJVgwpgALeXQ90Ye2Y8gr6SwIPtMup6SR2LVcCTDRGpVi": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
"substitute": {Mode: fs.ModeDir | 0700},
@@ -156,49 +156,6 @@ func checkTarHTTP(
"testdata": {Data: []byte(testdata), Mode: 0400},
}))
- wantIdent := func() pkg.ID {
- h := sha512.New384()
-
- // kind uint64
- h.Write([]byte{byte(pkg.KindTar), 0, 0, 0, 0, 0, 0, 0})
- // deps_sz uint64
- h.Write([]byte{1, 0, 0, 0, 0, 0, 0, 0})
-
- // kind uint64
- h.Write([]byte{byte(pkg.KindHTTPGet), 0, 0, 0, 0, 0, 0, 0})
- // ident ID
- h0 := sha512.New384()
- // kind uint64
- h0.Write([]byte{byte(pkg.KindHTTPGet), 0, 0, 0, 0, 0, 0, 0})
- // deps_sz uint64
- h0.Write([]byte{0, 0, 0, 0, 0, 0, 0, 0})
- // url string
- h0.Write([]byte{byte(pkg.IRKindString), 0, 0, 0})
- h0.Write([]byte{0x10, 0, 0, 0})
- h0.Write([]byte("file:///testdata"))
- // end(KnownChecksum)
- h0.Write([]byte{byte(pkg.IRKindEnd), 0, 0, 0})
- h0.Write([]byte{byte(pkg.IREndKnownChecksum), 0, 0, 0})
- // checksum Checksum
- h0.Write(testdataChecksum[:])
- h.Write(h0.Sum(nil))
- // compression uint32
- h.Write([]byte{byte(pkg.IRKindUint32), 0, 0, 0})
- h.Write([]byte{pkg.TarGzip, 0, 0, 0})
- // end
- h.Write([]byte{byte(pkg.IRKindEnd), 0, 0, 0})
- h.Write([]byte{0, 0, 0, 0})
-
- return pkg.ID(h.Sum(nil))
- }()
-
- a := pkg.NewHTTPGetTar(
- &client,
- "file:///testdata",
- testdataChecksum,
- pkg.TarGzip,
- )
-
tarDir := stubArtifact{
kind: pkg.KindExec,
params: []byte("directory containing a single regular file"),
@@ -251,27 +208,28 @@ func checkTarHTTP(
defer newDestroyArtifactFunc(&tarDirType)(t, base, c)
cureMany(t, c, []cureStep{
- {"file", a, base.Append(
- "identifier",
- pkg.Encode(wantIdent),
- ), want, nil},
+ {"file", pkg.NewTar(pkg.NewDecompress(pkg.NewHTTPGet(
+ &client,
+ "file:///testdata",
+ testdataChecksum,
+ ), pkg.Gzip)), ignorePathname, want, nil},
- {"directory", pkg.NewTar(
+ {"directory", pkg.NewTar(pkg.NewDecompress(
&tarDir,
- pkg.TarGzip,
- ), ignorePathname, want, nil},
+ pkg.Gzip,
+ )), ignorePathname, want, nil},
- {"multiple entries", pkg.NewTar(
+ {"multiple entries", pkg.NewTar(pkg.NewDecompress(
&tarDirMulti,
- pkg.TarGzip,
- ), nil, nil, errors.New(
+ pkg.Gzip,
+ )), nil, nil, errors.New(
"input directory does not contain a single regular file",
)},
- {"bad type", pkg.NewTar(
+ {"bad type", pkg.NewTar(pkg.NewDecompress(
&tarDirType,
- pkg.TarGzip,
- ), nil, nil, errors.New(
+ pkg.Gzip,
+ )), nil, nil, errors.New(
"input directory does not contain a single regular file",
)},
@@ -281,6 +239,6 @@ func checkTarHTTP(
cure: func(t *pkg.TContext) error {
return stub.UniqueError(0xcafe)
},
- }, pkg.TarGzip), nil, nil, stub.UniqueError(0xcafe)},
+ }), nil, nil, stub.UniqueError(0xcafe)},
})
}
diff --git a/internal/rosa/builtins.go b/internal/rosa/builtins.go
index b0ec65b1..55ac0cf1 100644
--- a/internal/rosa/builtins.go
+++ b/internal/rosa/builtins.go
@@ -21,8 +21,13 @@ const (
)
// newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature.
-func newTar(url, checksum string, compression uint32) pkg.Artifact {
- return pkg.NewHTTPGetTar(nil, url, mustDecode(checksum), compression)
+func newTar(url, checksum string, compress uint32) pkg.Artifact {
+ return pkg.NewTar(
+ pkg.NewDecompress(
+ pkg.NewHTTPGet(nil, url, mustDecode(checksum)),
+ compress,
+ ),
+ )
}
// newFromCPAN is a helper for downloading release from CPAN.
@@ -32,7 +37,7 @@ func newFromCPAN(author, name, version, checksum string) pkg.Artifact {
author[:1]+"/"+author[:2]+"/"+author+"/"+
name+"-"+version+".tar.gz",
checksum,
- pkg.TarGzip,
+ pkg.Gzip,
)
}
@@ -43,7 +48,7 @@ func newFromGitLab(domain, suffix, ref, checksum string) pkg.Artifact {
ref+"/"+path.Base(suffix)+"-"+
strings.ReplaceAll(ref, "/", "-")+".tar.bz2",
checksum,
- pkg.TarBzip2,
+ pkg.Bzip2,
)
}
@@ -53,7 +58,7 @@ func newFromGitHub(suffix, tag, checksum string) pkg.Artifact {
"https://github.com/"+suffix+
"/archive/refs/tags/"+tag+".tar.gz",
checksum,
- pkg.TarGzip,
+ pkg.Gzip,
)
}
diff --git a/internal/rosa/etc.go b/internal/rosa/etc.go
index 7b5542db..4ffebdba 100644
--- a/internal/rosa/etc.go
+++ b/internal/rosa/etc.go
@@ -140,7 +140,7 @@ func newIANAEtc() pkg.Artifact {
version,
"iana-etc-"+version+".tar.gz",
checksum,
- pkg.TarGzip,
+ pkg.Gzip,
)
}
diff --git a/internal/rosa/go.go b/internal/rosa/go.go
index fbee360b..26b99929 100644
--- a/internal/rosa/go.go
+++ b/internal/rosa/go.go
@@ -16,7 +16,7 @@ func (t Toolchain) newGo(
return t.NewPackage("go", version, newTar(
"https://go.dev/dl/go"+version+".src.tar.gz",
checksum,
- pkg.TarGzip,
+ pkg.Gzip,
), &PackageAttr{
EnterSource: true,
Env: slices.Concat([]string{
@@ -79,7 +79,7 @@ func init() {
bootstrapEarly = []pkg.Artifact{t.NewPackage("go", "1.4-bootstrap", newTar(
"https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz",
"8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23",
- pkg.TarGzip,
+ pkg.Gzip,
), &PackageAttr{
EnterSource: true,
Env: []string{
diff --git a/internal/rosa/llvm_test.go b/internal/rosa/llvm_test.go
index de63cb6b..48adcf20 100644
--- a/internal/rosa/llvm_test.go
+++ b/internal/rosa/llvm_test.go
@@ -8,7 +8,7 @@ import (
)
func TestLLVMInputs(t *testing.T) {
- const wantInputCount = 688
+ const wantInputCount = 857
_, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm"))
var n int
diff --git a/internal/rosa/state.go b/internal/rosa/state.go
index d55610fe..feb06f82 100644
--- a/internal/rosa/state.go
+++ b/internal/rosa/state.go
@@ -433,10 +433,11 @@ func (s *S) getFrame() azalea.Frame {
identDefault := k("default")
identArch := unique.Make(azalea.Ident(s.arch))
+ const compressOffset = 1 << 8
enumCompress := map[unique.Handle[azalea.Ident]]any{
- k("uncompressed"): uint32(pkg.TarUncompressed),
- k("gzip"): uint32(pkg.TarGzip),
- k("bzip2"): uint32(pkg.TarBzip2),
+ k("uncompressed"): 0,
+ k("gzip"): pkg.Gzip + compressOffset,
+ k("bzip2"): pkg.Bzip2 + compressOffset,
}
s.frame.Val = map[unique.Handle[azalea.Ident]]any{
@@ -609,15 +610,19 @@ func (s *S) getFrame() azalea.Frame {
args azalea.FArgs,
) (v any, set bool, err error) {
var url, checksum string
- var compress uint32
+ var _compress int
if err = args.Apply(map[unique.Handle[azalea.Ident]]any{
k("url"): &url,
k("checksum"): &checksum,
- k("compress"): &compress,
+ k("compress"): &_compress,
}); err != nil {
return
}
- v = pkg.NewHTTPGetTar(nil, url, mustDecode(checksum), compress)
+ f := pkg.NewHTTPGet(nil, url, mustDecode(checksum))
+ if _compress != 0 {
+ f = pkg.NewDecompress(f, uint32(_compress-compressOffset))
+ }
+ v = pkg.NewTar(f)
set = true
return
}, V: enumCompress},
@@ -744,7 +749,10 @@ func (s *S) getFrame() azalea.Frame {
v = newFromGitHubRelease(suffix, tag, name, checksum, compress)
set = true
return
- }, V: enumCompress},
+ }, V: map[unique.Handle[azalea.Ident]]any{
+ k("gzip"): uint32(pkg.Gzip),
+ k("bzip2"): uint32(pkg.Bzip2),
+ }},
// high-level helpers
@@ -1275,7 +1283,7 @@ func (s *S) SetSource(fsys fs.FS) error {
Description: "hakurei source tree (current)",
Version: "1.0.0-CURRENT",
Exclude: true,
- }, pkg.NewTar(a, pkg.TarGzip)
+ }, pkg.NewTar(pkg.NewDecompress(a, pkg.Gzip))
}),
)
s.DropCaches(s.Arch(), s.Flags())