bundler

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// BundleManifestVersion1 is the original tar-based bundle format.
	BundleManifestVersion1 = 1

	// BundleManifestVersion2 is the content-addressable deduplicated format.
	BundleManifestVersion2 = 2

	// DefaultDedupeThreshold is the minimum file size for individual layer extraction.
	// Files smaller than this are grouped into a single tar layer.
	DefaultDedupeThreshold int64 = 4 * 1024 // 4 KB
)
View Source
const (
	// LockFileVersion is the current lock file format version.
	LockFileVersion = 1

	// DefaultLockFileName is the default lock file name.
	DefaultLockFileName = "solution.lock"
)
View Source
const (
	// BundleManifestPath is the path within the tar archive for the bundle manifest.
	BundleManifestPath = ".scafctl/bundle-manifest.json"

	// DefaultMaxBundleSize is the default maximum total size of bundled files (50 MB).
	DefaultMaxBundleSize int64 = 50 * 1024 * 1024
)
View Source
const (
	// VendorDirName is the directory name within the bundle for vendored artifacts.
	VendorDirName = ".scafctl/vendor"
)

Variables

This section is empty.

Functions

func CheckPluginUpdates added in v0.5.0

func CheckPluginUpdates(lock *LockFile) []string

CheckPluginUpdates returns formatted status messages for plugin dependencies.

func CheckVersionConstraint

func CheckVersionConstraint(constraint, resolved string) (bool, error)

CheckVersionConstraint checks if a resolved version satisfies a version constraint.

func CleanBuildCache added in v0.3.0

func CleanBuildCache(cacheDir string) error

CleanBuildCache removes all entries from the build cache directory.

func Compose

func Compose(sol *solution.Solution, bundleRoot string, opts ...ComposeOption) (*solution.Solution, error)

Compose loads and merges all composed files referenced by the solution. The composed files are expected to contain partial YAML with spec.resolvers, spec.workflow.actions, and/or bundle.include sections.

Returns a new Solution with all parts merged. The original is not modified. bundleRoot is the directory containing the root solution YAML — composed file paths are resolved relative to it.

Merge rules:

  • Resolvers: merged by name. Duplicate resolver names across files are rejected.
  • Actions: merged by name. Duplicate action names across files are rejected.
  • Finally actions: merged by name. Same duplicate rules apply.
  • Testing.Cases: merged by name. Duplicate test names across files are rejected.
  • Testing.Config: skipBuiltins (true-wins for bool, union for lists), env (last wins), setup/cleanup (appended in compose-file order).
  • bundle.include: unioned (deduplicated).
  • Circular compose references are detected and rejected.

func ComputeBuildFingerprint added in v0.3.0

func ComputeBuildFingerprint(solutionContent []byte, bundleRoot string, discoveredFiles []FileEntry, plugins []BundlePluginEntry, lockDigest string) (string, error)

ComputeBuildFingerprint computes a SHA-256 fingerprint from the solution content, discovered file contents, plugin versions, and lock file digest.

The fingerprint changes when any input to the build changes, enabling incremental builds by skipping the entire pipeline when inputs are unchanged.

func CopyFile added in v0.5.0

func CopyFile(src, dst string) error

CopyFile copies a file from src to dst, creating parent directories as needed.

func CountBuildCacheEntries added in v0.3.0

func CountBuildCacheEntries(cacheDir string) int

CountBuildCacheEntries returns the number of cache entries in the directory.

func CountChanges added in v0.5.0

func CountChanges(result *DiffResult) string

CountChanges returns a human-readable summary of all changes in a DiffResult.

func ExtractActionFiles added in v0.5.0

func ExtractActionFiles(a *actionpkg.Action) []string

ExtractActionFiles traces files referenced by an action.

func ExtractDeduplicatedBundle

func ExtractDeduplicatedBundle(manifest *BundleManifest, destDir string, layerFetcher func(layer int) ([]byte, error)) error

ExtractDeduplicatedBundle extracts a version 2 bundle from individual OCI layers. layerFetcher returns the raw bytes of a layer by its 0-based index.

func ExtractLiteralFromInputs added in v0.5.0

func ExtractLiteralFromInputs(inputs map[string]*spec.ValueRef, key string) string

ExtractLiteralFromInputs returns the literal string value for the given key, or empty string.

func ExtractProviderStepFiles added in v0.5.0

func ExtractProviderStepFiles(provider string, inputs map[string]*spec.ValueRef) []string

ExtractProviderStepFiles returns file paths referenced by a provider step's inputs.

func ExtractResolverName added in v0.5.0

func ExtractResolverName(name string) string

ExtractResolverName strips any selector from a resolver reference, e.g. "myResolver.result" → "myResolver".

func ExtractVersionFromRef added in v0.5.0

func ExtractVersionFromRef(ref string) string

ExtractVersionFromRef extracts the version part after the last '@' in a catalog reference. Returns "latest" if no '@' is found.

