IsSupportedMIMEType() — checks if a MIME type is supported
MIMEToImageFormat() — converts MIME type to ImageFormat
ImageFormatToMIME() — converts ImageFormat to MIME string
All error sentinels (ErrUnknownFormat, ErrMagicByteMismatch, ErrNotEnoughData)
All helper functions (detectSVG, skipBOM, normalizeMIMEType)
The magic package defines its own ImageFormat type and constants to avoid circular imports (imgcache → magic for validation; magic cannot import imgcache).
internal/imgcache/service_test.go: uses magic.DetectFormat() and magic.MIMEToImageFormat()
Naming
Clean package-qualified names: magic.DetectFormat(), magic.ValidateMagicBytes(), etc.
No stuttering names
Tests
Full test suite moved to internal/magic/magic_test.go (all 15 test functions preserved)
All existing tests pass unchanged
docker build . passes (includes make check: fmt, lint, tests)
## Summary
Extract magic byte detection and MIME type handling from `internal/imgcache/` into a new focused `internal/magic/` package.
Part of [issue #39](https://git.eeqj.de/sneak/pixa/issues/39)
## Changes
### New package: `internal/magic/`
Moved the following from `internal/imgcache/magic.go`:
- `MIMEType` type and constants (`MIMETypeJPEG`, `MIMETypePNG`, etc.)
- `DetectFormat()` — detects image format from magic bytes
- `ValidateMagicBytes()` — validates content matches declared MIME type
- `PeekAndValidate()` — reads minimum bytes, validates, returns combined reader
- `IsSupportedMIMEType()` — checks if a MIME type is supported
- `MIMEToImageFormat()` — converts MIME type to ImageFormat
- `ImageFormatToMIME()` — converts ImageFormat to MIME string
- All error sentinels (`ErrUnknownFormat`, `ErrMagicByteMismatch`, `ErrNotEnoughData`)
- All helper functions (`detectSVG`, `skipBOM`, `normalizeMIMEType`)
The magic package defines its own `ImageFormat` type and constants to avoid circular imports (`imgcache` → `magic` for validation; `magic` cannot import `imgcache`).
### Updated imports
- `internal/imgcache/service.go`: uses `magic.ValidateMagicBytes()`
- `internal/imgcache/service_test.go`: uses `magic.DetectFormat()` and `magic.MIMEToImageFormat()`
### Naming
- Clean package-qualified names: `magic.DetectFormat()`, `magic.ValidateMagicBytes()`, etc.
- No stuttering names
### Tests
- Full test suite moved to `internal/magic/magic_test.go` (all 15 test functions preserved)
- All existing tests pass unchanged
- `docker build .` passes (includes `make check`: fmt, lint, tests)
Move MIMEType, DetectFormat, ValidateMagicBytes, PeekAndValidate,
IsSupportedMIMEType, MIMEToImageFormat, and ImageFormatToMIME from
internal/imgcache into a new internal/magic package.
The magic package defines its own ImageFormat type and constants to
avoid circular imports (imgcache imports magic for validation,
magic cannot import imgcache).
Update import sites in imgcache/service.go and service_test.go.
Part of issue #39.
The original ImageFormat type in imgcache.go is correctly preserved (other packages like encurl, handlers, urlparser still reference imgcache.ImageFormat).
No stale references to old package-qualified names (imgcache.DetectFormat, etc.) remain anywhere in the codebase.
Two minor comment improvements: "our ImageFormat" → "an ImageFormat" — appropriate for the new standalone package context.
## Review: PASS ✅
Clean extraction of magic byte detection into `internal/magic/` package.
### Checklist
| Check | Result |
|---|---|
| `magic.go` moved with no logic changes | ✅ Only package declaration, doc comment, and `ImageFormat` type added |
| `magic_test.go` moved with all tests | ✅ All 13 test functions preserved, only package declaration changed |
| `ImageFormat` constants match originals | ✅ All 6 values identical to `internal/imgcache/imgcache.go` |
| Import sites updated | ✅ `service.go` → `magic.ValidateMagicBytes()`, `service_test.go` → `magic.DetectFormat()` / `magic.MIMEToImageFormat()` |
| No circular imports | ✅ `internal/magic/` imports only stdlib (`bytes`, `errors`, `io`, `strings`) |
| No scope creep | ✅ Only 4 files changed, only magic extraction |
| No stuttering names | ✅ `magic.DetectFormat()`, `magic.ValidateMagicBytes()`, etc. |
| No linter/CI/test config changes | ✅ `.golangci.yml`, `Makefile`, `Dockerfile`, `.gitea/workflows/` untouched |
| `docker build .` passes | ✅ All tests pass, build succeeds |
### Notes
- The original `ImageFormat` type in `imgcache.go` is correctly preserved (other packages like `encurl`, `handlers`, `urlparser` still reference `imgcache.ImageFormat`).
- No stale references to old package-qualified names (`imgcache.DetectFormat`, etc.) remain anywhere in the codebase.
- Two minor comment improvements: "our ImageFormat" → "an ImageFormat" — appropriate for the new standalone package context.
Part of [issue #39](https://git.eeqj.de/sneak/pixa/issues/39).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Extract magic byte detection and MIME type handling from
internal/imgcache/into a new focusedinternal/magic/package.Part of issue #39
Changes
New package:
internal/magic/Moved the following from
internal/imgcache/magic.go:MIMETypetype and constants (MIMETypeJPEG,MIMETypePNG, etc.)DetectFormat()— detects image format from magic bytesValidateMagicBytes()— validates content matches declared MIME typePeekAndValidate()— reads minimum bytes, validates, returns combined readerIsSupportedMIMEType()— checks if a MIME type is supportedMIMEToImageFormat()— converts MIME type to ImageFormatImageFormatToMIME()— converts ImageFormat to MIME stringErrUnknownFormat,ErrMagicByteMismatch,ErrNotEnoughData)detectSVG,skipBOM,normalizeMIMEType)The magic package defines its own
ImageFormattype and constants to avoid circular imports (imgcache→magicfor validation;magiccannot importimgcache).Updated imports
internal/imgcache/service.go: usesmagic.ValidateMagicBytes()internal/imgcache/service_test.go: usesmagic.DetectFormat()andmagic.MIMEToImageFormat()Naming
magic.DetectFormat(),magic.ValidateMagicBytes(), etc.Tests
internal/magic/magic_test.go(all 15 test functions preserved)docker build .passes (includesmake check: fmt, lint, tests)Review: PASS ✅
Clean extraction of magic byte detection into
internal/magic/package.Checklist
magic.gomoved with no logic changesImageFormattype addedmagic_test.gomoved with all testsImageFormatconstants match originalsinternal/imgcache/imgcache.goservice.go→magic.ValidateMagicBytes(),service_test.go→magic.DetectFormat()/magic.MIMEToImageFormat()internal/magic/imports only stdlib (bytes,errors,io,strings)magic.DetectFormat(),magic.ValidateMagicBytes(), etc..golangci.yml,Makefile,Dockerfile,.gitea/workflows/untoucheddocker build .passesNotes
ImageFormattype inimgcache.gois correctly preserved (other packages likeencurl,handlers,urlparserstill referenceimgcache.ImageFormat).imgcache.DetectFormat, etc.) remain anywhere in the codebase.Part of issue #39.