Skip to content

feat(inspect): Docker-compatible container inspect output (closes #36)#40

Merged
us merged 1 commit into
mainfrom
feat/container-inspect-docker-compat
Jun 26, 2026
Merged

feat(inspect): Docker-compatible container inspect output (closes #36)#40
us merged 1 commit into
mainfrom
feat/container-inspect-docker-compat

Conversation

@us

@us us commented Jun 26, 2026

Copy link
Copy Markdown
Owner

What & why

Closes #36. mocker container inspect <id> (and mocker inspect --type=container <id>) returned mocker's internal ContainerInfo shape instead of Docker's ContainerInspect shape. This completes the follow-up that #37 scaffolded.

Changes

  • New ContainerInspect DTO + pure mapToContainerInspect mapper (Sources/MockerKit/Models/ContainerInspect.swift), mirroring the existing image-inspect pattern: PascalCase CodingKeys, optional fields omitted when absent.
  • inspectContainers widened to return [ContainerInspect] (the Docker DTO) — exactly the widening refactor: split container inspect into dedicated subcommand #37 anticipated.
  • Output is now Docker-shaped: a single JSON array with unescaped slashes, across container inspect, inspect --type=container, and the inspect auto path.

Example output:

[
  {
    "Id": "abc123def456",
    "Created": "2023-11-14T22:13:20.000Z",
    "Name": "/web",
    "Image": "nginx:latest",
    "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 4242 },
    "Config": { "Image": "nginx:latest", "Cmd": ["nginx","-g","daemon","off;"], "Labels": { "com.example": "x" } },
    "NetworkSettings": { "IPAddress": "192.168.64.3", "Ports": { "80/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "8080" } ] } }
  }
]

Scope / honesty

Fields Apple's Containerization runtime does not surface (HostConfig, Mounts, RestartCount, env, exit code, start/finish timestamps, …) are omitted rather than fabricated — same approach as image inspect. --format (Go templates) and --size remain accepted-but-deferred; they are out of scope for the shape fix #36 asks for.

Tests

swift test: 202/202 pass. New ContainerInspectMappingTests (8 tests) cover the Docker shape: /-prefixed name, stoppedexited mapping, ports map shape, RFC3339 Created string, omitted-when-absent fields, and PascalCase JSON serialization.

container inspect (and inspect --type=container) returned the internal
ContainerInfo shape instead of Docker's ContainerInspect shape. Add a
ContainerInspect DTO + pure mapToContainerInspect mapper (mirroring the
image-inspect pattern) and widen inspectContainers to return it. Output is
now a single JSON array with Docker PascalCase keys (Id, Created, Name,
State, Config, NetworkSettings, ...) and unescaped slashes.

Fields Apple's Containerization runtime does not surface (HostConfig,
Mounts, env, exit code, ...) are omitted rather than fabricated. --format
and --size remain accepted-but-deferred.

Closes #36
@us us merged commit b064631 into main Jun 26, 2026
1 check passed
alex-mextner added a commit to alex-mextner/mocker that referenced this pull request Jun 26, 2026
…ct commands

`inspect` -- and the dedicated `container inspect` / `image inspect` subcommands
-- declared `-f/--format` mirroring `docker inspect`, but parsed and then ignored
it: the full JSON array was always printed. Docker callers drive inspect with a
template and expect a bare scalar, e.g. dev stands and CI health gates:

    docker inspect -f '{{.State.Running}}' <container> | grep -q true

Against the unevaluated flag that grep is a coin-flip on the substring "true"
appearing somewhere in the JSON dump.

Add a small Go text/template evaluator (`GoTemplate`) for the `{{ .Dotted.Path }}`
field-access subset real inspect callers use, and route every inspect entry point
through a shared `InspectFormat` helper that renders `--format` (one line per
record) and otherwise prints the JSON exactly as before. This also wires
`--format` into `container inspect` and `image inspect`, which previously accepted
the flag for Docker surface parity but never applied it.

Behavior:
- Paths resolve against the Docker-shaped inspect JSON from us#40 (`.State.Running`,
  `.State.Status`, `.Id`, `.Name`, `.Config.Image`, `.NetworkSettings.IPAddress`,
  ...). Scalars render the Go way: bare `true`/`false`, integers without a decimal
  point, strings verbatim; an unknown/null path and array/object leaves render empty.
- Substitution is a single left-to-right pass by match range, so a resolved value
  that itself contains `{{...}}` is emitted verbatim and never re-triggers
  substitution.
- `--format json` is treated as Docker's documented special value (emit the JSON),
  not as a template.
- Any `{{...}}` block outside the supported field-access subset (`if`, `range`,
  `json`, `index`, a bare `{{.}}`, ...) throws rather than passing through as
  misleading literal text -- a silently-unevaluated template would feed false data
  to the grep/jq pipelines these outputs drive.

Add GoTemplateTests covering the dev-stand health-gate paths, integer-vs-bool
scalars (incl. Pid 0 on a stopped container), whitespace, multi-token / repeated
tokens, no cross-token / re-entrant substitution, array-leaf-empty, the
JSONSerialization bool->NSNumber bridging path, and fail-loud rejection of
unsupported actions.
us pushed a commit that referenced this pull request Jun 27, 2026
…ct commands

`inspect` -- and the dedicated `container inspect` / `image inspect` subcommands
-- declared `-f/--format` mirroring `docker inspect`, but parsed and then ignored
it: the full JSON array was always printed. Docker callers drive inspect with a
template and expect a bare scalar, e.g. dev stands and CI health gates:

    docker inspect -f '{{.State.Running}}' <container> | grep -q true

Against the unevaluated flag that grep is a coin-flip on the substring "true"
appearing somewhere in the JSON dump.

Add a small Go text/template evaluator (`GoTemplate`) for the `{{ .Dotted.Path }}`
field-access subset real inspect callers use, and route every inspect entry point
through a shared `InspectFormat` helper that renders `--format` (one line per
record) and otherwise prints the JSON exactly as before. This also wires
`--format` into `container inspect` and `image inspect`, which previously accepted
the flag for Docker surface parity but never applied it.

Behavior:
- Paths resolve against the Docker-shaped inspect JSON from #40 (`.State.Running`,
  `.State.Status`, `.Id`, `.Name`, `.Config.Image`, `.NetworkSettings.IPAddress`,
  ...). Scalars render the Go way: bare `true`/`false`, integers without a decimal
  point, strings verbatim; an unknown/null path and array/object leaves render empty.
- Substitution is a single left-to-right pass by match range, so a resolved value
  that itself contains `{{...}}` is emitted verbatim and never re-triggers
  substitution.
- `--format json` is treated as Docker's documented special value (emit the JSON),
  not as a template.
- Any `{{...}}` block outside the supported field-access subset (`if`, `range`,
  `json`, `index`, a bare `{{.}}`, ...) throws rather than passing through as
  misleading literal text -- a silently-unevaluated template would feed false data
  to the grep/jq pipelines these outputs drive.

Add GoTemplateTests covering the dev-stand health-gate paths, integer-vs-bool
scalars (incl. Pid 0 on a stopped container), whitespace, multi-token / repeated
tokens, no cross-token / re-entrant substitution, array-leaf-empty, the
JSONSerialization bool->NSNumber bridging path, and fail-loud rejection of
unsupported actions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

container inspect output is not Docker-compatible

1 participant