Documentation
¶
Overview ¶
Package spec contains types and parsers for the devcontainer specification as documented at https://containers.dev/implementors/json_reference/.
Index ¶
- Constants
- func MigrateLegacyVSCode(data []byte, devPort bool) ([]byte, bool, error)
- func StripJSONC(in []byte) []byte
- func UnmarshalJSONC(data []byte, v any) error
- type Build
- type Command
- type DevContainer
- func (d *DevContainer) BaseImage() string
- func (d *DevContainer) BuildContextDir() (string, error)
- func (d *DevContainer) ComposeFiles() []string
- func (d *DevContainer) DockerfileFile() string
- func (d *DevContainer) DockerfilePath() string
- func (d *DevContainer) Mode() Mode
- func (d *DevContainer) Validate() error
- type Mode
- type OrderedMap
- type StringOrSlice
Constants ¶
const ( ShutdownNone = "none" ShutdownStopContainer = "stopContainer" ShutdownStopCompose = "stopCompose" )
Allowed shutdownAction values per the devcontainer spec. "none" is valid in both modes; "stopContainer" only in single-container mode; "stopCompose" only in compose mode.
Variables ¶
This section is empty.
Functions ¶
func MigrateLegacyVSCode ¶
MigrateLegacyVSCode moves top-level extensions and settings into customizations.vscode, as upstream's updateFromOldProperties does. Extensions append; settings already in customizations win. With devPort, a top-level devPort moves too unless customizations.vscode already has one, as for configurations. It reports whether data changed.
func StripJSONC ¶
StripJSONC removes comments and trailing commas from a JSON-with-comments document, producing a strictly valid JSON byte slice.
Supported JSONC features:
- Line comments (// ...)
- Block comments (/* ... */)
- Trailing commas in objects and arrays
Strings, including escape sequences, are preserved verbatim.
func UnmarshalJSONC ¶
UnmarshalJSONC parses a JSON-with-comments document into v.
Types ¶
type Build ¶
type Build struct {
Dockerfile string `json:"dockerfile,omitempty"`
Context string `json:"context,omitempty"`
Args map[string]string `json:"args,omitempty"`
Target string `json:"target,omitempty"`
CacheFrom StringOrSlice `json:"cacheFrom,omitempty"`
Options []string `json:"options,omitempty"`
}
Build models the inline build object inside devcontainer.json.
type Command ¶
type Command struct {
Shell string // string form
Args []string // array form
Parallel map[string]Command // object form; each value is itself a Command
}
Command models the three forms a devcontainer lifecycle command can take in devcontainer.json:
- String form ("npm install") — runs in a shell.
- Array form (["npm", "install"]) — exec'd directly without a shell.
- Object form ({"server": "npm start", "watch": ["npm", "watch"]}) — multiple named commands run in parallel, each interpreted as string or array per the same rules.
Exactly zero or one of Shell, Args, Parallel will be non-empty for a well-formed value.
func (Command) MarshalJSON ¶
MarshalJSON preserves the string, argv, or parallel-object command form.
func (*Command) UnmarshalJSON ¶
UnmarshalJSON accepts string / []string / object-of-(string|[]string).
type DevContainer ¶
type DevContainer struct {
WaitFor string `json:"waitFor,omitempty"`
UserEnvProbe string `json:"userEnvProbe,omitempty"`
PortsAttributes map[string]any `json:"portsAttributes,omitempty"`
OtherPortsAttributes map[string]any `json:"otherPortsAttributes,omitempty"`
HostRequirements map[string]any `json:"hostRequirements,omitempty"`
Name string `json:"name,omitempty"`
Image string `json:"image,omitempty"`
Dockerfile string `json:"dockerFile,omitempty"`
Build *Build `json:"build,omitempty"`
DockerComposeFile StringOrSlice `json:"dockerComposeFile,omitempty"`
Service string `json:"service,omitempty"`
RunServices []string `json:"runServices,omitempty"`
ShutdownAction string `json:"shutdownAction,omitempty"`
OverrideCommand *bool `json:"overrideCommand,omitempty"`
Features OrderedMap `json:"features,omitempty"`
OverrideFeature []string `json:"overrideFeatureInstallOrder,omitempty"`
RemoteUser string `json:"remoteUser,omitempty"`
ContainerUser string `json:"containerUser,omitempty"`
UpdateRemoteEnv map[string]any `json:"remoteEnv,omitempty"`
ContainerEnv map[string]any `json:"containerEnv,omitempty"`
WorkspaceFolder string `json:"workspaceFolder,omitempty"`
WorkspaceMount string `json:"workspaceMount,omitempty"`
Mounts []any `json:"mounts,omitempty"`
ForwardPorts []any `json:"forwardPorts,omitempty"`
AppPort any `json:"appPort,omitempty"`
UpdateRemoteUserUID *bool `json:"updateRemoteUserUID,omitempty"`
OnCreate Command `json:"onCreateCommand,omitempty"`
UpdateContent Command `json:"updateContentCommand,omitempty"`
PostCreate Command `json:"postCreateCommand,omitempty"`
PostStart Command `json:"postStartCommand,omitempty"`
PostAttach Command `json:"postAttachCommand,omitempty"`
Init *bool `json:"init,omitempty"`
Privileged *bool `json:"privileged,omitempty"`
CapAdd []string `json:"capAdd,omitempty"`
SecurityOpt []string `json:"securityOpt,omitempty"`
RunArgs []string `json:"runArgs,omitempty"`
Customizations map[string]any `json:"customizations,omitempty"`
// Path is the on-disk location the spec was loaded from. Not part of
// the JSON document itself.
Path string `json:"-"`
// Raw retains the original (jsonc-stripped) bytes for round-trip needs.
Raw json.RawMessage `json:"-"`
}
DevContainer is a partial model of the devcontainer.json schema. It covers the fields needed to drive an image build: base image, build context, features, lifecycle hooks, user, and customizations relevant to the VS Code remote experience.
The full spec is much larger; unknown fields are preserved through Raw so callers can pass data through to downstream tooling untouched.
func Load ¶
func Load(path string) (*DevContainer, error)
Load reads and parses a devcontainer.json file (with JSONC support).
func LoadFromWorkspace ¶
func LoadFromWorkspace(workspace string) (*DevContainer, error)
LoadFromWorkspace finds and loads the conventional devcontainer.json from a workspace directory. It checks .devcontainer/devcontainer.json first, then .devcontainer.json.
func (*DevContainer) BaseImage ¶
func (d *DevContainer) BaseImage() string
BaseImage returns the directly-specified image, if any.
func (*DevContainer) BuildContextDir ¶
func (d *DevContainer) BuildContextDir() (string, error)
BuildContextDir resolves the build context directory relative to the devcontainer.json location. Without a context it is the Dockerfile's directory, as in upstream. If the spec uses an `image`, the empty string is returned with no error.
func (*DevContainer) ComposeFiles ¶
func (d *DevContainer) ComposeFiles() []string
ComposeFiles returns the docker-compose file paths declared by the spec, resolved relative to the devcontainer.json directory. Returns nil when the spec is not in compose mode.
func (*DevContainer) DockerfileFile ¶
func (d *DevContainer) DockerfileFile() string
DockerfileFile resolves DockerfilePath relative to the devcontainer.json location, independent of the build context. It is empty when the spec names no Dockerfile.
func (*DevContainer) DockerfilePath ¶
func (d *DevContainer) DockerfilePath() string
DockerfilePath returns the Dockerfile path indicated by the spec, if any.
func (*DevContainer) Mode ¶
func (d *DevContainer) Mode() Mode
Mode returns the container model the spec describes. Only valid after Validate has succeeded; otherwise the result is whichever mode the compose discriminator fields suggest.
func (*DevContainer) Validate ¶
func (d *DevContainer) Validate() error
Validate enforces the discriminator: a spec is either single-container (image / build / dockerFile) or compose (dockerComposeFile + service), and the two sets of fields cannot mix. Validate is invoked from Load so callers using Load never see a malformed spec; tests and other in-memory construction paths can call it directly.
type OrderedMap ¶
type OrderedMap struct {
Keys []string
Values map[string]json.RawMessage
}
OrderedMap preserves insertion order while still decoding JSON object payloads. It's used for `features`, where install order can matter.
func ParseFeatures ¶
func ParseFeatures(data []byte) (OrderedMap, error)
ParseFeatures parses a JSONC object in the form of the devcontainer.json features property, such as the value of upstream's --additional-features.
func (OrderedMap) Len ¶
func (m OrderedMap) Len() int
func (*OrderedMap) UnmarshalJSON ¶
func (m *OrderedMap) UnmarshalJSON(data []byte) error
func (OrderedMap) WithAdditional ¶
func (m OrderedMap) WithAdditional(extra OrderedMap) OrderedMap
WithAdditional returns m followed by each feature of extra whose key m does not declare. For an equal key the options in m win, as in upstream userFeaturesToArray. Neither m nor extra is modified.
type StringOrSlice ¶
type StringOrSlice []string
StringOrSlice accepts either a single string or a list of strings, which the devcontainer spec allows for command fields. Retained for fields that don't need the parallel-object form.
func (*StringOrSlice) UnmarshalJSON ¶
func (s *StringOrSlice) UnmarshalJSON(data []byte) error