Skip to content

Commit f2e6c5c

Browse files
RISCfutureclaude
andcommitted
Simplify CI matrix
Standardize the CI matrix around a category-based strategy (Category C: macOS 15 + Swift 6.0, macOS 15 + Swift 6.2, macOS 26 + Swift 6.2). Guard CoreLocation usage behind #if canImport(CoreLocation). Guard String(localized:comment:) calls behind #if canImport(Darwin) with plain string fallbacks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fdbaa63 commit f2e6c5c

4 files changed

Lines changed: 148 additions & 37 deletions

File tree

.github/workflows/ci.yml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# CI Matrix Policy
2+
#
3+
# Category A (tools-version 6.2 + macOS 26 min): macos-26 + Swift 6.2
4+
# Category B (tools-version 6.2 + older macOS): macos-15 + 6.2, macos-26 + 6.2
5+
# Category C (tools-version 6.0): macos-15 + 6.0, macos-15 + 6.2, macos-26 + 6.2
6+
# Linux (if viable): ubuntu + Swift 6.0, ubuntu + Swift 6.2
7+
#
8+
# When Swift 6.3 ships: bump 6.0→6.1 and 6.2→6.3 in Category C
9+
# When bumping tools-version to 6.2: drop 6.0/6.1, move to Category A or B
10+
111
name: CI
212

313
on:
@@ -17,12 +27,12 @@ jobs:
1727
fail-fast: false
1828
matrix:
1929
include:
20-
- os: macos-14
21-
swift: "6.1"
2230
- os: macos-15
23-
swift: "6.1"
31+
swift: "6.0"
2432
- os: macos-15
2533
swift: "6.2"
34+
- os: macos-26
35+
swift: "6.2"
2636
runs-on: ${{ matrix.os }}
2737
steps:
2838
- uses: actions/checkout@v4
@@ -46,15 +56,9 @@ jobs:
4656
image: swift:latest
4757
steps:
4858
- uses: actions/checkout@v4
49-
- name: Install dependencies
50-
run: apt-get update && apt-get install -y wget
5159
- name: Download .swift-format config
52-
run: wget -O .swift-format https://gist.githubusercontent.com/RISCfuture/e0c21afb7bd80a88d128a42bf40d2ecd/raw/.swift-format
53-
- name: Install swift-format
5460
run: |
55-
git clone https://github.com/swiftlang/swift-format.git
56-
cd swift-format
57-
swift build -c release
58-
cp .build/release/swift-format /usr/local/bin/
61+
apt-get update && apt-get install -y wget
62+
wget -O .swift-format https://gist.githubusercontent.com/RISCfuture/e0c21afb7bd80a88d128a42bf40d2ecd/raw/.swift-format
5963
- name: Run swift-format lint
60-
run: swift-format lint -r .
64+
run: swift format lint -r .

.github/workflows/doc.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
21
name: Deploy Documentation
32

43
on:
54
push:
65
branches: [master]
6+
workflow_dispatch:
77

8-
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
98
permissions:
109
contents: read
1110
pages: write
1211
id-token: write
1312

14-
# Allow one concurrent deployment
1513
concurrency:
1614
group: pages
1715
cancel-in-progress: true
1816

1917
jobs:
20-
# Build job
2118
build:
2219
name: Generate Documentation
2320
runs-on: macos-latest
@@ -57,7 +54,6 @@ jobs:
5754
with:
5855
path: "docs/"
5956

60-
# Deployment job
6157
deploy:
6258
environment:
6359
name: github-pages

