Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strict Concurrency Support #10

Merged
merged 11 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/danger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Run Danger
on:
workflow_dispatch:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review

jobs:
build:
if: github.event.pull_request.draft == false
name: Run Danger
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Git checkout
uses: actions/checkout@v4
- name: Danger
uses: 417-72KI/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 changes: 15 additions & 0 deletions Dangerfile.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Danger

extension String: Error {}

let danger = Danger()

if danger.github.pullRequest.body == nil {
danger.fail("Please add a description to this Pull Request")
}

SwiftLint
.lint(
.all(directory: nil),
configFile: ".swiftlint.yml"
)
111 changes: 6 additions & 105 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/awslabs/aws-crt-swift",
"state" : {
"revision" : "fd1756b6e5c9fd1a906edfb743f7cb64c2c98639",
"version" : "0.17.0"
"revision" : "7b42e0343f28b3451aab20840dc670abd12790bd",
"version" : "0.36.0"
}
},
{
"identity" : "aws-sdk-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/awslabs/aws-sdk-swift",
"state" : {
"revision" : "3d2cfde16273c8fabd02416647d88e2824bded90",
"version" : "0.32.0"
}
},
{
"identity" : "collectionconcurrencykit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
"state" : {
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
"version" : "0.2.0"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
"state" : {
"revision" : "db51c407d3be4a051484a141bf0bff36c43d3b1e",
"version" : "1.8.0"
"revision" : "57b74dba32d24e52d07953a2ce5f9d3d27cbc975",
"version" : "1.0.24"
}
},
{
"identity" : "smithy-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/smithy-lang/smithy-swift",
"state" : {
"revision" : "ca28bf2c2b44ceb8c60b1e72b08f63aebc9b68b6",
"version" : "0.36.0"
}
},
{
"identity" : "sourcekitten",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/SourceKitten.git",
"state" : {
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
"version" : "0.34.1"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
"version" : "1.2.3"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections",
"state" : {
"revision" : "a902f1823a7ff3c9ab2fba0f992396b948eda307",
"version" : "1.0.5"
"revision" : "041be5fd2755309fb3132fffc43b12a26c8bf6a8",
"version" : "0.82.0"
}
},
{
Expand All @@ -80,60 +35,6 @@
"revision" : "532d8b529501fb73a2455b179e0bbb6d49b652ed",
"version" : "1.5.3"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
"version" : "509.0.2"
}
},
{
"identity" : "swiftlint",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/SwiftLint.git",
"state" : {
"revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
"version" : "0.54.0"
}
},
{
"identity" : "swiftytexttable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
"state" : {
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
"version" : "0.9.0"
}
},
{
"identity" : "swxmlhash",
"kind" : "remoteSourceControl",
"location" : "https://github.com/drmohundro/SWXMLHash.git",
"state" : {
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
"version" : "7.0.2"
}
},
{
"identity" : "xmlcoder",
"kind" : "remoteSourceControl",
"location" : "https://github.com/MaxDesiatov/XMLCoder.git",
"state" : {
"revision" : "80b4a1646399b8e4e0ce80711653476a85bd5e37",
"version" : "0.17.0"
}
},
{
"identity" : "yams",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/Yams.git",
"state" : {
"revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
"version" : "5.0.6"
}
}
],
"version" : 2
Expand Down
15 changes: 6 additions & 9 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.7
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -12,7 +12,7 @@ let package = Package(
.library(name: "Secrets", targets: ["Secrets"])
],
dependencies: [
.package(url: "https://github.com/awslabs/aws-sdk-swift.git", from: "0.19.0")
.package(url: "https://github.com/awslabs/aws-sdk-swift.git", from: "1.0.0")
],
targets: [
.testTarget(
Expand All @@ -30,7 +30,7 @@ let package = Package(
]
)

let genericTargets: [Target] = [
let regularTargets: [Target] = [
.target(
name: "EmailSender",
dependencies: [
Expand All @@ -51,11 +51,8 @@ let genericTargets: [Target] = [
)
]

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

package.targets.append(contentsOf: genericTargets)
package.targets.append(contentsOf: regularTargets)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Swifty helpers for working with the Swift [AWS SDK](https://github.com/awslabs/a

## 📱 Requirements

Swift 5.7 toolchain with Swift Package Manager.
Swift 5.9 toolchain with Swift Package Manager.

## 🖥 Installation

Expand Down
4 changes: 2 additions & 2 deletions Sources/EmailSender/EmailSender.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// Created by Mathew Gacy on 12/8/23.
//

import AWSSES
@preconcurrency import AWSSES
import Foundation

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

Expand Down
6 changes: 3 additions & 3 deletions Sources/Persistence/Persistence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Mathew Gacy on 12/8/23.
//

import AWSDynamoDB
@preconcurrency import AWSDynamoDB
import Foundation

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

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

/// A type that creates ``Persistence`` instances.
public struct PersistenceFactory {
public struct PersistenceFactory: Sendable {
/// The region where the table is located.
public typealias Region = String

Expand Down
25 changes: 16 additions & 9 deletions Sources/Persistence/TimestampProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,28 @@
import Foundation

/// A class of types providing user-readable representations of dates.
public protocol DateFormatting {
public protocol DateFormatting: Sendable {
/// Returns a string representation of the specified date.
///
/// - Parameter date: The date to be represented.
/// - Returns: A user-readable string representing the date.
func string(from date: Date) -> String
}

extension DateFormatter: DateFormatting {}

extension ISO8601DateFormatter: DateFormatting {}
extension DateFormatter: DateFormatting {
public static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}

/// A type to provide timestamps.
public struct TimestampProvider {
private let dateProvider: () -> Date
public struct TimestampProvider: Sendable {
private let dateProvider: @Sendable () -> Date
private let formatter: any DateFormatting

/// Creates an instance.
Expand All @@ -31,7 +38,7 @@ public struct TimestampProvider {
/// - dateProvider: A closure returning the current date.
/// - formatter: The date formatter to use to format the current date.
public init(
dateProvider: @escaping () -> Date,
dateProvider: @escaping @Sendable () -> Date,
formatter: DateFormatting
) {
self.dateProvider = dateProvider
Expand All @@ -48,7 +55,7 @@ public extension TimestampProvider {
/// A live implementation.
static var live: Self {
.init(
dateProvider: Date.init,
formatter: ISO8601DateFormatter())
dateProvider: { Date() },
formatter: DateFormatter.iso8601)
}
}
16 changes: 16 additions & 0 deletions Sources/Secrets/SecretValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ protocol SecretValue: Equatable {
var secretString: String? { get }
}

extension AWSSecretsManager.GetSecretValueOutput: Swift.Equatable {
public static func == (lhs: GetSecretValueOutput, rhs: GetSecretValueOutput) -> Bool {
lhs.arn == rhs.arn
&& lhs.name == rhs.name
&& lhs.secretBinary == rhs.secretBinary
&& lhs.secretString == rhs.secretString
}
}
extension GetSecretValueOutput: SecretValue {}

extension AWSSecretsManager.SecretsManagerClientTypes.SecretValueEntry: Swift.Equatable {
public static func == (lhs: SecretsManagerClientTypes.SecretValueEntry, rhs: SecretsManagerClientTypes.SecretValueEntry) -> Bool {
lhs.arn == rhs.arn
&& lhs.name == rhs.name
&& lhs.secretBinary == rhs.secretBinary
&& lhs.secretString == rhs.secretString
}
}
extension SecretsManagerClientTypes.SecretValueEntry: SecretValue {}
2 changes: 1 addition & 1 deletion Sources/Secrets/Secrets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Mathew Gacy on 12/22/23.
//

import AWSSecretsManager
@preconcurrency import AWSSecretsManager
import Foundation

/// A secret stored by AWS Secrets Manager.
Expand Down
4 changes: 2 additions & 2 deletions Tests/PersistenceTests/PersistenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class PersistenceTests: XCTestCase {
}
}

let timeoutInterval: TimeInterval = 0.1
let timeoutInterval: TimeInterval = 0.1

func testPersistence() async throws {
let expected: [String: AttributeValue] = [
Expand All @@ -35,7 +35,7 @@ final class PersistenceTests: XCTestCase {

let timestampProvider = TimestampProvider(
dateProvider: { Date(timeIntervalSince1970: 0) },
formatter: ISO8601DateFormatter())
formatter: DateFormatter.iso8601)

let expectation = expectation(description: "Model persisted")
let sut = Persistence.addingTimestamp(named: "CreatedAt", from: timestampProvider) { actual in
Expand Down
4 changes: 1 addition & 3 deletions Tests/PersistenceTests/TimestampProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
// Created by Mathew Gacy on 12/8/23.
//

import Foundation

@testable import Persistence
import Foundation
import XCTest
Expand All @@ -17,7 +15,7 @@ final class TimestampProviderTests: XCTestCase {

let sut = TimestampProvider(
dateProvider: { Date(timeIntervalSince1970: 0) },
formatter: ISO8601DateFormatter())
formatter: DateFormatter.iso8601)
let actual = sut.timestamp()
XCTAssertEqual(actual, expected)
}
Expand Down
Loading