func FetchAndExtract added in v0.5.0

func FetchAndExtract(ctx context.Context, cat *catalog.LocalCatalog, refStr string) (*ExtractedArtifact, *BundleManifest, error)

FetchAndExtract fetches a solution artifact from the catalog, parses it, and extracts any bundle data into a temporary directory.

func FormatSize added in v0.5.0

func FormatSize(b int64) string

FormatSize returns a human-readable file size string.

func IsLocalFilePath added in v0.5.0

func IsLocalFilePath(path string) bool

IsLocalFilePath returns true if path looks like a local relative file path (not a URL, registry reference, or absolute path).

func MapKeys added in v0.5.0

func MapKeys[V any](m map[string]V) map[string]bool

MapKeys converts a map with string keys to a map[string]bool.

func MatchGlob added in v0.5.0

func MatchGlob(pattern, path string) bool

MatchGlob tests whether a path matches a glob pattern. Uses filepath.Match for single-level patterns and a simple recursive check for **.

func MergePluginDefaults

func MergePluginDefaults(sol *solution.Solution)

MergePluginDefaults shallow-merges plugin default inputs beneath inline provider inputs in the solution's resolvers and actions. Inline inputs always win. This should be called before DAG construction so that the DAG sees the merged result.

func ShouldIgnore added in v0.5.0

func ShouldIgnore(path string, patterns []string) bool

ShouldIgnore returns true if the given path matches any of the provided glob patterns.

func SplitNameVersion added in v0.5.0

func SplitNameVersion(s string) (string, string)

SplitNameVersion splits a "name@version" string into name and version parts.

func TraceResolverDeps added in v0.5.0

func TraceResolverDeps(name string, sol *solution.Solution, visited map[string]bool) []string

TraceResolverDeps performs static analysis on a resolver to find referenced files, following rslvr: bindings transitively.

func TruncateDigest added in v0.5.0

func TruncateDigest(digest string) string

TruncateDigest truncates a digest string for display purposes.

func ValidatePlugins

func ValidatePlugins(sol *solution.Solution) error

ValidatePlugins validates all plugin declarations in a solution's bundle. Returns an error if any plugin has invalid name, kind, or version constraint.

func VendorFileNameFromRef

func VendorFileNameFromRef(ref string, info catalog.ArtifactInfo) string

VendorFileNameFromRef generates the file name for a vendored artifact (exported).

func WriteBuildCache added in v0.3.0

func WriteBuildCache(cacheDir, fingerprint string, entry *BuildCacheEntry) error

WriteBuildCache writes a build cache entry for the given fingerprint.

func WriteLockFile

func WriteLockFile(path string, lf *LockFile) error

WriteLockFile serializes and writes the lock file to the given path.

Types

type BuildCacheEntry added in v0.3.0

type BuildCacheEntry struct {
	// Fingerprint is the SHA-256 hash of all build inputs.
	Fingerprint string `json:"fingerprint"`

	// ArtifactName is the name of the built artifact.
	ArtifactName string `json:"artifactName"`

	// ArtifactVersion is the version of the built artifact.
	ArtifactVersion string `json:"artifactVersion"`

	// ArtifactDigest is the OCI digest of the stored artifact.
	ArtifactDigest string `json:"artifactDigest"`

	// CreatedAt is when this cache entry was written.
	CreatedAt time.Time `json:"createdAt"`

	// InputFiles records the number of input files that contributed to the fingerprint.
	InputFiles int `json:"inputFiles"`
}

BuildCacheEntry records a successful build result for cache hit detection.

func CheckBuildCache added in v0.3.0

func CheckBuildCache(cacheDir, fingerprint string) (*BuildCacheEntry, bool)

CheckBuildCache checks if a build cache entry exists for the given fingerprint. Returns the cache entry and true if found, nil and false if not.

type BundleFileEntry

type BundleFileEntry struct {
	// Path is the file's path relative to the bundle root.
	Path string `json:"path"`
	// Size is the file size in bytes.
	Size int64 `json:"size"`
	// Digest is the SHA-256 content digest.
	Digest string `json:"digest"`
	// Layer is the OCI layer index for this file (version 2 only).
	// In version 1 manifests, this is omitted (all files are in the tar layer).
	Layer int `json:"layer,omitempty"`
}

BundleFileEntry describes a single file in the bundle.

type BundleManifest

type BundleManifest struct {
	// Version is the manifest format version.
	Version int `json:"version"`
	// Root is the bundle root directory (always ".").
	Root string `json:"root"`
	// Files lists all bundled files with their paths, sizes, and content digests.
	Files []BundleFileEntry `json:"files"`
	// Plugins lists plugin dependencies (informational, recorded from bundle.plugins).
	Plugins []BundlePluginEntry `json:"plugins,omitempty"`
}

BundleManifest describes the contents of a bundle tar archive.

