pkg

package
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 8, 2026 License: MIT Imports: 39 Imported by: 0

Documentation

Overview

Package pkg provides utilities for packaging software.

Index

Constants

View Source
const (
	// ExecTimeoutDefault replaces out of range [NewExec] timeout values.
	ExecTimeoutDefault = 15 * time.Minute
	// ExecTimeoutMax is the arbitrary upper bound of [NewExec] timeout.
	ExecTimeoutMax = 48 * time.Hour
)
View Source
const (
	// TarUncompressed denotes an uncompressed tarball.
	TarUncompressed = iota
	// TarGzip denotes a tarball compressed via [gzip].
	TarGzip
	// TarBzip2 denotes a tarball compressed via [bzip2].
	TarBzip2
)

Variables

View Source
var (
	// ErrIRValues is returned for an [Artifact] with too many parameter values.
	ErrIRValues = errors.New("artifact has too many IR parameter values")

	// ErrIRDepend is returned for an [Artifact] with too many dependencies.
	ErrIRDepend = errors.New("artifact has too many dependencies")

	// ErrAlreadyFinalised is returned when attempting to use an [IRReader] that
	// has already been finalised.
	ErrAlreadyFinalised = errors.New("reader has already finalised")
)
View Source
var (
	// ErrUnexpectedChecksum is returned by a [IRReadFunc] that does not expect
	// a checksum but received one in [IRKindEnd] anyway.
	ErrUnexpectedChecksum = errors.New("checksum specified on unsupported artifact")
	// ErrExpectedChecksum is returned by a [IRReadFunc] that expects a checksum
	// but did not receive one in [IRKindEnd].
	ErrExpectedChecksum = errors.New("checksum required but not specified")
)
View Source
var AbsWork = fhs.AbsRoot.Append("work/")

AbsWork is the container pathname [CureContext.GetWorkDir] is mounted on.

View Source
var ErrDependencyDepleted = errors.New("reading past end of dependencies")

ErrDependencyDepleted is returned when attempting to advance to the next unstructured dependency when there are none left.

View Source
var ErrInsecurePath = errors.New("insecure file path")

ErrInsecurePath is returned by FlatEntry.Decode if validation is requested and a nonlocal path is encountered in the stream.

View Source
var ErrRemainingIR = errors.New("implementation did not consume final value")

ErrRemainingIR is returned for a IRReadFunc that failed to call IRReader.Finalise before returning.

Functions

func Decode

func Decode(buf *Checksum, s string) (err error)

Decode is abbreviation for base64.URLEncoding.Decode(checksum[:], []byte(s)).

func Encode

func Encode(checksum Checksum) string

Encode is abbreviation for base64.URLEncoding.EncodeToString(checksum[:]).

func Flatten

func Flatten(fsys fs.FS, root string, w io.Writer) (n int, err error)

Flatten writes a deterministic representation of the contents of fsys to w. The resulting data can be hashed to produce a deterministic checksum for the directory.

func Flood

func Flood(a Artifact) iter.Seq[Artifact]

Flood returns an iterator over the dependency tree of an Artifact.

func HashDir

func HashDir(buf *Checksum, pathname *check.Absolute) error

HashDir returns a checksum produced by hashing the result of Flatten.

func HashFS

func HashFS(buf *Checksum, fsys fs.FS, root string) error

HashFS returns a checksum produced by hashing the result of Flatten.

func Register added in v0.3.5

func Register(k Kind, f IRReadFunc)

Register records the IRReadFunc of a custom implementation of Artifact under the specified Kind. Expecting to be used only during initialization, it panics if the mapping between Kind and IRReadFunc is not a bijection, or the specified Kind is below KindCustomOffset.

Register is not safe for concurrent use. Register must not be called after the first instance of Cache has been opened.

Types

type Artifact

