Documentation
¶
Overview ¶
Package pack implements specd's declarative scaffold packs: named bundles of files (with template variables) that `specd init`/`new` can apply to seed a spec directory. Pack manifests are pure data — parsing explicitly rejects any hook/exec/command/script field and any file path that could escape the project root — so applying a pack can only ever write files, never run code. Built-in packs are embedded at build time via go:embed and validated through the same ParsePack path as user-supplied manifests.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Pack ¶
type Pack struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Files []PackFile `json:"files"`
Vars map[string]string `json:"vars,omitempty"`
}
Pack is a declarative spec-scaffold bundle. The manifest is pure data: a set of files to write plus template variables. It is intentionally NOT executable — there is no hook, command, or script field — so resolving and applying a pack carries no code-execution surface.
func BuiltinPack ¶
BuiltinPack returns the embedded pack with the given name, or an error if no such built-in exists.
func BuiltinPacks ¶
BuiltinPacks returns the embedded built-in packs, sorted by name. A malformed embedded pack is a build/test failure surfaced here, not a silent skip.
func ParsePack ¶
ParsePack decodes and validates a pack manifest. It fails closed: unknown fields (including any executable-hook key), unsafe file paths, and missing required fields are all rejected with no partial Pack returned.
func ResolvePack ¶
ResolvePack resolves a pack reference to a validated Pack. A bare name (no scheme) resolves against the embedded built-in packs. An http(s) URL is a remote pack and MUST carry a pinned sha256 digest: the bytes are downloaded, hashed, and compared before parsing — on any mismatch nothing is returned (fail-closed), mirroring `specd update`'s SHA256SUMS contract. Either way the manifest passes ParsePack, so a resolved pack is always declarative-only and path-safe.
func VerifyAndParsePack ¶
VerifyAndParsePack checks raw bytes against a pinned SHA256 digest and, only on an exact match, parses them as a pack manifest. A digest mismatch returns an error and no pack — the caller must write nothing. Exposed for direct testing of the fail-closed contract without a network round-trip.
type PackApplyResult ¶
PackApplyResult reports what an ApplyPack call did. Written lists the repo-relative paths created; Skipped lists declared files that already existed (only populated when force is false).
func ApplyPack ¶
func ApplyPack(root string, p *Pack, force bool) (PackApplyResult, error)
ApplyPack writes a resolved pack's files under root. It is transactional: it pre-checks the whole plan (paths are re-validated, collisions detected) before writing anything, and if any write fails it removes every file it created in this call — so a failed apply never leaves a partial scaffold. Without force, a pre-existing target is a hard error (fail-closed) rather than an overwrite, keeping the apply all-or-nothing. Vars are substituted into file content.