Skip to content

Fix a guaranteed crash, modernize date parsing, add Swift 6.4 CI - #8

Merged
RISCfuture merged 4 commits into
mainfrom
swift-6.4/modernization
Sep 15, 2026
Merged

RISCfuture merged 4 commits into
mainfrom
swift-6.4/modernization

Conversation

@RISCfuture

Copy link
Copy Markdown
Owner
  • Fixes a guaranteed trap in both archive downloaders: throw Error.badResponse(response as! HTTPURLResponse) sat inside the else of a failed as?, so a non-HTTP response crashed instead of throwing.
  • Removes linkerSettings: [.linkedLibrary("swift_Concurrency")] from all three targets — a legacy workaround, verified unnecessary on 6.4.
  • DateFormatterDate.ParseStrategy, deduplicating the same MMMM d, yyyy formatter that was rebuilt in four places.
  • Strict validation on that swap. Date.ParseStrategy is lenient where DateFormatter was strict — it rolls out-of-range components over (October 32 → Nov 1) and accepts trailing text. Since callers turn the result straight into a download URL, a lenient parse would silently fetch the wrong 28-day subscription. parseReadmeCycleDate re-renders and compares; 11 new parameterized cases cover it.
  • Adds Swift 6.4 CI legs.

All 7 @preconcurrency imports were tested individually and kept — still load-bearing, since Regex is not Sendable in 6.4.


🤖 Generated with Claude Code

https://claude.ai/code/session_01EbZbx5D2gGeXT8UxuiKEdq

@RISCfuture
RISCfuture force-pushed the swift-6.4/modernization branch 2 times, most recently from 033de08 to 9ef860c Compare September 14, 2026 23:07
RISCfuture and others added 4 commits September 14, 2026 20:10
Fix a guaranteed trap in both archive downloaders: the non-HTTP-response
guard threw `Error.badResponse(response as! HTTPURLResponse)`, force-casting
the very value whose `as?` had just failed. `badResponse` already accepts a
`URLResponse`, so pass the response through unchanged. The file downloader
also cleans up its tempfile on that path, matching the other error exits.

Replace `DateFormatter` with `Date.ParseStrategy` and
`Date.VerbatimFormatStyle` for the fixed-pattern cycle dates: one shared
strategy for the README effective date (previously rebuilt in four places)
and two format styles for the TXT and CSV distribution URLs. The
`FixedWidthField.datetime` payload carries a parse strategy accordingly,
which also makes the case Sendable.

Drop the legacy `.linkedLibrary("swift_Concurrency")` linker setting from all
three targets, and add Swift 6.4 CI legs for each OS already in the matrix.

All seven `@preconcurrency` imports remain required: `Regex`'s `Reference` is
still non-Sendable in Swift 6.4, as is ZIPFoundation's `Archive`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbZbx5D2gGeXT8UxuiKEdq
Date.ParseStrategy is lenient in two ways the README format cannot tolerate:
it rolls out-of-range components over, reading "October 32, 2025" as November
1st, and it stops at the first match, accepting trailing text. DateFormatter
rejected both. Callers turn the result straight into a download URL, so a
lenient parse silently fetches the wrong 28-day subscription rather than
reporting no cycle.

Route the four README call sites through parseReadmeCycleDate, which re-renders
the parsed date and requires it to equal the input. Surrounding whitespace is
still tolerated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbZbx5D2gGeXT8UxuiKEdq
Adopt SE-0458 `.strictMemorySafety()` in the shared `swiftSettings` array
so every target audits its unsafe constructs, then acknowledge the eleven
existing unsafe uses:

- `@unsafe` on the seven `@preconcurrency` imports of RegexBuilder and
  ZIPFoundation, whose pre-Sendable types are only ever used within a
  single parser instance.
- `unsafe` on the three `String(format:)` calls, whose C variadic
  arguments match their format specifiers.
- `unsafe` on the `ioctl(TIOCGWINSZ)` call in the E2E progress tracker.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbZbx5D2gGeXT8UxuiKEdq
Progress now flows down into SwiftNASR as a `Subprogress` minted from the
caller's own `ProgressManager`, rather than up out of it as a `Progress`
handed to a handler block. Six public signatures trade their
`withProgress:` handler for `progress: consuming Subprogress? = nil`:
`NASR.load`, `NASR.parse`, `Loader.load`, `Downloader.load`,
`Distribution.readFile`, and `Distribution.readFileRaw`.

The platform floor rises to macOS/iOS/tvOS/watchOS/visionOS 27 and the
manifest to tools-version 6.4, which is where `ProgressManager` starts
existing: it carries no lower availability annotation on Apple platforms,
it is `@available(FoundationPreview 6.4)` on Linux, and `MacOSVersion.v27`
is itself `@available(_PackageDescription 6.4)`. CI follows: the Darwin
legs collapse into one `xcode-27` job driven by `maxim-lobanov/setup-xcode`
(no earlier image can supply the macOS 27 SDK), the Linux 6.3 leg is
dropped, and `.github/actionlint.yaml` declares `xcode-27` so
`actionlint` keeps checking runner labels.

`DirectoryDistribution` double-counted every file it read, adding each
line's length on top of the length of the chunk the line arrived in and
reporting 35 bytes read from a 21-byte file. `Progress` clamped
`fractionCompleted` to 1.0 and hid it; `ProgressManager` reports the
overshoot. The file's byte accounting is now pinned through the new
`completedByteCount`/`totalByteCount` metadata, which every read and
download reports alongside its unit counts.

Also: `CSVParser` sheds its vestigial `progress` and `bytesRead`
requirements, a diagnosed record no longer stalls the fixed-width parse
progress short of its total, and the E2E progress bar follows
`Observations.untilFinished` over the observable root manager instead of
re-reading `fractionCompleted` on a 10 Hz timer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbZbx5D2gGeXT8UxuiKEdq
@RISCfuture
RISCfuture force-pushed the swift-6.4/modernization branch from d78c15a to 35863c8 Compare September 15, 2026 03:11
@RISCfuture
RISCfuture merged commit 3961dd3 into main Sep 15, 2026
6 checks passed
@RISCfuture
RISCfuture deleted the swift-6.4/modernization branch September 15, 2026 03:35
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.

1 participant