type Artifact interface {
	// Kind returns the [Kind] of artifact. This is usually unique to the
	// concrete type but two functionally identical implementations of
	// [Artifact] is allowed to return the same [Kind] value.
	Kind() Kind

	// Params writes deterministic values describing [Artifact]. Implementations
	// must guarantee that these values are unique among differing instances
	// of the same implementation with identical dependencies and conveys enough
	// information to create another instance of [Artifact] identical to the
	// instance emitting these values. The new instance created via [IRReadFunc]
	// from these values must then produce identical IR values.
	//
	// Result must remain identical across multiple invocations.
	Params(ctx *IContext)

	// Dependencies returns a slice of [Artifact] that the current instance
	// depends on to produce its contents.
	//
	// Callers must not modify the retuned slice.
	//
	// Result must remain identical across multiple invocations.
	Dependencies() []Artifact

	// IsExclusive returns whether the [Artifact] is exclusive. Exclusive
	// artifacts might not run in parallel with each other, and are still
	// subject to the cures limit.
	//
	// Some implementations may saturate the CPU for a nontrivial amount of
	// time. Curing multiple such implementations simultaneously causes
	// significant CPU scheduler overhead. An exclusive artifact will generally
	// not be cured alongside another exclusive artifact, thus alleviating this
	// overhead.
	//
	// Note that [Cache] reserves the right to still cure exclusive
	// artifacts concurrently as this is not a synchronisation primitive but
	// an optimisation one. Implementations are forbidden from accessing global
	// state regardless of exclusivity.
	//
	// Result must remain identical across multiple invocations.
	IsExclusive() bool
}

An Artifact is a read-only reference to a piece of data that may be created deterministically but might not currently be available in memory or on the filesystem.

func NewExec

func NewExec(
	name string,
	checksum *Checksum,
	timeout time.Duration,
	exclusive bool,

	dir *check.Absolute,
	env []string,
	pathname *check.Absolute,
	args []string,

	paths ...ExecPath,
) Artifact

NewExec returns a new Artifact that executes the program path in a container with specified paths bind mounted read-only in order. A private instance of /proc and /dev is made available to the container.

The working and temporary directories are both created and mounted writable on AbsWork and fhs.AbsTmp respectively. If one or more paths target AbsWork, the final entry is set up as a writable overlay mount on /work for which the upperdir is the host side work directory. In this configuration, the W field is ignored, and the program must avoid causing whiteout files to be created. Cure fails if upperdir ends up with entries other than directory, regular or symlink.

If checksum is non-nil, the resulting Artifact implements KnownChecksum and its container runs in the host net namespace.

The container is allowed to run for the specified duration before the initial process and all processes originating from it is terminated. A zero or negative timeout value is equivalent tp ExecTimeoutDefault, a timeout value greater than ExecTimeoutMax is equivalent to ExecTimeoutMax.

The user-facing name and exclusivity value are not accessible from the container and does not affect curing outcome. Because of this, it is omitted from parameter data for computing identifier.

func NewHTTPGetTar

func NewHTTPGetTar(
	hc *http.Client,
	url string,
	checksum Checksum,
	compression uint32,
) Artifact

NewHTTPGetTar is abbreviation for NewHTTPGet passed to NewTar.

func NewTar

func NewTar(a Artifact, compression uint32) Artifact

NewTar returns a new Artifact backed by the supplied Artifact and compression method. The source Artifact must be compatible with TContext.Open.

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache is a support layer that implementations of Artifact can use to store cured Artifact data in a content addressed fashion.

func Open

func Open(
	ctx context.Context,
	msg message.Msg,
	cures int,
	base *check.Absolute,
) (*Cache, error)

Open returns the address of a newly opened instance of Cache.

Concurrent cures of a FloodArtifact dependency graph is limited to the caller-supplied value, however direct calls to Cache.Cure is not subject to this limitation.

A cures value of 0 or lower is equivalent to the value returned by runtime.NumCPU.

