Skip to content

Commit dcf0c85

Browse files
gh-action-runnergh-action-runner
authored andcommitted
Squashed 'apollo-ios-codegen/' changes from e4f12df6..92f94b4d
92f94b4d feature: Add suffix to schema type filenames (#580) git-subtree-dir: apollo-ios-codegen git-subtree-split: 92f94b4d9556b71359fbe7a55c5bcdb6bc3249c0
1 parent ddbe228 commit dcf0c85

9 files changed

+68
-10
lines changed

Sources/ApolloCodegenLib/CodegenConfiguration/ApolloCodegenConfiguration.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,9 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
690690
public let pruneGeneratedFiles: Bool
691691
/// Whether generated GraphQL operation and local cache mutation class types will be marked as `final`.
692692
public let markOperationDefinitionsAsFinal: Bool
693+
/// `true` will add a filename suffix matching the schema type, the default is `false`. This can be used to
694+
/// avoid filename conflicts when operation type names match schema type names.
695+
public let appendSchemaTypeFilenameSuffix: Bool
693696

694697
/// Default property values
695698
public struct Default {
@@ -705,6 +708,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
705708
public static let conversionStrategies: ConversionStrategies = .init()
706709
public static let pruneGeneratedFiles: Bool = true
707710
public static let markOperationDefinitionsAsFinal: Bool = false
711+
public static let appendSchemaTypeFilenameSuffix: Bool = false
708712
}
709713

710714
/// Designated initializer.
@@ -725,7 +729,11 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
725729
/// - conversionStrategies: Rules for how to convert the names of values from the schema in
726730
/// generated code.
727731
/// - pruneGeneratedFiles: Whether unused generated files will be automatically deleted.
728-
/// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation class types will be marked as `final`.
732+
/// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation
733+
/// class types will be marked as `final`.
734+
/// - appendSchemaTypeFilenameSuffix: `true` will add a filename suffix matching the schema type, the
735+
/// default is `false`. This can be used to avoid filename conflicts when operation type names match
736+
/// schema type names.
729737
public init(
730738
additionalInflectionRules: [InflectionRule] = Default.additionalInflectionRules,
731739
deprecatedEnumCases: Composition = Default.deprecatedEnumCases,
@@ -737,7 +745,8 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
737745
warningsOnDeprecatedUsage: Composition = Default.warningsOnDeprecatedUsage,
738746
conversionStrategies: ConversionStrategies = Default.conversionStrategies,
739747
pruneGeneratedFiles: Bool = Default.pruneGeneratedFiles,
740-
markOperationDefinitionsAsFinal: Bool = Default.markOperationDefinitionsAsFinal
748+
markOperationDefinitionsAsFinal: Bool = Default.markOperationDefinitionsAsFinal,
749+
appendSchemaTypeFilenameSuffix: Bool = Default.appendSchemaTypeFilenameSuffix
741750
) {
742751
self.additionalInflectionRules = additionalInflectionRules
743752
self.deprecatedEnumCases = deprecatedEnumCases
@@ -750,6 +759,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
750759
self.conversionStrategies = conversionStrategies
751760
self.pruneGeneratedFiles = pruneGeneratedFiles
752761
self.markOperationDefinitionsAsFinal = markOperationDefinitionsAsFinal
762+
self.appendSchemaTypeFilenameSuffix = appendSchemaTypeFilenameSuffix
753763
}
754764

755765
// MARK: Codable
@@ -768,6 +778,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
768778
case conversionStrategies
769779
case pruneGeneratedFiles
770780
case markOperationDefinitionsAsFinal
781+
case appendSchemaTypeFilenameSuffix
771782
}
772783

773784
public init(from decoder: any Decoder) throws {
@@ -833,6 +844,11 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
833844
Bool.self,
834845
forKey: .markOperationDefinitionsAsFinal
835846
) ?? Default.markOperationDefinitionsAsFinal
847+
848+
appendSchemaTypeFilenameSuffix = try values.decodeIfPresent(
849+
Bool.self,
850+
forKey: .appendSchemaTypeFilenameSuffix
851+
) ?? Default.appendSchemaTypeFilenameSuffix
836852
}
837853

838854
public func encode(to encoder: any Encoder) throws {
@@ -849,6 +865,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
849865
try container.encode(self.conversionStrategies, forKey: .conversionStrategies)
850866
try container.encode(self.pruneGeneratedFiles, forKey: .pruneGeneratedFiles)
851867
try container.encode(self.markOperationDefinitionsAsFinal, forKey: .markOperationDefinitionsAsFinal)
868+
try container.encode(self.appendSchemaTypeFilenameSuffix, forKey: .appendSchemaTypeFilenameSuffix)
852869
}
853870
}
854871

