Documentation
¶
Index ¶
- Constants
- func CheckVersionConstraint(constraint, resolved string) (bool, error)
- func Compose(sol *solution.Solution, bundleRoot string, opts ...ComposeOption) (*solution.Solution, error)
- func ExtractDeduplicatedBundle(manifest *BundleManifest, destDir string, ...) error
- func MergePluginDefaults(sol *solution.Solution)
- func ValidatePlugins(sol *solution.Solution) error
- func VendorFileNameFromRef(ref string, info catalog.ArtifactInfo) string
- func WriteLockFile(path string, lf *LockFile) error
- type BundleFileEntry
- type BundleManifest
- type BundlePluginEntry
- type CatalogFetcher
- type CatalogRefEntry
- type ComposeOption
- type DedupeFileBlob
- type DedupeOption
- type DedupeResult
- type DiscoverOption
- type DiscoveryResult
- type DiscoverySource
- type DynamicPathWarning
- type FileEntry
- type IgnoreChecker
- type LockDependency
- type LockFile
- type LockPlugin
- type ScafctlIgnore
- type TarOption
- type VendorOptions
- type VendorResult
Constants ¶
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 )
const ( // LockFileVersion is the current lock file format version. LockFileVersion = 1 // DefaultLockFileName is the default lock file name. DefaultLockFileName = "solution.lock" )
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 )
const (
// VendorDirName is the directory name within the bundle for vendored artifacts.
VendorDirName = ".scafctl/vendor"
)
Variables ¶
This section is empty.
Functions ¶
func CheckVersionConstraint ¶
CheckVersionConstraint checks if a resolved version satisfies a version constraint.
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.
- bundle.include: unioned (deduplicated).
- Circular compose references are detected and rejected.
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 MergePluginDefaults ¶
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 ValidatePlugins ¶
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 WriteLockFile ¶
WriteLockFile serializes and writes the lock file to the given path.
Types ¶
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)
}
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 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 )
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 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 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 LockDependency ¶
type LockDependency struct {
// Ref is the original catalog 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"`
// 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.
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 LoadLockFile ¶
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.
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 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 TarOption ¶
type TarOption func(*tarConfig)
TarOption configures tar creation behavior.
func WithMaxBundleSize ¶
WithMaxBundleSize sets the maximum total size for the bundle.
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 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.