A successful call to Open guarantees exclusive access to the on-filesystem cache for the resulting instance of Cache. The Cache.Close method cancels and waits for pending cures on Cache before releasing this lock and must be called once the Cache is no longer needed.

func (*Cache) Close

func (c *Cache) Close()

Close cancels all pending cures and waits for them to clean up.

func (*Cache) Cure

func (c *Cache) Cure(a Artifact) (
	pathname *check.Absolute,
	checksum unique.Handle[Checksum],
	err error,
)

Cure cures the Artifact and returns its pathname and Checksum. Direct calls to Cure are not subject to the cures limit.

func (*Cache) Encode added in v0.3.5

func (c *Cache) Encode(w io.Writer, a Artifact) (err error)

Encode writes a deterministic, efficient representation of a to w and returns the first non-nil error encountered while writing to w.

func (*Cache) EncodeAll added in v0.3.5

func (c *Cache) EncodeAll(w io.Writer, a Artifact) error

EncodeAll writes a self-describing IR stream of a to w and returns the first non-nil error encountered while writing to w.

EncodeAll tries to avoid encoding the same Artifact more than once, however it will fail to do so if they do not compare equal by value, as that will require buffering and greatly reduce performance. It is therefore up to the caller to avoid causing dependencies to be represented in a way such that two equivalent artifacts do not compare equal. While an IR stream with repeated artifacts is valid, it is somewhat inefficient, and the reference IRDecoder implementation produces a warning for it.

Note that while EncodeAll makes use of the ident free list, it does not use the ident cache, nor does it contribute identifiers it computes back to the ident cache. Because of this, multiple invocations of EncodeAll will have similar cost and does not amortise when combined with a call to Cure.

func (*Cache) Ident

func (c *Cache) Ident(a Artifact) unique.Handle[ID]

Ident returns the identifier of an Artifact.

func (*Cache) IsStrict

func (c *Cache) IsStrict() bool

IsStrict returns whether the Cache strictly verifies checksums.

func (*Cache) NewDecoder added in v0.3.5

func (c *Cache) NewDecoder(r io.Reader) *IRDecoder

NewDecoder returns a new IRDecoder that reads from the io.Reader.

func (*Cache) Scrub

func (c *Cache) Scrub(checks int) error

Scrub frees internal in-memory identifier to content pair cache, verifies all cached artifacts against their checksums, checks for dangling identifier symlinks and removes them if found.

This method is not safe for concurrent use with any other method.

func (*Cache) SetStrict

func (c *Cache) SetStrict(strict bool)

SetStrict sets whether the Cache strictly verifies checksums, even when the implementation promises to validate them internally. This significantly reduces performance and is not recommended outside of testing.

This method is not safe for concurrent use with any other method.

func (*Cache) SetThreshold

func (c *Cache) SetThreshold(threshold uintptr)

SetThreshold imposes a maximum size on the dependency graph, checked on every call to Cure. The zero value disables this check entirely.

This method is not safe for concurrent use with any other method.

type Checksum

type Checksum = [sha512.Size384]byte

A Checksum is a SHA-384 checksum computed for a cured Artifact.

func MustDecode

func MustDecode(s string) (checksum Checksum)

MustDecode decodes a string representation of Checksum and panics if there is a decoding error or the resulting data is too short.

type ChecksumMismatchError

type ChecksumMismatchError struct {
	// Actual and expected checksums.
	Got, Want Checksum
}

A ChecksumMismatchError describes an Artifact with unexpected content.

func (*ChecksumMismatchError) Error

func (e *ChecksumMismatchError) Error() string

type CureError

type CureError struct {
	Ident unique.Handle[ID]
	Err   error
}

CureError wraps a non-nil error returned attempting to cure an Artifact.

func (*CureError) Error

func (e *CureError) Error() string

Error returns the error message from the underlying Err.

func (*CureError) Unwrap

func (e *CureError) Unwrap() error

Unwrap returns the underlying error.

type DanglingIdentError added in v0.3.5

