Skip to content

Commit

Permalink
Swift 6 language mode (#619)
Browse files Browse the repository at this point in the history
* Swift 6 mode

* Fix AsyncHTTPClient deprecation
  • Loading branch information
adam-fowler authored Oct 24, 2024
1 parent ba5f22a commit 9d44bcd
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 64 deletions.
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let package = Package(
.package(url: "https://github.com/apple/swift-metrics.git", "1.0.0"..<"3.0.0"),
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.7.2"),
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.13.1"),
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.21.0"),
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.23.0"),
.package(url: "https://github.com/adam-fowler/jmespath.swift.git", from: "1.0.2"),
],
targets: [
Expand Down Expand Up @@ -117,5 +117,6 @@ let package = Package(
.testTarget(name: "INIParserTests", dependencies: [
.byName(name: "INIParser"),
]),
]
],
swiftLanguageVersions: [.v5, .version("6")]
)
9 changes: 9 additions & 0 deletions Sources/SotoCore/Encoder/CodableProperties/DateCoders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,21 @@ public struct ISO8601DateCoder: CustomDecoder, CustomEncoder {
self.dateFormatters[0].string(from: value)
}

#if compiler(>=5.10)
nonisolated(unsafe) static let dateFormatters: [ISO8601DateFormatter] = {
let dateFormatters: [ISO8601DateFormatter] = [ISO8601DateFormatter(), ISO8601DateFormatter()]
dateFormatters[0].formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
dateFormatters[1].formatOptions = [.withFullDate, .withFullTime]
return dateFormatters
}()
#else
static let dateFormatters: [ISO8601DateFormatter] = {
let dateFormatters: [ISO8601DateFormatter] = [ISO8601DateFormatter(), ISO8601DateFormatter()]
dateFormatters[0].formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
dateFormatters[1].formatOptions = [.withFullDate, .withFullTime]
return dateFormatters
}()
#endif
}

/// Date coder for HTTP header format
Expand Down
8 changes: 8 additions & 0 deletions Sources/SotoCore/Encoder/QueryEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,19 @@ extension _QueryEncoder {
}
}

#if compiler(>=5.10)
nonisolated(unsafe) static let dateFormatter: ISO8601DateFormatter = {
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
return dateFormatter
}()
#else
static let dateFormatter: ISO8601DateFormatter = {
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
return dateFormatter
}()
#endif
}

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion Sources/SotoCore/HTTP/AWSHTTPRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal import SotoXML
#endif

