Skip to content

fix(core): extract a shared image-reference parser#16

Open
PunGrumpy wants to merge 2 commits into
advisor/003-fix-rule-specificity-bugsfrom
advisor/004-shared-image-ref-parser
Open

fix(core): extract a shared image-reference parser#16
PunGrumpy wants to merge 2 commits into
advisor/003-fix-rule-specificity-bugsfrom
advisor/004-shared-image-ref-parser

Conversation

@PunGrumpy

Copy link
Copy Markdown
Owner

What

Extracts a single, correct image-reference parser (parseImageRef + collectStageAliases in @docker-doctor/core) and rewrites pin-image-version and prefer-slim-base to use it, replacing two hand-rolled "split on the first :" implementations that each produced wrong diagnostics.

Implements plan 004. Depends on 002 (CLI integration tests) and 003 (rule-specificity fixes to security.ts).

Why

Both rules split image references on the first :, producing four distinct wrong answers:

  • FROM myregistry.example.com:5000/team/app — registry port read as the tag, so a fully-untagged image was treated as pinned. pin-image-version (the flagship security rule) returned nothing on private-registry images.
  • FROM node@sha256:… — the : inside sha256: matched the split, so prefer-slim-base warned that a gold-standard digest pin "may be a full-OS distribution". The isSha guard was unreachable.
  • FROM builder (stage alias) and FROM ${NODE_IMAGE} (ARG-driven) — both produced bogus "does not specify a tag" warnings, so every multi-stage Dockerfile that names its stages got spurious output.

Behavior change (why the changeset)

.changeset/shy-lemons-parse.md@docker-doctor/cli patch. Diagnostics change on Dockerfiles using registry ports, digest pins, and multi-stage aliases. Verified live against the built CLI:

Dockerfile Before After
FROM myregistry.example.com:5000/team/app silent pin-image-version fires ✓
FROM node@sha256:… prefer-slim-base fired silent ✓
FROM node:22-alpine AS build / FROM build warned on build silent ✓
FROM node:22 warned prefer-slim-base fires ✓
FROM node:latest warned pin-image-version + prefer-slim-base

Division of labor (preserved deliberately)

pin-image-version owns "is it pinned"; prefer-slim-base owns "is the pinned thing slim". prefer-slim-base now stays silent on untagged images so one problem isn't double-penalized.

Tests

  • New packages/core/test/image-ref.test.ts — table-driven unit tests for parseImageRef (9 rows) and collectStageAliases (3 cases).
  • Extended pin-image-version (+4) and prefer-slim-base (+3) in rules.test.tspurely additive, no existing assertion changed.
  • core: 47 pass / 0 fail · cli: 12 pass / 0 fail · typecheck 0 · ultracite check 0.

Stacking

Base is advisor/003-fix-rule-specificity-bugs (PR #15), which itself stacks on advisor/002-... (PR #14) — both prerequisites are still open. GitHub auto-retargets this PR to main once #14 and #15 merge. Merge order: #14#15 → this.

🤖 Generated with Claude Code

…and stage aliases

Extract a shared parseImageRef/collectStageAliases helper and use it in
pinImageVersion and preferSlimBase, replacing manual first-colon splitting
that misread registry ports as tags, digest pins as untagged/non-slim
images, and multi-stage aliases as bare image names.
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docker-doctor Ready Ready Preview, Comment Jul 23, 2026 2:01am

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