Skip to content

Commit

Permalink
Custom codable for SDKVersion enum
Browse files Browse the repository at this point in the history
  • Loading branch information
BobaFetters committed Nov 27, 2024
1 parent d4fa49f commit 7be0e0c
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1316,11 +1316,7 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase {
"moduleType" : {
"swiftPackage" : {
"apolloSDKDependency" : {
"sdkVersion" : {
"default" : {
}
},
"sdkVersion" : "default",
"url" : "https://github.com/apollographql/apollo-ios"
}
}
Expand Down Expand Up @@ -1511,11 +1507,7 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase {
"moduleType" : {
"swiftPackage" : {
"apolloSDKDependency" : {
"sdkVersion" : {
"default" : {
}
},
"sdkVersion" : "default",
"url" : "https://github.com/apollographql/apollo-ios"
}
}
Expand Down Expand Up @@ -1706,11 +1698,7 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase {
"moduleType" : {
"swiftPackage" : {
"apolloSDKDependency" : {
"sdkVersion" : {
"default" : {
}
},
"sdkVersion" : "default",
"url" : "https://github.com/apollographql/apollo-ios"
}
}
Expand Down Expand Up @@ -2342,11 +2330,7 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase {
"moduleType" : {
"swiftPackage" : {
"apolloSDKDependency" : {
"sdkVersion" : {
"default" : {
}
},
"sdkVersion" : "default",
"url" : "www.myurl.com"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
/// Attention: This case has been deprecated, use .swiftPackage(apolloSDKVersion:) case instead.
case swiftPackageManager
/// Generates a `Package.swift` file that is suitable for linking then generated schema types
/// files to your project using Swift Package Manager. Uses the `apolloSDKVersion` associated
/// value to determine how to setup the dependency on `apollo-ios`.
/// files to your project using Swift Package Manager. Uses the `apolloSDKDependency`
/// to determine how to setup the dependency on `apollo-ios`.
case swiftPackage(apolloSDKDependency: ApolloSDKDependency = ApolloSDKDependency())
/// No module will be created for the generated types and you are required to create the
/// module to support your preferred dependency manager. You must specify the name of the
Expand Down Expand Up @@ -342,8 +342,12 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
}
}

/// Configuation for apollo-ios dependency in SPM modules
public struct ApolloSDKDependency: Codable, Equatable {
/// URL for the SPM package dependency, not used for local dependencies.
/// Defaults to 'https://github.com/apollographql/apollo-ios'.
let url: String
/// Type of SPM dependency to use.
let sdkVersion: SDKVersion

public init(
Expand All @@ -354,14 +358,101 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
self.sdkVersion = sdkVersion
}

enum CodingKeys: CodingKey, CaseIterable {
case url
case sdkVersion
}

public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(self.url, forKey: .url)

switch self.sdkVersion {
case .default:
try container.encode(self.sdkVersion.stringValue, forKey: .sdkVersion)
default:
try container.encode(self.sdkVersion, forKey: .sdkVersion)
}
}

public init(from decoder: any Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
try throwIfContainsUnexpectedKey(
container: values,
type: Self.self,
decoder: decoder
)

url = try values.decode(String.self, forKey: .url)

if let version = try? values.decodeIfPresent(SDKVersion.self, forKey: .sdkVersion) {
sdkVersion = version
} else if let versionString = try? values.decodeIfPresent(String.self, forKey: .sdkVersion) {
let version = try SDKVersion(fromString: versionString)
sdkVersion = version
} else {
throw DecodingError.typeMismatch(Self.self, DecodingError.Context.init(
codingPath: values.codingPath,
debugDescription: "No valid 'sdkVersion' provided.",
underlyingError: nil
))
}
}

/// Type of SPM dependency
public enum SDKVersion: Codable, Equatable {
/// Configures SPM dependency to use the exact version of apollo-ios
/// that matches the code generation library version currently in use.
/// Results in a dependency that looks like:
/// '.package(url: "https://github.com/apollographql/apollo-ios.git", exact: "{version}")'
case `default`
/// Configures SPM dependency to use the given branch name
/// for the apollo-ios dependency.
/// Results in a dependency that looks like:
/// '.package(url: "...", branch: "{name}")'
case branch(name: String)
/// Configures SPM dependency to use the given commit hash
/// for the apollo-ios dependency.
/// Results in a dependency that looks like:
/// '.package(url: "...", revision: "{hash}")'
case commit(hash: String)
/// Configures SPM dependency to use the given exact version
/// for the apollo-ios dependency.
/// Results in a dependency that looks like:
/// '.package(url: "...", exact: "{version}")'
case exact(version: String)
/// Configures SPM dependency to use a version
/// starting at the given version for the apollo-ios dependency.
/// Results in a dependency that looks like:
/// '.package(url: "...", from: "{version}")'
case from(version: String)
/// Configures SPM dependency to use a local
/// path for the apollo-ios dependency.
/// Results in a dependency that looks like:
/// '.package(path: "{path}")'
case local(path: String)

public var stringValue: String {
switch self {
case .default: return "default"
case .branch(_): return "branch"
case .commit(_): return "commit"
case .exact(_): return "exact"
case .from(_): return "from"
case .local(_): return "local"
}
}

public init(fromString str: String) throws {
switch str {
case Self.default.stringValue:
self = .default
default:
throw ApolloConfigurationError.invalidValueForKey(key: "sdkVersion", value: str)
}
}

public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

Expand Down Expand Up @@ -1269,6 +1360,24 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
operationManifest: operationManifest ?? Default.operationManifest
)
}

}

// MARK: Errors

extension ApolloCodegenConfiguration {
public enum ApolloConfigurationError: Error, LocalizedError {
case invalidValueForKey(key: String, value: String)

public var errorDescription: String? {
switch self {
case .invalidValueForKey(let key, let value):
return """
Invalid value '\(value)' provided for key '\(key)'.
"""
}
}
}
}

// MARK: - Helpers
Expand Down

0 comments on commit 7be0e0c

Please sign in to comment.