WSLC: Refactor ParseImage and ParseRepository (PR Feedback followup) - #41154
Merged
David Bennett (dkbennett) merged 1 commit intoJul 24, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors container image/repository parsing in the WSLC client-side code by replacing the legacy free functions with immutable parsed reference types, reducing repeated parsing and making derived forms (canonical, normalized server/path, tag vs digest) available via accessors.
Changes:
- Introduces
wslutil::RepositoryReferenceandwslutil::ImageReference(parse-once, immutable) and migrates callers offParseImage/NormalizeRepo/GetCanonicalImageReference. - Updates allowlist enforcement to accept a parsed
RepositoryReferenceto avoid redundant parsing on pull/push paths. - Tightens CLI pull behavior by only constructing the progress callback when not in
--quiet, and uses the parsed reference for canonical output.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/windows/WSLCTests.cpp | Updates/expands unit tests to validate the new parsed reference types (Name/Server/Path, Tag/Digest, TagOrDigest, Format, canonical). |
| src/windows/wslcsession/WSLCSession.cpp | Switches pull/push/import/tag-related codepaths to ImageReference/RepositoryReference and updates allowlist enforcement signature. |
| src/windows/wslcsession/DockerHTTPClient.cpp | Uses RepositoryReference::Parse(...).GetCanonical() when building Docker pull URL parameters. |
| src/windows/wslc/tasks/ImageTasks.cpp | Parses once for default-tag messaging + canonical output; avoids constructing progress callback in --quiet. |
| src/windows/wslc/services/ImageService.cpp | Uses ImageReference for server extraction, list parsing, and tag validation. |
| src/windows/common/wslutil.h | Removes old free-function APIs and adds the new RepositoryReference / ImageReference public types. |
| src/windows/common/wslutil.cpp | Implements the new Parse()/GetCanonical() methods and refactors the old logic into the new types. |
David Bennett (dkbennett)
marked this pull request as ready for review
July 23, 2026 22:20
Blue (OneBlue)
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
This is a follow-up from some PR commentary that had a fairly large blast radius to do it cleanly so it is a separate PR.
Replaces the free functions
ParseImage,GetCanonicalImageReference, andNormalizeRepoinwslutilwith two composable, immutable value types:RepositoryReferenceandImageReference. A reference is now parsed onceinto a single source of truth, and all derived forms (normalized server/path,
canonical strings, tag-or-digest collapsing) are available on demand via
accessors — instead of being recomputed by callers or threaded through helper
functions as loose
std::pair/std::stringvalues.Cleanup is entirely client-side:
no IDL, COM, or service-ABI changes.
PR Checklist
Detailed Description of the Pull Request / Additional comments
New types
RepositoryReference— an immutable container-repository reference.const std::string Name— the verbatim repository token as written.const std::string Server/const std::string Path— the normalizedregistry server and path (Docker client-side normalization,
e.g.
ubuntu→{docker.io, library/ubuntu}).static Parse(repository)— splits and normalizes (folds in the oldNormalizeRepo).GetCanonical()— the fully-qualifiedserver/pathform.ImageReference— an immutable image reference such asubuntu:22.04@sha256:....const RepositoryReference Repository— composed, not a raw string.const std::optional<std::string> Tag/Digest— kept as distinct fields.const EnumReferenceFormat Format— None / Tag / Digest classification.static Parse(input)— throwsE_INVALIDARG(with a user-facing message)on a malformed reference.
TagOrDigest()— collapses to a single field, digest taking precedence.GetCanonical()— the canonical string matchingdocker pulloutput(keeps both a tag and a digest when both are present).
Implementation details
ImageReferenceembeds aRepositoryReference; every part isconst, so a reference is fixed oncecreated. Consumers that need repository parts use accessors
(
.Repository.Server,.Repository.Name,.Repository.GetCanonical())rather than re-parsing.
Nameis retained. Normalization is lossy —ubuntu,docker.io/ubuntu, andindex.docker.io/library/ubuntuall normalize to thesame server/path. Consumers that must echo the repository exactly as written
(
wslc image listdisplay,wslc tag's C-APIRepo) readName.EnforceRegistryAllowlistnow takes aconst RepositoryReference&instead of a raw string, eliminating a secondnormalization/regex pass on the pull/push paths.
wslc image pull --quietnow only constructs theprogress callback when it is actually needed
(
std::optional<ImageProgressCallback>).Validation Steps Performed
WSLCTests::ImageParsing,RepoParsing,CanonicalImageReference(converted/expanded to cover the new types,including
Name/Server/Path,TagOrDigest(),Format, andGetCanonical()).intentional — stdin/terminal/build cases). Includes
WSLCE2E_Image_Pull_QuietOptionandWSLCE2E_Image_Pull_NameOnlyDefaultsTag,which exercise the quiet-callback and default-tag paths.