From 2c19ef093e3a5b7ed2e67a2c475152f446b05f5b Mon Sep 17 00:00:00 2001 From: Leonhardt Koepsell Date: Mon, 25 Sep 2017 09:36:12 -0700 Subject: [PATCH] wip --- build.gradle.kts | 35 ++---- css-inliner/build.gradle.kts | 29 +++++ .../codebandits/cssinliner}/CssInliner.kt | 2 + .../codebandits/cssinliner}/CssInlinerTest.kt | 2 + plugin/build.gradle.kts | 50 +++++++++ .../cssinliner/CSSInlinerFilter.kt | 16 +++ .../cssinliner/CssInlinerPlugin.kt | 30 ++++++ .../cssinliner/CssInlinerPluginExtension.kt | 8 ++ ....github.codebandits.css-inliner.properties | 1 + .../codebandits/cssinliner/AnotherTest.kt | 38 +++++++ .../codebandits/cssinliner/BasePluginTest.kt | 42 ++++++++ .../cssinliner/CssInlinerPluginTest.kt | 14 +++ .../jupiter/extensions/TempDirectory.java | 102 ++++++++++++++++++ settings.gradle | 2 + 14 files changed, 346 insertions(+), 25 deletions(-) create mode 100644 css-inliner/build.gradle.kts rename {src/main/kotlin => css-inliner/src/main/kotlin/com/github/codebandits/cssinliner}/CssInliner.kt (97%) rename {src/test/kotlin => css-inliner/src/test/kotlin/com/github/codebandits/cssinliner}/CssInlinerTest.kt (98%) create mode 100644 plugin/build.gradle.kts create mode 100644 plugin/src/main/kotlin/com/github/codebandits/cssinliner/CSSInlinerFilter.kt create mode 100644 plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPlugin.kt create mode 100644 plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginExtension.kt create mode 100644 plugin/src/main/resources/META-INF/gradle-plugins/com.github.codebandits.css-inliner.properties create mode 100644 plugin/src/test/kotlin/com/github/codebandits/cssinliner/AnotherTest.kt create mode 100644 plugin/src/test/kotlin/com/github/codebandits/cssinliner/BasePluginTest.kt create mode 100644 plugin/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginTest.kt create mode 100644 plugin/src/test/kotlin/org/junit/jupiter/extensions/TempDirectory.java create mode 100644 settings.gradle diff --git a/build.gradle.kts b/build.gradle.kts index 2502b22..72f139e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,29 +1,14 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath("org.junit.platform:junit-platform-gradle-plugin:1.0.0") - } -} - -plugins { - kotlin("jvm") version "1.1.50" -} +tasks { -apply { - plugin("org.junit.platform.gradle.plugin") -} + val plugin by creating(GradleBuild::class) { + dir = file("plugin") + tasks = listOf("publish") + } -repositories { - mavenCentral() -} + val sample by creating(GradleBuild::class) { + dir = file("sample") + tasks = listOf("processResources") + } -dependencies { - compile("org.jetbrains.kotlin:kotlin-stdlib") - compile("org.jsoup:jsoup:1.10.3") - compile("net.sourceforge.cssparser:cssparser:0.9.23") - testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0") - testCompile("org.assertj:assertj-core:3.8.0") - testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0") + sample.dependsOn(plugin) } diff --git a/css-inliner/build.gradle.kts b/css-inliner/build.gradle.kts new file mode 100644 index 0000000..2502b22 --- /dev/null +++ b/css-inliner/build.gradle.kts @@ -0,0 +1,29 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.junit.platform:junit-platform-gradle-plugin:1.0.0") + } +} + +plugins { + kotlin("jvm") version "1.1.50" +} + +apply { + plugin("org.junit.platform.gradle.plugin") +} + +repositories { + mavenCentral() +} + +dependencies { + compile("org.jetbrains.kotlin:kotlin-stdlib") + compile("org.jsoup:jsoup:1.10.3") + compile("net.sourceforge.cssparser:cssparser:0.9.23") + testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0") + testCompile("org.assertj:assertj-core:3.8.0") + testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0") +} diff --git a/src/main/kotlin/CssInliner.kt b/css-inliner/src/main/kotlin/com/github/codebandits/cssinliner/CssInliner.kt similarity index 97% rename from src/main/kotlin/CssInliner.kt rename to css-inliner/src/main/kotlin/com/github/codebandits/cssinliner/CssInliner.kt index 5cae637..073f537 100644 --- a/src/main/kotlin/CssInliner.kt +++ b/css-inliner/src/main/kotlin/com/github/codebandits/cssinliner/CssInliner.kt @@ -1,3 +1,5 @@ +package com.github.codebandits.cssinliner + import com.steadystate.css.parser.CSSOMParser import com.steadystate.css.parser.SACParserCSS3 import org.jsoup.Jsoup diff --git a/src/test/kotlin/CssInlinerTest.kt b/css-inliner/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerTest.kt similarity index 98% rename from src/test/kotlin/CssInlinerTest.kt rename to css-inliner/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerTest.kt index 9b124ba..5a36e39 100644 --- a/src/test/kotlin/CssInlinerTest.kt +++ b/css-inliner/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerTest.kt @@ -1,3 +1,5 @@ +package com.github.codebandits.cssinliner + import org.assertj.core.api.Assertions.assertThat import org.jsoup.Jsoup import org.jsoup.nodes.Document diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts new file mode 100644 index 0000000..a855ce9 --- /dev/null +++ b/plugin/build.gradle.kts @@ -0,0 +1,50 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.junit.platform:junit-platform-gradle-plugin:1.0.0") + } +} + +plugins { + kotlin("jvm") version "1.1.50" + `java-gradle-plugin` + `kotlin-dsl` +// `maven-publish` +} + +task("getCssFilePath") { + val cssFile = file("$projectDir/src/main/resources/templates/style.css") + println(cssFile.absolutePath) +} + +apply { + plugin("org.junit.platform.gradle.plugin") +} + +group = "com.github.codebandits" +version = "1.0" + +// TODO instead of src/main/resources/META-INF/gradle-plugins/com.github.codebandits.css-inliner.properties +//gradlePlugin { +// (plugins) { +// "CSS Inliner" { +// id = "com.github.codebandits.css-inliner" +// implementationClass = "com.github.codebandits.cssinliner.CssInlinerPlugin" +// } +// } +//} + +repositories { + mavenCentral() +} + +dependencies { + compile("org.jetbrains.kotlin:kotlin-stdlib") + compile(project(":css-inliner")) + testImplementation(gradleTestKit()) + testCompile("org.assertj:assertj-core:3.8.0") + testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0") + testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0") +} diff --git a/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CSSInlinerFilter.kt b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CSSInlinerFilter.kt new file mode 100644 index 0000000..0ed21f9 --- /dev/null +++ b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CSSInlinerFilter.kt @@ -0,0 +1,16 @@ +package com.github.codebandits.cssinliner + +import java.io.File +import java.io.FilterReader +import java.io.Reader +import java.io.StringReader + +internal class CSSInlinerFilter(properties: Map, `in`: Reader) : FilterReader(StringReader(inlineCSS(properties, `in`.readText()))) { + + companion object { + private fun inlineCSS(properties: Map, input: String): String { + val css = (properties["css"] as File).readText() + return CssInliner().inlineCss(input, css) + } + } +} diff --git a/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPlugin.kt b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPlugin.kt new file mode 100644 index 0000000..69532df --- /dev/null +++ b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPlugin.kt @@ -0,0 +1,30 @@ +package com.github.codebandits.cssinliner + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.invoke +import org.gradle.language.jvm.tasks.ProcessResources + +open class CssInlinerPlugin : Plugin { + override fun apply(target: Project) { + + val extension = target.extensions.create("css-inliner", CssInlinerPluginExtension::class.java) + + target.run { + tasks { + "processResources"(ProcessResources::class) { + filesMatching(extension.filesMatching) { + filter(mapOf("cssFile" to extension.cssFile), CSSInlinerFilter::class.java) + } + } + } + } +// target.tasks { +// "processResources"(ProcessResources::class) { +// filesMatching("**/*.yaml") { +// filter(com.github.codebandits.cssinliner.CSSInlinerFilter::class) +// } +// } +// } + } +} diff --git a/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginExtension.kt b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginExtension.kt new file mode 100644 index 0000000..564ab0b --- /dev/null +++ b/plugin/src/main/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginExtension.kt @@ -0,0 +1,8 @@ +package com.github.codebandits.cssinliner + +import java.io.File + +open class CssInlinerPluginExtension( + var cssFile: File? = null, + val filesMatching: MutableList = mutableListOf("**/*.html", "**/*.ftl") +) diff --git a/plugin/src/main/resources/META-INF/gradle-plugins/com.github.codebandits.css-inliner.properties b/plugin/src/main/resources/META-INF/gradle-plugins/com.github.codebandits.css-inliner.properties new file mode 100644 index 0000000..a2f49da --- /dev/null +++ b/plugin/src/main/resources/META-INF/gradle-plugins/com.github.codebandits.css-inliner.properties @@ -0,0 +1 @@ +implementation-class=com.github.codebandits.cssinliner.CssInlinerPlugin diff --git a/plugin/src/test/kotlin/com/github/codebandits/cssinliner/AnotherTest.kt b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/AnotherTest.kt new file mode 100644 index 0000000..4fdbec0 --- /dev/null +++ b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/AnotherTest.kt @@ -0,0 +1,38 @@ +package com.github.codebandits.cssinliner + +import org.junit.jupiter.api.Test + +class AnotherTest : BasePluginTest() { + + @Test + fun `new setup`() { + withBuildScript(""" + plugins { + `java-gradle-plugin` + `kotlin-dsl` + } + + repositories { + jcenter() + } + + dependencies { + testCompile("junit:junit:4.12") + } + """.trimIndent()) + + withFile("src/main/kotlin/code.kt", """ + import org.gradle.api.Plugin + import org.gradle.api.Project + import org.gradle.kotlin.dsl.embeddedKotlinVersion + class MyPlugin : Plugin { + override fun apply(project: Project) { + project.run { + println("Plugin Using Embedded Kotlin " + embeddedKotlinVersion) + } + } + } + """) + } +} + diff --git a/plugin/src/test/kotlin/com/github/codebandits/cssinliner/BasePluginTest.kt b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/BasePluginTest.kt new file mode 100644 index 0000000..962da45 --- /dev/null +++ b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/BasePluginTest.kt @@ -0,0 +1,42 @@ +package com.github.codebandits.cssinliner + +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.extensions.TempDirectory +import org.junit.jupiter.extensions.TempDirectory.Root +import java.io.File +import java.nio.file.Path + +@ExtendWith(TempDirectory::class) +abstract class BasePluginTest { + + private lateinit var projectRoot: File + + @BeforeEach + fun setUp(@Root tempDirectory: Path) { + projectRoot = tempDirectory.toFile() + } + + protected fun withBuildScript(script: String, produceFile: (String) -> File = this::newFile): File = + withBuildScriptIn(".", script, produceFile) + + private fun withBuildScriptIn(baseDir: String, script: String, produceFile: (String) -> File = this::newFile): File = + withFile("$baseDir/build.gradle.kts", script, produceFile) + + protected fun withFile(fileName: String, text: String = "", produceFile: (String) -> File = this::newFile) = + writeFile(produceFile(fileName), text) + + private fun writeFile(file: File, text: String): File = + file.apply { writeText(text) } + + private fun newFile(fileName: String): File { + makeParentFoldersOf(fileName) + return File(projectRoot, fileName).canonicalFile.apply { createNewFile() } + } + + private fun makeParentFoldersOf(fileName: String) = + parentFileOf(fileName).mkdirs() + + private fun parentFileOf(fileName: String): File = + File(projectRoot, fileName).parentFile +} diff --git a/plugin/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginTest.kt b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginTest.kt new file mode 100644 index 0000000..748504c --- /dev/null +++ b/plugin/src/test/kotlin/com/github/codebandits/cssinliner/CssInlinerPluginTest.kt @@ -0,0 +1,14 @@ +package com.github.codebandits.cssinliner + +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.Test + +class CssInlinerPluginTest { + + private val project = ProjectBuilder.builder().build() + + @Test + fun `should not fail when applied`() { + project.apply { it.plugin("com.github.codebandits.css-inliner") } + } +} diff --git a/plugin/src/test/kotlin/org/junit/jupiter/extensions/TempDirectory.java b/plugin/src/test/kotlin/org/junit/jupiter/extensions/TempDirectory.java new file mode 100644 index 0000000..3ca310b --- /dev/null +++ b/plugin/src/test/kotlin/org/junit/jupiter/extensions/TempDirectory.java @@ -0,0 +1,102 @@ +package org.junit.jupiter.extensions; + +import java.io.IOException; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; + +/** + * @since 1.0 + */ +public class TempDirectory implements AfterEachCallback, ParameterResolver { + + @Target(ElementType.PARAMETER) + @Retention(RetentionPolicy.RUNTIME) + @Documented + public @interface Root { + } + + private static final String KEY = "tempDirectory"; + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().isAnnotationPresent(Root.class) + && parameterContext.getParameter().getType() == Path.class; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext context) { + return getLocalStore(context).getOrComputeIfAbsent(KEY, key -> createTempDirectory(context)); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + Path tempDirectory = (Path) getLocalStore(context).get(KEY); + if (tempDirectory != null) { + delete(tempDirectory); + } + } + + private ExtensionContext.Store getLocalStore(ExtensionContext context) { + return context.getStore(localNamespace(context)); + } + + private Namespace localNamespace(ExtensionContext context) { + return Namespace.create(TempDirectory.class, context); + } + + private Path createTempDirectory(ExtensionContext context) { + try { + String tempDirName; + if (context.getTestMethod().isPresent()) { + tempDirName = context.getTestMethod().get().getName(); + } + else if (context.getTestClass().isPresent()) { + tempDirName = context.getTestClass().get().getName(); + } + else { + tempDirName = context.getDisplayName(); + } + + return Files.createTempDirectory(tempDirName); + } + catch (IOException e) { + throw new ParameterResolutionException("Could not create temp directory", e); + } + } + + private void delete(Path tempDirectory) throws IOException { + Files.walkFileTree(tempDirectory, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + return deleteAndContinue(file); + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return deleteAndContinue(dir); + } + + private FileVisitResult deleteAndContinue(Path path) throws IOException { + Files.delete(path); + return FileVisitResult.CONTINUE; + } + }); + } + +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..1a2e40f --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +include 'css-inliner' +include 'plugin'