Skip to content

Commit a8ac0b2

Browse files
allow any number of any horizontal whitespace character between "//" and "swift-tools-version"
- Replaced the regex pattern for matching 1 single space character (" ") with the pattern `\h*?` for matching 0 or more (as few as possible) horizontal whitespace character between "//" and "swift-tools-version". - Made the comments right above `regex` into `regex`'s documentation by changing "//"s into "///"s. - Specified that only _horizontal_ whitespace characters are allowed. - Expanded test cases to account for different numbers of different whitespace characters. - FIXME: Newline and line feed cause tests failures.
1 parent a6daacf commit a8ac0b2

File tree

2 files changed

+73
-5
lines changed

2 files changed

+73
-5
lines changed

Sources/PackageLoading/ToolsVersionLoader.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ public class ToolsVersionLoader: ToolsVersionLoaderProtocol {
174174
return (versionSpecifier, splitted.count == 1 ? [] : Array(splitted[1]))
175175
}
176176

177-
// The regex to match swift tools version specification:
178-
// * It should start with `//` followed by any amount of whitespace.
179-
// * Following that it should contain the case insensitive string `swift-tools-version:`.
180-
// * The text between the above string and `;` or string end becomes the tools version specifier.
177+
/// The regex to match swift tools version specification:
178+
/// * It should start with `//` followed by any amount of _horizontal_ whitespace characters.
179+
/// * Following that it should contain the case insensitive string `swift-tools-version:`.
180+
/// * The text between the above string and `;` or string end becomes the tools version specifier.
181181
static let regex = try! NSRegularExpression(
182-
pattern: "^// swift-tools-version:(.*?)(?:;.*|$)",
182+
pattern: "^//\\h*?swift-tools-version:(.*?)(?:;.*|$)",
183183
options: [.caseInsensitive])
184184
}

