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
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
package com.github.jengelman.gradle.plugins.shadow

import com.github.jengelman.gradle.plugins.shadow.executable.CodeSnippetExtractor
import com.github.jengelman.gradle.plugins.shadow.executor.GroovyBuildExecutor
import com.github.jengelman.gradle.plugins.shadow.executor.NoopExecutor
import com.github.jengelman.gradle.plugins.shadow.fixture.GroovyDslFixture
import com.github.jengelman.gradle.plugins.shadow.snippet.CodeSnippetExtractor
import com.github.jengelman.gradle.plugins.shadow.snippet.DslLang
import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.createTempDirectory
import org.junit.jupiter.api.DynamicTest
import org.junit.jupiter.api.TestFactory
import org.junit.jupiter.api.io.TempDir

class DocCodeSnippetTest {

@OptIn(ExperimentalStdlibApi::class)
@TestFactory
fun provideDynamicTests(@TempDir root: Path): List<DynamicTest> {
return fixtures.flatMap { (selector, executor) ->
CodeSnippetExtractor.extract(root, docsDir, selector, executor)
}.map {
DynamicTest.dynamicTest(it.testName, it)
val langExecutables = DslLang.entries.map { executor ->
CodeSnippetExtractor.extract(executor)
}
}

companion object {
private val fixtures = mapOf(
"groovy" to GroovyBuildExecutor(
GroovyDslFixture,
GroovyDslFixture.importsExtractor,
),
"groovy no-run" to NoopExecutor,
)
check(langExecutables.sumOf { it.size } > 0) {
"No code snippets found."
}
check(langExecutables.size == DslLang.entries.size) {
"We must provide build script snippets for all languages."
}
check(langExecutables.map { it.size }.distinct().size == 1) {
"All languages must have the same number of code snippets."
}

val docsDir: Path = Path(System.getProperty("DOCS_DIR"))
return langExecutables.flatten().map {
// Create a temporary directory for each test, root will be deleted after all tests are run.
it.tempDir = createTempDirectory(root)
DynamicTest.dynamicTest(it.displayName, it)
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.github.jengelman.gradle.plugins.shadow.snippet

import java.nio.file.Path
import java.util.regex.Pattern
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.Path
import kotlin.io.path.name
import kotlin.io.path.pathString
import kotlin.io.path.readText
import kotlin.io.path.relativeTo
import kotlin.io.path.walk

object CodeSnippetExtractor {
private val docRoot = Path(System.getProperty("DOCS_DIR"))

@OptIn(ExperimentalPathApi::class)
private val markdownPaths = docRoot.walk()
.filter { it.name.endsWith(".md", ignoreCase = true) }
.toList()

fun extract(lang: DslLang): List<SnippetExecutable> {
return markdownPaths.flatMap { path ->
createExecutables(lang, path)
}
}

private fun createExecutables(
lang: DslLang,
markdownPath: Path,
): List<SnippetExecutable> {
val relativeDocPath = markdownPath.relativeTo(docRoot).pathString
return createSnippets(markdownPath.readText(), lang).map { (lineNumber, snippet) ->
SnippetExecutable.create(
lang,
snippet,
"$relativeDocPath:$lineNumber",
) {
RuntimeException("The error line in the doc is near ${markdownPath.toUri()}:$lineNumber", it)
}
}
}

private fun createSnippets(source: String, lang: DslLang) = buildMap {
val pattern = Pattern.compile("(?ims)```${lang}\n(.*?)\n```")
val matcher = pattern.matcher(source)

while (matcher.find()) {
val line = source.lineNumberAt(matcher.start())
val code = matcher.group(1)
put(line, code)
}
}

private fun String.lineNumberAt(index: Int): Int {
var line = 1
for (i in 0 until index.coerceAtMost(length)) {
if (this[i] == '\n') line++
}
return line
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.github.jengelman.gradle.plugins.shadow.snippet

enum class DslLang {
// Kotlin,
Groovy,
;

override fun toString(): String = name.lowercase()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.jengelman.gradle.plugins.shadow.snippet

class GroovyBuildExecutable(
override val snippet: String,
override val displayName: String,
override val exceptionTransformer: (Throwable) -> Throwable,
) : SnippetExecutable() {

override val lang: DslLang = DslLang.Groovy

override val buildScriptName: String = "build.gradle"

override val pluginsBlock: String = """
plugins {
id 'java'
id 'com.gradleup.shadow'
}
""".trimIndent()
}
Loading
Loading