Skip to content

Commit 77d957f

Browse files
committed
Make the plugin output directory configurable
Make outputDir configurable, so that users can have full control over the output path. Additionally, the GenerateJavaTask lazy by converting inputs to gradle Properties. See: https://docs.gradle.org/current/userguide/lazy_configuration.html
1 parent a25d8ba commit 77d957f

File tree

4 files changed

+229
-106
lines changed

4 files changed

+229
-106
lines changed

graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/CodegenPlugin.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class CodegenPlugin : Plugin<Project> {
4444
val javaConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
4545
val sourceSets = javaConvention.sourceSets
4646
val mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
47-
val outputDir = generateJavaTaskProvider.map(GenerateJavaTask::getOutputDir)
47+
val outputDir = generateJavaTaskProvider.flatMap(GenerateJavaTask::outputDir)
48+
4849
mainSourceSet.java.srcDirs(project.files(outputDir).builtBy(generateJavaTaskProvider))
4950

5051
project.afterEvaluate { p ->

graphql-dgs-codegen-gradle/src/main/kotlin/com/netflix/graphql/dgs/codegen/gradle/GenerateJavaTask.kt

Lines changed: 143 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -22,136 +22,186 @@ import com.netflix.graphql.dgs.codegen.CodeGen
2222
import com.netflix.graphql.dgs.codegen.CodeGenConfig
2323
import com.netflix.graphql.dgs.codegen.Language
2424
import org.gradle.api.DefaultTask
25+
import org.gradle.api.file.DirectoryProperty
26+
import org.gradle.api.file.ProjectLayout
27+
import org.gradle.api.model.ObjectFactory
28+
import org.gradle.api.provider.ListProperty
29+
import org.gradle.api.provider.MapProperty
30+
import org.gradle.api.provider.Property
31+
import org.gradle.api.provider.ProviderFactory
32+
import org.gradle.api.provider.SetProperty
2533
import org.gradle.api.tasks.Input
2634
import org.gradle.api.tasks.InputFiles
2735
import org.gradle.api.tasks.OutputDirectory
2836
import org.gradle.api.tasks.TaskAction
2937
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
30-
import java.io.File
3138
import java.nio.file.Paths
32-
import java.util.*
33-
34-
open class GenerateJavaTask : DefaultTask() {
35-
@Input
36-
var generatedSourcesDir: String = project.buildDir.absolutePath
37-
38-
@InputFiles
39-
var schemaPaths = mutableListOf<Any>("${project.projectDir}/src/main/resources/schema")
40-
41-
@Input
42-
var packageName = "com.netflix.dgs.codegen.generated"
43-
44-
@Input
45-
var subPackageNameClient = "client"
46-
47-
@Input
48-
var subPackageNameDatafetchers = "datafetchers"
49-
50-
@Input
51-
var subPackageNameTypes = "types"
52-
53-
private val hasKotlinPluginWrapperClass = try {
54-
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
55-
true
56-
} catch (ex: Exception) {
57-
false
39+
import java.util.Locale
40+
import javax.inject.Inject
41+
42+
abstract class GenerateJavaTask @Inject constructor(
43+
projectLayout: ProjectLayout,
44+
providerFactory: ProviderFactory,
45+
objectFactory: ObjectFactory
46+
) : DefaultTask() {
47+
@get:Input
48+
val generatedSourcesDir: Property<String> = objectFactory.property(String::class.java)
49+
.convention(projectLayout.buildDirectory.map { it.asFile.absolutePath })
50+
51+
@get:InputFiles
52+
val schemaPaths: ListProperty<Any> = objectFactory.listProperty(Any::class.java)
53+
.convention(listOf(projectLayout.projectDirectory.dir("src/main/resources/schema").toString()))
54+
55+
@get:Input
56+
val packageName: Property<String> = objectFactory.property(String::class.java)
57+
.convention("com.netflix.dgs.codegen.generated")
58+
59+
@get:Input
60+
val subPackageNameClient: Property<String> = objectFactory.property(String::class.java)
61+
.convention("client")
62+
63+
@get:Input
64+
val subPackageNameDatafetchers: Property<String> = objectFactory.property(String::class.java)
65+
.convention("datafetchers")
66+
67+
@get:Input
68+
val subPackageNameTypes: Property<String> = objectFactory.property(String::class.java)
69+
.convention("types")
70+
71+
private val hasKotlinPluginWrapperClass: Boolean by lazy(LazyThreadSafetyMode.PUBLICATION) {
72+
try {
73+
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
74+
true
75+
} catch (ex: Exception) {
76+
false
77+
}
5878
}
5979

60-
@Input
61-
var language = if (hasKotlinPluginWrapperClass && project.plugins.hasPlugin(KotlinPluginWrapper::class.java)) "KOTLIN" else "JAVA"
80+
@get:Input
81+
val language: Property<String> = objectFactory.property(String::class.java)
82+
.convention(
83+
providerFactory.provider {
84+
val hasKotlinPluginWrapperClass = try {
85+
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
86+
true
87+
} catch (ex: Exception) {
88+
false
89+
}
90+
if (hasKotlinPluginWrapperClass && project.plugins.hasPlugin(KotlinPluginWrapper::class.java)) "KOTLIN" else "JAVA"
91+
}
92+
)
6293

63-
@Input
64-
var typeMapping = mutableMapOf<String, String>()
94+
@get:Input
95+
val typeMapping: MapProperty<String, String> = objectFactory.mapProperty(String::class.java, String::class.java)
6596

66-
@Input
67-
var generateBoxedTypes = false
97+
@get:Input
98+
val generateBoxedTypes: Property<Boolean> = objectFactory.property(Boolean::class.java)
99+
.convention(false)
68100

69-
@Input
70-
var generateClient = false
101+
@get:Input
102+
val generateClient: Property<Boolean> = objectFactory.property(Boolean::class.java)
103+
.convention(false)
71104

72-
@Input
73-
var generateDataTypes = true
105+
@get:Input
106+
val generateDataTypes: Property<Boolean> = objectFactory.property(Boolean::class.java)
107+
.convention(true)
74108

75-
@Input
76-
var generateInterfaces = false
109+
@get:Input
110+
val generateInterfaces: Property<Boolean> = objectFactory.property(Boolean::class.java)
111+
.convention(false)
77112

78-
@Input
79-
var generateInterfaceSetters = true
113+
@get:Input
114+
val generateInterfaceSetters: Property<Boolean> = objectFactory.property(Boolean::class.java)
115+
.convention(true)
80116

81-
@OutputDirectory
82-
fun getOutputDir(): File {
83-
return Paths.get("$generatedSourcesDir/generated/sources/dgs-codegen").toFile()
84-
}
117+
@get:OutputDirectory
118+
val outputDir: DirectoryProperty = objectFactory.directoryProperty()
119+
.convention(
120+
generatedSourcesDir.flatMap { baseDir ->
121+
projectLayout.dir(providerFactory.provider { project.file("$baseDir/generated/sources/dgs-codegen") })
122+
}
123+
)
85124

86-
@OutputDirectory
87-
fun getExampleOutputDir(): File {
88-
return Paths.get("$generatedSourcesDir/generated/sources/dgs-codegen-generated-examples").toFile()
89-
}
125+
@get:OutputDirectory
126+
val exampleOutputDir: DirectoryProperty = objectFactory.directoryProperty()
127+
.convention(
128+
generatedSourcesDir.flatMap { baseDir ->
129+
projectLayout.dir(providerFactory.provider { project.file("$baseDir/generated/sources/dgs-codegen-generated-examples") })
130+
}
131+
)
90132

91-
@Input
92-
var includeQueries = mutableListOf<String>()
133+
@get:Input
134+
val includeQueries: SetProperty<String> = objectFactory.setProperty(String::class.java)
93135

94-
@Input
95-
var includeMutations = mutableListOf<String>()
136+
@get:Input
137+
val includeMutations: SetProperty<String> = objectFactory.setProperty(String::class.java)
96138

97-
@Input
98-
var includeSubscriptions = mutableListOf<String>()
139+
@get:Input
140+
val includeSubscriptions: SetProperty<String> = objectFactory.setProperty(String::class.java)
99141

100-
@Input
101-
var skipEntityQueries = false
142+
@get:Input
143+
val skipEntityQueries: Property<Boolean> = objectFactory.property(Boolean::class.java)
144+
.convention(false)
102145

103-
@Input
104-
var shortProjectionNames = false
146+
@get:Input
147+
val shortProjectionNames: Property<Boolean> = objectFactory.property(Boolean::class.java)
148+
.convention(false)
105149

106-
@Input
107-
var omitNullInputFields = false
150+
@get:Input
151+
val omitNullInputFields: Property<Boolean> = objectFactory.property(Boolean::class.java)
152+
.convention(false)
108153

109-
@Input
110-
var maxProjectionDepth = 10
154+
@get:Input
155+
val maxProjectionDepth: Property<Int> = objectFactory.property(Int::class.javaObjectType)
156+
.convention(10)
111157

112-
@Input
113-
var kotlinAllFieldsOptional = false
158+
@get:Input
159+
val kotlinAllFieldsOptional: Property<Boolean> = objectFactory.property(Boolean::class.java)
160+
.convention(false)
114161

115-
@Input
116-
var snakeCaseConstantNames = false
162+
@get:Input
163+
val snakeCaseConstantNames: Property<Boolean> = objectFactory.property(Boolean::class.java)
164+
.convention(false)
117165

118166
@TaskAction
119167
fun generate() {
120-
val schemaPaths = schemaPaths.map { Paths.get(it.toString()).toFile() }.sorted().toSet()
121-
schemaPaths.filter { !it.exists() }.forEach {
122-
logger.warn("Schema location ${it.absolutePath} does not exist")
168+
val schemaPaths = schemaPaths.get().asSequence()
169+
.map { Paths.get(it.toString()).toFile() }
170+
.toSortedSet()
171+
schemaPaths.asSequence().filter { !it.exists() }.forEach {
172+
logger.warn("Schema location {} does not exist", it.absolutePath)
123173
}
124174
logger.info("Processing schema files:")
125175
schemaPaths.forEach {
126-
logger.info("Processing $it")
176+
logger.info("Processing {}", it)
127177
}
128178

129179
val config = CodeGenConfig(
130180
schemas = emptySet(),
131181
schemaFiles = schemaPaths,
132-
outputDir = getOutputDir().toPath(),
133-
examplesOutputDir = getExampleOutputDir().toPath(),
182+
outputDir = outputDir.get().asFile.toPath(),
183+
examplesOutputDir = exampleOutputDir.get().asFile.toPath(),
134184
writeToFiles = true,
135-
packageName = packageName,
136-
subPackageNameClient = subPackageNameClient,
137-
subPackageNameDatafetchers = subPackageNameDatafetchers,
138-
subPackageNameTypes = subPackageNameTypes,
139-
language = Language.valueOf(language.uppercase(Locale.getDefault())),
140-
generateBoxedTypes = generateBoxedTypes,
141-
generateClientApi = generateClient,
142-
generateInterfaces = generateInterfaces,
143-
generateInterfaceSetters = generateInterfaceSetters,
144-
typeMapping = typeMapping,
145-
includeQueries = includeQueries.toSet(),
146-
includeMutations = includeMutations.toSet(),
147-
includeSubscriptions = includeSubscriptions.toSet(),
148-
skipEntityQueries = skipEntityQueries,
149-
shortProjectionNames = shortProjectionNames,
150-
generateDataTypes = generateDataTypes,
151-
omitNullInputFields = omitNullInputFields,
152-
maxProjectionDepth = maxProjectionDepth,
153-
kotlinAllFieldsOptional = kotlinAllFieldsOptional,
154-
snakeCaseConstantNames = snakeCaseConstantNames
185+
packageName = packageName.get(),
186+
subPackageNameClient = subPackageNameClient.get(),
187+
subPackageNameDatafetchers = subPackageNameDatafetchers.get(),
188+
subPackageNameTypes = subPackageNameTypes.get(),
189+
language = Language.valueOf(language.get().uppercase(Locale.getDefault())),
190+
generateBoxedTypes = generateBoxedTypes.get(),
191+
generateClientApi = generateClient.get(),
192+
generateInterfaces = generateInterfaces.get(),
193+
generateInterfaceSetters = generateInterfaceSetters.get(),
194+
typeMapping = typeMapping.get(),
195+
includeQueries = includeQueries.get(),
196+
includeMutations = includeMutations.get(),
197+
includeSubscriptions = includeSubscriptions.get(),
198+
skipEntityQueries = skipEntityQueries.get(),
199+
shortProjectionNames = shortProjectionNames.get(),
200+
generateDataTypes = generateDataTypes.get(),
201+
omitNullInputFields = omitNullInputFields.get(),
202+
maxProjectionDepth = maxProjectionDepth.get(),
203+
kotlinAllFieldsOptional = kotlinAllFieldsOptional.get(),
204+
snakeCaseConstantNames = snakeCaseConstantNames.get()
155205
)
156206

157207
logger.info("Codegen config: {}", config)

0 commit comments

Comments
 (0)