1+ import com.fasterxml.jackson.databind.JsonNode
2+ import com.fasterxml.jackson.databind.ObjectMapper
3+ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
4+ import com.networknt.schema.JsonSchema
5+ import com.networknt.schema.JsonSchemaFactory
6+ import com.networknt.schema.SpecVersion
7+ import com.networknt.schema.ValidationMessage
8+ import org.gradle.api.DefaultTask
9+ import org.gradle.api.file.DirectoryProperty
10+ import org.gradle.api.file.RegularFileProperty
11+ import org.gradle.api.tasks.InputDirectory
12+ import org.gradle.api.tasks.InputFile
13+ import org.gradle.api.tasks.TaskAction
14+ import org.gradle.api.GradleException
15+
16+ abstract class ValidateYamlAgainstSchema : DefaultTask () {
17+
18+ @get:InputDirectory
19+ abstract val yamlDirectory: DirectoryProperty
20+
21+ @get:InputFile
22+ abstract val schemaFile: RegularFileProperty
23+
24+ @TaskAction
25+ fun validateYaml () {
26+ val objectMapper = ObjectMapper (YAMLFactory ()) // Registers YAML module
27+ objectMapper.readTree(schemaFile.get().asFile.readText())
28+ val schemaFactory = JsonSchemaFactory .getInstance(SpecVersion .VersionFlag .V201909 ) // Or V7, V201909, etc.
29+ val schemaNode: JsonNode = objectMapper.readTree(schemaFile.asFile.get())
30+ val schema: JsonSchema = schemaFactory.getSchema(schemaNode)
31+
32+ val validationResults = yamlDirectory.asFile.get().walk()
33+ .filter { it.isFile && (it.extension == " yaml" || it.extension == " yml" ) }
34+ .map { file ->
35+ try {
36+ val yamlNode: JsonNode = objectMapper.readTree(file)
37+ val validationResult: Set <ValidationMessage > = schema.validate(yamlNode)
38+ file to validationResult
39+ } catch (e: Exception ) {
40+ println (" Fail read or validation failed, path: ${file.absolutePath} , message: ${e.message} " )
41+ file to setOf () // Create a validation message for errors
42+ }
43+ }
44+ .toList() // Evaluate and collect all results immediately
45+
46+ val failedValidations = validationResults.filter { it.second.isNotEmpty() }
47+
48+ if (failedValidations.isNotEmpty()) {
49+ val errorMessage = StringBuilder (" YAML validation failed for the following files:\n " )
50+ failedValidations.forEach { (file, errors) ->
51+ errorMessage.append(" - file://${file} :\n " )
52+ errors.forEach { message ->
53+ errorMessage.append(" - ${message.message} (path: ${message.schemaPath} )\n " )
54+ }
55+ }
56+ throw GradleException (errorMessage.toString())
57+ } else {
58+ println (" All YAML files validated successfully." )
59+ }
60+ }
61+ }
0 commit comments