/// Object encapsulating all the information needed to generate a raw HTTP request to AWS
public struct AWSHTTPRequest {
public struct AWSHTTPRequest: Sendable {
/// request URL
public var url: URL
/// request HTTP method
Expand Down
2 changes: 1 addition & 1 deletion Sources/SotoCore/HTTP/AsyncHTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extension AsyncHTTPClient.HTTPClient: AWSHTTPClient {
case .asyncSequence(let sequence, let length):
requestBody = .stream(
sequence,
length: length.map { .known($0) } ?? .unknown
length: length.map { .known(Int64($0)) } ?? .unknown
)
}
var httpRequest = HTTPClientRequest(url: request.url.absoluteString)
Expand Down
64 changes: 34 additions & 30 deletions Sources/SotoTestUtils/TestServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import SotoXML
import XCTest

/// Test server for AWSClient. Input and Output shapes are defined by process function
public class AWSTestServer {
public final class AWSTestServer: Sendable {
public enum Error: Swift.Error {
case notHead
case notBody
Expand All @@ -33,14 +33,14 @@ public class AWSTestServer {
}

// what are we returning
public enum ServiceProtocol {
public enum ServiceProtocol: Sendable {
case restjson
case json
case xml
}

// http incoming request
public struct Request {
public struct Request: Sendable {
public let method: HTTPMethod
public let uri: String
public let headers: [String: String]
Expand All @@ -55,7 +55,7 @@ public class AWSTestServer {
}

// http outgoing response
public struct Response {
public struct Response: Sendable {
public let httpStatus: HTTPResponseStatus
public let headers: [String: String]
public let body: ByteBuffer?
Expand All @@ -66,30 +66,30 @@ public class AWSTestServer {
self.body = body
}

public static let ok = Response(httpStatus: .ok)
public static var ok: Response { Response(httpStatus: .ok) }
}

/// Error type
public struct ErrorType {
public struct ErrorType: Sendable {
public let status: Int
public let errorCode: String
public let message: String

public var json: String { return "{\"__type\":\"\(self.errorCode)\", \"message\": \"\(self.message)\"}" }
public var xml: String { return "<Error><Code>\(self.errorCode)</Code><Message>\(self.message)</Message></Error>" }

public static let badRequest = ErrorType(status: 400, errorCode: "BadRequest", message: "AWSTestServer_ErrorType_BadRequest")
public static let accessDenied = ErrorType(status: 401, errorCode: "AccessDenied", message: "AWSTestServer_ErrorType_AccessDenied")
public static let notFound = ErrorType(status: 404, errorCode: "NotFound", message: "AWSTestServer_ErrorType_NotFound")
public static let tooManyRequests = ErrorType(status: 429, errorCode: "TooManyRequests", message: "AWSTestServer_ErrorType_TooManyRequests")
public static var badRequest: ErrorType { ErrorType(status: 400, errorCode: "BadRequest", message: "AWSTestServer_ErrorType_BadRequest") }
public static var accessDenied: ErrorType { ErrorType(status: 401, errorCode: "AccessDenied", message: "AWSTestServer_ErrorType_AccessDenied") }
public static var notFound: ErrorType { ErrorType(status: 404, errorCode: "NotFound", message: "AWSTestServer_ErrorType_NotFound") }
public static var tooManyRequests: ErrorType { ErrorType(status: 429, errorCode: "TooManyRequests", message: "AWSTestServer_ErrorType_TooManyRequests") }

public static let `internal` = ErrorType(status: 500, errorCode: "InternalFailure", message: "AWSTestServer_ErrorType_InternalFailure")
public static let notImplemented = ErrorType(status: 501, errorCode: "NotImplemented", message: "AWSTestServer_ErrorType_NotImplemented")
public static let serviceUnavailable = ErrorType(status: 503, errorCode: "ServiceUnavailable", message: "AWSTestServer_ErrorType_ServiceUnavailable")
public static var `internal`: ErrorType { ErrorType(status: 500, errorCode: "InternalFailure", message: "AWSTestServer_ErrorType_InternalFailure") }
public static var notImplemented: ErrorType { ErrorType(status: 501, errorCode: "NotImplemented", message: "AWSTestServer_ErrorType_NotImplemented") }
public static var serviceUnavailable: ErrorType { ErrorType(status: 503, errorCode: "ServiceUnavailable", message: "AWSTestServer_ErrorType_ServiceUnavailable") }
}

/// result from process
public enum Result<Output> {
public enum Result<Output: Sendable>: Sendable {
case result(Output, continueProcessing: Bool = false)
case error(ErrorType, continueProcessing: Bool = false)
}
Expand Down Expand Up @@ -174,15 +174,17 @@ extension AWSTestServer {
public let lastUpdated: Date
public let type: String

public static let `default` = EC2InstanceMetaData(
accessKeyId: "EC2ACCESSKEYID",
secretAccessKey: "EC2SECRETACCESSKEY",
token: "EC2SESSIONTOKEN",
expiration: Date(timeIntervalSinceNow: 3600),
code: "ec2-test-role",
lastUpdated: Date(timeIntervalSinceReferenceDate: 0),
type: "type"
)
public static var `default`: EC2InstanceMetaData {
.init(
accessKeyId: "EC2ACCESSKEYID",
secretAccessKey: "EC2SECRETACCESSKEY",
token: "EC2SESSIONTOKEN",
expiration: Date(timeIntervalSinceNow: 3600),
code: "ec2-test-role",
lastUpdated: Date(timeIntervalSinceReferenceDate: 0),
type: "type"
)
}

enum CodingKeys: String, CodingKey {
case accessKeyId = "AccessKeyId"
Expand All @@ -202,13 +204,15 @@ extension AWSTestServer {
public let expiration: Date
public let roleArn: String

public static let `default` = ECSMetaData(
accessKeyId: "ECSACCESSKEYID",
secretAccessKey: "ECSSECRETACCESSKEY",
token: "ECSSESSIONTOKEN",
expiration: Date(timeIntervalSinceNow: 3600),
roleArn: "arn:aws:iam:000000000000:role/ecs-test-role"
)
public static var `default`: ECSMetaData {
.init(
accessKeyId: "ECSACCESSKEYID",
secretAccessKey: "ECSSECRETACCESSKEY",
token: "ECSSESSIONTOKEN",
expiration: Date(timeIntervalSinceNow: 3600),
roleArn: "arn:aws:iam:000000000000:role/ecs-test-role"
)
}

enum CodingKeys: String, CodingKey {
case accessKeyId = "AccessKeyId"
Expand Down
9 changes: 9 additions & 0 deletions Sources/SotoXML/XMLDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -658,12 +658,21 @@ private class _XMLDecoder: Decoder {
}
}

#if compiler(>=5.10)
nonisolated(unsafe) static let dateFormatters: [ISO8601DateFormatter] = {
let dateFormatters: [ISO8601DateFormatter] = [ISO8601DateFormatter(), ISO8601DateFormatter()]
dateFormatters[0].formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
dateFormatters[1].formatOptions = [.withFullDate, .withFullTime]
return dateFormatters
}()
#else
static let dateFormatters: [ISO8601DateFormatter] = {
let dateFormatters: [ISO8601DateFormatter] = [ISO8601DateFormatter(), ISO8601DateFormatter()]
dateFormatters[0].formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
dateFormatters[1].formatOptions = [.withFullDate, .withFullTime]
return dateFormatters
}()
#endif
}

//===----------------------------------------------------------------------===//
Expand Down
8 changes: 8 additions & 0 deletions Sources/SotoXML/XMLEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -560,11 +560,19 @@ extension _XMLEncoder {
}
}

#if compiler(>=5.10)
nonisolated(unsafe) static let dateFormatter: ISO8601DateFormatter = {
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
return dateFormatter
}()
#else
static let dateFormatter: ISO8601DateFormatter = {
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate, .withFullTime, .withFractionalSeconds]
return dateFormatter
}()
#endif
}

// MARK: - _XMLReferencingEncoder
Expand Down
4 changes: 0 additions & 4 deletions Tests/INIParserTests/INIParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,4 @@ class INIParserTests: XCTestCase {
XCTAssertEqual(ini?.sections["汉化"]?["变量2"] ?? "", "加拿大。")
XCTAssertNotNil(ini?.sections[" 乱死了 "])
}

static var allTests = [
("testExample", testExample),
]
}
6 changes: 3 additions & 3 deletions Tests/SotoCoreTests/AWSClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class AWSClientTests: XCTestCase {

func testRequestStreaming(config: AWSServiceConfig, client: AWSClient, server: AWSTestServer, bufferSize: Int, blockSize: Int) async throws {
struct Input: AWSEncodableShape {
static var _options: AWSShapeOptions = [.allowStreaming]
static var _options: AWSShapeOptions { [.allowStreaming] }
let payload: AWSHTTPBody
func encode(to encoder: Encoder) throws {
try self.payload.encode(to: encoder)
Expand Down Expand Up @@ -309,7 +309,7 @@ class AWSClientTests: XCTestCase {

func testRequestStreamingWithPayload(_ payload: AWSHTTPBody) async throws {
struct Input: AWSEncodableShape {
static var _options: AWSShapeOptions = [.allowStreaming]
static var _options: AWSShapeOptions { [.allowStreaming] }
let payload: AWSHTTPBody
func encode(to encoder: Encoder) throws {
try self.payload.encode(to: encoder)
Expand Down Expand Up @@ -359,7 +359,7 @@ class AWSClientTests: XCTestCase {

func testRequestChunkedStreaming() async throws {
struct Input: AWSEncodableShape {
static var _options: AWSShapeOptions = [.allowStreaming, .allowChunkedStreaming, .rawPayload]
static let _options: AWSShapeOptions = [.allowStreaming, .allowChunkedStreaming, .rawPayload]
let payload: AWSHTTPBody
func encode(to encoder: Encoder) throws {
try self.payload.encode(to: encoder)
Expand Down
2 changes: 1 addition & 1 deletion Tests/SotoCoreTests/AWSRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ class AWSRequestTests: XCTestCase {
let number: Int
}
struct Input: AWSEncodableShape {
static var _xmlRootNodeName: String? = "Payload"
static let _xmlRootNodeName: String? = "Payload"
let payload: Payload

func encode(to encoder: Encoder) throws {
Expand Down
11 changes: 5 additions & 6 deletions Tests/SotoCoreTests/LoggingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -243,21 +243,20 @@ struct LoggingCollector: LogHandler {
var logs: Logs
var internalHandler: LogHandler

class Logs {
struct Logs {
struct Entry {
var level: Logger.Level
var message: String
var metadata: [String: String]
}

private var lock = NIOLock()
private var logs: [Entry] = []
private let logs: NIOLockedValueBox<[Entry]> = .init([])

var allEntries: [Entry] { return self.lock.withLock { self.logs } }
var allEntries: [Entry] { return self.logs.withLockedValue { $0 } }

func append(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?) {
self.lock.withLock {
self.logs.append(Entry(
self.logs.withLockedValue {
$0.append(Entry(
level: level,
message: message.description,
metadata: metadata?.mapValues { $0.description } ?? [:]
Expand Down
2 changes: 0 additions & 2 deletions Tests/SotoCoreTests/QueryEncoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import SotoTestUtils
import XCTest

class QueryEncoderTests: XCTestCase {
@EnvironmentVariable("ENABLE_TIMING_TESTS", default: true) static var enableTimingTests: Bool

func testQuery(_ value: some Encodable, query: String) {
do {
let query2 = try QueryEncoder().encode(value)
Expand Down
2 changes: 1 addition & 1 deletion Tests/SotoCoreTests/TracingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ final class TracingTests: XCTestCase {
private func XCTAssertSpanAttributesEqual(
_ lhs: @autoclosure () -> SpanAttributes,
_ rhs: @autoclosure () -> [String: SpanAttribute],
file: StaticString = #file,
file: StaticString = #filePath,
line: UInt = #line
) {
var rhs = rhs()
Expand Down
Loading

0 comments on commit 9d44bcd

Please sign in to comment.