in gradle-plugin/src/main/groovy/mozilla/telemetry/glean-gradle-plugin/GleanGradlePlugin.groovy [170:374]
def setupTasks(Project project, File envDir, boolean isApplication, String parserVersion) {
return { variant ->
// Get the name of the package as if it were to be used in the R or BuildConfig
// files. This is required since applications can define different application ids
// depending on the variant type: the generated API definitions don't need to be
// different due to that.
def namespaceProvider = variant.getGenerateBuildConfigProvider().map({ p -> "namespace=${p.namespace.get()}.GleanMetrics" })
def sourceOutputDir = "${project.buildDir}/generated/source/glean/${variant.dirName}/kotlin"
def generateKotlinAPI = project.task("${TASK_NAME_PREFIX}SourceFor${variant.name.capitalize()}", type: Exec) {
description = "Generate the Kotlin code for the Metrics API"
if (project.ext.has("allowMetricsFromAAR")) {
// This is sufficiently lazy to be valid at configuration time. See the model at
// https://github.com/google/protobuf-gradle-plugin/blob/6d99a421c8d15710045e4e8d31a3af6cb0cc3b70/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy#L270-L277
inputs.files variant.compileConfiguration.incoming.artifactView {
attributes {
it.attribute(ArtifactAttributes.ARTIFACT_FORMAT, 'glean-metrics-yaml')
}
}.files
}
// Add local registry files as input to this task. They will be turned
// into `arg`s later.
for (String item : getYamlFiles(project)) {
if (project.file(item).exists()) {
inputs.file item
}
}
outputs.dir sourceOutputDir
workingDir project.rootDir
commandLine getPythonCommand(envDir, isOffline)
def gleanNamespace = "mozilla.components.service.glean"
if (project.ext.has("gleanNamespace")) {
gleanNamespace = project.ext.get("gleanNamespace")
}
args "-c"
args runPythonScript
args isOffline ? "offline" : "online"
args "glean_parser"
args parserVersion
args "translate"
args "--allow-missing-files"
args "-f"
args "kotlin"
args "-o"
args "$sourceOutputDir"
args "-s"
args "glean_namespace=$gleanNamespace"
// If we're building the Glean library itself (rather than an
// application using Glean) pass the --allow-reserved flag so we can
// use metrics in the "glean..." category
if (project.ext.has("allowGleanInternal")) {
args "--allow-reserved"
}
// Only generate build info for applications, not for libraries.
// From android-gradle 7.0 on the `VERSION_CODE` and `VERSION_NAME` fields
// are not set for libraries anymore
if (!isApplication) {
args "-s"
args "with_buildinfo=false"
} else {
// For applications check if they overwrote the build date.
if (project.ext.has("gleanBuildDate")) {
args "-s"
args "build_date=${project.ext.get("gleanBuildDate")}"
}
}
// Enable expiration by major version, if a major version is provided.
if (project.ext.has("gleanExpireByVersion")) {
args "--expire-by-version=${project.ext.get("gleanExpireByVersion")}"
}
doFirst {
args "-s"
args namespaceProvider.get().toString()
// Add the potential 'metrics.yaml' files at evaluation-time, rather than
// configuration-time. Otherwise the Gradle build will fail.
inputs.files.forEach { file ->
logger.lifecycle("Glean SDK - generating API from ${file.path}")
args file.path
}
}
// Only show the output if something went wrong.
ignoreExitValue = true
standardOutput = System.out
errorOutput = System.err
doLast {
if (executionResult.get().exitValue != 0) {
throw new GradleException("Glean code generation failed.\n\n${standardOutput.toString()}")
}
}
}
def generateGleanMetricsDocs = project.task("${TASK_NAME_PREFIX}DocsFor${variant.name.capitalize()}", type: Exec) {
description = "Generate the Markdown docs for the collected metrics"
def gleanDocsDirectory = "${project.projectDir}/docs"
if (project.ext.has("gleanDocsDirectory")) {
gleanDocsDirectory = project.ext.get("gleanDocsDirectory")
}
if (project.ext.has("allowMetricsFromAAR")) {
// This is sufficiently lazy to be valid at configuration time. See the model at
// https://github.com/google/protobuf-gradle-plugin/blob/6d99a421c8d15710045e4e8d31a3af6cb0cc3b70/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy#L270-L277
inputs.files variant.compileConfiguration.incoming.artifactView {
attributes {
it.attribute(ArtifactAttributes.ARTIFACT_FORMAT, 'glean-metrics-yaml')
}
}.files
}
// Add local registry files as input to this task. They will be turned
// into `arg`s later.
for (String item : getYamlFiles(project)) {
if (project.file(item).exists()) {
inputs.file item
}
}
outputs.dir gleanDocsDirectory
workingDir project.rootDir
commandLine getPythonCommand(envDir, isOffline)
args "-c"
args runPythonScript
args isOffline ? "offline" : "online"
args "glean_parser"
args parserVersion
args "translate"
args "--allow-missing-files"
args "-f"
args "markdown"
args "-o"
args gleanDocsDirectory
// If we're building the Glean library itself (rather than an
// application using Glean) pass the --allow-reserved flag so we can
// use metrics in the "glean..." category
if (project.ext.has("allowGleanInternal")) {
args "--allow-reserved"
}
// Enable expiration by major version, if a major version is provided.
if (project.ext.has("gleanExpireByVersion")) {
args "--expire-by-version=${project.ext.get("gleanExpireByVersion")}"
}
doFirst {
// Add the potential 'metrics.yaml' files at evaluation-time, rather than
// configuration-time. Otherwise the Gradle build will fail.
inputs.files.forEach{ file ->
project.logger.lifecycle("Glean SDK - generating docs for ${file.path} in $gleanDocsDirectory")
args file.path
}
}
// Only show the output if something went wrong.
ignoreExitValue = true
standardOutput = new ByteArrayOutputStream()
errorOutput = standardOutput
doLast {
if (executionResult.get().exitValue != 0) {
throw new GradleException("Glean documentation generation failed.\n\n${standardOutput.toString()}")
}
}
}
// Only attach the generation task if the metrics file is available or we're requested
// to fetch them from AAR files. We don't need to fail hard otherwise, as some 3rd party
// project might just want metrics included in Glean and nothing more.
def yamlFileExists = false
for (String item : getYamlFiles(project)) {
if (project.file(item).exists()) {
yamlFileExists = true
break
}
}
if (yamlFileExists
|| project.ext.has("allowMetricsFromAAR")) {
// Generate the metrics docs, if requested
if (project.ext.has("gleanGenerateMarkdownDocs")) {
generateKotlinAPI.dependsOn(generateGleanMetricsDocs)
}
// This is an Android-Gradle plugin 3+-ism. Culted from reading the source,
// searching for "registerJavaGeneratingTask", and finding
// https://github.com/GoogleCloudPlatform/endpoints-framework-gradle-plugin/commit/2f2b91476fb1c6647791e2c6fe531a47615a1e85.
// The added directory doesn't appear in the paths listed by the
// `sourceSets` task, for reasons unknown.
variant.registerJavaGeneratingTask(generateKotlinAPI, new File(sourceOutputDir))
}
}
}