func CreateBundleTar

func CreateBundleTar(bundleRoot string, files []FileEntry, plugins []BundlePluginEntry, opts ...TarOption) ([]byte, *BundleManifest, error)

CreateBundleTar creates a tar archive containing the discovered files and a bundle manifest. Returns the tar bytes and the manifest.

func ExtractBundleTar

func ExtractBundleTar(tarData []byte, destDir string) (*BundleManifest, error)

ExtractBundleTar extracts a bundle tar archive to a destination directory. Returns the bundle manifest.

func ExtractBundleTarFromReader

func ExtractBundleTarFromReader(r io.Reader, destDir string) (*BundleManifest, error)

ExtractBundleTarFromReader extracts a tar archive from a reader to a destination directory.

type BundlePluginEntry

type BundlePluginEntry struct {
	// Name is the plugin's catalog reference.
	Name string `json:"name"`
	// Kind is the plugin type (provider, auth-handler).
	Kind string `json:"kind"`
	// Version is the semver constraint.
	Version string `json:"version"`
}

BundlePluginEntry describes a plugin dependency in the bundle manifest.

func PluginsToBundleEntries

func PluginsToBundleEntries(plugins []solution.PluginDependency) []BundlePluginEntry

PluginsToBundleEntries converts solution plugin dependencies to bundle manifest entries.

type CatalogFetcher

type CatalogFetcher interface {
	// FetchSolution retrieves a solution by name[@version] and returns
	// the content bytes, the resolved reference info, and any error.
	FetchSolution(ctx context.Context, nameWithVersion string) (content []byte, info catalog.ArtifactInfo, err error)

	// ListSolutions returns all available versions for a named solution artifact.
	// Used for resolving semver constraints to the best matching version.
	ListSolutions(ctx context.Context, name string) ([]catalog.ArtifactInfo, error)
}

CatalogFetcher fetches solution content from a catalog by reference.

type CatalogRefEntry

type CatalogRefEntry struct {
	// Ref is the original catalog reference (e.g., "deploy-to-k8s@2.0.0").
	Ref string
	// VendorPath is the path within the bundle where the vendored artifact is stored.
	VendorPath string
}

CatalogRefEntry represents a catalog dependency to vendor.

type ComposeOption

type ComposeOption func(*composeConfig)

ComposeOption configures Compose behavior.

func WithReadFileFunc

func WithReadFileFunc(fn func(string) ([]byte, error)) ComposeOption

WithReadFileFunc overrides the function used to read composed files. Useful for testing without touching the filesystem.

type DedupeFileBlob

type DedupeFileBlob struct {
	// RelPath is the file path relative to the bundle root.
	RelPath string
	// Content is the file's raw bytes.
	Content []byte
	// Digest is the SHA-256 content digest.
	Digest string
	// Size is the file size in bytes.
	Size int64
	// Layer is the 0-based layer index in the OCI manifest (set after partitioning).
	Layer int
}

DedupeFileBlob represents a single file prepared for content-addressable storage.

type DedupeOption

type DedupeOption func(*dedupeConfig)

DedupeOption configures deduplication behavior.

func WithDedupeMaxSize

func WithDedupeMaxSize(size int64) DedupeOption

WithDedupeMaxSize sets the maximum total size of all bundled files.

func WithDedupeReadFileFunc

func WithDedupeReadFileFunc(fn func(string) ([]byte, error)) DedupeOption

WithDedupeReadFileFunc overrides the file reading function for testing.

func WithDedupeThreshold

func WithDedupeThreshold(size int64) DedupeOption

WithDedupeThreshold sets the minimum file size for individual blob layers. Files smaller than this threshold are grouped into a combined tar layer.

type DedupeResult

type DedupeResult struct {
	// Manifest is the bundle manifest (version 2).
	Manifest *BundleManifest
	// ManifestJSON is the serialized manifest.
	ManifestJSON []byte
	// LargeBlobs are individual file blobs stored as separate OCI layers.
	LargeBlobs []DedupeFileBlob
	// SmallBlobsTar is a tar archive of files below the dedup threshold.
	// May be nil if there are no small files.
	SmallBlobsTar []byte
	// TotalSize is the sum of all file sizes.
	TotalSize int64
}

DedupeResult contains the output of content-addressable deduplication.

func CreateDeduplicatedBundle

func CreateDeduplicatedBundle(bundleRoot string, files []FileEntry, plugins []BundlePluginEntry, opts ...DedupeOption) (*DedupeResult, error)

CreateDeduplicatedBundle prepares files for content-addressable OCI storage. Large files (>= threshold) become individual layers; small files are tarred together. Returns a DedupeResult containing the manifest and all blobs to push.

type DiffResult added in v0.5.0