Tests/PackageLoadingTests/ToolsVersionLoaderTests.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ class ToolsVersionLoaderTests: XCTestCase {
3333
func testBasics() throws {
3434

3535
let validVersions = [
36+
// No space between "//" and "swift-tools-version":
37+
"//swift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
38+
"//swift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
39+
"//swift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
40+
"//swift-tools-version:5.8.0-dev.al+sha.x" : (5, 8, 0, "5.8.0"),
41+
"//swift-tools-version:3.1.2" : (3, 1, 2, "3.1.2"),
42+
"//swift-tools-version:3.1.2;" : (3, 1, 2, "3.1.2"),
43+
"//swift-tools-vErsion:3.1.2;;;;;" : (3, 1, 2, "3.1.2"),
44+
"//swift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
45+
"//swift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
46+
"//sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
47+
// 1 space character (" ") between "//" and "swift-tools-version":
3648
"// swift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
3749
"// swift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
3850
"// swift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
@@ -43,6 +55,39 @@ class ToolsVersionLoaderTests: XCTestCase {
4355
"// swift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
4456
"// swift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
4557
"// sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
58+
// 1 horizontal tab character (" ") between "//" and "swift-tools-version":
59+
"//\tswift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
60+
"//\tswift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
61+
"//\tswift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
62+
"//\tswift-tools-version:5.8.0-dev.al+sha.x" : (5, 8, 0, "5.8.0"),
63+
"//\tswift-tools-version:3.1.2" : (3, 1, 2, "3.1.2"),
64+
"//\tswift-tools-version:3.1.2;" : (3, 1, 2, "3.1.2"),
65+
"//\tswift-tools-vErsion:3.1.2;;;;;" : (3, 1, 2, "3.1.2"),
66+
"//\tswift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
67+
"//\tswift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
68+
"//\tsWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
69+
// 1 horizontal tab character followed by 1 space character (" ") between "//" and "swift-tools-version":
70+
"// \tswift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
71+
"// \tswift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
72+
"// \tswift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
73+
"// \tswift-tools-version:5.8.0-dev.al+sha.x" : (5, 8, 0, "5.8.0"),
74+
"// \tswift-tools-version:3.1.2" : (3, 1, 2, "3.1.2"),
75+
"// \tswift-tools-version:3.1.2;" : (3, 1, 2, "3.1.2"),
76+
"// \tswift-tools-vErsion:3.1.2;;;;;" : (3, 1, 2, "3.1.2"),
77+
"// \tswift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
78+
"// \tswift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
79+
"// \tsWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
80+
// An assortment of horizontal whitespace characters between "//" and "swift-tools-version":
81+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
82+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
83+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
84+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:5.8.0-dev.al+sha.x" : (5, 8, 0, "5.8.0"),
85+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:3.1.2" : (3, 1, 2, "3.1.2"),
86+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:3.1.2;" : (3, 1, 2, "3.1.2"),
87+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-vErsion:3.1.2;;;;;" : (3, 1, 2, "3.1.2"),
88+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
89+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}swift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
90+
"//\u{A0}\u{1680}\t\u{2000}\u{2001} \u{2002}\u{202F}\u{3000}sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
4691
]
4792

4893
for (version, result) in validVersions {
@@ -105,6 +150,29 @@ class ToolsVersionLoaderTests: XCTestCase {
105150
assertFailure("// swift-tools-version:6.1.2.0\n", "6.1.2.0")
106151
assertFailure("// swift-tools-version:-1.1.2\n", "-1.1.2")
107152
assertFailure("// swift-tools-version:3.1hello", "3.1hello")
153+
154+
// FIXME: Newline and line feed characters following "//" cause test failures.
155+
156+
// Verify no matching for vertical white space charaters between "//" and "swift-tools-version":
157+
assertFailure("//\nswift-tools-version:5.3\n", "//\nswift-tools-version:5.3")
158+
assertFailure("// \nswift-tools-version:5.3\n", "// \nswift-tools-version:5.3")
159+
assertFailure("//\n swift-tools-version:5.3\n", "//\n swift-tools-version:5.3")
160+
assertFailure("//\rswift-tools-version:5.3\n", "//\rswift-tools-version:5.3")
161+
assertFailure("// \rswift-tools-version:5.3\n", "// \rswift-tools-version:5.3")
162+
assertFailure("//\r swift-tools-version:5.3\n", "//\r swift-tools-version:5.3")
163+
assertFailure("//\r\nswift-tools-version:5.3\n", "//\r\nswift-tools-version:5.3")
164+
assertFailure("//\n\rswift-tools-version:5.3\n", "//\n\rswift-tools-version:5.3")
165+
assertFailure("//\u{B}swift-tools-version:5.3\n", "//\u{B}swift-tools-version:5.3")
166+
assertFailure("//\u{2028}swift-tools-version:5.3\n", "//\u{2028}swift-tools-version:5.3")
167+
assertFailure("//\u{2029}swift-tools-version:5.3\n", "//\u{2029}swift-tools-version:5.3")
168+
169+
// Verify no matching for related Unicode characters without `White_Space` property, between "//" and "swift-tools-version":
170+
assertFailure("//\u{180E}swift-tools-version:5.3\n", "//\u{180E}swift-tools-version:5.3")
171+
assertFailure("//\u{200B}swift-tools-version:5.3\n", "//\u{200B}swift-tools-version:5.3")
172+
assertFailure("//\u{200C}swift-tools-version:5.3\n", "//\u{200C}swift-tools-version:5.3")
173+
assertFailure("//\u{200D}swift-tools-version:5.3\n", "//\u{200D}swift-tools-version:5.3")
174+
assertFailure("//\u{2060}swift-tools-version:5.3\n", "//\u{2060}swift-tools-version:5.3")
175+
assertFailure("//\u{FEFF}swift-tools-version:5.3\n", "//\u{FEFF}swift-tools-version:5.3")
108176
}
109177

110178
func testVersionSpecificManifest() throws {

0 commit comments

Comments
 (0)