From c2d900ec74e03e9c782cfe7b7ce06ff62cda6601 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 29 Aug 2026 18:58:06 +0900 Subject: pkg: move from internal Closes #43. Signed-off-by: Ophestra --- pkg/file.go | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 pkg/file.go (limited to 'pkg/file.go') diff --git a/pkg/file.go b/pkg/file.go new file mode 100644 index 00000000..14467153 --- /dev/null +++ b/pkg/file.go @@ -0,0 +1,100 @@ +package pkg + +import ( + "bytes" + "crypto/sha512" + "fmt" + "io" +) + +// A fileArtifact is an [Artifact] that cures into data known ahead of time. +type fileArtifact []byte + +var _ KnownChecksum = new(fileArtifact) +var _ CuresExempt = new(fileArtifact) +var _ RevisionArtifact = new(fileArtifact) + +// fileArtifactNamed embeds fileArtifact alongside a caller-supplied name. +type fileArtifactNamed struct { + fileArtifact + // Caller-supplied user-facing reporting name. + name string +} + +var _ fmt.Stringer = new(fileArtifactNamed) +var _ KnownChecksum = new(fileArtifactNamed) + +// String returns the caller-supplied reporting name. +func (a *fileArtifactNamed) String() string { return a.name } + +// Params writes the caller-supplied reporting name and the file body. +func (a *fileArtifactNamed) Params(ctx *IContext) { + ctx.WriteString(a.name) + ctx.Write(a.fileArtifact) +} + +// NewFile returns a [FileArtifact] that cures into a caller-supplied byte slice. +// +// Caller must not modify data after NewFile returns. +func NewFile(name string, data []byte) FileArtifact { + f := fileArtifact(data) + if name != "" { + return &fileArtifactNamed{f, name} + } + return &f +} + +// Kind returns the hardcoded [Kind] constant. +func (*fileArtifact) Kind() Kind { return KindFile } + +// Params writes an empty string and the file body. +func (a *fileArtifact) Params(ctx *IContext) { + ctx.WriteString("") + ctx.Write(*a) +} + +func init() { + register(KindFile, func(r *IRReader) Artifact { + name := r.ReadString() + data := r.ReadStringBytes() + if _, ok := r.Finalise(); !ok { + panic(ErrExpectedChecksum) + } + return NewFile(name, data) + }) +} + +// Inputs returns a nil slice. +func (*fileArtifact) Inputs() []Artifact { return nil } + +// IsExclusive returns false: Cure returns a prepopulated buffer. +func (*fileArtifact) IsExclusive() bool { return false } + +// Checksum computes and returns the checksum of caller-supplied data. +func (a *fileArtifact) Checksum() Checksum { + h := sha512.New384() + h.Write(*a) + 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. +func (a *fileArtifact) Cure(*RContext) (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader(*a)), nil +} + +// CuresExempt exempts the cheap [KindFile] implementation. +func (*fileArtifact) CuresExempt() {} -- cgit v1.3.1