Skip to content

Commit

Permalink
Merge pull request #940 from apollographql/swift-codegen
Browse files Browse the repository at this point in the history
Move Code Generation From Bash to Swift Scripts
  • Loading branch information
designatednerd authored Feb 19, 2020
2 parents b53ee9d + d0cdf75 commit bbd3730
Show file tree
Hide file tree
Showing 75 changed files with 3,298 additions and 36 deletions.
13 changes: 13 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ jobs:
steps:
- common_test_steps

CodegenLibmacOS_current:
macos:
xcode: << pipeline.parameters.xcode_version >>
environment:
DESTINATION: platform=macOS,arch=x86_64
CIRCLE_XCODE_SCHEME: ApolloCodegenLib
CIRCLE_XCODE_SDK: << pipeline.parameters.macos_sdk >>
steps:
- common_test_steps

CocoaPodsTrunk:
macos:
xcode: << pipeline.parameters.xcode_version >>
Expand Down Expand Up @@ -195,6 +205,8 @@ workflows:
name: ApolloWebSocket iOS << pipeline.parameters.ios_current_version >>
- WebSocketiOS_previous:
name: ApolloWebSocket iOS << pipeline.parameters.ios_previous_version >>
- CodegenLibmacOS_current:
name: Swift Code Generation
- CocoaPodsTrunk:
name: Push Podspec to CocoaPods Trunk
requires:
Expand All @@ -208,6 +220,7 @@ workflows:
- ApolloWebSocket macOS << pipeline.parameters.macos_version >>
- ApolloWebSocket iOS << pipeline.parameters.ios_current_version >>
- ApolloWebSocket iOS << pipeline.parameters.ios_previous_version >>
- Swift Code Generation
filters:
# Only build semver tags
tags:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ node_modules/
package-lock.json
scripts/apollo
scripts/apollo.tar.gz
Codegen/ApolloCLI
294 changes: 291 additions & 3 deletions Apollo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions Apollo.xcodeproj/xcshareddata/xcschemes/ApolloCodegenLib.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9B7B6F46233C26D100F32205"
BuildableName = "ApolloCodegenLib.framework"
BlueprintName = "ApolloCodegenLib"
ReferencedContainer = "container:Apollo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9B7B6F46233C26D100F32205"
BuildableName = "ApolloCodegenLib.framework"
BlueprintName = "ApolloCodegenLib"
ReferencedContainer = "container:Apollo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "SRCROOT"
value = "$SRCROOT"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9B7B6F46233C26D100F32205"
BuildableName = "ApolloCodegenLib.framework"
BlueprintName = "ApolloCodegenLib"
ReferencedContainer = "container:Apollo.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9BAEEBFB234BB8FD00808306"
BuildableName = "ApolloCodegenTests.xctest"
BlueprintName = "ApolloCodegenTests"
ReferencedContainer = "container:Apollo.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9B7B6F46233C26D100F32205"
BuildableName = "ApolloCodegenLib.framework"
BlueprintName = "ApolloCodegenLib"
ReferencedContainer = "container:Apollo.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Starscream
1 change: 1 addition & 0 deletions Codegen/ApolloCLI/.keep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is here to preserve folder structure in git.
43 changes: 43 additions & 0 deletions Codegen/Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"object": {
"pins": [
{
"package": "SQLite.swift",
"repositoryURL": "https://github.com/stephencelis/SQLite.swift.git",
"state": {
"branch": null,
"revision": "0a9893ec030501a3956bee572d6b4fdd3ae158a1",
"version": "0.12.2"
}
},
{
"package": "Starscream",
"repositoryURL": "https://github.com/daltoniam/Starscream",
"state": {
"branch": null,
"revision": "e6b65c6d9077ea48b4a7bdda8994a1d3c6969c8d",
"version": "3.1.1"
}
},
{
"package": "swift-nio-zlib-support",
"repositoryURL": "https://github.com/apple/swift-nio-zlib-support.git",
"state": {
"branch": null,
"revision": "37760e9a52030bb9011972c5213c3350fa9d41fd",
"version": "1.0.0"
}
},
{
"package": "swift-tools-support-core",
"repositoryURL": "https://github.com/apple/swift-tools-support-core",
"state": {
"branch": null,
"revision": "693aba4c4c9dcc4767cc853a0dd38bf90ad8c258",
"version": "0.0.1"
}
}
]
},
"version": 1
}
22 changes: 22 additions & 0 deletions Codegen/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Codegen",
dependencies: [
.package(path: ".."),
.package(url: "https://github.com/apple/swift-tools-support-core", from: "0.0.1")
],
targets: [
.target(
name: "Codegen",
dependencies: ["ApolloCodegenLib", "SwiftToolsSupport-auto"]),
.target(name: "SchemaDownload",
dependencies: ["ApolloCodegenLib"]),
.testTarget(
name: "CodegenTests",
dependencies: ["Codegen"]),
]
)
3 changes: 3 additions & 0 deletions Codegen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Codegen