type DanglingIdentError unique.Handle[ID]

DanglingIdentError is an identifier in a IRKindIdent value that was never described in the IR stream before it was encountered.

func (DanglingIdentError) Error added in v0.3.5

func (e DanglingIdentError) Error() string

type DependencyCureError

type DependencyCureError []*CureError

A DependencyCureError wraps errors returned while curing dependencies.

func (*DependencyCureError) Error

func (e *DependencyCureError) Error() string

Error returns a user-facing multiline error message.

func (*DependencyCureError) Unwrap

func (e *DependencyCureError) Unwrap() []error

Unwrap returns a deduplicated slice of underlying errors.

type DependencyError

type DependencyError struct{ A Artifact }

DependencyError refers to an artifact with a dependency tree larger than the threshold specified by a previous call to Cache.SetThreshold.

func (DependencyError) Error

func (e DependencyError) Error() string

type DirScanner

type DirScanner struct {
	// contains filtered or unexported fields
}

DirScanner provides an efficient interface for reading a stream of encoded FlatEntry. Successive calls to the Scan method will step through the entries in the stream.

func NewDirScanner

func NewDirScanner(r io.Reader, validate bool) *DirScanner

NewDirScanner returns the address of a new instance of DirScanner reading from r. The caller must no longer read from r after this function returns.

func (*DirScanner) Entry

func (s *DirScanner) Entry() *FlatEntry

Entry returns the address to the FlatEntry value storing the last result.

func (*DirScanner) Err

func (s *DirScanner) Err() error

Err returns the first non-EOF I/O error.

func (*DirScanner) Scan

func (s *DirScanner) Scan() bool

Scan advances to the next FlatEntry.

type DisallowedTypeflagError

type DisallowedTypeflagError byte

A DisallowedTypeflagError describes a disallowed typeflag encountered while unpacking a tarball.

func (DisallowedTypeflagError) Error

func (e DisallowedTypeflagError) Error() string

type ExecPath

type ExecPath struct {
	// Pathname in the container mount namespace.
	P *check.Absolute
	// Artifacts to mount on the pathname, must contain at least one [Artifact].
	// If there are multiple entries or W is true, P is set up as an overlay
	// mount, and entries of A must not implement [FileArtifact].
	A []Artifact
	// Whether to make the mount point writable via the temp directory.
	W bool
}

ExecPath is a slice of Artifact and the check.Absolute pathname to make it available at under in the container.

func MustPath

func MustPath(pathname string, writable bool, a ...Artifact) ExecPath

MustPath is like Path, but takes a string pathname via check.MustAbs.

func Path

func Path(pathname *check.Absolute, writable bool, a ...Artifact) ExecPath

Path returns a populated ExecPath.

type FContext

type FContext struct {
	TContext
	// contains filtered or unexported fields
}

FContext is passed to [FloodArtifact.Cure] and provides information and methods required for curing the FloodArtifact.

Methods of FContext are safe for concurrent use. FContext is valid until [FloodArtifact.Cure] returns.

func (*FContext) GetArtifact

func (f *FContext) GetArtifact(a Artifact) (
	pathname *check.Absolute,
	checksum unique.Handle[Checksum],
)

GetArtifact returns the identifier pathname and checksum of an Artifact. Calling Pathname with an Artifact not part of the slice returned by [Artifact.Dependencies] panics.

type FileArtifact

type FileArtifact interface {
	// Cure returns [io.ReadCloser] of the full contents of [FileArtifact]. If
	// [FileArtifact] implements [KnownChecksum], Cure is responsible for
	// validating any data it produces and must return [ChecksumMismatchError]
	// if validation fails. This error is conventionally returned during the
	// first call to Close, but may be returned during any call to Read before
	// EOF, or by Cure itself.
	//
	// Callers are responsible for closing the resulting [io.ReadCloser].
	//
	// Result must remain identical across multiple invocations.
	Cure(r *RContext) (io.ReadCloser, error)

	Artifact
}

