From 8272e9f266f94cda52b7231d369931317f88e4a1 Mon Sep 17 00:00:00 2001 From: Tony Arnold Date: Sun, 18 Aug 2024 13:59:45 +1000 Subject: [PATCH 1/2] feature: propose additional capitalization rules configuration --- ...olloCodegenConfigurationCodableTests.swift | 10 ++++++++ .../ApolloCodegenConfiguration.swift | 23 +++++++++++++++++-- .../ApolloCodegenLib/Capitalizer.swift | 9 ++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift diff --git a/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift b/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift index aee606c90..ede8d6bb2 100644 --- a/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift +++ b/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift @@ -38,6 +38,9 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase { testMocks: .swiftPackage(targetName: "SchemaTestMocks") ), options: .init( + additionalCapitalizationRules: [ + .uppercase(regex: "[Ii]d") + ], additionalInflectionRules: [ .pluralization(singularRegex: "animal", replacementRegex: "animals") ], @@ -100,6 +103,13 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase { "version" : "persistedQueries" }, "options" : { + "additionalCapitalizationRules" : [ + { + "uppercase" : { + "regex" : "[Ii]d" + } + } + ], "additionalInflectionRules" : [ { "pluralization" : { diff --git a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift index 3219bd6af..de64eea94 100644 --- a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift +++ b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift @@ -458,6 +458,8 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { // MARK: - Other Types public struct OutputOptions: Codable, Equatable { + /// Any non-default rules for capitalization you wish to include. + public let additionalCapitalizationRules: [CapitalizationRule] /// Any non-default rules for pluralization or singularization you wish to include. public let additionalInflectionRules: [InflectionRule] /// How deprecated enum cases from the schema should be handled. @@ -511,6 +513,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { /// Default property values public struct Default { + public static let additionalCapitalizationRules: [CapitalizationRule] = [] public static let additionalInflectionRules: [InflectionRule] = [] public static let deprecatedEnumCases: Composition = .include public static let schemaDocumentation: Composition = .include @@ -528,6 +531,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { /// Designated initializer. /// /// - Parameters: + /// - additionalCapitalizationRules: Any non-default rules for capitalization you wish to include. /// - additionalInflectionRules: Any non-default rules for pluralization or singularization /// you wish to include. /// - deprecatedEnumCases: How deprecated enum cases from the schema should be handled. @@ -545,6 +549,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { /// - pruneGeneratedFiles: Whether unused generated files will be automatically deleted. /// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation class types will be marked as `final`. public init( + additionalCapitalizationRules: [CapitalizationRule] = Default.additionalCapitalizationRules, additionalInflectionRules: [InflectionRule] = Default.additionalInflectionRules, deprecatedEnumCases: Composition = Default.deprecatedEnumCases, schemaDocumentation: Composition = Default.schemaDocumentation, @@ -557,6 +562,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { pruneGeneratedFiles: Bool = Default.pruneGeneratedFiles, markOperationDefinitionsAsFinal: Bool = Default.markOperationDefinitionsAsFinal ) { + self.additionalCapitalizationRules = additionalCapitalizationRules self.additionalInflectionRules = additionalInflectionRules self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation @@ -573,6 +579,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { // MARK: Codable enum CodingKeys: CodingKey, CaseIterable { + case additionalCapitalizationRules case additionalInflectionRules case queryStringLiteralFormat case deprecatedEnumCases @@ -592,6 +599,11 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { let values = try decoder.container(keyedBy: CodingKeys.self) try throwIfContainsUnexpectedKey(container: values, type: Self.self, decoder: decoder) + additionalCapitalizationRules = try values.decodeIfPresent( + [CapitalizationRule].self, + forKey: .additionalCapitalizationRules + ) ?? Default.additionalCapitalizationRules + additionalInflectionRules = try values.decodeIfPresent( [InflectionRule].self, forKey: .additionalInflectionRules @@ -656,6 +668,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(self.additionalCapitalizationRules, forKey: .additionalCapitalizationRules) try container.encode(self.additionalInflectionRules, forKey: .additionalInflectionRules) try container.encode(self.deprecatedEnumCases, forKey: .deprecatedEnumCases) try container.encode(self.schemaDocumentation, forKey: .schemaDocumentation) @@ -1483,6 +1496,7 @@ extension ApolloCodegenConfiguration.OutputOptions { /// Deprecated initializer. /// /// - Parameters: + /// - additionalCapitalizationRules: Any non-default rules for capitalization you wish to include. /// - additionalInflectionRules: Any non-default rules for pluralization or singularization /// you wish to include. /// - queryStringLiteralFormat: Formatting of the GraphQL query string literal that is @@ -1502,9 +1516,10 @@ extension ApolloCodegenConfiguration.OutputOptions { /// - pruneGeneratedFiles: Whether unused generated files will be automatically deleted. /// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation class types will be marked as `final`. @available(*, deprecated, - renamed: "init(additionalInflectionRules:queryStringLiteralFormat:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:)" + renamed: "init(additionalCapitalizationRules:additionalInflectionRules:queryStringLiteralFormat:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:)" ) public init( + additionalCapitalizationRules: [CapitalizationRule] = Default.additionalCapitalizationRules, additionalInflectionRules: [InflectionRule] = Default.additionalInflectionRules, queryStringLiteralFormat: QueryStringLiteralFormat = .singleLine, deprecatedEnumCases: ApolloCodegenConfiguration.Composition = Default.deprecatedEnumCases, @@ -1517,6 +1532,7 @@ extension ApolloCodegenConfiguration.OutputOptions { pruneGeneratedFiles: Bool = Default.pruneGeneratedFiles, markOperationDefinitionsAsFinal: Bool = Default.markOperationDefinitionsAsFinal ) { + self.additionalCapitalizationRules = additionalCapitalizationRules self.additionalInflectionRules = additionalInflectionRules self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation @@ -1533,6 +1549,7 @@ extension ApolloCodegenConfiguration.OutputOptions { /// Deprecated initializer. /// /// - Parameters: + /// - additionalCapitalizationRules: Any non-default rules for capitalization you wish to include. /// - additionalInflectionRules: Any non-default rules for pluralization or singularization /// you wish to include. /// - queryStringLiteralFormat: Formatting of the GraphQL query string literal that is @@ -1552,9 +1569,10 @@ extension ApolloCodegenConfiguration.OutputOptions { /// - pruneGeneratedFiles: Whether unused generated files will be automatically deleted. /// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation class types will be marked as `final`. @available(*, deprecated, - renamed: "init(additionalInflectionRules:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:)" + renamed: "init(additionalCapitalizationRules:additionalInflectionRules:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:)" ) public init( + additionalCapitalizationRules: [CapitalizationRule] = Default.additionalCapitalizationRules, additionalInflectionRules: [InflectionRule] = Default.additionalInflectionRules, queryStringLiteralFormat: QueryStringLiteralFormat, deprecatedEnumCases: ApolloCodegenConfiguration.Composition = Default.deprecatedEnumCases, @@ -1567,6 +1585,7 @@ extension ApolloCodegenConfiguration.OutputOptions { pruneGeneratedFiles: Bool = Default.pruneGeneratedFiles, markOperationDefinitionsAsFinal: Bool = Default.markOperationDefinitionsAsFinal ) { + self.additionalCapitalizationRules = additionalCapitalizationRules self.additionalInflectionRules = additionalInflectionRules self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation diff --git a/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift b/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift new file mode 100644 index 000000000..179904796 --- /dev/null +++ b/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift @@ -0,0 +1,9 @@ +import Foundation + +public enum CapitalizationRule: Codable, Equatable { + case uppercase(regex: String) + case lowercase(regex: String) + case titlecase(regex: String) + case camelcase(regex: String) + case pascalcase(regex: String) +} From 0cda6f096ade9821fbe655b0ed855a6581a78383 Mon Sep 17 00:00:00 2001 From: Tony Arnold Date: Sun, 25 Aug 2024 11:41:39 +1000 Subject: [PATCH 2/2] feature: update the implementation of CapitalizationRule to be more flexible --- ...olloCodegenConfigurationCodableTests.swift | 9 ++++--- .../ApolloCodegenLib/Capitalizer.swift | 26 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift b/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift index ede8d6bb2..602a98a1d 100644 --- a/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift +++ b/Tests/ApolloCodegenTests/ApolloCodegenConfigurationCodableTests.swift @@ -39,7 +39,7 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase { ), options: .init( additionalCapitalizationRules: [ - .uppercase(regex: "[Ii]d") + CapitalizationRule(term: .regex("[Ii]d"), strategy: .upper) ], additionalInflectionRules: [ .pluralization(singularRegex: "animal", replacementRegex: "animals") @@ -105,8 +105,11 @@ class ApolloCodegenConfigurationCodableTests: XCTestCase { "options" : { "additionalCapitalizationRules" : [ { - "uppercase" : { - "regex" : "[Ii]d" + "strategy" : "upper", + "term" : { + "regex" : { + "_0" : "[Ii]d" + } } } ], diff --git a/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift b/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift index 179904796..2f2bb9432 100644 --- a/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift +++ b/apollo-ios-codegen/Sources/ApolloCodegenLib/Capitalizer.swift @@ -1,9 +1,23 @@ import Foundation -public enum CapitalizationRule: Codable, Equatable { - case uppercase(regex: String) - case lowercase(regex: String) - case titlecase(regex: String) - case camelcase(regex: String) - case pascalcase(regex: String) +public struct CapitalizationRule: Codable, Equatable, Sendable { + public enum Term: Codable, Equatable, Sendable { + case string(String) + case regex(String) + } + + public enum CaseStrategy: String, Codable, Equatable, Sendable { + case upper + case lower + case camel + case pascal + } + + public let term: Term + public let strategy: CaseStrategy + + public init(term: Term, strategy: CaseStrategy) { + self.term = term + self.strategy = strategy + } }