Skip to content

Commit

Permalink
Make the plugin output directory configurable
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kilink committed Mar 22, 2022
1 parent a25d8ba commit 77d957f
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class CodegenPlugin : Plugin<Project> {
val javaConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
val sourceSets = javaConvention.sourceSets
val mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
val outputDir = generateJavaTaskProvider.map(GenerateJavaTask::getOutputDir)
val outputDir = generateJavaTaskProvider.flatMap(GenerateJavaTask::outputDir)

mainSourceSet.java.srcDirs(project.files(outputDir).builtBy(generateJavaTaskProvider))

project.afterEvaluate { p ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,136 +22,186 @@ import com.netflix.graphql.dgs.codegen.CodeGen
import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.Language
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
import java.io.File
import java.nio.file.Paths
import java.util.*

open class GenerateJavaTask : DefaultTask() {
@Input
var generatedSourcesDir: String = project.buildDir.absolutePath

@InputFiles
var schemaPaths = mutableListOf<Any>("${project.projectDir}/src/main/resources/schema")

@Input
var packageName = "com.netflix.dgs.codegen.generated"

@Input
var subPackageNameClient = "client"

@Input
var subPackageNameDatafetchers = "datafetchers"

@Input
var subPackageNameTypes = "types"

private val hasKotlinPluginWrapperClass = try {
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
true
} catch (ex: Exception) {
false
import java.util.Locale
import javax.inject.Inject

abstract class GenerateJavaTask @Inject constructor(
projectLayout: ProjectLayout,
providerFactory: ProviderFactory,
objectFactory: ObjectFactory
) : DefaultTask() {
@get:Input
val generatedSourcesDir: Property<String> = objectFactory.property(String::class.java)
.convention(projectLayout.buildDirectory.map { it.asFile.absolutePath })

@get:InputFiles
val schemaPaths: ListProperty<Any> = objectFactory.listProperty(Any::class.java)
.convention(listOf(projectLayout.projectDirectory.dir("src/main/resources/schema").toString()))

@get:Input
val packageName: Property<String> = objectFactory.property(String::class.java)
.convention("com.netflix.dgs.codegen.generated")

@get:Input
val subPackageNameClient: Property<String> = objectFactory.property(String::class.java)
.convention("client")

@get:Input
val subPackageNameDatafetchers: Property<String> = objectFactory.property(String::class.java)
.convention("datafetchers")

@get:Input
val subPackageNameTypes: Property<String> = objectFactory.property(String::class.java)
.convention("types")

private val hasKotlinPluginWrapperClass: Boolean by lazy(LazyThreadSafetyMode.PUBLICATION) {
try {
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
true
} catch (ex: Exception) {
false
}
}

@Input
var language = if (hasKotlinPluginWrapperClass && project.plugins.hasPlugin(KotlinPluginWrapper::class.java)) "KOTLIN" else "JAVA"
@get:Input
val language: Property<String> = objectFactory.property(String::class.java)
.convention(
providerFactory.provider {
val hasKotlinPluginWrapperClass = try {
this.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper")
true
} catch (ex: Exception) {
false
}
if (hasKotlinPluginWrapperClass && project.plugins.hasPlugin(KotlinPluginWrapper::class.java)) "KOTLIN" else "JAVA"
}
)

@Input
var typeMapping = mutableMapOf<String, String>()
@get:Input
val typeMapping: MapProperty<String, String> = objectFactory.mapProperty(String::class.java, String::class.java)

@Input
var generateBoxedTypes = false
@get:Input
val generateBoxedTypes: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var generateClient = false
@get:Input
val generateClient: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var generateDataTypes = true
@get:Input
val generateDataTypes: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(true)

@Input
var generateInterfaces = false
@get:Input
val generateInterfaces: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var generateInterfaceSetters = true
@get:Input
val generateInterfaceSetters: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(true)

@OutputDirectory
fun getOutputDir(): File {
return Paths.get("$generatedSourcesDir/generated/sources/dgs-codegen").toFile()
}
@get:OutputDirectory
val outputDir: DirectoryProperty = objectFactory.directoryProperty()
.convention(
generatedSourcesDir.flatMap { baseDir ->
projectLayout.dir(providerFactory.provider { project.file("$baseDir/generated/sources/dgs-codegen") })
}
)

@OutputDirectory
fun getExampleOutputDir(): File {
return Paths.get("$generatedSourcesDir/generated/sources/dgs-codegen-generated-examples").toFile()
}
@get:OutputDirectory
val exampleOutputDir: DirectoryProperty = objectFactory.directoryProperty()
.convention(
generatedSourcesDir.flatMap { baseDir ->
projectLayout.dir(providerFactory.provider { project.file("$baseDir/generated/sources/dgs-codegen-generated-examples") })
}
)

@Input
var includeQueries = mutableListOf<String>()
@get:Input
val includeQueries: SetProperty<String> = objectFactory.setProperty(String::class.java)

@Input
var includeMutations = mutableListOf<String>()
@get:Input
val includeMutations: SetProperty<String> = objectFactory.setProperty(String::class.java)

@Input
var includeSubscriptions = mutableListOf<String>()
@get:Input
val includeSubscriptions: SetProperty<String> = objectFactory.setProperty(String::class.java)

@Input
var skipEntityQueries = false
@get:Input
val skipEntityQueries: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var shortProjectionNames = false
@get:Input
val shortProjectionNames: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var omitNullInputFields = false
@get:Input
val omitNullInputFields: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var maxProjectionDepth = 10
@get:Input
val maxProjectionDepth: Property<Int> = objectFactory.property(Int::class.javaObjectType)
.convention(10)

@Input
var kotlinAllFieldsOptional = false
@get:Input
val kotlinAllFieldsOptional: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@Input
var snakeCaseConstantNames = false
@get:Input
val snakeCaseConstantNames: Property<Boolean> = objectFactory.property(Boolean::class.java)
.convention(false)

@TaskAction
fun generate() {
val schemaPaths = schemaPaths.map { Paths.get(it.toString()).toFile() }.sorted().toSet()
schemaPaths.filter { !it.exists() }.forEach {
logger.warn("Schema location ${it.absolutePath} does not exist")
val schemaPaths = schemaPaths.get().asSequence()
.map { Paths.get(it.toString()).toFile() }
.toSortedSet()
schemaPaths.asSequence().filter { !it.exists() }.forEach {
logger.warn("Schema location {} does not exist", it.absolutePath)
}
logger.info("Processing schema files:")
schemaPaths.forEach {
logger.info("Processing $it")
logger.info("Processing {}", it)
}

val config = CodeGenConfig(
schemas = emptySet(),
schemaFiles = schemaPaths,
outputDir = getOutputDir().toPath(),
examplesOutputDir = getExampleOutputDir().toPath(),
outputDir = outputDir.get().asFile.toPath(),
examplesOutputDir = exampleOutputDir.get().asFile.toPath(),
writeToFiles = true,
packageName = packageName,
subPackageNameClient = subPackageNameClient,
subPackageNameDatafetchers = subPackageNameDatafetchers,
subPackageNameTypes = subPackageNameTypes,
language = Language.valueOf(language.uppercase(Locale.getDefault())),
generateBoxedTypes = generateBoxedTypes,
generateClientApi = generateClient,
generateInterfaces = generateInterfaces,
generateInterfaceSetters = generateInterfaceSetters,
typeMapping = typeMapping,
includeQueries = includeQueries.toSet(),
includeMutations = includeMutations.toSet(),
includeSubscriptions = includeSubscriptions.toSet(),
skipEntityQueries = skipEntityQueries,
shortProjectionNames = shortProjectionNames,
generateDataTypes = generateDataTypes,
omitNullInputFields = omitNullInputFields,
maxProjectionDepth = maxProjectionDepth,
kotlinAllFieldsOptional = kotlinAllFieldsOptional,
snakeCaseConstantNames = snakeCaseConstantNames
packageName = packageName.get(),
subPackageNameClient = subPackageNameClient.get(),
subPackageNameDatafetchers = subPackageNameDatafetchers.get(),
subPackageNameTypes = subPackageNameTypes.get(),
language = Language.valueOf(language.get().uppercase(Locale.getDefault())),
generateBoxedTypes = generateBoxedTypes.get(),
generateClientApi = generateClient.get(),
generateInterfaces = generateInterfaces.get(),
generateInterfaceSetters = generateInterfaceSetters.get(),
typeMapping = typeMapping.get(),
includeQueries = includeQueries.get(),
includeMutations = includeMutations.get(),
includeSubscriptions = includeSubscriptions.get(),
skipEntityQueries = skipEntityQueries.get(),
shortProjectionNames = shortProjectionNames.get(),
generateDataTypes = generateDataTypes.get(),
omitNullInputFields = omitNullInputFields.get(),
maxProjectionDepth = maxProjectionDepth.get(),
kotlinAllFieldsOptional = kotlinAllFieldsOptional.get(),
snakeCaseConstantNames = snakeCaseConstantNames.get()
)

logger.info("Codegen config: {}", config)
Expand Down
Loading

0 comments on commit 77d957f

Please sign in to comment.