Skip to content

Commit

Permalink
Fix codegen cocoapods support (#2442)
Browse files Browse the repository at this point in the history
* fix: Don't import ApolloAPI if being used in CocoaPods environment

* fix: ApolloAPI subfolder source files should be included in podspec

* fix: Removes ApolloAPI namespacing from types

* fix: Import ApolloAPI for JSON typealias definitions

* fix: ApolloTestSupport shouldn't import ApolloAPI in CocoaPods environment

* WIP: Integrating Cocoapods for Cocoapod Test Target

* Cleanup accidental imports

* Add cli created from Cocoapods test configuration to gitignore

* Add cocoapodsCompatibleImportStatements and regenerate cocoapods test project

* When cli is build from Cocoapods, defaults the cocoapods compatibility import statements to true

* Fix broken unit tests

Co-authored-by: Calvin Cestari <[email protected]>
  • Loading branch information
AnthonyMDev and calvincestari authored Aug 16, 2022
1 parent c07e4a4 commit 5b9fe74
Show file tree
Hide file tree
Showing 157 changed files with 9,007 additions and 822 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Build generated
build/
DerivedData/
apollo-ios-cli

## Various settings
*.pbxuser
Expand Down
6 changes: 3 additions & 3 deletions Apollo.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ Pod::Spec.new do |s|
cli_directory = 'CodegenCLI'
cli_binary_name = 'apollo-ios-cli'
s.preserve_paths = ['CodegenCLI/**/*', cli_binary_name]
s.prepare_command = <<-CMD
make --directory=CodegenCLI
s.prepare_command = <<-CMD
make clean build-for-cocoapods --directory=CodegenCLI
cp #{cli_directory}/.build/release/#{cli_binary_name} #{cli_binary_name}
chmod +x #{cli_binary_name}
CMD

s.subspec 'Core' do |ss|
ss.source_files = 'Sources/Apollo/*.swift','Sources/ApolloAPI/*.swift'
ss.source_files = 'Sources/Apollo/*.swift','Sources/ApolloAPI/**/*.swift'
end

# Apollo provides exactly one persistent cache out-of-the-box, as a reasonable default choice for
Expand Down
13 changes: 13 additions & 0 deletions CodegenCLI/Sources/Commands/Initialize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ struct Initialize: ParsableCommand {

fileprivate extension ApolloCodegenConfiguration {
static var `default`: ApolloCodegenConfiguration {
#if COCOAPODS
ApolloCodegenConfiguration(
schemaName: "GraphQLSchemaName",
input: .init(
schemaPath: "schema.graphqls"
),
output: .init(
schemaTypes: .init(path: "./", moduleType: .swiftPackageManager)
),
options: .init(cocoapodsCompatibleImportStatements: true)
)
#else
ApolloCodegenConfiguration(
schemaName: "GraphQLSchemaName",
input: .init(
Expand All @@ -103,6 +115,7 @@ fileprivate extension ApolloCodegenConfiguration {
schemaTypes: .init(path: "./", moduleType: .swiftPackageManager)
)
)
#endif
}

func encoded() throws -> Data {
Expand Down
7 changes: 4 additions & 3 deletions CodegenCLI/Tests/Commands/InitializeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,14 @@ class InitializeTests: XCTestCase {
{
"schemaName" : "GraphQLSchemaName",
"options" : {
"schemaDocumentation" : "include",
"warningsOnDeprecatedUsage" : "include",
"deprecatedEnumCases" : "include",
"apqs" : "disabled",
"additionalInflectionRules" : [
],
"warningsOnDeprecatedUsage" : "include",
"deprecatedEnumCases" : "include",
"schemaDocumentation" : "include",
"cocoapodsCompatibleImportStatements" : false,
"queryStringLiteralFormat" : "multiline"
},
"input" : {
Expand Down
5 changes: 4 additions & 1 deletion CodegenCLI/makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: clean wipe build test
.PHONY: clean wipe build build-for-cocoapods test

default: clean build

Expand All @@ -11,5 +11,8 @@ wipe:
build:
swift build -c release

build-for-cocoapods:
swift build -c release -Xswiftc -DCOCOAPODS

test:
swift test
4 changes: 3 additions & 1 deletion Sources/AnimalKingdomAPI/AnimalKingdomAPI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ let package = Package(
.library(name: "AnimalKingdomAPI", targets: ["AnimalKingdomAPI"]),
],
dependencies: [
.package(url: "https://github.com/apollographql/apollo-ios.git", from: "1.0.0-beta.1"),
.package( name: "apollo-ios",
url: "https://github.com/apollographql/apollo-ios.git",
.branch("release/1.0")),
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion Sources/Apollo/ApolloStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public class ApolloStore {
)
}

public func updateObject<SelectionSet: ApolloAPI.MutableRootSelectionSet>(
public func updateObject<SelectionSet: MutableRootSelectionSet>(
ofType type: SelectionSet.Type,
withKey key: CacheKey,
variables: GraphQLOperation.Variables? = nil,
Expand Down
2 changes: 2 additions & 0 deletions Sources/Apollo/GraphQLResult.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
#if !COCOAPODS
import ApolloAPI
#endif

/// Represents the result of a GraphQL operation.
public struct GraphQLResult<Data: RootSelectionSet> {
Expand Down
2 changes: 1 addition & 1 deletion Sources/ApolloAPI/Selection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public enum Selection {
/// A fragment spread of a named fragment definition.
case fragment(Fragment.Type)
/// An inline fragment with a child selection set nested in a parent selection set.
case inlineFragment(ApolloAPI.InlineFragment.Type)
case inlineFragment(InlineFragment.Type)
/// A group of selections that have `@include/@skip` directives.
case conditional(Conditions, [Selection])

Expand Down
18 changes: 16 additions & 2 deletions Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
///
/// See `APQConfig` for more information on Automatic Persisted Queries.
public let apqs: APQConfig
/// Generate import statements that are compatible with including `Apollo` via Cocoapods.
///
/// Cocoapods bundles all files from subspecs into the main target for a pod. This means that
/// when including `Apollo` via Cocoapods, the files in `ApolloAPI` will be added to the
/// `Apollo` target. In order for the generated code to compile, all `import ApolloAPI`
/// statements must be generated as `import Apollo` instead. Setting this option to `true`
/// configures the import statements to be compatible with Cocoapods.
///
/// Defaults to `false`.
public let cocoapodsCompatibleImportStatements: Bool
/// Annotate generated Swift code with the Swift `available` attribute and `deprecated`
/// argument for parts of the GraphQL schema annotated with the built-in `@deprecated`
/// directive.
Expand All @@ -304,22 +314,26 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
/// - deprecatedEnumCases: How deprecated enum cases from the schema should be handled.
/// - schemaDocumentation: Whether schema documentation is added to the generated files.
/// - apqs: Whether the generated operations should use Automatic Persisted Queries.
/// - cocoapodsCompatibleImportStatements: Generate import statements that are compatible with
/// including `Apollo` via Cocoapods.
/// - warningsOnDeprecatedUsage: Annotate generated Swift code with the Swift `available`
/// attribute and `deprecated` argument for parts of the GraphQL schema annotated with the
/// built-in `@deprecated` directive.
/// attribute and `deprecated` argument for parts of the GraphQL schema annotated with the
/// built-in `@deprecated` directive.
public init(
additionalInflectionRules: [InflectionRule] = [],
queryStringLiteralFormat: QueryStringLiteralFormat = .multiline,
deprecatedEnumCases: Composition = .include,
schemaDocumentation: Composition = .include,
apqs: APQConfig = .disabled,
cocoapodsCompatibleImportStatements: Bool = false,
warningsOnDeprecatedUsage: Composition = .include
) {
self.additionalInflectionRules = additionalInflectionRules
self.queryStringLiteralFormat = queryStringLiteralFormat
self.deprecatedEnumCases = deprecatedEnumCases
self.schemaDocumentation = schemaDocumentation
self.apqs = apqs
self.cocoapodsCompatibleImportStatements = cocoapodsCompatibleImportStatements
self.warningsOnDeprecatedUsage = warningsOnDeprecatedUsage
}
}
Expand Down
11 changes: 6 additions & 5 deletions Sources/ApolloCodegenLib/Templates/SchemaTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,18 @@ struct SchemaTemplate: TemplateRenderer {
}

private func protocolDefinition(prefix: String?, schemaName: String) -> TemplateString {
TemplateString("""
public protocol \(prefix ?? "")SelectionSet: ApolloAPI.SelectionSet & ApolloAPI.RootSelectionSet
let apolloAPITargetName = ImportStatementTemplate.ApolloAPIImportTargetName(forConfig: config)
return TemplateString("""
public protocol \(prefix ?? "")SelectionSet: \(apolloAPITargetName).SelectionSet & \(apolloAPITargetName).RootSelectionSet
where Schema == \(schemaName).Schema {}
public protocol \(prefix ?? "")InlineFragment: ApolloAPI.SelectionSet & ApolloAPI.InlineFragment
public protocol \(prefix ?? "")InlineFragment: \(apolloAPITargetName).SelectionSet & \(apolloAPITargetName).InlineFragment
where Schema == \(schemaName).Schema {}
public protocol \(prefix ?? "")MutableSelectionSet: ApolloAPI.MutableRootSelectionSet
public protocol \(prefix ?? "")MutableSelectionSet: \(apolloAPITargetName).MutableRootSelectionSet
where Schema == \(schemaName).Schema {}
public protocol \(prefix ?? "")MutableInlineFragment: ApolloAPI.MutableSelectionSet & ApolloAPI.InlineFragment
public protocol \(prefix ?? "")MutableInlineFragment: \(apolloAPITargetName).MutableSelectionSet & \(apolloAPITargetName).InlineFragment
where Schema == \(schemaName).Schema {}
"""
)
Expand Down
30 changes: 18 additions & 12 deletions Sources/ApolloCodegenLib/Templates/TemplateRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ extension TemplateRenderer {
return TemplateString(
"""
\(ifLet: headerTemplate, { "\($0)\n" })
\(ImportStatementTemplate.SchemaType.template)
\(ImportStatementTemplate.SchemaType.template(forConfig: config ))
\(ifLet: detachedTemplate, { "\($0)\n" })
\(ifLet: namespace, template.wrappedInNamespace(_:), else: template)
Expand Down Expand Up @@ -171,24 +171,30 @@ private struct HeaderCommentTemplate {
// MARK: Import Statement Template

/// Provides the format to import Swift modules required by the template type.
private struct ImportStatementTemplate {
static let template: StaticString =
"""
import ApolloAPI
"""
struct ImportStatementTemplate {
static func ApolloAPIImportTargetName(
forConfig config: ApolloCodegen.ConfigurationContext
) -> String {
config.options.cocoapodsCompatibleImportStatements ? "Apollo" : "ApolloAPI"
}

enum SchemaType {
static let template: StaticString = ImportStatementTemplate.template
static func template(
forConfig config: ApolloCodegen.ConfigurationContext
) -> String {
"import \(ImportStatementTemplate.ApolloAPIImportTargetName(forConfig: config))"
}
}

enum Operation {
static func template(
forConfig config: ApolloCodegen.ConfigurationContext
) -> TemplateString {
"""
\(ImportStatementTemplate.template)
@_exported import enum ApolloAPI.GraphQLEnum
@_exported import enum ApolloAPI.GraphQLNullable
let apolloAPITargetName = ImportStatementTemplate.ApolloAPIImportTargetName(forConfig: config)
return """
import \(apolloAPITargetName)
@_exported import enum \(apolloAPITargetName).GraphQLEnum
@_exported import enum \(apolloAPITargetName).GraphQLNullable
\(if: config.output.operations != .inSchemaModule, "import \(config.schemaModuleName)")
"""
}
Expand All @@ -197,7 +203,7 @@ private struct ImportStatementTemplate {
enum TestMock {
static func template(forConfig config: ApolloCodegen.ConfigurationContext) -> TemplateString {
return """
import ApolloTestSupport
import \(config.options.cocoapodsCompatibleImportStatements ? "Apollo" : "ApolloTestSupport")
import \(config.schemaModuleName)
"""
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/ApolloTestSupport/Field.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if !COCOAPODS
import ApolloAPI
#endif

@propertyWrapper
public struct Field<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/ApolloTestSupport/TestMock.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if !COCOAPODS
@_exported import ApolloAPI
#endif
import Foundation

@dynamicMemberLookup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension ApolloCodegenConfiguration {

public static func mock(
_ moduleType: ApolloCodegenConfiguration.SchemaTypesFileOutput.ModuleType,
warningsOnDeprecatedUsage: ApolloCodegenConfiguration.Composition = .exclude,
options: ApolloCodegenConfiguration.OutputOptions = .init(),
schemaName: String = "TestSchema",
to path: String = "MockModulePath"
) -> Self {
Expand All @@ -33,9 +33,7 @@ extension ApolloCodegenConfiguration {
output: .init(
schemaTypes: .init(path: path, moduleType: moduleType)
),
options: .init(
warningsOnDeprecatedUsage: warningsOnDeprecatedUsage
)
options: options
)
}
}
Expand Down
Loading

0 comments on commit 5b9fe74

Please sign in to comment.