type DiffResult struct {
	RefA     string        `json:"refA" yaml:"refA"`
	RefB     string        `json:"refB" yaml:"refB"`
	Solution *SolutionDiff `json:"solution,omitempty" yaml:"solution,omitempty"`
	Files    *FilesDiff    `json:"files,omitempty" yaml:"files,omitempty"`
	Vendored *VendoredDiff `json:"vendoredDependencies,omitempty" yaml:"vendoredDependencies,omitempty"`
	Plugins  *PluginsDiff  `json:"plugins,omitempty" yaml:"plugins,omitempty"`
}

DiffResult is the structured output of a bundle diff, describing all changes between two bundled solution versions including solution YAML, files, vendored dependencies, and plugin changes.

type DiffSets added in v0.5.0

type DiffSets struct {
	Added    []string `json:"added,omitempty" yaml:"added,omitempty"`
	Removed  []string `json:"removed,omitempty" yaml:"removed,omitempty"`
	Modified []string `json:"modified,omitempty" yaml:"modified,omitempty"`
}

DiffSets contains added/removed/modified name lists.

func ComputeDiffSets added in v0.5.0

func ComputeDiffSets(a, b map[string]bool) DiffSets

ComputeDiffSets computes added/removed/modified sets from two maps.

func ComputeDiffSetsFromBool added in v0.5.0

func ComputeDiffSetsFromBool(a, b map[string]bool) DiffSets

ComputeDiffSetsFromBool computes added/removed/modified sets from two bool maps.

type DiscoverOption

type DiscoverOption func(*discoverConfig)

DiscoverOption configures DiscoverFiles behavior.

func WithDiscoverReadFileFunc

func WithDiscoverReadFileFunc(fn func(string) ([]byte, error)) DiscoverOption

WithDiscoverReadFileFunc overrides os.ReadFile for testing.

func WithIgnoreChecker

func WithIgnoreChecker(ic IgnoreChecker) DiscoverOption

WithIgnoreChecker sets a custom ignore checker for file exclusion.

func WithStatFunc

func WithStatFunc(fn func(string) (os.FileInfo, error)) DiscoverOption

WithStatFunc overrides os.Stat for testing.

func WithWalkDirFunc

func WithWalkDirFunc(fn func(string, filepath.WalkFunc) error) DiscoverOption

WithWalkDirFunc overrides filepath.Walk for testing.

type DiscoveryResult

type DiscoveryResult struct {
	// LocalFiles are local file paths relative to the bundle root.
	LocalFiles []FileEntry
	// CatalogRefs are catalog references to vendor.
	CatalogRefs []CatalogRefEntry
}

DiscoveryResult contains all files and dependencies discovered during analysis.

func DiscoverFiles

func DiscoverFiles(sol *solution.Solution, bundleRoot string, opts ...DiscoverOption) (*DiscoveryResult, error)

DiscoverFiles performs static analysis on a parsed (and composed) solution to find local file references and catalog references, then combines them with explicit bundle includes.

Returns deduplicated lists of local files and catalog references.

type DiscoverySource

type DiscoverySource int

DiscoverySource indicates how a file was discovered for bundling.

const (
	// StaticAnalysis means the file was discovered by walking provider inputs.
	StaticAnalysis DiscoverySource = iota
	// ExplicitInclude means the file was declared in bundle.include.
	ExplicitInclude
	// TestInclude means the file was referenced in spec.testing.cases[*].files.
	TestInclude
)

func (DiscoverySource) String

func (d DiscoverySource) String() string

String returns a human-readable label for the discovery source.

type DynamicPathWarning

type DynamicPathWarning struct {
	// Location describes where in the solution the dynamic path was found
	// (e.g., "resolver 'templatePath'").
	Location string
	// Kind is the type of dynamic reference ("expr", "tmpl", "rslvr").
	Kind string
	// Expression is the dynamic expression value.
	Expression string
}

DynamicPathWarning describes a provider input that uses a dynamic path (CEL expression, Go template, or resolver binding) which cannot be statically analyzed for file bundling.

func DetectDynamicPaths

func DetectDynamicPaths(sol *solution.Solution) []DynamicPathWarning

DetectDynamicPaths scans a solution for provider inputs that use dynamic paths (CEL, Go templates, resolver bindings) in file-related fields. These paths cannot be statically analyzed and should be covered by bundle.include patterns.

type ExtractedArtifact added in v0.5.0

type ExtractedArtifact struct {
	Sol    *solution.Solution
	TmpDir string
}

ExtractedArtifact holds a fetched and parsed solution with its temporary directory.

func (*ExtractedArtifact) Cleanup added in v0.5.0

func (e *ExtractedArtifact) Cleanup()

Cleanup removes the temporary directory if one was created.

type FileDiffEntry added in v0.5.0

type FileDiffEntry struct {
	Path string `json:"path" yaml:"path"`
	Size int64  `json:"size,omitempty" yaml:"size,omitempty"`
}

FileDiffEntry describes a changed file.

