Skip to content

rmi by image ID, COMPOSE_PROJECT_NAME interpolation, and Chinese docs - #83

Merged
us merged 4 commits into
mainfrom
fix/rmi-by-id-and-interpolation
Aug 9, 2026
Merged

rmi by image ID, COMPOSE_PROJECT_NAME interpolation, and Chinese docs#83
us merged 4 commits into
mainfrom
fix/rmi-by-id-and-interpolation

Conversation

@us

@us us commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Closes the follow-ups #77 and #80 left open, and brings the Chinese docs up to date with
what v0.9.0 changed.

rmi by image ID (#79)

mocker images -q | xargs mocker rmi — the standard cleanup — failed, because references
resolved only as names. Resolution now falls back to matching stored image digests by
prefix, but only after every name candidate has been tried, so a real repository name
always wins. The forms accepted are the ones people actually have in hand: a full
sha256:..., the truncated form images -q prints, and a bare hex prefix.

A prefix that matches more than one distinct image is an error naming the count, rather
than deleting whichever came first. rmi is destructive, so guessing is the one thing it
must not do. Every command sharing ImageManager.resolve (inspect, tag, save,
history, push's existence check) gets this for free.

${COMPOSE_PROJECT_NAME} in compose files

The project name was resolved after parsing, so a file interpolating
${COMPOSE_PROJECT_NAME} got an empty string. It is now resolved first — from -p, the
environment, .env, then the directory — and passed into parsing as a variable that wins
over .env and the environment. The file's own name: is one of the sources and cannot be
known before parsing, so the file is parsed again when the resolved name turns out to
differ — what the file reads then equals what its resources are called.

$ mocker compose -p custom-name config | grep -E '^name:|PROJECT'
name: custom-name
      - PROJECT=custom-name

Docs

  • COMMANDS.md: rmi documents ID and prefix resolution, including the ambiguity error.
  • docs/compose.md: notes that the resolved name is readable as ${COMPOSE_PROJECT_NAME}.
  • README.zh-CN.md and docs/zh-CN/compose.md had not caught up with v0.9.0: they still
    advertised network connect/disconnect and described the project name as simply the
    directory name. They now carry the five-step precedence, external:/name: for networks
    and volumes, the project-scoped default network, and the one-network-per-container limit.

Not fixed, now tracked

A compose service can still only join one network (#82). That is the runtime's limit, not
the parser's — attaching a container to two networks fails inside the guest — and it is
also why network connect/disconnect report that they are unsupported.

Verification

swift build clean, swift test 445 tests / 35 suites green (434 before). Against the
real backend: mocker images -q prints sha256:d9e85, and rmi sha256:d9e85, rmi <full digest> and
the bare rmi d9e853e87e55 all remove that image, while rmi sha / rmi sha256: are
rejected rather than matched. compose config interpolates the project name for the directory default,
-p, and the environment.

The matching rule is a pure helper (ImageManager.matchingDigests), so the cases that
matter are unit-tested directly: full digest, bare hex prefix, a prefix shared by two
images (ambiguous, never picked), several tags of one image counting as one, and a prefix
matching nothing.

ref #79, ref #82

us added 4 commits August 9, 2026 22:17
`mocker images -q | xargs mocker rmi` failed: references resolved only as
names, so the IDs that command prints matched nothing. Resolution now falls
back to matching stored digests, accepting the full `sha256:...`, the truncated
form `images -q` prints, and a bare hex prefix, comparing the hex on both sides.

The fallback runs only after every name candidate has missed, so a repository
that happens to look like hex still wins as a name. A prefix matching more than
one distinct image is an error naming the count rather than a deletion of
whichever came first. Every command sharing the resolver gains the same.
A file interpolating `${COMPOSE_PROJECT_NAME}` got an empty string: the name was
resolved after parsing. It is resolved first now and passed in as a variable
that outranks `.env` and the environment, since it is the name the project
actually runs under.

The file's own `name:` is one of the sources, so it cannot be known before
parsing; the file is parsed again when the resolved name turns out to differ,
which keeps what the file reads equal to what its resources are called. Values
the caller did not resolve keep their previous precedence, `.env` below the
shell.
They still advertised `network connect`/`disconnect` and described the project
name as the directory name. Both now match the code: the five-step precedence,
`external:`/`name:` for networks and volumes, the project-scoped default
network, and one network per container.

Also documents that `rmi` accepts an image ID, and that a compose file can read
the resolved project name back.
The matching itself was only exercised through the CLI. Extracting it as a pure
helper puts the cases that matter under test: a bare hex prefix (the form that
was broken), a prefix shared by two images, and several tags of one image
counting as one match rather than an ambiguity.
@us
us merged commit 0c6daf0 into main Aug 9, 2026
1 check passed
@us
us deleted the fix/rmi-by-id-and-interpolation branch August 9, 2026 19:29
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.

1 participant