Sources/SwiftNASR/Error.swift

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,121 +120,225 @@ extension Error: LocalizedError {
120120
public var errorDescription: String? {
121121
switch self {
122122
case .nullDistribution, .noSuchFilePrefix, .noSuchFile:
123+
#if canImport(Darwin)
123124
return String(localized: "Couldn’t load distribution.", comment: "error description")
125+
#else
126+
return "Couldn’t load distribution."
127+
#endif
124128
case .badResponse, .noData, .downloadFailed:
129+
#if canImport(Darwin)
125130
return String(localized: "Couldn’t download distribution.", comment: "error description")
131+
#else
132+
return "Couldn’t download distribution."
133+
#endif
126134
case .unknownARTCC, .unknownARTCCFrequency, .unknownFieldId,
127135
.unknownFrequencyFieldId, .invalidFrequency, .unknownFSS,
128136
.invalidRunwaySurface, .invalidPavementClassification,
129137
.invalidVGSI, .unknownNavaid, .invalidAltitudeFormat:
138+
#if canImport(Darwin)
130139
return String(localized: "Couldn’t parse distribution data.", comment: "error description")
140+
#else
141+
return "Couldn’t parse distribution data."
142+
#endif
131143
case .notYetLoaded:
144+
#if canImport(Darwin)
132145
return String(localized: "This NASR has not been loaded yet.", comment: "error description")
146+
#else
147+
return "This NASR has not been loaded yet."
148+
#endif
133149
}
134150
}
135151

136152
public var failureReason: String? {
137153
switch self {
138154
case .nullDistribution:
155+
#if canImport(Darwin)
139156
return String(
140157
localized: "Called .load() on a null distribution.",
141158
comment: "failure reason"
142159
)
160+
#else
161+
return "Called .load() on a null distribution."
162+
#endif
143163
case .badResponse(let response):
164+
#if canImport(Darwin)
144165
return String(
145166
localized: "Bad response: \(response.description).",
146167
comment: "failure reason"
147168
)
169+
#else
170+
return "Bad response: \(response.description)."
171+
#endif
148172
case .downloadFailed(let reason):
173+
#if canImport(Darwin)
149174
return String(localized: "Download failed: \(reason)", comment: "failure reason")
175+
#else
176+
return "Download failed: \(reason)"
177+
#endif
150178
case .noSuchFilePrefix(let prefix):
179+
#if canImport(Darwin)
151180
return String(
152181
localized: "Couldn’t find file in archive with prefix ‘\(prefix).’",
153182
comment: "failure reason"
154183
)
184+
#else
185+
return "Couldn’t find file in archive with prefix ‘\(prefix).’"
186+
#endif
155187
case .noData:
188+
#if canImport(Darwin)
156189
return String(localized: "No data was downloaded.", comment: "failure reason")
190+
#else
191+
return "No data was downloaded."
192+
#endif
157193
case .unknownARTCC(let ID):
194+
#if canImport(Darwin)
158195
return String(
159196
localized: "Referenced undefined ARTCC record with ID ‘\(ID)’.",
160197
comment: "failure reason"
161198
)
199+
#else
200+
return "Referenced undefined ARTCC record with ID ‘\(ID)’."
201+
#endif
162202
case let .unknownARTCCFrequency(frequency, ARTCC):
203+
#if canImport(Darwin)
163204
return String(
164205
localized: "Referenced undefined frequency ‘\(frequency)’ for ARTCC \(ARTCC.code).",
165206
comment: "failure reason"
166207
)
208+
#else
209+
return "Referenced undefined frequency ‘\(frequency)’ for ARTCC \(ARTCC.code)."
210+
#endif
167211
case let .unknownFieldId(fieldId, ARTCC):
212+
#if canImport(Darwin)
168213
return String(
169214
localized: "Unknown field ID ‘\(fieldId)’ at ‘\(ARTCC.code) \(ARTCC.locationName)’.",
170215
comment: "failure reason"
171216
)
217+
#else
218+
return "Unknown field ID ‘\(fieldId)’ at ‘\(ARTCC.code) \(ARTCC.locationName)’."
219+
#endif
172220
case let .unknownFrequencyFieldId(fieldId, frequency, ARTCC):
221+
#if canImport(Darwin)
173222
return String(
174223
localized:
175224
"Unknown field ID '\(fieldId)' for \(frequency.frequencyKHz) kHz at '\(ARTCC.code) \(ARTCC.locationName)'.",
176225
comment: "failure reason"
177226
)
227+
#else
228+
return "Unknown field ID '\(fieldId)' for \(frequency.frequencyKHz) kHz at '\(ARTCC.code) \(ARTCC.locationName)'."
229+
#endif
178230
case .invalidFrequency(let string):
231+
#if canImport(Darwin)
179232
return String(localized: "Invalid frequency ‘\(string)’.", comment: "failure reason")
233+
#else
234+
return "Invalid frequency ‘\(string)’."
235+
#endif
180236
case .unknownFSS(let ID):
237+
#if canImport(Darwin)
181238
return String(
182239
localized: "Continuation record references unknown FSS ‘\(ID)’.",
183240
comment: "failure reason"
184241
)
242+
#else
243+
return "Continuation record references unknown FSS ‘\(ID)’."
244+
#endif
185245
case .notYetLoaded:
246+
#if canImport(Darwin)
186247
return String(
187248
localized: "Attempted to access NASR data before .load() was called.",
188249
comment: "failure reason"
189250
)
251+
#else
252+
return "Attempted to access NASR data before .load() was called."
253+
#endif
190254
case .noSuchFile(let path):
255+
#if canImport(Darwin)
191256
return String(
192257
localized: "No such file in distribution: \(path).",
193258
comment: "failure reason"
194259
)
260+
#else
261+
return "No such file in distribution: \(path)."
262+
#endif
195263
case .invalidRunwaySurface(let string):
264+
#if canImport(Darwin)
196265
return String(localized: "Unknown runway surface ‘\(string)’.", comment: "failure reason")
266+
#else
267+
return "Unknown runway surface ‘\(string)’."
268+
#endif
197269
case .invalidPavementClassification(let string):
270+
#if canImport(Darwin)
198271
return String(
199272
localized: "Unknown pavement classification ‘\(string)’ for PCN.",
200273
comment: "failure reason"
201274
)
275+
#else
276+
return "Unknown pavement classification ‘\(string)’ for PCN."
277+
#endif
202278
case .invalidVGSI(let string):
279+
#if canImport(Darwin)
203280
return String(localized: "Unknown VGSI identifier ‘\(string)’.", comment: "failure reason")
281+
#else
282+
return "Unknown VGSI identifier ‘\(string)’."
283+
#endif
204284
case .unknownNavaid(let string):
285+
#if canImport(Darwin)
205286
return String(localized: "Unknown navaid ‘\(string)’.", comment: "failure reason")
287+
#else
288+
return "Unknown navaid ‘\(string)’."
289+
#endif
206290
case .invalidAltitudeFormat(let string):
291+
#if canImport(Darwin)
207292
return String(localized: "Invalid altitude format ‘\(string)’.", comment: "failure reason")
293+
#else
294+
return "Invalid altitude format ‘\(string)’."
295+
#endif
208296
}
209297
}
210298

211299
public var recoverySuggestion: String? {
212300
switch self {
213301
case .nullDistribution:
302+
#if canImport(Darwin)
214303
return String(
215304
localized:
216305
"Do not call .load() on a NullDistribution. Use NullDistribution for distributions that were previously loaded and serialized to disk.",
217306
comment: "recovery suggestion"
218307
)
308+
#else
309+
return "Do not call .load() on a NullDistribution. Use NullDistribution for distributions that were previously loaded and serialized to disk."
310+
#endif
219311
case .badResponse, .noData, .downloadFailed:
312+
#if canImport(Darwin)
220313
return String(
221314
localized: "Verify that the URL to the distribution is correct and accessible.",
222315
comment: "recovery suggestion"
223316
)
317+
#else
318+
return "Verify that the URL to the distribution is correct and accessible."
319+
#endif
224320
case .unknownARTCC, .unknownARTCCFrequency, .unknownFieldId,
225321
.unknownFrequencyFieldId, .invalidFrequency, .unknownFSS,
226322
.invalidRunwaySurface, .invalidPavementClassification,
227323
.invalidVGSI, .unknownNavaid, .noSuchFilePrefix, .noSuchFile,
228324
.invalidAltitudeFormat:
325+
#if canImport(Darwin)
229326
return String(
230327
localized: "The NASR FADDS format may have changed, requiring an update to SwiftNASR.",
231328
comment: "recovery suggestion"
232329
)
330+
#else
331+
return "The NASR FADDS format may have changed, requiring an update to SwiftNASR."
332+
#endif
233333
case .notYetLoaded:
334+
#if canImport(Darwin)
234335
return String(
235336
localized: "Call .load() before accessing NASR data.",
236337
comment: "recovery suggestion"
237338
)
339+
#else
340+
return "Call .load() before accessing NASR data."
341+
#endif
238342
}
239343
}
240344
}

