Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ if (jdkVersion != System.getProperty("java.version")) {

plugins {
kotlin("jvm") version "1.9.22"
kotlin("plugin.serialization") version "1.9.22"

// configured by `jvmWrapper` block below
id("me.filippov.gradle.jvm.wrapper") version "0.14.0"
}

// NOTE: `./gradlew wrapper` must be run for edit to this config to take effect
// NOTE: `./gradlew wrapper` must be run for edits to this config to take effect
jvmWrapper {
unixJvmInstallDir = jdkProperties.getProperty("unixJvmInstallDir")
winJvmInstallDir = jdkProperties.getProperty("winJvmInstallDir")
Expand Down Expand Up @@ -67,4 +68,5 @@ dependencies {
implementation(gradleApi())
testImplementation(kotlin("test"))
implementation("org.eclipse.jgit:org.eclipse.jgit:6.7.0.202309050840-r")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1")
}
52 changes: 30 additions & 22 deletions buildSrc/src/main/kotlin/GenerateJsonTestSuiteTask.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.*
import org.kson.jsonsuite.JsonSuiteGitCheckout
import org.kson.jsonsuite.JsonTestSuiteGenerator
import org.kson.jsonsuite.SchemaSuiteGitCheckout
import java.io.File
import java.nio.file.Paths

/**
* The Git SHA in the [JSONTestSuite](https://github.com/nst/JSONTestSuite) we currently test against.
* This can be updated if/when we want to pull in newer tests from that project.
* The Git SHAs in [JSONTestSuite](https://github.com/nst/JSONTestSuite) and [JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite)
* that we currently test against.
*
* These can be updated if/when we want to pull in newer tests from those projects.
*/
private const val testSuiteSHA = "984defc2deaa653cb73cd29f4144a720ec9efe7c"
const val jsonTestSuiteSHA = "984defc2deaa653cb73cd29f4144a720ec9efe7c"
const val schemaTestSuiteSHA = "9fc880bfb6d8ccd093bc82431f17d13681ffae8e"

/**
* This task exposes [JsonTestSuiteGenerator] to our Gradle build, ensuring the task's
Expand All @@ -17,33 +21,36 @@ private const val testSuiteSHA = "984defc2deaa653cb73cd29f4144a720ec9efe7c"
* if/when the test at [getGeneratedTestPath] is deleted)
*/
open class GenerateJsonTestSuiteTask : DefaultTask() {
private val jsonTestSuiteGenerator =
JsonTestSuiteGenerator(
testSuiteSHA,
project.projectDir.toPath(),
Paths.get("src/commonTest/kotlin/"),
private val jsonTestSuiteGenerator: JsonTestSuiteGenerator

init {
val projectRoot = project.projectDir.toPath()
val destinationDir = projectRoot.resolve("buildSrc").resolve("support/jsonsuite")

val sourceRoot = projectRoot.resolve("src/commonTest/kotlin/")

val jsonSuiteGitCheckout = JsonSuiteGitCheckout(jsonTestSuiteSHA, destinationDir)
val schemaSuiteGitCheckout = SchemaSuiteGitCheckout(schemaTestSuiteSHA, destinationDir)

jsonTestSuiteGenerator = JsonTestSuiteGenerator(
jsonSuiteGitCheckout,
schemaSuiteGitCheckout,
projectRoot,
sourceRoot,
"org.kson.parser.json.generated"
)

init {
// ensure we're out of date when/if the repo of test source files is deleted
outputs.upToDateWhen {
jsonTestSuiteGenerator.testSuiteRootDir.toFile().exists()
jsonSuiteGitCheckout.checkoutDir.exists()
&& schemaSuiteGitCheckout.checkoutDir.exists()
}
}

/**
* Register [JsonTestSuiteGenerator.jsonTestSuiteSHA] as an input to this script so that it is marked
* "out of date" whenever the script changes and re-runs
*/
@Input
fun getTestSuiteSHA(): String {
return jsonTestSuiteGenerator.jsonTestSuiteSHA
}

@OutputFiles
fun getGeneratedTestPath(): List<File> {
return listOf(jsonTestSuiteGenerator.generatedTestPath.toFile())
return listOf(jsonTestSuiteGenerator.generatedJsonSuiteTestPath.toFile(),
jsonTestSuiteGenerator.generatedSchemaSuiteTestPath.toFile())
}

@TaskAction
Expand All @@ -53,6 +60,7 @@ open class GenerateJsonTestSuiteTask : DefaultTask() {

@Internal
override fun getDescription(): String? {
return "Generates src/commonTest/kotlin/org/kson/parser/json/generated/JsonSuiteTest.kt"
return "Generates ${jsonTestSuiteGenerator.generatedJsonSuiteTestPath} and " +
"${jsonTestSuiteGenerator.generatedSchemaSuiteTestPath}"
}
}
76 changes: 76 additions & 0 deletions buildSrc/src/main/kotlin/org/kson/CleanGitCheckout.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.kson

import org.eclipse.jgit.api.Git
import java.io.File
import java.nio.file.Path

class NoRepoException(msg: String) : RuntimeException(msg)
class DirtyRepoException(msg: String) : RuntimeException(msg)

/**
* Ensures there is a clean git checkout of [repoUri] in [cloneParentDir] at SHA [checkoutSHA]
* Note: will clone if does not exist, will error if not clean
*
* @param repoUri the URI of the repo to clone. May be any git URI that [org.eclipse.jgit.transport.URIish.URIish(java.lang.String)]
* can parse, including `https://` URIs and local file paths
* @param checkoutSHA the SHA of the desired clean checkout of the repo found at [repoUri]
* @param cloneParentDir the directory to place our cloned [repoUri] into
* @param cloneName the name of the directory in [cloneParentDir] to clone [repoUri] into
*/
open class CleanGitCheckout(private val repoUri: String,
private val checkoutSHA: String,
private val cloneParentDir: Path,
cloneName: String) {
val checkoutDir: File = File(cloneParentDir.toFile(), cloneName)
init {
ensureCleanGitCheckout()
}

private fun ensureCleanGitCheckout() {
if (!checkoutDir.exists()) {
checkoutDir.mkdirs()
cloneRepository(repoUri, checkoutDir)
} else if (!File(checkoutDir, ".git").exists()) {
throw NoRepoException(
"ERROR: $checkoutDir should contain a checkout of https://github.com/nst/JSONTestSuite," +
"but it does not appear to be a git repo")
}

val git = Git.init().setDirectory(checkoutDir).call()
if(!git.status().call().isClean) {
// throw if we're not clean... don't want to build because the source files might be incorrect,
// but also don't want to immediately blow it away since someone may have made changes on purpose
// for reasons we're not guessing, and quietly nuking those changes as a side-effect of the build
// could do them a real disservice
throw DirtyRepoException(
"ERROR: Dirty git status in $cloneParentDir. Please ensure the git status is clean " +
"or delete the directory and re-run this script")
}

checkoutCommit(checkoutDir, checkoutSHA)
}

/**
* Clone the given [uri] into [dir]
*
* @param uri will be passed to [org.eclipse.jgit.api.CloneCommand.setURI] to be parsed as a [org.eclipse.jgit.transport.URIish])
* @param dir the directory to clone the repo at [uri] into
*/
private fun cloneRepository(uri: String, dir: File) {
Git.cloneRepository()
.setURI(uri)
.setDirectory(dir)
.call()
}

/**
* Checks out the given [commit] of the repo found in [dir]
*
* @param dir a directory containing a git repo
* @param commit the commit of the repo in [dir] to be checked out
*/
private fun checkoutCommit(dir: File, commit: String) {
val git = Git.open(dir)
git.checkout().setName(commit).call()
}
}
Loading