Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ config-inversion-linter:
needs: []
script:
- ./gradlew --version
- ./gradlew logEnvVarUsages checkEnvironmentVariablesUsage checkConfigStrings
- ./gradlew logEnvVarUsages checkEnvironmentVariablesUsage checkConfigStrings verifyAliasKeysAreSupported

test_published_artifacts:
extends: .gradle_build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,46 @@ class ConfigInversionLinter : Plugin<Project> {
registerLogEnvVarUsages(target, extension)
registerCheckEnvironmentVariablesUsage(target)
registerCheckConfigStringsTask(target, extension)
verifyAliasKeysAreSupported(target, extension)
}
}

// Data class for fields from generated class
private data class LoadedConfigFields(
val supported: Set<String>,
val aliases: Map<String, List<String>> = emptyMap(),
val aliasMapping: Map<String, String> = emptyMap()
)

// Cache for fields from generated class
private var cachedConfigFields: LoadedConfigFields? = null

// Helper function to load fields from the generated class
private fun loadConfigFields(
mainSourceSetOutput: org.gradle.api.file.FileCollection,
generatedClassName: String
): LoadedConfigFields {
return cachedConfigFields ?: run {
val urls = mainSourceSetOutput.files.map { it.toURI().toURL() }.toTypedArray()
URLClassLoader(urls, LoadedConfigFields::class.java.classLoader).use { cl ->
val clazz = Class.forName(generatedClassName, true, cl)

val supportedField = clazz.getField("SUPPORTED").get(null)
@Suppress("UNCHECKED_CAST")
val supportedSet = when (supportedField) {
is Set<*> -> supportedField as Set<String>
is Map<*, *> -> supportedField.keys as Set<String>
else -> throw IllegalStateException("SUPPORTED field must be either Set<String> or Map<String, Any>, but was ${supportedField?.javaClass}")
}

@Suppress("UNCHECKED_CAST")
val aliases = clazz.getField("ALIASES").get(null) as Map<String, List<String>>

@Suppress("UNCHECKED_CAST")
val aliasMappingMap = clazz.getField("ALIAS_MAPPING").get(null) as Map<String, String>

LoadedConfigFields(supportedSet, aliases, aliasMappingMap)
}.also { cachedConfigFields = it }
}
}

Expand Down Expand Up @@ -246,3 +286,44 @@ private fun registerCheckConfigStringsTask(project: Project, extension: Supporte
}
}
}


/** Registers `verifyAliasKeysAreSupported` to ensure all alias keys are documented as supported configurations. */
private fun verifyAliasKeysAreSupported(project: Project, extension: SupportedTracerConfigurations) {
val ownerPath = extension.configOwnerPath
val generatedFile = extension.className

project.tasks.register("verifyAliasKeysAreSupported") {
group = "verification"
description =
"Verifies that all alias keys in `metadata/supported-configurations.json` are also documented as supported configurations."

val mainSourceSetOutput = ownerPath.map {
project.project(it)
.extensions.getByType<SourceSetContainer>()
.named(SourceSet.MAIN_SOURCE_SET_NAME)
.map { main -> main.output }
}
inputs.files(mainSourceSetOutput)

doLast {
val configFields = loadConfigFields(mainSourceSetOutput.get().get(), generatedFile.get())
val supported = configFields.supported
val aliases = configFields.aliases.keys

val unsupportedAliasKeys = aliases - supported
val violations = buildList {
unsupportedAliasKeys.forEach { key ->
add("$key is listed as an alias key but is not documented as a supported configuration in the `supportedConfigurations` key")
}
}
if (violations.isNotEmpty()) {
logger.error("\nFound alias keys not documented as supported configurations:")
violations.forEach { logger.lifecycle(it) }
throw GradleException("Undocumented alias keys found. Please add the above keys to the `supportedConfigurations` in '${extension.jsonFile.get()}'.")
} else {
logger.info("All alias keys are documented as supported configurations.")
}
}
}
}
Loading