Sources/SwiftNASR/Models/Types+Measurement.swift

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import CoreLocation
21
import Foundation
32

3+
#if canImport(CoreLocation)
4+
import CoreLocation
5+
#endif
6+
47
// MARK: - Location
58

69
public extension Location {
@@ -18,29 +21,33 @@ public extension Location {
1821
var elevation: Measurement<UnitLength>? {
1922
elevationFtMSL.map { Measurement(value: Double($0), unit: .feet) }
2023
}
24+
}
2125

22-
/// The coordinate as a CoreLocation coordinate.
23-
var coordinate: CLLocationCoordinate2D {
24-
CLLocationCoordinate2D(
25-
latitude: latitude.converted(to: .degrees).value,
26-
longitude: longitude.converted(to: .degrees).value
27-
)
28-
}
29-
30-
/// The location as a CoreLocation location, including altitude if available.
31-
var location: CLLocation {
32-
if let elevation {
33-
return CLLocation(
34-
coordinate: coordinate,
35-
altitude: elevation.converted(to: .meters).value,
36-
horizontalAccuracy: -1,
37-
verticalAccuracy: -1,
38-
timestamp: .distantPast
26+
#if canImport(CoreLocation)
27+
public extension Location {
28+
/// The coordinate as a CoreLocation coordinate.
29+
var coordinate: CLLocationCoordinate2D {
30+
CLLocationCoordinate2D(
31+
latitude: latitude.converted(to: .degrees).value,
32+
longitude: longitude.converted(to: .degrees).value
3933
)
4034
}
41-
return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
35+
36+
/// The location as a CoreLocation location, including altitude if available.
37+
var location: CLLocation {
38+
if let elevation {
39+
return CLLocation(
40+
coordinate: coordinate,
41+
altitude: elevation.converted(to: .meters).value,
42+
horizontalAccuracy: -1,
43+
verticalAccuracy: -1,
44+
timestamp: .distantPast
45+
)
46+
}
47+
return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
48+
}
4249
}
43-
}
50+
#endif
4451

4552
// MARK: - Bearing
4653

0 commit comments

Comments
 (0)