Skip to content

Commit

Permalink
update: CLI defaults (#2673)
Browse files Browse the repository at this point in the history
  • Loading branch information
calvincestari authored Nov 17, 2022
1 parent 69538a3 commit 5b2336c
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 397 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ commands:
name: CocoaPods - Install
- run:
working_directory: Tests/CodegenCLITests/pod-install-test/
command: ./Pods/Apollo/apollo-ios-cli init --schema-name NewTestSchema
command: ./Pods/Apollo/apollo-ios-cli init --schema-name NewTestSchema --module-type other
name: CocoaPods - CLI Test (init)
- run:
working_directory: Tests/CodegenCLITests/pod-install-test/
Expand Down
4 changes: 2 additions & 2 deletions Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6627,8 +6627,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-argument-parser.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 1.1.3;
kind = upToNextMajorVersion;
minimumVersion = 1.2.0;
};
};
E6E4209026A7DF4200B82624 /* XCRemoteSwiftPackageReference "InflectorKit" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "df9ee6676cd5b3bf5b330ec7568a5644f547201b",
"version" : "1.1.3"
"revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d",
"version" : "1.2.0"
}
},
{
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "df9ee6676cd5b3bf5b330ec7568a5644f547201b",
"version" : "1.1.3"
"revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d",
"version" : "1.2.0"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ let package = Package(
.upToNextMajor(from: "1.0.0")),
.package(
url: "https://github.com/apple/swift-argument-parser.git",
.upToNextMajor(from: "1.1.2")),
.upToNextMajor(from: "1.2.0")),
],
targets: [
.target(
Expand Down
7 changes: 3 additions & 4 deletions Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {

/// Default property values
public struct Default {
public static let operations: OperationsFileOutput = .relative(subpath: nil)
public static let operations: OperationsFileOutput = .inSchemaModule
public static let testMocks: TestMockFileOutput = .none
public static let operationIdentifiersPath: String? = nil
}
Expand All @@ -179,7 +179,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
/// - Parameters:
/// - schemaTypes: The local path structure for the generated schema types files.
/// - operations: The local path structure for the generated operation object files.
/// Defaults to `.relative` with a `subpath` of `nil`.
/// Defaults to `.inSchemaModule`.
/// - testMocks: The local path structure for the test mock operation object files.
/// If `.none`, test mocks will not be generated. Defaults to `.none`.
/// - operationIdentifiersPath: An absolute location to an operation id JSON map file.
Expand Down Expand Up @@ -226,8 +226,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
public struct SchemaTypesFileOutput: Codable, Equatable {
/// Local path where the generated schema types files should be stored.
public let path: String
/// Automation to ease the integration of the generated schema types file with compatible
/// dependency managers.
/// How to package the schema types for dependency management.
public let moduleType: ModuleType

/// Designated initializer.
Expand Down
94 changes: 82 additions & 12 deletions Sources/CodegenCLI/Commands/Initialize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,26 @@ public struct Initialize: ParsableCommand {
name: [.long, .customShort("n")],
help: "Name used to scope the generated schema type files."
)
var schemaName: String = ""
var schemaName: String

@Option(
name: [.long, .customShort("m")],
help: """
How to package the schema types for dependency management. Possible types: \
\(ModuleTypeExpressibleByArgument.allValueStrings.joined(separator: ", ")).
"""
)
var moduleType: ModuleTypeExpressibleByArgument

@Option(
name: [.long, .customShort("t")],
help: """
Name of the target in which the schema types files will be manually embedded. This is \
required for the \"embeddedInTarget\" module type and will be ignored for all other module \
types.
"""
)
var targetName: String? = nil

@Option(
name: .shortAndLong,
Expand Down Expand Up @@ -45,8 +64,19 @@ public struct Initialize: ParsableCommand {
public init() { }

public func validate() throws {
guard !schemaName.isEmpty else {
throw ValidationError("Schema name is missing, use the --schema-name option to specify.")
guard !schemaName.trimmingCharacters(in: .whitespaces).isEmpty else {
throw ValidationError("--schema-name value cannot be empty.")
}

switch (moduleType, targetName?.isEmpty) {
case (.embeddedInTarget, nil), (.embeddedInTarget, true):
throw ValidationError("""
Target name is required when using \"embeddedInTarget\" module type. Use --target-name \
to specify.
"""
)
default:
break;
}
}

Expand All @@ -56,8 +86,11 @@ public struct Initialize: ParsableCommand {

func _run(fileManager: ApolloFileManager = .default, output: OutputClosure? = nil) throws {
let encoded = try ApolloCodegenConfiguration
.minimalJSON(schemaName: schemaName)
.asData()
.minimalJSON(
schemaName: schemaName,
moduleType: moduleType,
targetName: targetName
).asData()

if print {
try print(data: encoded, output: output)
Expand Down Expand Up @@ -119,22 +152,50 @@ public struct Initialize: ParsableCommand {
// MARK: - Internal extensions

extension ApolloCodegenConfiguration {
static func minimalJSON(schemaName: String) -> String {
static func minimalJSON(
schemaName: String,
moduleType: ModuleTypeExpressibleByArgument,
targetName: String?
) -> String {
#if COCOAPODS
minimalJSON(schemaName: schemaName, supportCocoaPods: true)
minimalJSON(
schemaName: schemaName,
supportCocoaPods: true,
moduleType: moduleType,
targetName: targetName
)
#else
minimalJSON(schemaName: schemaName, supportCocoaPods: false)
minimalJSON(
schemaName: schemaName,
supportCocoaPods: false,
moduleType: moduleType,
targetName: targetName
)
#endif
}

static func minimalJSON(schemaName: String, supportCocoaPods: Bool) -> String {
static func minimalJSON(
schemaName: String,
supportCocoaPods: Bool,
moduleType: ModuleTypeExpressibleByArgument,
targetName: String?
) -> String {
let cocoaPodsOption = supportCocoaPods ? """
"options" : {
"cocoapodsCompatibleImportStatements" : true
},
""" : ""

let moduleTarget: String = {
guard let targetName = targetName else { return "}" }

return """
"name" : "\(targetName)"
}
"""
}()

return """
{
"schemaName" : "\(schemaName)",\(cocoaPodsOption)
Expand All @@ -154,16 +215,25 @@ extension ApolloCodegenConfiguration {
"schemaTypes" : {
"path" : "./\(schemaName)",
"moduleType" : {
\(supportCocoaPods ? "\"other\"" : "\"swiftPackageManager\"") : {
}
"\(moduleType)" : {
\(moduleTarget)
}
},
"operations" : {
"relative" : {
"inSchemaModule" : {
}
}
}
}
"""
}
}

/// A custom enum that matches ApolloCodegenConfiguration.SchemaTypesFileOutput.ModuleType, but
/// specifically without associated values so that it can conform to ExpressibleByArgument and be
/// parsed from the command line.
enum ModuleTypeExpressibleByArgument: String, ExpressibleByArgument, CaseIterable {
case embeddedInTarget
case swiftPackageManager
case other
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class ApolloCodegenConfigurationTests: XCTestCase {

// then
expect(output.operationIdentifiersPath).to(beNil())
expect(output.operations).to(equal(.relative(subpath: nil)))
expect(output.operations).to(equal(.inSchemaModule))
}

func test__initializer__givenMinimalApolloCodegenConfiguration_buildsCorrectDefaults() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,12 @@ class InputObjectTemplateTests: XCTestCase {
intField: GraphQLNullable<Int> = nil,
boolField: GraphQLNullable<Bool> = nil,
floatField: GraphQLNullable<Double> = nil,
customScalarField: GraphQLNullable<TestSchema.CustomScalar> = nil,
lowercaseCustomScalarField: GraphQLNullable<TestSchema.LowercaseCustomScalar> = nil,
enumField: GraphQLNullable<GraphQLEnum<TestSchema.EnumType>> = nil,
lowercaseEnumField: GraphQLNullable<GraphQLEnum<TestSchema.LowercaseEnumType>> = nil,
inputField: GraphQLNullable<TestSchema.InnerInputObject> = nil,
lowercaseInputField: GraphQLNullable<TestSchema.LowercaseInnerInputObject> = nil,
customScalarField: GraphQLNullable<CustomScalar> = nil,
lowercaseCustomScalarField: GraphQLNullable<LowercaseCustomScalar> = nil,
enumField: GraphQLNullable<GraphQLEnum<EnumType>> = nil,
lowercaseEnumField: GraphQLNullable<GraphQLEnum<LowercaseEnumType>> = nil,
inputField: GraphQLNullable<InnerInputObject> = nil,
lowercaseInputField: GraphQLNullable<LowercaseInnerInputObject> = nil,
listField: GraphQLNullable<[String?]> = nil
) {
__data = InputDict([
Expand Down Expand Up @@ -304,32 +304,32 @@ class InputObjectTemplateTests: XCTestCase {
set { __data["floatField"] = newValue }
}
public var customScalarField: GraphQLNullable<TestSchema.CustomScalar> {
public var customScalarField: GraphQLNullable<CustomScalar> {
get { __data["customScalarField"] }
set { __data["customScalarField"] = newValue }
}
public var lowercaseCustomScalarField: GraphQLNullable<TestSchema.LowercaseCustomScalar> {
public var lowercaseCustomScalarField: GraphQLNullable<LowercaseCustomScalar> {
get { __data["lowercaseCustomScalarField"] }
set { __data["lowercaseCustomScalarField"] = newValue }
}
public var enumField: GraphQLNullable<GraphQLEnum<TestSchema.EnumType>> {
public var enumField: GraphQLNullable<GraphQLEnum<EnumType>> {
get { __data["enumField"] }
set { __data["enumField"] = newValue }
}
public var lowercaseEnumField: GraphQLNullable<GraphQLEnum<TestSchema.LowercaseEnumType>> {
public var lowercaseEnumField: GraphQLNullable<GraphQLEnum<LowercaseEnumType>> {
get { __data["lowercaseEnumField"] }
set { __data["lowercaseEnumField"] = newValue }
}
public var inputField: GraphQLNullable<TestSchema.InnerInputObject> {
public var inputField: GraphQLNullable<InnerInputObject> {
get { __data["inputField"] }
set { __data["inputField"] = newValue }
}
public var lowercaseInputField: GraphQLNullable<TestSchema.LowercaseInnerInputObject> {
public var lowercaseInputField: GraphQLNullable<LowercaseInnerInputObject> {
get { __data["lowercaseInputField"] }
set { __data["lowercaseInputField"] = newValue }
}
Expand Down Expand Up @@ -749,21 +749,22 @@ class InputObjectTemplateTests: XCTestCase {
func test__render__given_NullableListOfNullableEnum_NoDefault__generates_NullableParameter_OptionalItem_InitializerNilDefault() throws {
// given
buildSubject(fields: [
GraphQLInputField.mock("nullableListNullableItem",
type: .list(.enum(.mock(name: "EnumValue"))),
defaultValue: nil)
GraphQLInputField.mock(
"nullableListNullableItem",
type: .list(.enum(.mock(name: "EnumValue"))),
defaultValue: nil)
])

let expected = """
public init(
nullableListNullableItem: GraphQLNullable<[GraphQLEnum<TestSchema.EnumValue>?]> = nil
nullableListNullableItem: GraphQLNullable<[GraphQLEnum<EnumValue>?]> = nil
) {
__data = InputDict([
"nullableListNullableItem": nullableListNullableItem
])
}
public var nullableListNullableItem: GraphQLNullable<[GraphQLEnum<TestSchema.EnumValue>?]> {
public var nullableListNullableItem: GraphQLNullable<[GraphQLEnum<EnumValue>?]> {
"""

// when
Expand Down Expand Up @@ -2042,7 +2043,10 @@ class InputObjectTemplateTests: XCTestCase {
"nullableListNullableItem",
type: .list(.enum(.mock(name: "EnumValue"))),
defaultValue: nil)],
config: .mock(schemaName: "testschema")
config: .mock(
schemaName: "testschema",
output: .mock(operations: .relative(subpath: nil))
)
)

let expected = """
Expand Down Expand Up @@ -2071,7 +2075,10 @@ class InputObjectTemplateTests: XCTestCase {
"nullableListNullableItem",
type: .list(.enum(.mock(name: "EnumValue"))),
defaultValue: nil)],
config: .mock(schemaName: "TESTSCHEMA")
config: .mock(
schemaName: "TESTSCHEMA",
output: .mock(operations: .relative(subpath: nil))
)
)

let expected = """
Expand Down Expand Up @@ -2100,7 +2107,10 @@ class InputObjectTemplateTests: XCTestCase {
"nullableListNullableItem",
type: .list(.enum(.mock(name: "EnumValue"))),
defaultValue: nil)],
config: .mock(schemaName: "TestSchema")
config: .mock(
schemaName: "TestSchema",
output: .mock(operations: .relative(subpath: nil))
)
)

let expected = """
Expand Down
Loading

0 comments on commit 5b2336c

Please sign in to comment.