FileArtifact refers to an Artifact backed by a single file.

func NewFile

func NewFile(name string, data []byte) FileArtifact

NewFile returns a FileArtifact that cures into a caller-supplied byte slice.

Caller must not modify data after NewFile returns.

func NewHTTPGet

func NewHTTPGet(
	c *http.Client,
	url string,
	checksum Checksum,
) FileArtifact

NewHTTPGet returns a new FileArtifact backed by the supplied client. A GET request is set up for url. If c is nil, http.DefaultClient is used instead.

type FlatEntry

type FlatEntry struct {
	Mode fs.FileMode // file mode bits
	Path string      // pathname of the file
	Data []byte      // file content or symlink destination
}

FlatEntry is a directory entry to be encoded for Flatten.

func (*FlatEntry) Decode

func (ent *FlatEntry) Decode(r io.Reader, validate bool) (n int, err error)

Decode decodes the entry from its representation produced by Encode.

func (*FlatEntry) Encode

func (ent *FlatEntry) Encode(w io.Writer) (n int, err error)

Encode encodes the entry for transmission or hashing.

type FloodArtifact

type FloodArtifact interface {
	// Cure cures the current [Artifact] to the working directory obtained via
	// [TContext.GetWorkDir] embedded in [FContext].
	//
	// Implementations must not retain c.
	Cure(f *FContext) (err error)

	Artifact
}

FloodArtifact refers to an Artifact requiring its entire dependency graph to be cured prior to curing itself.

type IContext

type IContext struct {
	// contains filtered or unexported fields
}

IContext is passed to [Artifact.Params] and provides methods for writing values to the IR writer. It does not expose the underlying io.Writer.

IContext is valid until [Artifact.Params] returns.

func (*IContext) Unwrap

func (i *IContext) Unwrap() context.Context

Unwrap returns the underlying context.Context.

func (*IContext) Write added in v0.3.5

func (i *IContext) Write(p []byte)

Write writes p as a string value to the IR.

func (*IContext) WriteIdent

func (i *IContext) WriteIdent(a Artifact)

WriteIdent writes the identifier of Artifact to the IR. The behaviour of WriteIdent is not defined for an Artifact not part of the slice returned by [Artifact.Dependencies].

func (*IContext) WriteString added in v0.3.5

func (i *IContext) WriteString(s string)

WriteString writes s as a string value to the IR.

func (*IContext) WriteUint32 added in v0.3.5

func (i *IContext) WriteUint32(v uint32)

WriteUint32 writes a uint32 value to the IR.

type ID

type ID Checksum

An ID is a unique identifier returned by [Artifact.ID]. This value must be deterministically determined ahead of time.

type IRDecoder added in v0.3.5

type IRDecoder struct {
	// contains filtered or unexported fields
}

IRDecoder decodes Artifact from an IR stream. The stream is read to EOF and the final Artifact is returned. Previous artifacts may be looked up by their identifier.

An Artifact may appear more than once in the same IR stream. A repeating Artifact generates a warning via Cache and will appear if verbose logging is enabled. Artifacts may only depend on artifacts previously described in the IR stream.

Methods of IRDecoder are not safe for concurrent use.

func (*IRDecoder) Decode added in v0.3.5

func (d *IRDecoder) Decode() (a Artifact, err error)

Decode consumes the IR stream to EOF and returns the final Artifact. After Decode returns, Lookup is available and Decode must not be called again.

func (*IRDecoder) Lookup added in v0.3.5

func (d *IRDecoder) Lookup(id unique.Handle[ID]) (a Artifact, ok bool)

Lookup looks up an Artifact described by the IR stream by its identifier.

type IREndFlag added in v0.3.5

type IREndFlag uint32

IREndFlag is ancillary data encoded in the header of an IRKindEnd value and specifies the presence of optional fields in the remaining IRKindEnd data. Order of present fields is the order of their corresponding constants defined below.

