fix(cli): read an array preload back whatever quotes it is written in - #40
Merged
Merged
Conversation
config/importmap.rb is Ruby, and this gem treats single-quoted pins as a supported shape everywhere else — packager_single_quotes_test.rb and the single_quote_* fixtures exist for exactly that. The preload option was the one place that disagreed: it was read back through JSON.parse, so `pin 'md5', preload: ['admin']` raised JSON::ParserError on every command that reads a pin, not just the one rewriting it. `preload: []` had a second problem in the same option. PRELOAD_OPTION_REGEXP required at least one character between the brackets, so an empty array matched nothing, extract_existing_pin_options returned no preload at all, and the next pin/update/pristine wrote the line back without it — restoring the `preload: true` default on a package the app had deliberately asked to preload for no entry point. Array() flattens nil and [] alike, so the emitting side had to learn the difference too. The entry points are scanned out of the literal now instead of parsed, which costs nothing and accepts every shape Ruby does. A single-element array still normalises to a string (`preload: ["admin"]` -> `preload: "admin"`): the CLI's `--preload admin` reaches the same method as the same value, Map compares both through Array(), and packager_test.rb:79 has asserted it since upstream. ## Test coverage - test/packager_test.rb: single-quoted, multi-entry and empty array preloads read back correctly; pin_for writes `preload: []` and still writes nothing for nil; a single-quoted array survives read-then-write as valid Ruby - test/packager_single_quotes_test.rb: option extraction against a single-quoted map, which had no coverage at all - test/fixtures/files/single_quote_array_preload_import_map.rb: the three array shapes as one fixture Closes #28
4 tasks
mhenrixon
added a commit
that referenced
this pull request
Sep 19, 2026
CHANGELOG.md was the only conflict: #40 and this branch each appended a bullet to 1.2.0's "### Fixed" at the same spot. Union, main's bullet first.
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
Packager#extract_existing_pin_optionsread an arraypreload:back throughJSON.parse. Two shapes broke on it:Single-quoted pins are a supported shape in this gem —
test/packager_single_quotes_test.rband thesingle_quote_*fixtures are there for it — so an app withpin 'x', preload: ['admin']crashed on every command that reads a pin, not only the one rewriting it. Andpreload: []never matchedPRELOAD_OPTION_REGEXP(\[[^\]]+\]needs a character), so the nextpin/update/pristinewrote the line back without it and restored thepreload: truedefault on a package the app had asked to preload for no entry point.Three additive changes in
lib/importmap/packager.rb:PRELOAD_OPTION_REGEXP—[^\]]+→[^\]]*, so[]matches.preload_from_string— the entry points are scanned out of the literal (value.scan(/["']([^"']*)["']/)) instead of parsed.config/importmap.rbis Ruby, not JSON.preload—return "" if preloads.nil?beforeArray(), which flattensniland[]to the same thing;[]now writespreload: [].Docs page updated:
docs/app/views/docs/pages/pinning.rb("Pin options survive a rewrite" now lists the array and empty-array forms and says quoting doesn't matter).CHANGELOG entry under
## 1.2.0→### Fixed.Closes #28
Test plan
bundle exec rake test— 437 runs, 0 failures, with bun installed--minifytests ran rather than skipped (test/minifier_test.rb5 runs / 0 skips,commands_test.rb -n /minify/2 runs / 0 skips)cd docs && bundle exec rake lint && bundle exec rspec— 53 files no offenses, 54 examples passedJSON::ParserErrorfor the single-quoted cases,{}andpin "react"for the empty-array onespin 'md5', preload: ['admin']andpin "crypt", preload: []in an app'sconfig/importmap.rb, runbin/importmap update md5, and confirm both lines come back with their preloads intactDeviations & judgment calls
JSON.parse. The issue offered either. The scan needs no JSON at all and also accepts the Ruby-isms JSON rejects (a trailing comma,[ ]), which is the right bar for a file that is Ruby.preload: ["admin"]is rewritten aspreload: "admin". Not fixed on purpose: the CLI's--preload adminarrives atpreload()as exactly the same value (["admin"]),Mapcompares both throughArray()so the meaning is identical, andtest/packager_test.rb:79has asserted the string form since upstream. Telling the two apart would mean moving CLI-shape normalisation out ofpreload()— a restructure of an upstream-owned method for no semantic gain.commands_test.rbcase. No new CDN contract and no new printed sentence;.claude/rules/testing.mdsays each live case costs a round-trip on every matrix cell. The round-trip is proven at unit level instead (read →pin_for→ same line).extract_existing_pin_options with single quotesis regression coverage, not proof. It passes onmaintoo — a boolean preload with single quotes always worked. It is there because that test class covered onlypackaged?andremove. The array cases are the ones that were red.commands.rbon a different code path and has its own product decision; the diffs don't overlap.Summary by cubic
Fixes array
preload:handling when CLI commands read pins back fromconfig/importmap.rb. Previously single-quoted pins likepin 'md5', preload: ['admin']crashed withJSON::ParserError, andpreload: []was silently dropped, sopin,update, andpristinerestored thepreload: truedefault.preload: []in rewritten pins instead of omitting it.preload: ["admin"]becomespreload: "admin"), matching existing CLI behavior.Closes #28.
Written for commit 0018b3f. Summary will update on new commits.