type FileEntry

type FileEntry struct {
	// RelPath is the path relative to the bundle root.
	RelPath string
	// Source indicates how the file was discovered.
	Source DiscoverySource
}

FileEntry represents a local file to be bundled.

type FilesDiff added in v0.5.0

type FilesDiff struct {
	Added    []FileDiffEntry `json:"added,omitempty" yaml:"added,omitempty"`
	Removed  []FileDiffEntry `json:"removed,omitempty" yaml:"removed,omitempty"`
	Modified []FileDiffEntry `json:"modified,omitempty" yaml:"modified,omitempty"`
}

FilesDiff holds changes to bundled files.

func DiffFiles added in v0.5.0

func DiffFiles(a, b *BundleManifest, ignore []string) *FilesDiff

DiffFiles compares two bundle manifests and returns the file differences.

type IgnoreChecker

type IgnoreChecker interface {
	// IsIgnored returns true if the given relative path should be excluded.
	IsIgnored(relPath string) bool
}

IgnoreChecker determines whether a file path should be excluded from bundling.

func LoadScafctlIgnore

func LoadScafctlIgnore(bundleRoot string) (IgnoreChecker, error)

LoadScafctlIgnore reads a .scafctlignore file and returns an IgnoreChecker. If the file does not exist, a no-op checker is returned (nothing is ignored).

func LoadScafctlIgnoreFrom

func LoadScafctlIgnoreFrom(path string) (IgnoreChecker, error)

LoadScafctlIgnoreFrom reads ignore patterns from a specific file path.

func ParseIgnorePatterns

func ParseIgnorePatterns(patterns []string) IgnoreChecker

ParseIgnorePatterns creates an IgnoreChecker from a list of pattern strings. Useful for testing.

type LocalCatalogFetcherAdapter added in v0.5.0

type LocalCatalogFetcherAdapter struct {
	// Catalog is the local catalog instance.
	Catalog *catalog.LocalCatalog
}

LocalCatalogFetcherAdapter adapts a catalog.LocalCatalog to the CatalogFetcher interface.

func (*LocalCatalogFetcherAdapter) FetchSolution added in v0.5.0

func (a *LocalCatalogFetcherAdapter) FetchSolution(ctx context.Context, nameWithVersion string) ([]byte, catalog.ArtifactInfo, error)

FetchSolution retrieves a solution by name[@version] from the local catalog.

func (*LocalCatalogFetcherAdapter) ListSolutions added in v0.5.0

func (a *LocalCatalogFetcherAdapter) ListSolutions(ctx context.Context, name string) ([]catalog.ArtifactInfo, error)

ListSolutions returns all available versions of a named solution artifact from the local catalog.

type LockDependency

type LockDependency struct {
	// Ref is the original catalog reference (e.g., "deploy-to-k8s@2.0.0" or "deploy-to-k8s@^1.5.0").
	Ref string `json:"ref" yaml:"ref" doc:"Original catalog reference" maxLength:"255" example:"deploy-to-k8s@2.0.0"`

	// ResolvedVersion is the exact semver version that was resolved and vendored.
	// For exact refs like "deploy-to-k8s@2.0.0" this equals the version in Ref.
	// For constraint refs like "deploy-to-k8s@^1.5.0" this is the resolved version (e.g., "1.5.2").
	ResolvedVersion string `json:"resolvedVersion,omitempty" yaml:"resolvedVersion,omitempty" doc:"Exact resolved version" maxLength:"50" example:"1.5.2"`

	// Constraint is the original version constraint, if any (e.g., "^1.5.0", ">=2.0.0").
	// Empty for exact version references.
	Constraint string `json:"constraint,omitempty" yaml:"constraint,omitempty" doc:"Original version constraint" maxLength:"100" example:"^1.5.0"`

	// Digest is the SHA-256 content digest of the vendored file.
	Digest string `json:"digest" yaml:"digest" doc:"SHA-256 content digest" maxLength:"128" example:"sha256:abc123..."`

	// ResolvedFrom is the catalog name from which the dependency was fetched.
	ResolvedFrom string `json:"resolvedFrom" yaml:"resolvedFrom" doc:"Source catalog name" maxLength:"255" example:"company-catalog"`

	// VendoredAt is the path relative to the bundle root where the file is stored.
	VendoredAt string `` /* 139-byte string literal not displayed */
}

LockDependency records metadata about a vendored catalog dependency.

func FilterDependencies added in v0.5.0

func FilterDependencies(deps []LockDependency, filter []string) ([]LockDependency, error)

FilterDependencies returns only the dependencies whose refs match the filter list. Returns an error if any filter value is not found in the deps slice.

type LockFile