const (
	// IREndKnownChecksum denotes a [KnownChecksum] artifact. For an [IRKindEnd]
	// value with this flag set, the remaining data contains the [Checksum].
	IREndKnownChecksum IREndFlag = 1 << iota
)

type IRKindError added in v0.3.5

type IRKindError struct {
	Got, Want IRValueKind
	Ancillary uint32
}

IRKindError describes an attempt to read an IR value of unexpected kind.

func (*IRKindError) Error added in v0.3.5

func (e *IRKindError) Error() string

type IRReadFunc added in v0.3.5

type IRReadFunc func(r *IRReader) Artifact

IRReadFunc reads IR values written by [Artifact.Params] to produce an instance of Artifact identical to the one to produce these values.

type IRReader added in v0.3.5

type IRReader struct {
	// contains filtered or unexported fields
}

IRReader provides methods to decode the IR wire format and read values from the reader embedded in the underlying IRDecoder. It is deliberately impossible to obtain the IRValueKind of the next value, and callers must never recover from panics in any read method.

It is the responsibility of the caller to call Finalise after all IR values have been read. Failure to call Finalise causes the resulting Artifact to be rejected with ErrRemainingIR.

For an Artifact expected to have dependencies, the caller must consume all dependencies by calling Next until all dependencies are depleted, or call DiscardAll to explicitly discard them and rely on values encoded as IRKindIdent instead. Failure to consume all unstructured dependencies causes the resulting Artifact to be rejected with MissedDependencyError.

Requesting the value of an unstructured dependency not yet described in the IR stream via Next, or reading an IRKindIdent value not part of unstructured dependencies via ReadIdent may cause the resulting Artifact to be rejected with DanglingIdentError, however either method may return a non-nil Artifact implementation of unspecified value.

func (*IRReader) DiscardAll added in v0.3.5

func (ir *IRReader) DiscardAll()

DiscardAll discards all unstructured dependencies. This is useful to implementations that encode dependencies as IRKindIdent which are read back via ReadIdent.

func (*IRReader) Finalise added in v0.3.5

func (ir *IRReader) Finalise() (checksum unique.Handle[Checksum], ok bool)

Finalise reads the final IRKindEnd value and marks r as finalised. Methods of r are invalid upon entry into Finalise. If a Checksum is available via IREndKnownChecksum, its handle is returned and the caller must store its value in the resulting Artifact.

func (*IRReader) Next added in v0.3.5

func (ir *IRReader) Next() Artifact

Next returns the next unstructured dependency.

func (*IRReader) ReadIdent added in v0.3.5

func (ir *IRReader) ReadIdent() Artifact

ReadIdent reads the next value as IRKindIdent.

func (*IRReader) ReadString added in v0.3.5

func (ir *IRReader) ReadString() string

ReadString reads the next value as IRKindString.

func (*IRReader) ReadStringBytes added in v0.3.5

func (ir *IRReader) ReadStringBytes() []byte

ReadStringBytes reads the next value as IRKindString but returns it as a byte slice instead.

func (*IRReader) ReadUint32 added in v0.3.5

func (ir *IRReader) ReadUint32() uint32

ReadUint32 reads the next value as IRKindUint32.

type IRStringError added in v0.3.5

type IRStringError string

IRStringError is a string value too big to encode in IR.

func (IRStringError) Error added in v0.3.5

func (IRStringError) Error() string

type IRValueKind added in v0.3.5

type IRValueKind uint32

IRValueKind denotes the kind of encoded value.

const (
	// IRKindEnd denotes the end of the current parameters stream. The ancillary
	// value is interpreted as [IREndFlag].
	IRKindEnd IRValueKind = iota
	// IRKindIdent denotes the identifier of a dependency [Artifact]. The
	// ancillary value is reserved for future use.
	IRKindIdent
	// IRKindUint32 denotes an inlined uint32 value.
	IRKindUint32
	// IRKindString denotes a string with its true length encoded in header
	// ancillary data. Its wire length is always aligned to 8 byte boundary.
	IRKindString
)