@@ -1702,7 +1719,7 @@ extension ApolloCodegenConfiguration.OutputOptions {
17021719
/// - pruneGeneratedFiles: Whether unused generated files will be automatically deleted.
17031720
/// - markOperationDefinitionsAsFinal: Whether generated GraphQL operation and local cache mutation class types will be marked as `final`.
17041721
@available(*, deprecated,
1705-
renamed: "init(additionalInflectionRules:queryStringLiteralFormat:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:)"
1722+
renamed: "init(additionalInflectionRules:queryStringLiteralFormat:deprecatedEnumCases:schemaDocumentation:selectionSetInitializers:operationDocumentFormat:cocoapodsCompatibleImportStatements:warningsOnDeprecatedUsage:conversionStrategies:pruneGeneratedFiles:markOperationDefinitionsAsFinal:appendSchemaTypeFilenameSuffix:)"
17061723
)
17071724
public init(
17081725
additionalInflectionRules: [InflectionRule] = Default.additionalInflectionRules,
@@ -1728,6 +1745,7 @@ extension ApolloCodegenConfiguration.OutputOptions {
17281745
self.pruneGeneratedFiles = pruneGeneratedFiles
17291746
self.markOperationDefinitionsAsFinal = markOperationDefinitionsAsFinal
17301747
self.schemaCustomization = Default.schemaCustomization
1748+
self.appendSchemaTypeFilenameSuffix = Default.appendSchemaTypeFilenameSuffix
17311749
}
17321750

17331751
/// Deprecated initializer.
@@ -1778,6 +1796,7 @@ extension ApolloCodegenConfiguration.OutputOptions {
17781796
self.pruneGeneratedFiles = pruneGeneratedFiles
17791797
self.markOperationDefinitionsAsFinal = markOperationDefinitionsAsFinal
17801798
self.schemaCustomization = Default.schemaCustomization
1799+
self.appendSchemaTypeFilenameSuffix = Default.appendSchemaTypeFilenameSuffix
17811800
}
17821801

17831802
/// Whether the generated operations should use Automatic Persisted Queries.

Sources/ApolloCodegenLib/FileGenerators/CustomScalarFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ struct CustomScalarFileGenerator: FileGenerator {
1414

1515
var target: FileTarget { .customScalar }
1616
var fileName: String { graphqlScalar.render(as: .filename) }
17+
var fileSuffix: String? { ".scalar" }
1718
var overwrite: Bool { false }
1819
}

Sources/ApolloCodegenLib/FileGenerators/EnumFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ struct EnumFileGenerator: FileGenerator {
1414

1515
var target: FileTarget { .enum }
1616
var fileName: String { graphqlEnum.render(as: .filename) }
17+
var fileSuffix: String? { ".enum" }
1718
}

Sources/ApolloCodegenLib/FileGenerators/FileGenerator.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import GraphQLCompiler
77
protocol FileGenerator {
88
var fileName: String { get }
99
var fileExtension: String { get }
10+
var fileSuffix: String? { get }
1011
var overwrite: Bool { get }
1112
var template: any TemplateRenderer { get }
1213
var target: FileTarget { get }
@@ -15,6 +16,7 @@ protocol FileGenerator {
1516
extension FileGenerator {
1617
var overwrite: Bool { true }
1718
var fileExtension: String { overwrite ? "graphql.swift" : "swift" }
19+
var fileSuffix: String? { nil }
1820

1921
/// Generates the file writing the template content to the specified config output paths.
2022
///
@@ -25,15 +27,27 @@ extension FileGenerator {
2527
forConfig config: ApolloCodegen.ConfigurationContext,
2628
fileManager: ApolloFileManager = .default
2729
) async throws -> [ApolloCodegen.NonFatalError] {
30+
let filename = resolveFilename(forConfig: config)
2831
let directoryPath = target.resolvePath(forConfig: config)
2932
let filePath = URL(fileURLWithPath: directoryPath)
3033
.resolvingSymlinksInPath()
31-
.appendingPathComponent(fileName.firstUppercased)
34+
.appendingPathComponent(filename)
3235
.appendingPathExtension(fileExtension)
3336
.path
3437

3538
let (rendered, errors) = template.render()
3639

40+
if !self.overwrite, let _ = fileSuffix {
41+
let preSuffixFilename = fileName.firstUppercased
42+
let preSuffixFilePath = URL(fileURLWithPath: directoryPath)
43+
.resolvingSymlinksInPath()
44+
.appendingPathComponent(preSuffixFilename)
45+
.appendingPathExtension(fileExtension)
46+
.path
47+
48+
try await fileManager.renameFile(atPath: preSuffixFilePath, toPath: filePath)
49+
}
50+
3751
try await fileManager.createFile(
3852
atPath: filePath,
3953
data: rendered.data(using: .utf8),
@@ -42,6 +56,16 @@ extension FileGenerator {
4256

4357
return errors
4458
}
59+
60+
/// Filename to be used taking into account any generated filename options.
61+
private func resolveFilename(forConfig config: ApolloCodegen.ConfigurationContext) -> String {
62+
let prefix = fileName.firstUppercased
63+
guard config.options.appendSchemaTypeFilenameSuffix, let suffix = self.fileSuffix else {
64+
return prefix
65+
}
66+
67+
return prefix + suffix
68+
}
4569
}
4670

4771
// MARK: - FileTarget (path resolver)

Sources/ApolloCodegenLib/FileGenerators/InputObjectFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ struct InputObjectFileGenerator: FileGenerator {
1818
}
1919
var target: FileTarget { .inputObject }
2020
var fileName: String { graphqlInputObject.render(as: .filename) }
21+
var fileSuffix: String? { ".inputObject" }
2122
}

Sources/ApolloCodegenLib/FileGenerators/InterfaceFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ struct InterfaceFileGenerator: FileGenerator {
1414

1515
var target: FileTarget { .interface }
1616
var fileName: String { graphqlInterface.render(as: .filename) }
17+
var fileSuffix: String? { ".interface" }
1718
}

Sources/ApolloCodegenLib/FileGenerators/ObjectFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ struct ObjectFileGenerator: FileGenerator {
1515

1616
var target: FileTarget { .object }
1717
var fileName: String { graphqlObject.render(as: .filename) }
18+
var fileSuffix: String? { ".object" }
1819
}

Sources/ApolloCodegenLib/FileGenerators/UnionFileGenerator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ struct UnionFileGenerator: FileGenerator {
1414
) }
1515
var target: FileTarget { .union }
1616
var fileName: String { graphqlUnion.render(as: .filename) }
17+
var fileSuffix: String? { ".union" }
1718
}

Sources/ApolloCodegenLib/FileManager+Apollo.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ public class ApolloFileManager {
8585
try base.removeItem(atPath: path)
8686
}
8787

88-
/// Creates a file at the specified path and writes any given data to it. If a file already exists at `path`, this method overwrites the
89-
/// contents of that file if the current process has the appropriate privileges to do so.
88+
/// Creates a file at the specified path and writes any given data to it. If a file already exists at `path` this
89+
/// method can be configured to overwrite the contents of that file, if the current process has the appropriate
90+
/// privileges to do so.
9091
///
9192
/// - Parameters:
9293
/// - path: Path to the file.
@@ -106,17 +107,25 @@ public class ApolloFileManager {
106107
await _writtenFiles.addWrittenFile(path: path)
107108
}
108109

109-
/// Creates the containing directory (including all intermediate directories) for the given file URL if necessary. This method will not
110-
/// overwrite any existing directory.
110+
public func renameFile(atPath oldPath: String, toPath newPath: String) async throws {
111+
guard doesFileExist(atPath: oldPath) else { return }
112+
113+
try base.moveItem(atPath: oldPath, toPath: newPath)
114+
115+
await _writtenFiles.addWrittenFile(path: newPath)
116+
}
117+
118+
/// Creates the containing directory (including all intermediate directories) for the given file URL if necessary.
119+
/// This method will not overwrite any existing directory.
111120
///
112121
/// - Parameter fileURL: The URL of the file to create a containing directory for if necessary.
113122
public func createContainingDirectoryIfNeeded(forPath path: String) throws {
114123
let parent = URL(fileURLWithPath: path).deletingLastPathComponent()
115124
try createDirectoryIfNeeded(atPath: parent.path)
116125
}
117126

118-
/// Creates the directory (including all intermediate directories) for the given URL if necessary. This method will not overwrite any
119-
/// existing directory.
127+
/// Creates the directory (including all intermediate directories) for the given URL if necessary. This method will
128+
/// not overwrite any existing directory.
120129
///
121130
/// - Parameter path: The path of the directory to create if necessary.
122131
public func createDirectoryIfNeeded(atPath path: String) throws {

0 commit comments

Comments
 (0)