feature

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package feature fetches Dev Container Features referenced by a devcontainer.json, along with the metadata carried by the "devcontainer.metadata" label of the image it names, and merges the properties they contribute into the parsed configuration, producing the effective configuration defined by the Dev Container specification's merge logic (see https://containers.dev/implementors/spec/#merge-logic).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Merge

func Merge(ctx context.Context, f *Fetcher, fsRoot *os.Root, configDir string, localEnv map[string]string, root *hujson.Value) error

Merge resolves everything a devcontainer.json inherits and folds it into root in place, following the Dev Container specification's merge logic. The inputs are the Features referenced under "/features" (and, recursively, those their "dependsOn" names) and the metadata carried by the configuration's base image, resolved by [baseImageContributors]. Compose files named by "dockerComposeFile" are interpolated with localEnv as the environment (see [loadComposeService]).

Every node Merge adds carries the byte offset of the key it was pulled in through, so findings on merged-in properties point at that reference. Any fetch or parse failure, or a dependency cycle, is returned as an error.

Types

type Dependency

type Dependency struct {
	Ref     string
	Options optionValue
}

Dependency is one entry of a Feature's "dependsOn": the reference of a required Feature and the options it is requested with. The options make an otherwise identical dependency a distinct contributor for install ordering.

type Fetcher

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

Fetcher retrieves Feature metadata for the references found in devcontainer.json files, and the Dev Container metadata carried by container image labels. It caches every result in memory for the lifetime of the Fetcher, including failures, so a reference shared by several files is fetched at most once per run.

func NewFetcher

func NewFetcher(opts ...Option) *Fetcher

NewFetcher returns a Fetcher with a default HTTP client, configured by the given options.

func (*Fetcher) Fetch

func (f *Fetcher) Fetch(ctx context.Context, raw string, fsRoot *os.Root, configDir string) (*Metadata, error)

Fetch retrieves the metadata of the Feature referenced by raw. fsRoot and configDir together locate the devcontainer.json that references the Feature (fsRoot is discovery.ConfigFile.Root and configDir is the directory of its Path): fsRoot is the boundary every filesystem access is confined to, and configDir is the referencing file's directory within it. A local reference is resolved by joining configDir with it and reading the result through fsRoot, so the resolution cannot escape fsRoot's boundary. fsRoot and configDir are unused for an OCI or tarball reference.

func (*Fetcher) FetchDockerfileMetadata added in v0.3.0

func (f *Fetcher) FetchDockerfileMetadata(ctx context.Context, dockerfile []byte, buildArgs, labels map[string]string, target string) ([]*Metadata, error)

FetchDockerfileMetadata computes the Dev Container metadata entries the image built from dockerfile would carry in its "devcontainer.metadata" label: the value set by its own LABEL instructions, or, absent one, the value inherited from the base image its FROM names, whose config is fetched through the registry. A "devcontainer.metadata" entry in labels overrides the Dockerfile's own, as "docker build --label" does. It returns no entries, and no error, when the built image would carry no such label.

func (*Fetcher) FetchImageMetadata added in v0.3.0

func (f *Fetcher) FetchImageMetadata(ctx context.Context, raw string) ([]*Metadata, error)

FetchImageMetadata retrieves the Dev Container metadata entries carried by the "devcontainer.metadata" label of the container image referenced by raw, in label order. It returns no entries when the image carries no such label; a label that is not valid JSON is ignored, matching the reference implementation. The underlying image config, including a failure, is cached for the lifetime of the Fetcher; the cheap label parse is redone on each call.

type Metadata

type Metadata struct {
	// ID is the Feature's declared identifier, or "" when it declares none (as image-metadata
	// entries do; see [contributor.hasID]).
	ID      string
	Version string
	// DependsOn lists the Features this Feature depends on, in declaration order. Dependencies are
	// installed before the Feature and contribute properties of their own.
	DependsOn []Dependency
	// InstallsAfter lists Feature IDs this Feature prefers to be installed after. Unlike DependsOn
	// it does not pull in new Features; it only influences installation order.
	InstallsAfter []string
	// Aliases are the Feature's identifiers, its ID followed by any legacy IDs. They match a renamed
	// Feature named by another Feature's "installsAfter" or by "overrideFeatureInstallOrder".
	Aliases []string
	// Digest is the resolved manifest digest of an OCI Feature (e.g. "sha256:..."). It is empty for
	// local and tarball Features. It distinguishes otherwise identical references for install order.
	Digest string
	// Root is the parsed devcontainer-feature.json. It is the source of truth for the properties
	// the Feature contributes (e.g. Root.Find("/containerEnv")); values grafted from it are
	// stripped of comments and re-anchored into the target document at merge time.
	Root hujson.Value
}

Metadata is the declaration of one fetched Feature: the content of its devcontainer-feature.json.

type Option added in v0.3.0

type Option func(*Fetcher)

Option configures a Fetcher created by NewFetcher.

func WithLogWriter added in v0.3.0

func WithLogWriter(w io.Writer) Option

WithLogWriter announces each remote download (an OCI artifact or a tarball) as a human-readable line on w. Without it a Fetcher downloads silently.

type Ref

type Ref struct {
	// Raw is the reference exactly as written.
	Raw string
	// Kind identifies how the reference locates the Feature.
	Kind RefKind
	// OCI holds the parsed registry reference (registry, repository, and the tag or digest) for a
	// KindOCI reference; it is the zero value for other kinds.
	OCI registry.Reference
}

Ref is a parsed Feature reference, as used for the keys of the "features" object in a devcontainer.json.

func ParseRef

func ParseRef(raw string) (Ref, error)

ParseRef parses a Feature reference. Relative paths ("./..." or "../...") are local Features, HTTPS URIs are tarball Features, and everything else is parsed as an OCI reference of the form "registry/repository[:tag][@digest]".

type RefKind

type RefKind int

RefKind identifies how a Feature reference locates the Feature.

const (
	// KindOCI is a reference to a Feature distributed as an OCI artifact, e.g.
	// "ghcr.io/devcontainers/features/node:1".
	KindOCI RefKind = iota
	// KindTarball is a direct HTTPS URI to a Feature tarball.
	KindTarball
	// KindLocal is a relative path to a Feature directory next to the devcontainer.json.
	KindLocal
)

Jump to

Keyboard shortcuts

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