A description of this package.
84 changes: 84 additions & 0 deletions Codegen/Sources/Codegen/ArgumentSetup.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import Foundation
import ApolloCodegenLib
import TSCUtility

enum Target {
case starWars
case gitHub

init?(name: String) {
switch name {
case "StarWars":
self = .starWars
case "GitHub":
self = .gitHub
default:
return nil
}
}

func targetRootURL(fromSourceRoot sourceRootURL: Foundation.URL) -> Foundation.URL {
switch self {
case .gitHub:
return sourceRootURL
.appendingPathComponent("Tests")
.appendingPathComponent("GitHubAPI")
case .starWars:
return sourceRootURL
.appendingPathComponent("Tests")
.appendingPathComponent("StarWarsAPI")
}
}

func options(fromSourceRoot sourceRootURL: Foundation.URL) -> ApolloCodegenOptions {
let targetRootURL = self.targetRootURL(fromSourceRoot: sourceRootURL)
switch self {
case .starWars:
return ApolloCodegenOptions(targetRootURL: targetRootURL)
case .gitHub:
let json = targetRootURL.appendingPathComponent("schema.json")
let outputFileURL = targetRootURL.appendingPathComponent("API.swift")
let operationIDsURL = targetRootURL.appendingPathComponent("operationIDs.json")

return ApolloCodegenOptions(mergeInFieldsFromFragmentSpreads: true,
operationIDsURL: operationIDsURL,
outputFormat: .singleFile(atFileURL: outputFileURL),
suppressSwiftMultilineStringLiterals: true,
urlToSchemaFile: json)
}
}
}

struct ArgumentSetup {

enum ArgumentError: Error, LocalizedError {
case targetNotProvided(args: [String])

var errorDescription: String? {
switch self {
case .targetNotProvided(let args):
return "No valid was provided to generate code for. Args were: \(args)"
}
}
}

static func parse(arguments: [String] = Array(ProcessInfo.processInfo.arguments.dropFirst())) throws -> Target {

let parser = ArgumentParser(usage: "Codegen <options>", overview: "This is what this tool is for")

let target: OptionArgument<String> = parser.add(option: "--target",
shortName: "-t",
kind: String.self,
usage: "The target to generate code for")
let parsedArguments = try parser.parse(arguments)


if
let targetName = parsedArguments.get(target),
let target = Target(name: targetName) {
return target
} else {
throw ArgumentError.targetNotProvided(args: arguments)
}
}
}
39 changes: 39 additions & 0 deletions Codegen/Sources/Codegen/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Foundation
import ApolloCodegenLib
import TSCUtility

// Grab the parent folder of this file on the filesystem
let parentFolderOfScriptFile = FileFinder.findParentFolder()

// Use that to calculate the source root
let sourceRootURL = parentFolderOfScriptFile
.deletingLastPathComponent() // Sources
.deletingLastPathComponent() // Codegen
.deletingLastPathComponent() // apollo-ios

// In a typical app, you'll only need to do this for one target, so you'd
// set these up directly within this file. Here, we're using more than one
// target, so we're using an arg parser to figure out which one to build,
// and an enum to hold related options.
let target = try ArgumentSetup.parse()
let targetURL = target.targetRootURL(fromSourceRoot: sourceRootURL)
let options = target.options(fromSourceRoot: sourceRootURL)

// This more necessary if you're using a sub-folder, but make sure
// there's actually a place to write out what you're doing.
try FileManager.default.apollo_createFolderIfNeeded(at: targetURL)

// Calculate where you want to download the CLI folder.
let cliFolderURL = sourceRootURL
.appendingPathComponent("Codegen")
.appendingPathComponent("ApolloCLI")

do {
// Actually attempt to generate code.
try ApolloCodegen.run(from: targetURL,
with: cliFolderURL,
options: options)
} catch {
// This makes the error message in Xcode a lot more legible.
exit(1)
}
32 changes: 32 additions & 0 deletions Codegen/Sources/SchemaDownload/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Foundation
import ApolloCodegenLib

// Grab the parent folder of this file on the filesystem
let parentFolderOfScriptFile = FileFinder.findParentFolder()

// Use that to calculate the source root
let sourceRootURL = parentFolderOfScriptFile
.deletingLastPathComponent() // Sources
.deletingLastPathComponent() // Codegen
.deletingLastPathComponent() // apollo-ios

let cliFolderURL = sourceRootURL
.appendingPathComponent("Codegen")
.appendingPathComponent("ApolloCLI")

let endpoint = URL(string: "http://localhost:8080/graphql")!

let output = sourceRootURL
.appendingPathComponent("Tests")
.appendingPathComponent("StarWarsAPI")

let options = ApolloSchemaOptions(schemaFileName: "downloaded_schema",
endpointURL: endpoint,
outputFolderURL: output)

do {
try ApolloSchemaDownloader.run(with: cliFolderURL,
options: options)
} catch {
exit(1)
}
Loading

0 comments on commit bbd3730

Please sign in to comment.