func (IRValueKind) String added in v0.3.5

func (k IRValueKind) String() string

String returns a user-facing name of k.

type InvalidArtifactError

type InvalidArtifactError ID

InvalidArtifactError describes an artifact that does not implement a supported Cure method.

func (InvalidArtifactError) Error

func (e InvalidArtifactError) Error() string

type InvalidFileModeError

type InvalidFileModeError fs.FileMode

InvalidFileModeError describes a [FloodArtifact.Cure] or [TrivialArtifact.Cure] that did not result in a regular file or directory located at the work pathname.

func (InvalidFileModeError) Error

func (e InvalidFileModeError) Error() string

Error returns a constant string.

type InvalidKindError added in v0.3.5

type InvalidKindError Kind

InvalidKindError is an unregistered Kind value.

func (InvalidKindError) Error added in v0.3.5

func (e InvalidKindError) Error() string

type InvalidLookupError

type InvalidLookupError ID

InvalidLookupError is the identifier of non-dependency Artifact looked up via [FContext.Pathname] by a misbehaving Artifact implementation.

func (InvalidLookupError) Error

func (e InvalidLookupError) Error() string

type Kind

type Kind uint64

Kind corresponds to the concrete type of Artifact and is used to create identifier for an Artifact with dependencies.

const (
	// KindHTTPGet is the kind of [Artifact] returned by [NewHTTPGet].
	KindHTTPGet Kind = iota
	// KindTar is the kind of [Artifact] returned by [NewTar].
	KindTar
	// KindExec is the kind of [Artifact] returned by [NewExec].
	KindExec
	// KindExecNet is the kind of [Artifact] returned by [NewExec] but with a
	// non-nil checksum.
	KindExecNet
	// KindFile is the kind of [Artifact] returned by [NewFile].
	KindFile

	// KindCustomOffset is the first [Kind] value reserved for implementations
	// not from this package.
	KindCustomOffset = 1 << 31
)

type KnownChecksum

type KnownChecksum interface {
	// Checksum returns the address of a known checksum.
	//
	// Callers must not modify the [Checksum].
	//
	// Result must remain identical across multiple invocations.
	Checksum() Checksum
}

KnownChecksum is optionally implemented by Artifact for an artifact with output known ahead of time.

type KnownIdent

type KnownIdent interface {
	// ID returns a globally unique identifier referring to the current
	// [Artifact]. This value must be known ahead of time and guaranteed to be
	// unique without having obtained the full contents of the [Artifact].
	ID() ID
}

KnownIdent is optionally implemented by Artifact and is used instead of [Kind.Ident] when it is available.

This is very subtle to use correctly. The implementation must ensure that this value is globally unique, otherwise Cache can enter an inconsistent state. This should not be implemented outside of testing.

type MissedDependencyError added in v0.3.5

type MissedDependencyError int

MissedDependencyError is the number of unstructured dependencies remaining in IRReader that was never requested or explicitly discarded before finalisation.

func (MissedDependencyError) Error added in v0.3.5

func (e MissedDependencyError) Error() string

type NoOutputError

type NoOutputError struct{}

NoOutputError describes a [FloodArtifact.Cure] or [TrivialArtifact.Cure] that did not populate its work pathname despite completing successfully.

func (NoOutputError) Error

func (NoOutputError) Error() string

Error returns a constant string.

func (NoOutputError) Unwrap

func (NoOutputError) Unwrap() error

Unwrap returns os.ErrNotExist.

type RContext

type RContext struct {
	// contains filtered or unexported fields
}

RContext is passed to [FileArtifact.Cure] and provides helper methods useful for curing the FileArtifact.

Methods of RContext are safe for concurrent use. RContext is valid until [FileArtifact.Cure] returns.