type LockFile struct {
	// Version is the lock file format version.
	Version int `json:"version" yaml:"version" doc:"Lock file format version" example:"1"`

	// Dependencies lists vendored solution dependencies with their digests.
	Dependencies []LockDependency `json:"dependencies,omitempty" yaml:"dependencies,omitempty" doc:"Vendored solution dependencies" maxItems:"1000"`

	// Plugins lists vendored plugin dependencies with their digests.
	Plugins []LockPlugin `json:"plugins,omitempty" yaml:"plugins,omitempty" doc:"Vendored plugin dependencies" maxItems:"100"`
}

LockFile represents the lock file that records vendored dependency state. It enables reproducible builds by replaying exact versions and digests.

func ApplyUpdates added in v0.5.0

func ApplyUpdates(entries []UpdateEntry, existingLock *LockFile, bundleRoot string, lockOnly bool, lgr logr.Logger) (*LockFile, error)

ApplyUpdates writes vendored files for entries that need updating and builds a new LockFile reflecting the updates.

func LoadLockFile

func LoadLockFile(path string) (*LockFile, error)

LoadLockFile reads and parses a lock file from the given path. Returns nil without error if the file does not exist.

func (*LockFile) FindDependency

func (lf *LockFile) FindDependency(ref string) *LockDependency

FindDependency returns the lock entry for the given ref, or nil if not found. It first tries an exact Ref match, then falls back to matching by name (the part before @) to support constraint-based refs where the constraint string may differ between runs.

func (*LockFile) FindDependencyByName added in v0.3.0

func (lf *LockFile) FindDependencyByName(name string) *LockDependency

FindDependencyByName returns the lock entry matching the artifact name, or nil.

func (*LockFile) FindPlugin

func (lf *LockFile) FindPlugin(name, kind string) *LockPlugin

FindPlugin returns the lock entry for a plugin by name and kind, or nil if not found.

type LockPlugin

type LockPlugin struct {
	// Name is the plugin name.
	Name string `json:"name" yaml:"name" doc:"Plugin name" maxLength:"100" example:"azure-provider"`

	// Kind is the plugin kind (e.g., "provider", "auth-handler").
	Kind string `json:"kind" yaml:"kind" doc:"Plugin kind" maxLength:"50" example:"provider"`

	// Version is the resolved version string.
	Version string `json:"version" yaml:"version" doc:"Resolved version" maxLength:"50" example:"1.2.3"`

	// Digest is the SHA-256 content digest.
	Digest string `json:"digest" yaml:"digest" doc:"SHA-256 content digest" maxLength:"128" example:"sha256:abc123..."`

	// ResolvedFrom is the source registry or catalog.
	ResolvedFrom string `json:"resolvedFrom" yaml:"resolvedFrom" doc:"Source registry or catalog" maxLength:"255" example:"plugins.example.com"`
}

LockPlugin records metadata about a vendored plugin dependency.

type PluginDiffEntry added in v0.5.0

type PluginDiffEntry struct {
	Name        string `json:"name" yaml:"name"`
	VersionFrom string `json:"versionFrom,omitempty" yaml:"versionFrom,omitempty"`
	VersionTo   string `json:"versionTo,omitempty" yaml:"versionTo,omitempty"`
}

PluginDiffEntry describes a plugin change.

type PluginResolver added in v0.3.0

type PluginResolver interface {
	// ResolvePlugin resolves a plugin by name and kind, returning its metadata.
	// If version constraint is non-empty, the resolver should pick the best
	// matching version. Returns the artifact info with the resolved version and digest.
	ResolvePlugin(ctx context.Context, name string, kind catalog.ArtifactKind, versionConstraint string) (catalog.ArtifactInfo, error)
}

PluginResolver resolves plugin artifacts from the catalog.

type PluginsDiff added in v0.5.0

type PluginsDiff struct {
	Added    []PluginDiffEntry `json:"added,omitempty" yaml:"added,omitempty"`
	Removed  []PluginDiffEntry `json:"removed,omitempty" yaml:"removed,omitempty"`
	Modified []PluginDiffEntry `json:"modified,omitempty" yaml:"modified,omitempty"`
}

PluginsDiff lists plugin dependency changes.

func DiffPlugins added in v0.5.0

func DiffPlugins(a, b *BundleManifest) *PluginsDiff

DiffPlugins compares plugin dependencies between two bundle manifests.

type ScafctlIgnore

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

ScafctlIgnore implements IgnoreChecker using .scafctlignore rules. It supports a subset of .gitignore syntax:

  • Blank lines and lines starting with # are ignored.
  • Patterns are matched against relative paths using filepath.Match.
  • A trailing / matches only directories (not supported yet — treated as prefix match).
  • A leading / anchors to the bundle root.
  • ** is supported via doublestar matching.

func (*ScafctlIgnore) IsIgnored

func (si *ScafctlIgnore) IsIgnored(relPath string) bool

IsIgnored returns true if the relative path matches any ignore pattern.

type SolutionDiff added in v0.5.0

