Skip to content

Commit e13c1d6

Browse files
authored
Strict Concurrency Support (#10)
* Declare Sendable conformances * Enable strict concurrency checking * Address Sendable warnings * Fix warning * Upgrade AWS SDK * Replace use of ISO8601DateFormatter * Replace SwiftLint plugin with Danger Swift * SwiftLint fixes * Remove macOS directive * Update toolchain * Replace @retroactive with fully qualified names
1 parent e0a4d3b commit e13c1d6

File tree

12 files changed

+95
-135
lines changed

12 files changed

+95
-135
lines changed

.github/workflows/danger.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Run Danger
2+
on:
3+
workflow_dispatch:
4+
pull_request:
5+
types:
6+
- opened
7+
- reopened
8+
- synchronize
9+
- ready_for_review
10+
11+
jobs:
12+
build:
13+
if: github.event.pull_request.draft == false
14+
name: Run Danger
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: write
18+
issues: write
19+
pull-requests: write
20+
steps:
21+
- name: Git checkout
22+
uses: actions/checkout@v4
23+
- name: Danger
24+
uses: 417-72KI/danger-swiftlint@v5.9
25+
env:
26+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dangerfile.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Danger
2+
3+
extension String: Error {}
4+
5+
let danger = Danger()
6+
7+
if danger.github.pullRequest.body == nil {
8+
danger.fail("Please add a description to this Pull Request")
9+
}
10+
11+
SwiftLint
12+
.lint(
13+
.all(directory: nil),
14+
configFile: ".swiftlint.yml"
15+
)

Package.resolved

Lines changed: 6 additions & 105 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 5.7
1+
// swift-tools-version: 5.9
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
@@ -12,7 +12,7 @@ let package = Package(
1212
.library(name: "Secrets", targets: ["Secrets"])
1313
],
1414
dependencies: [
15-
.package(url: "https://github.com/awslabs/aws-sdk-swift.git", from: "0.19.0")
15+
.package(url: "https://github.com/awslabs/aws-sdk-swift.git", from: "1.0.0")
1616
],
1717
targets: [
1818
.testTarget(
@@ -30,7 +30,7 @@ let package = Package(
3030
]
3131
)
3232

33-
let genericTargets: [Target] = [
33+
let regularTargets: [Target] = [
3434
.target(
3535
name: "EmailSender",
3636
dependencies: [
@@ -51,11 +51,8 @@ let genericTargets: [Target] = [
5151
)
5252
]
5353

54-
#if os(macOS)
55-
package.dependencies.append(.package(url: "https://github.com/realm/SwiftLint.git", exact: "0.54.0"))
56-
for target in genericTargets {
57-
target.plugins = [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")]
54+
for target in regularTargets {
55+
target.swiftSettings = [.enableExperimentalFeature("StrictConcurrency")]
5856
}
59-
#endif
6057

61-
package.targets.append(contentsOf: genericTargets)
58+
package.targets.append(contentsOf: regularTargets)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Swifty helpers for working with the Swift [AWS SDK](https://github.com/awslabs/a
44

55
## 📱 Requirements
66

7-
Swift 5.7 toolchain with Swift Package Manager.
7+
Swift 5.9 toolchain with Swift Package Manager.
88

99
## 🖥 Installation
1010

Sources/EmailSender/EmailSender.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
// Created by Mathew Gacy on 12/8/23.
66
//
77

8-
import AWSSES
8+
@preconcurrency import AWSSES
99
import Foundation
1010

1111
/// A type that sends emails.
12-
public struct EmailSender {
12+
public struct EmailSender: Sendable {
1313
/// A closure returning a message ID after sending an email.
1414
public var send: @Sendable (Recipients, Sender, Subject, Body) async throws -> MessageID?
1515

Sources/Persistence/Persistence.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Created by Mathew Gacy on 12/8/23.
66
//
77

8-
import AWSDynamoDB
8+
@preconcurrency import AWSDynamoDB
99
import Foundation
1010

1111
/// Represents the data for an attribute. Each attribute value is described as a name-value pair.
@@ -15,7 +15,7 @@ import Foundation
1515
public typealias AttributeValue = DynamoDBClientTypes.AttributeValue
1616

1717
/// A type that persists collections of attributes.
18-
public struct Persistence {
18+
public struct Persistence: Sendable {
1919
/// A closure to modify the attributes of persisted values.
2020
///
2121
/// Use this to add additional attributes like a timestamp or to perform validation of all
@@ -67,7 +67,7 @@ public extension Persistence {
6767
}
6868

6969
/// A type that creates ``Persistence`` instances.
70-
public struct PersistenceFactory {
70+
public struct PersistenceFactory: Sendable {
7171
/// The region where the table is located.
7272
public typealias Region = String
7373

Sources/Persistence/TimestampProvider.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,28 @@
88
import Foundation
99

1010
/// A class of types providing user-readable representations of dates.
11-
public protocol DateFormatting {
11+
public protocol DateFormatting: Sendable {
1212
/// Returns a string representation of the specified date.
1313
///
1414
/// - Parameter date: The date to be represented.
1515
/// - Returns: A user-readable string representing the date.
1616
func string(from date: Date) -> String
1717
}
1818

19-
extension DateFormatter: DateFormatting {}
20-
21-
extension ISO8601DateFormatter: DateFormatting {}
19+
extension DateFormatter: DateFormatting {
20+
public static let iso8601: DateFormatter = {
21+
let formatter = DateFormatter()
22+
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
23+
formatter.calendar = Calendar(identifier: .iso8601)
24+
formatter.timeZone = TimeZone(secondsFromGMT: 0)
25+
formatter.locale = Locale(identifier: "en_US_POSIX")
26+
return formatter
27+
}()
28+
}
2229

2330
/// A type to provide timestamps.
24-
public struct TimestampProvider {
25-
private let dateProvider: () -> Date
31+
public struct TimestampProvider: Sendable {
32+
private let dateProvider: @Sendable () -> Date
2633
private let formatter: any DateFormatting
2734

2835
/// Creates an instance.
@@ -31,7 +38,7 @@ public struct TimestampProvider {
3138
/// - dateProvider: A closure returning the current date.
3239
/// - formatter: The date formatter to use to format the current date.
3340
public init(
34-
dateProvider: @escaping () -> Date,
41+
dateProvider: @escaping @Sendable () -> Date,
3542
formatter: DateFormatting
3643
) {
3744
self.dateProvider = dateProvider
@@ -48,7 +55,7 @@ public extension TimestampProvider {
4855
/// A live implementation.
4956
static var live: Self {
5057
.init(
51-
dateProvider: Date.init,
52-
formatter: ISO8601DateFormatter())
58+
dateProvider: { Date() },
59+
formatter: DateFormatter.iso8601)
5360
}
5461
}

Sources/Secrets/SecretValue.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ protocol SecretValue: Equatable {
3232
var secretString: String? { get }
3333
}
3434

35+
extension AWSSecretsManager.GetSecretValueOutput: Swift.Equatable {
36+
public static func == (lhs: GetSecretValueOutput, rhs: GetSecretValueOutput) -> Bool {
37+
lhs.arn == rhs.arn
38+
&& lhs.name == rhs.name
39+
&& lhs.secretBinary == rhs.secretBinary
40+
&& lhs.secretString == rhs.secretString
41+
}
42+
}
3543
extension GetSecretValueOutput: SecretValue {}
3644

45+
extension AWSSecretsManager.SecretsManagerClientTypes.SecretValueEntry: Swift.Equatable {
46+
public static func == (lhs: SecretsManagerClientTypes.SecretValueEntry, rhs: SecretsManagerClientTypes.SecretValueEntry) -> Bool {
47+
lhs.arn == rhs.arn
48+
&& lhs.name == rhs.name
49+
&& lhs.secretBinary == rhs.secretBinary
50+
&& lhs.secretString == rhs.secretString
51+
}
52+
}
3753
extension SecretsManagerClientTypes.SecretValueEntry: SecretValue {}

Sources/Secrets/Secrets.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Created by Mathew Gacy on 12/22/23.
66
//
77

8-
import AWSSecretsManager
8+
@preconcurrency import AWSSecretsManager
99
import Foundation
1010

1111
/// A secret stored by AWS Secrets Manager.

0 commit comments

Comments
 (0)