Skip to content

Commit

Permalink
Add Netflix DGS Codegen plugin support
Browse files Browse the repository at this point in the history
This commit adds a new dependency to start.spring.io, the "Netflix Data
Graph Service Codegen". This will not add a dependency to generated
project, but rather configure a Maven or a Gradle plugin in the build.

This Codegen plugin parses GraphQL schema files describing remote
GraphQL APIs and generates Java classes to easily create queries and
deserialize GraphQL responses.
  • Loading branch information
bclozel committed Nov 21, 2023
1 parent 4e5ec6e commit 4be7742
Show file tree
Hide file tree
Showing 16 changed files with 775 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import io.spring.initializr.generator.buildsystem.Build;
import io.spring.initializr.generator.spring.build.BuildCustomizer;

import org.springframework.core.Ordered;

/**
* {@link BuildCustomizer} that removes the "dgs-codegen" dependency as this is a build
* plugin only dependency.
*
* @author Brian Clozel
*/
class DgsCodegenBuildCustomizer implements BuildCustomizer<Build> {

@Override
public void customize(Build build) {
build.dependencies().remove("dgs-codegen");
}

@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 10;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import io.spring.initializr.generator.buildsystem.gradle.GradleBuild;
import io.spring.initializr.generator.spring.build.BuildCustomizer;

/**
* {@link BuildCustomizer} for Gradle Groovy DSL projects using DGS Codegen.
*
* @author Brian Clozel
*/
class DgsCodegenGroovyDslGradleBuildCustomizer implements BuildCustomizer<GradleBuild> {

private final String pluginVersion;

private final String packageName;

DgsCodegenGroovyDslGradleBuildCustomizer(String pluginVersion, String packageName) {
this.pluginVersion = pluginVersion;
this.packageName = packageName;
}

@Override
public void customize(GradleBuild build) {
build.plugins().add("com.netflix.dgs.codegen", (plugin) -> plugin.setVersion(this.pluginVersion));
build.snippets().add((writer) -> {
writer.println("generateJava {");
writer.indented(() -> {
writer.println("schemaPaths = [\"${projectDir}/src/main/resources/graphql-client\"]");
writer.println("packageName = '" + this.packageName + ".codegen'");
writer.println("generateClient = true");
});
writer.println("}");
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import java.util.HashMap;
import java.util.Map;

import io.spring.initializr.generator.buildsystem.BuildSystem;
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.spring.documentation.HelpDocument;
import io.spring.initializr.generator.spring.documentation.HelpDocumentCustomizer;

/**
* Provide additional information when DGS Codegen Support is selected.
*
* @author Brian Clozel
*/
class DgsCodegenHelpDocumentCustomizer implements HelpDocumentCustomizer {

private final BuildSystem buildSystem;

DgsCodegenHelpDocumentCustomizer(ProjectDescription description) {
this.buildSystem = description.getBuildSystem();
}

@Override
public void customize(HelpDocument document) {
Map<String, Object> model = new HashMap<>();

if (MavenBuildSystem.ID.equals(this.buildSystem.id())) {
model.put("dsgCodegenOptionsLink", "https://github.com/deweyjose/graphqlcodegen");
}
else if (GradleBuildSystem.ID.equals(this.buildSystem.id())) {
model.put("dsgCodegenOptionsLink",
"https://netflix.github.io/dgs/generating-code-from-schema/#configuring-code-generation");
}
document.addSection("dgscodegen", model);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import io.spring.initializr.generator.buildsystem.gradle.GradleBuild;
import io.spring.initializr.generator.spring.build.BuildCustomizer;

/**
* {@link BuildCustomizer} for Gradle Kotlin DSL projects using DGS Codegen.
*
* @author Brian Clozel
*/
class DgsCodegenKotlinDslGradleBuildCustomizer implements BuildCustomizer<GradleBuild> {

private final String pluginVersion;

private final String packageName;

DgsCodegenKotlinDslGradleBuildCustomizer(String pluginVersion, String packageName) {
this.pluginVersion = pluginVersion;
this.packageName = packageName;
}

@Override
public void customize(GradleBuild build) {
build.plugins().add("com.netflix.dgs.codegen", (plugin) -> plugin.setVersion(this.pluginVersion));
build.snippets().add((writer) -> {
writer.println("tasks.generateJava {");
writer.indented(() -> {
writer.println("schemaPaths.add(\"${projectDir}/src/main/resources/graphql-client\")");
writer.println("packageName = \"" + this.packageName + ".codegen\"");
writer.println("generateClient = true");
});
writer.println("}");
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.spring.build.BuildCustomizer;

/**
* {@link BuildCustomizer} for Maven projects using DGS Codegen (community maintained).
*
* @author Brian Clozel
* @see <a href="https://github.com/deweyjose/graphqlcodegen">Maven GraphQL Codegen
* plugin</a>
*/
public class DgsCodegenMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {

private final String pluginVersion;

private final String packageName;

public DgsCodegenMavenBuildCustomizer(String pluginVersion, String packageName) {
this.pluginVersion = pluginVersion;
this.packageName = packageName;
}

@Override
public void customize(MavenBuild build) {
build.plugins()
.add("io.github.deweyjose", "graphqlcodegen-maven-plugin",
(plugin) -> plugin.version(this.pluginVersion)
.execution("dgs-codegen",
(execution) -> execution.goal("generate")
.configuration((configuration) -> configuration
.add("schemaPaths",
(schemaPaths) -> schemaPaths.add("param",
"src/main/resources/graphql-client"))
.add("packageName", this.packageName + ".codegen")
.add("addGeneratedAnnotation", "true"))));
build.plugins()
.add("org.codehaus.mojo", "build-helper-maven-plugin",
(plugin) -> plugin.execution("add-dgs-source", (execution) -> execution.goal("add-source")
.phase("generate-sources")
.configuration((configuration) -> configuration.add("sources",
(sources) -> sources.add("source", "${project.build.directory}/generated-sources")))));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import io.spring.initializr.generator.project.contributor.ProjectContributor;

/**
* A {@link ProjectContributor} that creates the "graphql-client" resources directory when
* the DGS Codegen build plugin is requested.
*
* @author Brian Clozel
*/
class DgsCodegenProjectContributor implements ProjectContributor {

@Override
public void contribute(Path projectRoot) throws IOException {
Path graphQlDirectory = projectRoot.resolve("src/main/resources/graphql-client");
Files.createDirectories(graphQlDirectory);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.extension.dependency.dgs;

import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
import io.spring.initializr.generator.condition.ConditionalOnBuildSystem;
import io.spring.initializr.generator.condition.ConditionalOnPlatformVersion;
import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.metadata.InitializrMetadata;

import org.springframework.context.annotation.Bean;

/**
* {@link ProjectGenerationConfiguration} for generation of projects that use the Netflix
* DGS codegen.
*
* @author Brian Clozel
* @see <a href="https://netflix.github.io/dgs/generating-code-from-schema/">Netflix DGS
* codegen</a>
*/
@ProjectGenerationConfiguration
@ConditionalOnRequestedDependency("dgs-codegen")
@ConditionalOnPlatformVersion("3.0.0-M1")
class DgsCodegenProjectGenerationConfiguration {

private final String dgsCodegenPluginVersion;

DgsCodegenProjectGenerationConfiguration(InitializrMetadata metadata, ProjectDescription description) {
this.dgsCodegenPluginVersion = DgsCodegenVersionResolver.resolve(metadata, description.getPlatformVersion(),
description.getBuildSystem());
}

@Bean
DgsCodegenBuildCustomizer dgsCodegenBuildCustomizer() {
return new DgsCodegenBuildCustomizer();
}

@Bean
DgsCodegenProjectContributor dgsCodegenProjectContributor() {
return new DgsCodegenProjectContributor();
}

@Bean
DgsCodegenHelpDocumentCustomizer dgsCodegenHelpDocumentCustomizer(ProjectDescription description) {
return new DgsCodegenHelpDocumentCustomizer(description);
}

@Bean
@ConditionalOnBuildSystem(id = GradleBuildSystem.ID, dialect = GradleBuildSystem.DIALECT_GROOVY)
DgsCodegenGroovyDslGradleBuildCustomizer dgsCodegenGroovyDslGradleBuildCustomizer(ProjectDescription description) {
return new DgsCodegenGroovyDslGradleBuildCustomizer(this.dgsCodegenPluginVersion, description.getPackageName());
}

@Bean
@ConditionalOnBuildSystem(id = GradleBuildSystem.ID, dialect = GradleBuildSystem.DIALECT_KOTLIN)
DgsCodegenKotlinDslGradleBuildCustomizer dgsCodegenKotlinDslGradleBuildCustomizer(ProjectDescription description) {
return new DgsCodegenKotlinDslGradleBuildCustomizer(this.dgsCodegenPluginVersion, description.getPackageName());
}

@Bean
@ConditionalOnBuildSystem(MavenBuildSystem.ID)
DgsCodegenMavenBuildCustomizer dgsCodegenMavenBuildCustomizer(ProjectDescription description) {
return new DgsCodegenMavenBuildCustomizer(this.dgsCodegenPluginVersion, description.getPackageName());
}

}
Loading

0 comments on commit 4be7742

Please sign in to comment.