Skip to content

feat(create): implement --compatibility to fetch supported image list#2111

Merged
balanza merged 1 commit into
89luca89:nextfrom
balanza:feat/show-compatibility
Jun 5, 2026
Merged

feat(create): implement --compatibility to fetch supported image list#2111
balanza merged 1 commit into
89luca89:nextfrom
balanza:feat/show-compatibility

Conversation

@balanza

@balanza balanza commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Implements the distrobox create --compatibility flag in Go (resolves the TODO at internal/cli/create.go:240), porting the bash show_compatibility helper from the legacy distrobox-create script.
  • Fetches docs/compatibility.md from upstream for the current build version (falling back to main for dev builds, or to the nearest tag when git describe --tags produces a <tag>-N-g<sha>[-dirty] suffix), parses the "Containers Distros" table, and caches the deduplicated/sorted image list under $XDG_CACHE_HOME/distrobox/distrobox-compatibility-<ref> so subsequent invocations are offline-friendly.
  • Cache writes are atomic (temp file + rename) so a crashed or concurrent writer cannot leave a partially populated cache file visible to readers.
  • The build-time version string is sanitized before being embedded in the cache filename, preventing any ref containing /, .., or unusual characters from creating nested paths or escaping the cache directory.
  • The action passes its context.Context into the HTTP fetch so Ctrl+C / parent cancellation aborts the request.

Implementation notes

  • New file internal/cli/compatibility.go houses the fetch / parse / cache logic.
  • Parsing mirrors the original bash pipeline (sed -n '/| Alma/,/| Void/ p' | cut -f4 | sed s/<br>/\n/ | tr -d ' ' | sort -u) line-by-line in Go.
  • 33 unit tests (one function per case, no table-driven subtests) cover the parser, the cache read/write/atomic-replace path, ref normalization (including git describe shapes and bare hashes), ref sanitization for filename safety, the HTTP fetch helpers, and the XDG_CACHE_HOME / HOME fallback chain.

Test plan

  • make build succeeds
  • make test passes (33 new tests in internal/cli, full suite green)
  • make lint passes with zero issues
  • Smoke test: distrobox create --compatibility returns 122 image entries on first invocation and serves from cache on the second
  • Smoke test with VERSION=dev: falls back to main ref and writes distrobox-compatibility-main

@balanza balanza marked this pull request as draft May 19, 2026 15:42
@balanza balanza marked this pull request as ready for review May 19, 2026 15:54
@balanza balanza requested a review from dottorblaster May 22, 2026 07:58

@dottorblaster dottorblaster left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one thing but then we can merge 👍

Comment thread internal/cli/compatibility.go Outdated
Comment on lines +282 to +313
// first line that starts with "| Alma" and the next line that starts with
// "| Void". Returned slice is sorted and deduplicated, mirroring the
// `sort -u` behaviour of the original bash implementation.
func parseCompatibilityImages(markdown string) []string {
seen := make(map[string]struct{})

inTable := false
for _, line := range strings.Split(markdown, "\n") {
if !inTable {
if strings.HasPrefix(line, compatibilityTableStartMarker) {
inTable = true
} else {
continue
}
}

for _, image := range extractImagesFromRow(line) {
seen[image] = struct{}{}
}

if strings.HasPrefix(line, compatibilityTableEndMarker) {
break
}
}

images := make([]string, 0, len(seen))
for image := range seen {
images = append(images, image)
}
sort.Strings(images)
return images
}

@dottorblaster dottorblaster May 27, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table boundaries "| Alma" and "| Void" are extremely fragile structural markers.

Any of the following silently breaks with an error about parsing compatibility list:

  • AlmaLinux renamed/removed
  • a new distro added alphabetically before "Alma"
  • Void renamed
  • a new distro added alphabetically after "Void"

Two suggestions:

  • Anchor on the ## Containers Distros heading and the next ## heading instead of arbitrary cell content
  • When the markers can't be found, return an explicit error like compatibility table layout changed in upstream docs/compatibility.md.

I would especially pick the first one 😬

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done it. The previous implementation was mirroring what is done on main, but this is an improvement indeed

@balanza balanza force-pushed the feat/show-compatibility branch from 8e27494 to e0b11fa Compare June 5, 2026 11:06
Ports show_compatibility from bash distrobox-create. Downloads
docs/compatibility.md from upstream and caches the parsed list
in the user cache dir.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@balanza balanza force-pushed the feat/show-compatibility branch from 4b28132 to eb597d7 Compare June 5, 2026 11:45
@balanza balanza requested a review from dottorblaster June 5, 2026 11:49

@dottorblaster dottorblaster left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@balanza balanza merged commit e251b5e into 89luca89:next Jun 5, 2026
15 checks passed
@balanza balanza deleted the feat/show-compatibility branch June 5, 2026 17:48
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.

2 participants