Skip to content

fix(updater): stop re-downloading special-char mods#51

Merged
Caedis merged 1 commit into
masterfrom
caedis/fix-filename-sanitization-redownload
May 25, 2026
Merged

fix(updater): stop re-downloading special-char mods#51
Caedis merged 1 commit into
masterfrom
caedis/fix-filename-sanitization-redownload

Conversation

@Caedis

@Caedis Caedis commented May 25, 2026

Copy link
Copy Markdown
Owner

Problem

Mods whose canonical filename contains characters stripped by SanitizeFilename (spaces, [], (), ') were written to disk under a sanitized name, but the scan filename index, persisted state.Mods[].Filename, and stale-jar matcher all keyed on the raw name. The on-disk file never matched, so every run re-downloaded the mod and orphaned the old jar.

Confirmed on a real instance: BiblioCraft[v1.11.7][MC1.7.10].jar -> BiblioCraftv1.11.7MC1.7.10.jar. 5 mods re-downloaded every run before the fix, 0 after.

Fix

  • Record both names per mod: InstalledMod.RawFilename (canonical) and Filename (actual on-disk).
  • Key the filename index on every variant via fileutil.FilenameVariants (raw, current sanitized, legacy sanitized) so a jar written by any past rule still resolves.
  • reconcileSanitizedFilenames renames a drifted jar in place on a real run; skipped under --dry-run (no filesystem side effects).

Loosen sanitization

With the map bridging old/new names, SanitizeFilename now allows the actually-valid cross-OS set:

  • keeps [] () ', spaces, + - . _
  • decodes %XX (e.g. %2B -> +)
  • replaces only < > : " / \ | ? * and control chars with _
  • strips trailing dots/spaces, guards Windows reserved device names (CON/NUL/COM1-9/...)

Tests

  • fileutil/sanitize_test.go — full rule table + FilenameVariants
  • TestRun_SanitizedFilenameNotRedownloaded — legacy-named jar recognized as unchanged
  • TestRun_LegacyNamedJarMigratedNoDuplicate — real update migrates in place, exactly one jar left
  • TestReconcileSanitizedFilenames (+ skip stale/clean), updated assets/maven tests
  • go build, go vet, go test ./... all pass

Closes #49
Refs #43

Mods whose canonical filename contained characters stripped by
SanitizeFilename (spaces, brackets, apostrophes) were written to disk
under a sanitized name, but the scan index, persisted state, and
stale-jar matcher all keyed on the raw name. The on-disk file never
matched, so every run re-downloaded the mod and left the old jar
orphaned.

Record both names per mod (RawFilename = canonical, Filename = on-disk)
and key the filename index on every variant (raw, current sanitized,
legacy sanitized) so a jar written by any past rule still resolves.
reconcileSanitizedFilenames renames a drifted jar in place on a real
run, never under --dry-run.

With the map in place, loosen SanitizeFilename to the actually-valid
cross-OS set: keep [] () ' spaces + - . _, decode %XX, replace only
< > : " / \ | ? * and control chars, strip trailing dots/spaces, and
guard Windows reserved device names.

Closes #49
Refs #43
@Caedis Caedis merged commit a5fedc6 into master May 25, 2026
1 check passed
@Caedis Caedis deleted the caedis/fix-filename-sanitization-redownload branch May 25, 2026 14:49
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.

Constantly downloads mods that already exist

1 participant