Skip to content

Commit

Permalink
recognise any number of newline characters (U+000A) to be backward co…
Browse files Browse the repository at this point in the history
…mpatible with Swift ≤ 5.3
  • Loading branch information
WowbaggersLiquidLunch committed Nov 1, 2020
1 parent 5b50d3f commit d8887d0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 42 deletions.
8 changes: 4 additions & 4 deletions Sources/PackageLoading/ToolsVersionLoader.swift
Expand Up @@ -131,7 +131,7 @@ public class ToolsVersionLoader: ToolsVersionLoaderProtocol {
///
/// A backward-incompatibility is not necessarily a malformation.
public enum BackwardIncompatibilityPre5_3_1 {
/// The line terminators at the start of the manifest is not either empty or a single `U+000A`.
/// The line terminators at the start of the manifest are not all `U+000A`.
case leadingLineTerminators(_ lineTerminators: Substring)
/// The horizontal spacing between "//" and "swift-tools-version" either is empty or uses whitespace characters unsupported by Swift ≤ 5.3.
case spacingAfterCommentMarker(_ spacing: Substring)
Expand Down Expand Up @@ -205,7 +205,7 @@ public class ToolsVersionLoader: ToolsVersionLoaderProtocol {
case let .backwardIncompatiblePre5_3_1(incompatibility, specifiedVersion):
switch incompatibility {
case let .leadingLineTerminators(lineTerminators):
return "leading line terminator sequence \(unicodeCodePointsPrefixedByUPlus(of: lineTerminators)) in manifest is supported by only Swift > 5.3; for the specified version \(specifiedVersion), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
return "leading line terminator sequence \(unicodeCodePointsPrefixedByUPlus(of: lineTerminators)) in manifest is supported by only Swift > 5.3; for the specified version \(specifiedVersion), only newline characters (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
case let .spacingAfterCommentMarker(spacing):
return "\(spacing.isEmpty ? "zero spacing" : "horizontal whitespace sequence \(unicodeCodePointsPrefixedByUPlus(of: spacing))") between '//' and 'swift-tools-version' is supported by only Swift > 5.3; consider using a single space (U+0020) for Swift \(specifiedVersion)"
}
Expand All @@ -224,7 +224,7 @@ public class ToolsVersionLoader: ToolsVersionLoaderProtocol {
public let contentsAfterToolsVersionSpecification: Substring
/// A Boolean value indicating whether the manifest represented in its constituent parts is backward-compatible with Swift ≤ 5.3.
public var isCompatibleWithPreSwift5_3_1: Bool {
(leadingLineTerminators.isEmpty || leadingLineTerminators == "\n") && toolsVersionSpecificationComponents.isCompatibleWithPreSwift5_3_1
leadingLineTerminators.allSatisfy { $0 == "\n" } && toolsVersionSpecificationComponents.isCompatibleWithPreSwift5_3_1
}
}

Expand Down Expand Up @@ -351,7 +351,7 @@ public class ToolsVersionLoader: ToolsVersionLoaderProtocol {

guard version > .v5_3 || manifestComponents.isCompatibleWithPreSwift5_3_1 else {
let manifestLeadingLineTerminators = manifestComponents.leadingLineTerminators
if !manifestLeadingLineTerminators.isEmpty && manifestLeadingLineTerminators != "\n" {
if !manifestLeadingLineTerminators.allSatisfy({ $0 == "\n" }) {
throw Error.backwardIncompatiblePre5_3_1(.leadingLineTerminators(manifestLeadingLineTerminators), specifiedVersion: version)
}

Expand Down
53 changes: 15 additions & 38 deletions Tests/PackageLoadingTests/ToolsVersionLoaderTests.swift
Expand Up @@ -55,6 +55,17 @@ class ToolsVersionLoaderTests: XCTestCase {
"// swift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
"// swift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
"// sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
// leading newline characters (U+000A), and 1 space (U+0020) between "//" and "swift-tools-version":
"\n// swift-tools-version:3.1" : (3, 1, 0, "3.1.0"),
"\n\n// swift-tools-version:3.1-dev" : (3, 1, 0, "3.1.0"),
"\n\n\n// swift-tools-version:5.8.0" : (5, 8, 0, "5.8.0"),
"\n\n\n\n// swift-tools-version:5.8.0-dev.al+sha.x" : (5, 8, 0, "5.8.0"),
"\n\n\n\n\n// swift-tools-version:3.1.2" : (3, 1, 2, "3.1.2"),
"\n\n\n\n\n\n// swift-tools-version:3.1.2;" : (3, 1, 2, "3.1.2"),
"\n\n\n\n\n\n\n// swift-tools-vErsion:3.1.2;;;;;" : (3, 1, 2, "3.1.2"),
"\n\n\n\n\n\n\n\n// swift-tools-version:3.1.2;x;x;x;x;x;" : (3, 1, 2, "3.1.2"),
"\n\n\n\n\n\n\n\n\n// swift-toolS-version:3.5.2;hello" : (3, 5, 2, "3.5.2"),
"\n\n\n\n\n\n\n\n\n\n// sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : (3, 5, 2, "3.5.2"),
// 1 character tabulation (U+0009) between "//" and "swift-tools-version" for Swift > 5.3:
"//\tswift-tools-version:5.4" : (5, 4, 0, "5.4.0"),
"//\tswift-tools-version:5.4-dev" : (5, 4, 0, "5.4.0"),
Expand Down Expand Up @@ -407,40 +418,6 @@ class ToolsVersionLoaderTests: XCTestCase {
// 2. Test that backward-incompatible leading line terminators are diagnosed before backward-incompatible spacings after the comment marker.
// 3. Test spacings after the comment marker.

// MARK: 2 leading line feed (U+000A)

let manifestSnippetWith2LeadingLineFeeds = [
"\u{A}\u{A}//swift-tools-version:3.1" : "3.1.0",
"\u{A}\u{A}//swift-tools-version:3.1-dev" : "3.1.0",
"\u{A}\u{A}//swift-tools-version:5.3" : "5.3.0",
"\u{A}\u{A}//swift-tools-version:5.3.0" : "5.3.0",
"\u{A}\u{A}//swift-tools-version:5.3-dev" : "5.3.0",
"\u{A}\u{A}//swift-tools-version:4.8.0" : "4.8.0",
"\u{A}\u{A}//swift-tools-version:4.8.0-dev.al+sha.x" : "4.8.0",
"\u{A}\u{A}//swift-tools-version:3.1.2" : "3.1.2",
"\u{A}\u{A}//swift-tools-version:3.1.2;" : "3.1.2",
"\u{A}\u{A}//swift-tools-vErsion:3.1.2;;;;;" : "3.1.2",
"\u{A}\u{A}//swift-tools-version:3.1.2;x;x;x;x;x;" : "3.1.2",
"\u{A}\u{A}//swift-toolS-version:3.5.2;hello" : "3.5.2",
"\u{A}\u{A}//sWiFt-tOoLs-vErSiOn:3.5.2\nkkk\n" : "3.5.2",
]

for (specification, toolsVersionString) in manifestSnippetWith2LeadingLineFeeds {
XCTAssertThrowsError(
try load(ByteString(encodingAsUTF8: specification)),
"a 'ToolsVersionLoader.Error' should've been thrown, because the manifest starts with more than 1 line terminator, and the specified version \(toolsVersionString) (≤ 5.3) supports at most 1 leading U+000A."
) { error in
guard let error = error as? ToolsVersionLoader.Error, case .backwardIncompatiblePre5_3_1(.leadingLineTerminators, _) = error else {
XCTFail("'ToolsVersionLoader.Error.backwardIncompatiblePre5_3_1(.leadingLineTerminators, _)' should've been thrown, but a different error is thrown.")
return
}
XCTAssertEqual(
error.description,
"leading line terminator sequence [U+000A, U+000A] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
)
}
}

// MARK: 1 leading u+000D

let manifestSnippetWith1LeadingCarriageReturn = [
Expand Down Expand Up @@ -470,7 +447,7 @@ class ToolsVersionLoaderTests: XCTestCase {
}
XCTAssertEqual(
error.description,
"leading line terminator sequence [U+000D] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
"leading line terminator sequence [U+000D] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only newline characters (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
)
}
}
Expand Down Expand Up @@ -504,7 +481,7 @@ class ToolsVersionLoaderTests: XCTestCase {
}
XCTAssertEqual(
error.description,
"leading line terminator sequence [U+000D, U+000A] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
"leading line terminator sequence [U+000D, U+000A] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only newline characters (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
)
}
}
Expand Down Expand Up @@ -538,7 +515,7 @@ class ToolsVersionLoaderTests: XCTestCase {
}
XCTAssertEqual(
error.description,
"leading line terminator sequence [U+000A, U+000B, U+000C, U+000D, U+000D, U+000A, U+0085, U+2028, U+2029] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
"leading line terminator sequence [U+000A, U+000B, U+000C, U+000D, U+000D, U+000A, U+0085, U+2028, U+2029] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only newline characters (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
)
}
}
Expand Down Expand Up @@ -574,7 +551,7 @@ class ToolsVersionLoaderTests: XCTestCase {
}
XCTAssertEqual(
error.description,
"leading line terminator sequence [U+000A, U+000B, U+000C, U+000D, U+000D, U+000A, U+0085, U+2028, U+2029] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only zero or one newline (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
"leading line terminator sequence [U+000A, U+000B, U+000C, U+000D, U+000D, U+000A, U+0085, U+2028, U+2029] in manifest is supported by only Swift > 5.3; for the specified version \(toolsVersionString), only newline characters (U+000A) at the beginning of the manifest is supported; consider moving the Swift tools version specification to the first line of the manifest"
)
}
}
Expand Down

0 comments on commit d8887d0

Please sign in to comment.