Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back all the pluralization #1879

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
9B455CE52492D0A3002255A9 /* ApolloExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B455CE22492D0A3002255A9 /* ApolloExtension.swift */; };
9B455CE72492D0A3002255A9 /* Collection+Apollo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B455CE42492D0A3002255A9 /* Collection+Apollo.swift */; };
9B455CEB2492FB03002255A9 /* String+SHA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B455CEA2492FB03002255A9 /* String+SHA.swift */; };
9B47518D2575AA850001FB87 /* Pluralizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B47516D2575AA690001FB87 /* Pluralizer.swift */; };
9B4751AD2575B5070001FB87 /* PluralizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B4751AC2575B5070001FB87 /* PluralizerTests.swift */; };
9B4F453F244A27B900C2CF7D /* URLSessionClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B4F453E244A27B900C2CF7D /* URLSessionClient.swift */; };
9B518C87235F819E004C426D /* CLIDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B518C85235F8125004C426D /* CLIDownloader.swift */; };
9B518C8C235F8B5F004C426D /* ApolloFilePathHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B518C8A235F8B05004C426D /* ApolloFilePathHelper.swift */; };
Expand Down Expand Up @@ -240,6 +242,7 @@
DED46035261CEA660086EF63 /* ApolloTestSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F8A95781EC0FC1200304A2D /* ApolloTestSupport.framework */; };
DED46042261CEA8A0086EF63 /* TestServerURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DED45C172615308E0086EF63 /* TestServerURLs.swift */; };
DED46051261CEAD20086EF63 /* StarWarsAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FCE2CFA1E6C213D00E34457 /* StarWarsAPI.framework */; };
E6E4209226A7DF4200B82624 /* InflectorKit in Frameworks */ = {isa = PBXBuildFile; productRef = E6E4209126A7DF4200B82624 /* InflectorKit */; };
E86D8E05214B32FD0028EFE1 /* JSONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86D8E03214B32DA0028EFE1 /* JSONTests.swift */; };
F16D083C21EF6F7300C458B8 /* QueryFromJSONBuildingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F16D083B21EF6F7300C458B8 /* QueryFromJSONBuildingTests.swift */; };
F82E62E122BCD223000C311B /* AutomaticPersistedQueriesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F82E62E022BCD223000C311B /* AutomaticPersistedQueriesTests.swift */; };
Expand Down Expand Up @@ -548,6 +551,8 @@
9B455CE22492D0A3002255A9 /* ApolloExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApolloExtension.swift; sourceTree = "<group>"; };
9B455CE42492D0A3002255A9 /* Collection+Apollo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Collection+Apollo.swift"; sourceTree = "<group>"; };
9B455CEA2492FB03002255A9 /* String+SHA.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SHA.swift"; sourceTree = "<group>"; };
9B47516D2575AA690001FB87 /* Pluralizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pluralizer.swift; sourceTree = "<group>"; };
9B4751AC2575B5070001FB87 /* PluralizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluralizerTests.swift; sourceTree = "<group>"; };
9B4AA8AD239EFDC9003E1300 /* Apollo-Target-CodegenTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apollo-Target-CodegenTests.xcconfig"; sourceTree = "<group>"; };
9B4F453E244A27B900C2CF7D /* URLSessionClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionClient.swift; sourceTree = "<group>"; };
9B4F4540244A2A9200C2CF7D /* HTTPBinAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPBinAPI.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -820,6 +825,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E6E4209226A7DF4200B82624 /* InflectorKit in Frameworks */,
DECD47C3262F779800924527 /* ApolloUtils.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1135,6 +1141,14 @@
name = Extensions;
sourceTree = "<group>";
};
9B4751BD2575BAFB0001FB87 /* Naming */ = {
isa = PBXGroup;
children = (
9B47516D2575AA690001FB87 /* Pluralizer.swift */,
);
name = Naming;
sourceTree = "<group>";
};
9B6835472463486200337AE6 /* ApolloUtils */ = {
isa = PBXGroup;
children = (
Expand All @@ -1149,6 +1163,7 @@
isa = PBXGroup;
children = (
9FE1E54C2588C5E000AA967E /* Frontend */,
9B4751BD2575BAFB0001FB87 /* Naming */,
9BCB585D240758B2002F766E /* Extensions */,
9BD681332405F6BB000874CB /* Codegen */,
9BD681322405F69C000874CB /* CLI */,
Expand Down Expand Up @@ -1217,6 +1232,7 @@
9BAEEC14234C132600808306 /* CLIExtractorTests.swift */,
9BAEEC0D234BB95B00808306 /* FileManagerExtensionsTests.swift */,
9B68F0542416B33300E97318 /* LineByLineComparison.swift */,
9B4751AC2575B5070001FB87 /* PluralizerTests.swift */,
9B8C3FB4248DA3E000707B13 /* URLExtensionsTests.swift */,
9BAEEC0C234BB95B00808306 /* Info.plist */,
);
Expand Down Expand Up @@ -1859,10 +1875,12 @@
buildRules = (
);
dependencies = (
E6E4209426A7DF5800B82624 /* PBXTargetDependency */,
9B683549246348CB00337AE6 /* PBXTargetDependency */,
);
name = ApolloCodegenLib;
packageProductDependencies = (
E6E4209126A7DF4200B82624 /* InflectorKit */,
);
productName = ApolloCodegenLib;
productReference = 9B7B6F47233C26D100F32205 /* ApolloCodegenLib.framework */;
Expand Down Expand Up @@ -2204,6 +2222,7 @@
packageReferences = (
9B7BDAF423FDEE2600ACD198 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
DE8C84F2268BBF8000C54D02 /* XCRemoteSwiftPackageReference "Starscream" */,
E6E4209026A7DF4200B82624 /* XCRemoteSwiftPackageReference "InflectorKit" */,
);
productRefGroup = 9FC750451D2A532C00458D91 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -2419,6 +2438,7 @@
9F62DFD02590710E00E6E808 /* GraphQLSource.swift in Sources */,
9BAEEBF32346DDAD00808306 /* CodegenLogger.swift in Sources */,
9F628EB52593651B00F94F9D /* GraphQLValue.swift in Sources */,
9B47518D2575AA850001FB87 /* Pluralizer.swift in Sources */,
9B518C8C235F8B5F004C426D /* ApolloFilePathHelper.swift in Sources */,
9F628E9525935BE600F94F9D /* GraphQLType.swift in Sources */,
9B518C87235F819E004C426D /* CLIDownloader.swift in Sources */,
Expand Down Expand Up @@ -2475,6 +2495,7 @@
9F62DF8E2590539A00E6E808 /* SchemaIntrospectionTests.swift in Sources */,
9B68F0552416B33300E97318 /* LineByLineComparison.swift in Sources */,
9BAEEC15234C132600808306 /* CLIExtractorTests.swift in Sources */,
9B4751AD2575B5070001FB87 /* PluralizerTests.swift in Sources */,
9BAEEC19234C297800808306 /* ApolloCodegenTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -2853,6 +2874,10 @@
target = 9FCE2CF91E6C213D00E34457 /* StarWarsAPI */;
targetProxy = DED4606A261CEDD10086EF63 /* PBXContainerItemProxy */;
};
E6E4209426A7DF5800B82624 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = E6E4209326A7DF5800B82624 /* InflectorKit */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
Expand Down Expand Up @@ -3382,6 +3407,14 @@
minimumVersion = 3.1.2;
};
};
E6E4209026A7DF4200B82624 /* XCRemoteSwiftPackageReference "InflectorKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mattt/InflectorKit.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 1.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand Down Expand Up @@ -3415,6 +3448,16 @@
package = 9B7BDAF423FDEE2600ACD198 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
productName = SQLite;
};
E6E4209126A7DF4200B82624 /* InflectorKit */ = {
isa = XCSwiftPackageProductDependency;
package = E6E4209026A7DF4200B82624 /* XCRemoteSwiftPackageReference "InflectorKit" */;
productName = InflectorKit;
};
E6E4209326A7DF5800B82624 /* InflectorKit */ = {
isa = XCSwiftPackageProductDependency;
package = E6E4209026A7DF4200B82624 /* XCRemoteSwiftPackageReference "InflectorKit" */;
productName = InflectorKit;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 9FC7503B1D2A532C00458D91 /* Project object */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"object": {
"pins": [
{
"package": "InflectorKit",
"repositoryURL": "https://github.com/mattt/InflectorKit.git",
"state": {
"branch": null,
"revision": "d8cbcc04972690aaa5fc760a2b9ddb3e9f0decd7",
"version": "1.0.0"
}
},
{
"package": "SQLite.swift",
"repositoryURL": "https://github.com/stephencelis/SQLite.swift.git",
Expand Down
9 changes: 9 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"object": {
"pins": [
{
"package": "InflectorKit",
"repositoryURL": "https://github.com/mattt/InflectorKit",
"state": {
"branch": null,
"revision": "d8cbcc04972690aaa5fc760a2b9ddb3e9f0decd7",
"version": "1.0.0"
}
},
{
"package": "SQLite.swift",
"repositoryURL": "https://github.com/stephencelis/SQLite.swift.git",
Expand Down
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ let package = Package(
.package(
url: "https://github.com/apollographql/Starscream",
.upToNextMinor(from: "3.1.2")),
.package(
url: "https://github.com/mattt/InflectorKit",
.upToNextMinor(from: "1.0.0")),
],
targets: [
.target(
Expand Down Expand Up @@ -70,6 +73,7 @@ let package = Package(
name: "ApolloCodegenLib",
dependencies: [
"ApolloUtils",
.product(name: "InflectorKit", package: "InflectorKit"),
],
exclude: [
"Info.plist",
Expand Down
4 changes: 4 additions & 0 deletions Package@swift-5.2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ let package = Package(
.package(
url: "https://github.com/daltoniam/Starscream",
.upToNextMinor(from: "3.1.1")),
.package(
url: "https://github.com/mattt/InflectorKit",
.upToNextMinor(from: "1.0.0")),
],
targets: [
.target(
Expand All @@ -47,6 +50,7 @@ let package = Package(
name: "ApolloCodegenLib",
dependencies: [
"ApolloCore",
"InflectorKit",
]),
.target(
name: "ApolloSQLite",
Expand Down
6 changes: 5 additions & 1 deletion Sources/ApolloCodegenLib/ApolloCodegenOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public struct ApolloCodegenOptions {
}

let codegenEngine: CodeGenerationEngine
let additionalInflectionRules: [InflectionRule]
let includes: String
let mergeInFieldsFromFragmentSpreads: Bool
let namespace: String?
Expand All @@ -81,9 +82,10 @@ public struct ApolloCodegenOptions {
///
/// - Parameters:
/// - codegenEngine: The code generation engine to use. Defaults to `CodeGenerationEngine.default`
/// - additionalInflectionRules: Any non-default rules for pluralization or singularization you wish to include. Defaults to an empty array. Only used by the Swift code generation engine.
/// - includes: Glob of files to search for GraphQL operations. This should be used to find queries *and* any client schema extensions. Defaults to `./**/*.graphql`, which will search for `.graphql` files throughout all subfolders of the folder where the script is run.
/// - mergeInFieldsFromFragmentSpreads: Set true to merge fragment fields onto its enclosing type. Defaults to true.
/// - modifier: [EXPERIMENTAL SWIFT CODEGEN ONLY] - The access modifier to use on everything created by this tool. Defaults to `.public`.
/// - modifier: The access modifier to use on everything created by this tool. Defaults to `.public`. Only used by the Swift code generation engine.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine for now. I think when we release the swift codegen, we will need to keep support for legacy codegen for a while, but that it should probably have its own set of options entirely so we can diverge more easily. But that's not a concern for today.

/// - namespace: [optional] The namespace to emit generated code into. Defaults to nil.
/// - omitDeprecatedEnumCases: Whether deprecated enum cases should be omitted from generated code. Defaults to false.
/// - only: [optional] Parse all input files, but only output generated code for the file at this URL if non-nil. Defaults to nil.
Expand All @@ -94,6 +96,7 @@ public struct ApolloCodegenOptions {
/// - urlToSchemaFile: The URL to your schema file.
/// - downloadTimeout: The maximum time to wait before indicating that the download timed out, in seconds. Defaults to 30 seconds.
public init(codegenEngine: CodeGenerationEngine = .default,
additionalInflectionRules: [InflectionRule] = [],
includes: String = "./**/*.graphql",
mergeInFieldsFromFragmentSpreads: Bool = true,
modifier: AccessModifier = .public,
Expand All @@ -107,6 +110,7 @@ public struct ApolloCodegenOptions {
urlToSchemaFile: URL,
downloadTimeout: Double = 30.0) {
self.codegenEngine = codegenEngine
self.additionalInflectionRules = additionalInflectionRules
self.includes = includes
self.mergeInFieldsFromFragmentSpreads = mergeInFieldsFromFragmentSpreads
self.modifier = modifier
Expand Down
56 changes: 56 additions & 0 deletions Sources/ApolloCodegenLib/Pluralizer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Foundation
import InflectorKit

/// The types of inflection rules that can be used to customize pluralization.
public enum InflectionRule {

/// A pluralization rule that allows taking a singular word and pluralizing it.
/// - singularRegex: A regular expression representing the single version of the word
/// - replacementRegex: A regular expression representing how to replace the singular version.
case pluralization(singularRegex: String, replacementRegex: String)

/// A singularization rule that allows taking a plural word and singularizing it.
/// - pluralRegex: A regular expression represeinting the plural version of the word
/// - replacementRegex: A regular expression representing how to replace the singular version
case singularization(pluralRegex: String, replacementRegex: String)

/// A definition of an irregular pluralization rule not easily captured by regex - for example "person" and "people".
/// - singular: The singular version of the word
/// - plural: The plural version of the word.
case irregular(singular: String, plural: String)

/// A definition of a word that should never be pluralized or de-pluralized because it's the same no matter what the count - for example, "fish".
/// - word: The word that should never be adjusted.
case uncountable(word: String)
}

struct Pluralizer {

private let inflector: StringInflector

init(rules: [InflectionRule] = []) {
let inflector = StringInflector.default
for rule in rules {
switch rule {
case .pluralization(let pluralRegex, let replacementRegex):
inflector.addPluralRule(pluralRegex, replacement: replacementRegex)
case .singularization(let singularRegex, let replacementRegex):
inflector.addSingularRule(singularRegex, replacement: replacementRegex)
case .irregular(let singular, let plural):
inflector.addIrregular(singular: singular, plural: plural)
case .uncountable(let word):
inflector.addUncountable(word)
}
}

self.inflector = inflector
}

func singularize(_ string: String) -> String {
self.inflector.singularize(string)
}

func pluralize(_ string: String) -> String {
self.inflector.pluralize(string)
}
}
9 changes: 9 additions & 0 deletions SwiftScripts/Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"version": "0.17.0"
}
},
{
"package": "InflectorKit",
"repositoryURL": "https://github.com/mattt/InflectorKit",
"state": {
"branch": null,
"revision": "d8cbcc04972690aaa5fc760a2b9ddb3e9f0decd7",
"version": "1.0.0"
}
},
{
"package": "MarkdownGenerator",
"repositoryURL": "https://github.com/eneko/MarkdownGenerator.git",
Expand Down
Loading