func (*RContext) NewMeasuredReader

func (r *RContext) NewMeasuredReader(
	rc io.ReadCloser,
	checksum unique.Handle[Checksum],
) io.ReadCloser

NewMeasuredReader returns an io.ReadCloser implementing behaviour required by FileArtifact. The resulting io.ReadCloser holds a buffer originating from Cache and must be closed to return this buffer.

func (*RContext) Unwrap

func (r *RContext) Unwrap() context.Context

Unwrap returns the underlying context.Context.

type ResponseStatusError

type ResponseStatusError int

ResponseStatusError is returned for a response returned by an http.Client with a status code other than http.StatusOK.

func (ResponseStatusError) Error

func (e ResponseStatusError) Error() string

type ScrubError

type ScrubError struct {
	// Content-addressed entries not matching their checksum. This can happen
	// if an incorrect [FileArtifact] implementation was cured against
	// a non-strict [Cache].
	ChecksumMismatches []ChecksumMismatchError
	// Dangling identifier symlinks. This can happen if the content-addressed
	// entry was removed while scrubbing due to a checksum mismatch.
	DanglingIdentifiers []ID
	// Miscellaneous errors, including [os.ReadDir] on checksum and identifier
	// directories, [Decode] on entry names and [os.RemoveAll] on inconsistent
	// entries.
	Errs map[unique.Handle[string]][]error
}

ScrubError describes the outcome of a Cache.Scrub call where errors were found and removed from the underlying storage of Cache.

func (*ScrubError) Error

func (e *ScrubError) Error() string

Error returns a multi-line representation of ScrubError.

func (*ScrubError) Unwrap

func (e *ScrubError) Unwrap() []error

Unwrap returns a concatenation of ChecksumMismatches and Errs.

type TContext

type TContext struct {
	// contains filtered or unexported fields
}

TContext is passed to [TrivialArtifact.Cure] and provides information and methods required for curing the TrivialArtifact.

Methods of TContext are safe for concurrent use. TContext is valid until [TrivialArtifact.Cure] returns.

func (*TContext) GetMessage

func (t *TContext) GetMessage() message.Msg

GetMessage returns message.Msg held by the underlying Cache.

func (*TContext) GetTempDir

func (t *TContext) GetTempDir() *check.Absolute

GetTempDir returns a pathname which implementations may use as scratch space. A directory is not created automatically, implementations are expected to create it if they wish to use it, using os.MkdirAll.

func (*TContext) GetWorkDir

func (t *TContext) GetWorkDir() *check.Absolute

GetWorkDir returns a pathname to a directory which Artifact is expected to write its output to. This is not the final resting place of the Artifact and this pathname should not be directly referred to in the final contents.

func (*TContext) Open

func (t *TContext) Open(a Artifact) (r io.ReadCloser, err error)

Open tries to open Artifact for reading. If a implements FileArtifact, its reader might be used directly, eliminating the roundtrip to vfs. Otherwise, it must cure into a directory containing a single regular file.

If err is nil, the caller must close the resulting io.ReadCloser and return its error, if any. Failure to read r to EOF may result in a spurious ChecksumMismatchError, or the underlying implementation may block on Close.

func (*TContext) Unwrap

func (t *TContext) Unwrap() context.Context

Unwrap returns the underlying context.Context.

type TrivialArtifact

type TrivialArtifact interface {
	// Cure cures the current [Artifact] to the working directory obtained via
	// [TContext.GetWorkDir].
	//
	// Implementations must not retain c.
	Cure(t *TContext) (err error)

	Artifact
}

TrivialArtifact refers to an Artifact that cures without requiring that any other Artifact is cured before it. Its dependency tree is ignored after computing its identifier.

TrivialArtifact is unable to cure any other Artifact and it cannot access pathnames. This type of Artifact is primarily intended for dependency-less artifacts or direct dependencies that only consists of FileArtifact.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL