Skip to content

Commit 7274453

Browse files
Support multiple external configuration files #585 (#608)
* support https://github.com/lightbend/config * support HOCON * update pr * update pr * update descr Co-authored-by: Bogdan Kobylynskyi <[email protected]>
1 parent e95e60c commit 7274453

File tree

17 files changed

+287
-100
lines changed

17 files changed

+287
-100
lines changed

Diff for: build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies {
2323
implementation "org.freemarker:freemarker:2.3.31"
2424
implementation "com.graphql-java:graphql-java:15.0"
2525
implementation "com.fasterxml.jackson.core:jackson-databind:2.12.1"
26+
implementation "com.typesafe:config:1.4.1"
2627

2728
testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.1"
2829
testImplementation "org.junit.jupiter:junit-jupiter-params:5.7.1"

Diff for: docs/codegen-options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
| `graphqlSchemas` | *See<br>[graphqlSchemas](#option-graphqlschemas)* | All<br>`.graphqls`/`.graphql`<br>files in<br>resources | Block to define the input GraphQL schemas, when exact paths are too cumbersome. See table below for a list of options. *See [graphqlSchemas](#option-graphqlschemas)* |
77
| `graphqlQueryIntrospectionResu`<br>`ltPath` | String | None | Path to GraphQL Introspection Query result in json format (with root object `__schema` or `data.__schema`). Sample: [sample-introspection-query-result.json](../src/test/resources/introspection-result/sample-introspection-query-result.json)|
88
| `outputDir` | String | None | The output target directory into which code will be generated. |
9-
| `jsonConfigurationFile` | String | Empty | Path to an external mapping configuration. |
9+
| `configurationFiles` | List(String) | Empty | Paths to the files with mapping configurations. Supported formats. JSON, HOCON. Order of specified configuration files matters, so the default configuration should be placed at the end.|
1010
| `packageName` | String | Empty | Java package for generated classes. |
1111
| `apiPackageName` | String | Empty | Java package for generated api classes (Query, Mutation, Subscription). |
1212
| `modelPackageName` | String | Empty | Java package for generated model classes (type, input, interface, enum, union). |

Diff for: plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import com.kobylynskyi.graphql.codegen.model.MappingConfigConstants;
1313
import com.kobylynskyi.graphql.codegen.model.exception.LanguageNotSupportedException;
1414
import com.kobylynskyi.graphql.codegen.scala.ScalaGraphQLCodegen;
15-
import com.kobylynskyi.graphql.codegen.supplier.JsonMappingConfigSupplier;
15+
import com.kobylynskyi.graphql.codegen.supplier.MergeableMappingConfigSupplier;
1616
import com.kobylynskyi.graphql.codegen.supplier.MappingConfigSupplier;
1717
import com.kobylynskyi.graphql.codegen.supplier.SchemaFinder;
1818
import org.gradle.api.Action;
@@ -97,7 +97,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
9797
private Set<String> useObjectMapperForRequestSerialization = new HashSet<>();
9898

9999
private final ParentInterfacesConfig parentInterfaces = new ParentInterfacesConfig();
100-
private String jsonConfigurationFile;
100+
private List<String> configurationFiles;
101101
private GeneratedLanguage generatedLanguage = MappingConfigConstants.DEFAULT_GENERATED_LANGUAGE;
102102
private Boolean generateModelOpenClasses = MappingConfigConstants.DEFAULT_GENERATE_MODEL_OPEN_CLASSES;
103103

@@ -242,8 +242,8 @@ private java.util.Optional<Path> findDefaultResourcesDir() {
242242
}
243243

244244
private java.util.Optional<MappingConfigSupplier> buildJsonSupplier() {
245-
if (jsonConfigurationFile != null && !jsonConfigurationFile.isEmpty()) {
246-
return java.util.Optional.of(new JsonMappingConfigSupplier(jsonConfigurationFile));
245+
if (configurationFiles != null && !configurationFiles.isEmpty()) {
246+
return java.util.Optional.of(new MergeableMappingConfigSupplier(configurationFiles));
247247
}
248248
return java.util.Optional.empty();
249249
}
@@ -773,14 +773,14 @@ public String getResolverParentInterface() {
773773
return parentInterfaces.getResolver();
774774
}
775775

776-
@InputFile
776+
@InputFiles
777777
@Optional
778-
public String getJsonConfigurationFile() {
779-
return jsonConfigurationFile;
778+
public List<String> getConfigurationFiles() {
779+
return configurationFiles;
780780
}
781781

782-
public void setJsonConfigurationFile(String jsonConfigurationFile) {
783-
this.jsonConfigurationFile = jsonConfigurationFile;
782+
public void setConfigurationFiles(List<String> configurationFiles) {
783+
this.configurationFiles = configurationFiles;
784784
}
785785

786786
@Input

Diff for: plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import com.kobylynskyi.graphql.codegen.model.RelayConfig;
1414
import com.kobylynskyi.graphql.codegen.model.exception.LanguageNotSupportedException;
1515
import com.kobylynskyi.graphql.codegen.scala.ScalaGraphQLCodegen;
16-
import com.kobylynskyi.graphql.codegen.supplier.JsonMappingConfigSupplier;
1716
import com.kobylynskyi.graphql.codegen.supplier.MappingConfigSupplier;
17+
import com.kobylynskyi.graphql.codegen.supplier.MergeableMappingConfigSupplier;
1818
import com.kobylynskyi.graphql.codegen.supplier.SchemaFinder;
1919
import org.apache.maven.model.Resource;
2020
import org.apache.maven.plugin.AbstractMojo;
@@ -189,7 +189,7 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
189189
private GeneratedLanguage generatedLanguage;
190190

191191
@Parameter
192-
private String jsonConfigurationFile;
192+
private String[] configurationFiles;
193193

194194
/**
195195
* The project being built.
@@ -265,7 +265,7 @@ public void execute() throws MojoExecutionException {
265265
}
266266

267267
private GraphQLCodegen instantiateCodegen(MappingConfig mappingConfig) throws IOException {
268-
java.util.Optional<MappingConfigSupplier> mappingConfigSupplier = buildJsonSupplier(jsonConfigurationFile);
268+
java.util.Optional<MappingConfigSupplier> mappingConfigSupplier = buildJsonSupplier(configurationFiles);
269269
GeneratedLanguage language = mappingConfigSupplier.map(Supplier::get)
270270
.map(MappingConfig::getGeneratedLanguage)
271271
.orElse(generatedLanguage);
@@ -312,9 +312,9 @@ private Optional<Path> getDefaultResourcesDirectory() {
312312
return project.getResources().stream().findFirst().map(Resource::getDirectory).map(Paths::get);
313313
}
314314

315-
private java.util.Optional<MappingConfigSupplier> buildJsonSupplier(String jsonConfigurationFile) {
316-
if (jsonConfigurationFile != null && !jsonConfigurationFile.isEmpty()) {
317-
return java.util.Optional.of(new JsonMappingConfigSupplier(jsonConfigurationFile));
315+
private java.util.Optional<MappingConfigSupplier> buildJsonSupplier(String[] configurationFiles) {
316+
if (configurationFiles != null && configurationFiles.length != 0) {
317+
return java.util.Optional.of(new MergeableMappingConfigSupplier(Arrays.asList(configurationFiles.clone())));
318318
}
319319
return java.util.Optional.empty();
320320
}
@@ -580,8 +580,8 @@ public ParentInterfacesConfig getParentInterfaces() {
580580
return parentInterfaces;
581581
}
582582

583-
public String getJsonConfigurationFile() {
584-
return jsonConfigurationFile;
583+
public String[] getConfigurationFiles() {
584+
return configurationFiles;
585585
}
586586

587587
private static Map<String, List<String>> convertToListsMap(Map<String, Properties> sourceMap) {

Diff for: plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ trait GraphQLCodegenKeys {
8181

8282
val useObjectMapperForRequestSerialization = settingKey[util.Set[String]]("useObjectMapperForRequestSerialization")
8383

84-
val jsonConfigurationFile = settingKey[Option[String]]("jsonConfigurationFile")
84+
val configurationFiles = settingKey[Seq[String]]("configurationFiles, either JSON or HOCON. The same key is used in order, so the default configuration should be placed at the end.")
8585

8686
val parentInterfaces = settingKey[ParentInterfacesConfig]("parentInterfaces")
8787

Diff for: plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala

+9-6
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import com.kobylynskyi.graphql.codegen.model._
66
import com.kobylynskyi.graphql.codegen.model.exception.LanguageNotSupportedException
77
import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage._
88
import com.kobylynskyi.graphql.codegen.scala.ScalaGraphQLCodegen
9-
import com.kobylynskyi.graphql.codegen.supplier.{ JsonMappingConfigSupplier, SchemaFinder }
9+
import com.kobylynskyi.graphql.codegen.supplier.{ MergeableMappingConfigSupplier, SchemaFinder }
1010
import sbt.{ AutoPlugin, PluginTrigger, _ }
1111
import sbt.Keys.{ sLog, sourceManaged, _ }
1212
import sbt.internal.util.complete.DefaultParsers.spaceDelimited
13+
import com.kobylynskyi.graphql.codegen.kotlin.KotlinGraphQLCodegen
1314

1415
import java.nio.file.{ Path, Paths }
1516
import java.util.{ HashMap => JHashMap, HashSet => JHashSet, List => JList }
@@ -59,7 +60,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
5960
override lazy val globalSettings: Seq[Def.Setting[_]] = Seq(
6061
graphqlQueryIntrospectionResultPath := None,
6162
graphqlSchemas := schemaFinderConfig,
62-
jsonConfigurationFile := None,
63+
configurationFiles := Seq.empty[String],
6364
graphqlSchemaPaths := Seq.empty,
6465
graphqlSchemaValidate := Seq.empty,
6566
customTypesMapping := new JHashMap[String, String](), //TODO use scala Map, convert to java Map
@@ -201,7 +202,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
201202
args
202203
}, graphqlCodegen := {
203204
sLog.value.info(s"Generating files: ${BuildInfo.toString}")
204-
val mappingConfigSupplier = buildJsonSupplier(jsonConfigurationFile.value.orNull)
205+
val mappingConfigSupplier = buildJsonSupplier(configurationFiles.value)
205206
val language = mappingConfigSupplier.map(_.get()).map(_.getGeneratedLanguage).getOrElse(generatedLanguage.value)
206207
var result = Seq.empty[File]
207208
try {
@@ -213,6 +214,8 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
213214
new JavaGraphQLCodegen(getSchemas(), _introspectionResult, _outputDir, mappingConfig, mappingConfigSupplier.orNull)
214215
case SCALA =>
215216
new ScalaGraphQLCodegen(getSchemas(), _introspectionResult, _outputDir, mappingConfig, mappingConfigSupplier.orNull)
217+
case KOTLIN =>
218+
new KotlinGraphQLCodegen(getSchemas(), _introspectionResult, _outputDir, mappingConfig, mappingConfigSupplier.orNull)
216219
case _ =>
217220
throw new LanguageNotSupportedException(language)
218221
}
@@ -275,9 +278,9 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
275278
) ++ watchSourcesSetting ++ Seq(cleanFiles += generateCodegenTargetPath.value)
276279
}
277280

278-
protected def buildJsonSupplier(jsonConfigurationFile: String): Option[JsonMappingConfigSupplier] = {
279-
if (jsonConfigurationFile != null && jsonConfigurationFile.nonEmpty)
280-
Some(new JsonMappingConfigSupplier(jsonConfigurationFile)) else None
281+
protected def buildJsonSupplier(configurationFiles: Seq[String]): Option[MergeableMappingConfigSupplier] = {
282+
if (configurationFiles != null && configurationFiles.nonEmpty)
283+
Some(new MergeableMappingConfigSupplier(configurationFiles.asJava)) else None
281284
}
282285

283286
}

Diff for: src/main/java/com/kobylynskyi/graphql/codegen/supplier/JsonMappingConfigSupplier.java

-38
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.kobylynskyi.graphql.codegen.supplier;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.kobylynskyi.graphql.codegen.model.MappingConfig;
5+
import com.kobylynskyi.graphql.codegen.utils.Utils;
6+
import com.typesafe.config.Config;
7+
import com.typesafe.config.ConfigException;
8+
import com.typesafe.config.ConfigFactory;
9+
import com.typesafe.config.ConfigRenderOptions;
10+
11+
import java.io.File;
12+
import java.util.List;
13+
14+
/**
15+
* Retrieve a MappingConfig from JSON or HOCON configuration file.
16+
*
17+
* @author valinha
18+
*/
19+
public class MergeableMappingConfigSupplier implements MappingConfigSupplier {
20+
21+
private static final ConfigRenderOptions configRenderOptions = ConfigRenderOptions.concise();
22+
23+
private final String jsonConfig;
24+
25+
/**
26+
* Instantiates a new Json configuration file supplier.
27+
*
28+
* @param configFiles List of files, either JSON or HOCON.
29+
*/
30+
public MergeableMappingConfigSupplier(List<String> configFiles) {
31+
this.jsonConfig = parseConfigAndMerged(configFiles);
32+
}
33+
34+
@Override
35+
public MappingConfig get() {
36+
if (jsonConfig != null && !jsonConfig.isEmpty()) {
37+
try {
38+
return Utils.OBJECT_MAPPER.readValue(jsonConfig, MappingConfig.class);
39+
} catch (ConfigException | JsonProcessingException e) {
40+
throw new IllegalArgumentException(e);
41+
}
42+
}
43+
return null;
44+
}
45+
46+
47+
/**
48+
* parser list of config files.
49+
*
50+
* @param confFiles List of files, either JSON or HOCON.
51+
* @return The string of the configuration after merging.
52+
*/
53+
private static String parseConfigAndMerged(List<String> confFiles) {
54+
try {
55+
if (confFiles == null || confFiles.isEmpty()) {
56+
return null;
57+
}
58+
59+
return confFiles.stream()
60+
.map(c -> ConfigFactory.parseFile(new File(c)))
61+
.reduce(Config::withFallback)
62+
.map(value -> value.root().render(configRenderOptions))
63+
.orElse(null);
64+
} catch (ConfigException ce) {
65+
return null;
66+
}
67+
}
68+
}

Diff for: src/main/java/com/kobylynskyi/graphql/codegen/utils/Utils.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,5 +262,5 @@ public static String wrapString(String str, String wrapStart, String wrapEnd) {
262262
}
263263
return wrapStart + str + wrapEnd;
264264
}
265-
265+
266266
}

0 commit comments

Comments
 (0)