type SolutionDiff struct {
	Resolvers DiffSets `json:"resolvers,omitempty" yaml:"resolvers,omitempty"`
	Actions   DiffSets `json:"actions,omitempty" yaml:"actions,omitempty"`
}

SolutionDiff holds changes to the solution structure.

func DiffSolutions added in v0.5.0

func DiffSolutions(a, b *solution.Solution) *SolutionDiff

DiffSolutions compares two solution structures and returns the differences.

type TarOption

type TarOption func(*tarConfig)

TarOption configures tar creation behavior.

func WithMaxBundleSize

func WithMaxBundleSize(size int64) TarOption

WithMaxBundleSize sets the maximum total size for the bundle.

func WithTarReadFileFunc

func WithTarReadFileFunc(fn func(string) ([]byte, error)) TarOption

WithTarReadFileFunc overrides the file reading function for testing.

type UpdateEntry added in v0.5.0

type UpdateEntry struct {
	// Ref is the original lock file reference (e.g., "deploy-to-k8s@2.0.0").
	Ref string `json:"ref" yaml:"ref" doc:"Original catalog reference" maxLength:"255" example:"deploy-to-k8s@2.0.0"`
	// LockedVersion is the version from the existing lock file.
	LockedVersion string `json:"lockedVersion" yaml:"lockedVersion" doc:"Version from the existing lock file" maxLength:"50" example:"2.0.0"`
	// LockedDigest is the digest from the existing lock file.
	LockedDigest string `json:"lockedDigest" yaml:"lockedDigest" doc:"Digest from the existing lock file" maxLength:"128" example:"sha256:abc123..."`
	// LatestVersion is the latest resolved version from catalog.
	LatestVersion string `json:"latestVersion" yaml:"latestVersion" doc:"Latest resolved version from catalog" maxLength:"50" example:"2.1.0"`
	// LatestDigest is the digest of the latest content.
	LatestDigest string `json:"latestDigest" yaml:"latestDigest" doc:"Digest of the latest content" maxLength:"128" example:"sha256:def456..."`
	// Content is the raw bytes of the latest fetched content.
	Content []byte `json:"-" yaml:"-"`
	// Info is the artifact info from the catalog resolution.
	Info catalog.ArtifactInfo `json:"-" yaml:"-"`
	// NeedsUpdate indicates whether this entry needs updating.
	NeedsUpdate bool `json:"needsUpdate" yaml:"needsUpdate" doc:"Whether this entry needs updating"`
}

UpdateEntry tracks the state of a single dependency during a vendor update check.

func CheckForUpdates added in v0.5.0

func CheckForUpdates(ctx context.Context, deps []LockDependency, fetcher CatalogFetcher, lgr logr.Logger) ([]UpdateEntry, error)

CheckForUpdates re-resolves each dependency against the catalog and returns UpdateEntry values indicating which entries need updating.

type VendorOptions

type VendorOptions struct {
	// BundleRoot is the root directory of the solution bundle.
	BundleRoot string
	// VendorDir is the directory to store vendored artifacts.
	VendorDir string
	// LockPath is the path to the lock file.
	LockPath string
	// CatalogFetcher fetches artifacts from catalogs by name[@version].
	// If nil, vendoring will fail when catalog refs are discovered.
	CatalogFetcher CatalogFetcher
}

VendorOptions configures the vendoring process.

type VendorPluginsOptions added in v0.3.0

type VendorPluginsOptions struct {
	// PluginResolver resolves plugins from the catalog.
	// If nil, plugin vendoring is skipped.
	PluginResolver PluginResolver
}

VendorPluginsOptions configures the plugin vendoring process.

type VendorPluginsResult added in v0.3.0

type VendorPluginsResult struct {
	// ResolvedPlugins contains the lock entries for resolved plugins.
	ResolvedPlugins []LockPlugin
}

VendorPluginsResult describes the outcome of plugin vendoring.

func VendorPlugins added in v0.3.0

func VendorPlugins(ctx context.Context, plugins []solution.PluginDependency, existingLock *LockFile, opts VendorPluginsOptions) (*VendorPluginsResult, error)

VendorPlugins resolves plugin dependencies against the catalog and records them in the lock file for reproducible builds. Unlike solution vendoring, plugins are not downloaded during build — only their versions and digests are pinned. The runtime fetches plugin binaries as needed.

type VendorResult

type VendorResult struct {
	// VendoredFiles contains relative paths (from bundle root) to vendored files.
	VendoredFiles []string
	// Lock is the updated lock file content.
	Lock *LockFile
}

VendorResult describes the outcome of a vendoring operation.

func VendorDependencies

func VendorDependencies(ctx context.Context, sol *solution.Solution, refs []CatalogRefEntry, opts VendorOptions) (*VendorResult, error)

VendorDependencies fetches catalog dependencies, stores them locally, rewrites source references in the solution, and writes a lock file.

type VendorUpdateOptions added in v0.5.0

type VendorUpdateOptions struct {
	// SolutionPath is the path to the solution YAML file.
	SolutionPath string `json:"solutionPath" yaml:"solutionPath" doc:"Path to the solution YAML file" maxLength:"500" example:"./solution.yaml"`
	// Dependencies restricts the update to only these dependency refs.
	Dependencies []string `json:"dependencies,omitempty" yaml:"dependencies,omitempty" doc:"Filter to these dependency refs" maxItems:"100"`
	// DryRun previews changes without writing.
	DryRun bool `json:"dryRun" yaml:"dryRun" doc:"Preview without writing"`
	// LockOnly updates the lock file without re-vendoring files.
	LockOnly bool `json:"lockOnly" yaml:"lockOnly" doc:"Update lock file only"`
	// PreRelease includes pre-release versions when resolving.
	PreRelease bool `json:"preRelease" yaml:"preRelease" doc:"Include pre-release versions"`
}

VendorUpdateOptions contains the domain-level options for a vendor update operation.

type VendorUpdateResult added in v0.5.0

type VendorUpdateResult struct {
	// Entries are the resolved update entries for each dependency.
	Entries []UpdateEntry `json:"entries" yaml:"entries" doc:"Resolved update entries" maxItems:"1000"`
	// UpdateCount is the number of entries that need updating.
	UpdateCount int `json:"updateCount" yaml:"updateCount" doc:"Number of entries needing update" example:"3"`
	// Messages collects informational messages produced during the operation.
	Messages []string `json:"messages,omitempty" yaml:"messages,omitempty" doc:"Informational messages" maxItems:"500"`
	// PluginMessages collects plugin status messages.
	PluginMessages []string `json:"pluginMessages,omitempty" yaml:"pluginMessages,omitempty" doc:"Plugin status messages" maxItems:"100"`
}

VendorUpdateResult describes the outcome of a vendor update check.

type VendoredDiff added in v0.5.0

type VendoredDiff struct {
	Added    []VendoredEntry   `json:"added,omitempty" yaml:"added,omitempty"`
	Removed  []VendoredEntry   `json:"removed,omitempty" yaml:"removed,omitempty"`
	Upgraded []VendoredUpgrade `json:"upgraded,omitempty" yaml:"upgraded,omitempty"`
}

VendoredDiff lists vendored dependency changes.

func DiffVendored added in v0.5.0

func DiffVendored(a, b *BundleManifest) *VendoredDiff

DiffVendored compares vendored dependencies between two bundle manifests.

type VendoredEntry added in v0.5.0

type VendoredEntry struct {
	Name    string `json:"name" yaml:"name"`
	Version string `json:"version,omitempty" yaml:"version,omitempty"`
}

VendoredEntry describes a vendored dependency.

type VendoredUpgrade added in v0.5.0

type VendoredUpgrade struct {
	Name string `json:"name" yaml:"name"`
	From string `json:"from" yaml:"from"`
	To   string `json:"to" yaml:"to"`
}

VendoredUpgrade describes a vendored dependency version change.

type VerifyError added in v0.5.0

type VerifyError struct {
	// Path is the file or dependency path that failed verification.
	Path string `json:"path" yaml:"path" doc:"File or dependency path" maxLength:"500"`
	// Reason describes why the verification failed.
	Reason string `json:"reason" yaml:"reason" doc:"Failure reason" maxLength:"1000"`
}

VerifyError describes a single verification failure.

type VerifyResult added in v0.5.0

type VerifyResult struct {
	// Errors are hard failures — missing files or dependencies.
	Errors []VerifyError `json:"errors,omitempty" yaml:"errors,omitempty" doc:"Hard verification failures" maxItems:"10000"`
	// Warnings are non-fatal issues (e.g., empty glob patterns, missing bundle).
	Warnings []string `json:"warnings,omitempty" yaml:"warnings,omitempty" doc:"Non-fatal verification issues" maxItems:"10000"`
	// Successes are items that passed verification.
	Successes []string `json:"successes,omitempty" yaml:"successes,omitempty" doc:"Items that passed verification" maxItems:"10000"`
}

VerifyResult holds the outcome of bundle verification.

func VerifyBundle added in v0.5.0

func VerifyBundle(ctx context.Context, sol *solution.Solution, bundleData []byte, lgr logr.Logger) (*VerifyResult, error)

VerifyBundle performs completeness verification of a solution bundle.

It checks:

  • Static file paths referenced by providers exist in the bundle
  • Glob patterns in bundle.include match at least one bundled file
  • Vendored catalog dependencies are present
  • Plugin entries are recorded

When bundleData is empty the function checks whether a bundle would be needed and returns warnings if local files or catalog dependencies are detected.

func (*VerifyResult) Passed added in v0.5.0

func (r *VerifyResult) Passed() bool

Passed returns true when there are no errors.

Jump to

Keyboard shortcuts

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