Add features + ktlint as first feature
This commit is contained in:
parent
aa585358be
commit
68fdac4d64
@ -16,6 +16,11 @@ display = "Java Version"
|
|||||||
default = "1.4.10"
|
default = "1.4.10"
|
||||||
display = "Kotlin Version"
|
display = "Kotlin Version"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
[features.ktlint]
|
||||||
|
default = true
|
||||||
|
|
||||||
[versions]
|
[versions]
|
||||||
http4k = "3.265.0"
|
http4k = "3.265.0"
|
||||||
pebble = "3.1.4"
|
pebble = "3.1.4"
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -150,7 +150,6 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
@ -195,7 +194,6 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|||||||
51
src/main/kotlin/pebble/DepAsXmlPebbleFunction.kt
Normal file
51
src/main/kotlin/pebble/DepAsXmlPebbleFunction.kt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package pebble
|
||||||
|
|
||||||
|
import com.mitchellbosecke.pebble.extension.escaper.SafeString
|
||||||
|
import com.mitchellbosecke.pebble.template.EvaluationContext
|
||||||
|
import com.mitchellbosecke.pebble.template.PebbleTemplate
|
||||||
|
import org.intellij.lang.annotations.Language
|
||||||
|
import starter.Dependency
|
||||||
|
import starter.utils.PebbleFunction
|
||||||
|
|
||||||
|
// We need a custom function since pebble inserts whitespace everywhere
|
||||||
|
class DepAsXmlPebbleFunction : PebbleFunction {
|
||||||
|
override val name = "depAsXml"
|
||||||
|
override fun getArgumentNames() = listOf("dependency")
|
||||||
|
|
||||||
|
override fun execute(
|
||||||
|
args: Map<String, Any>,
|
||||||
|
self: PebbleTemplate,
|
||||||
|
context: EvaluationContext,
|
||||||
|
lineNumber: Int,
|
||||||
|
): SafeString {
|
||||||
|
val dep = args["dependency"] as Dependency
|
||||||
|
|
||||||
|
fun tagName(name: String) = """<span class="text-red-700">$name</span>"""
|
||||||
|
|
||||||
|
fun startTag(name: String): String {
|
||||||
|
@Language("html") @Suppress("UnnecessaryVariable")
|
||||||
|
val result = """<span class="text-gray-700"><</span>""" +
|
||||||
|
"""${tagName(name)}<span class="text-gray-700">></span>"""
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun endTag(name: String): String {
|
||||||
|
@Language("html") @Suppress("UnnecessaryVariable")
|
||||||
|
val result = """<span class="text-gray-700"></</span>""" +
|
||||||
|
"""${tagName(name)}<span class="text-gray-700">></span>"""
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tag(name: String, content: String) = """${startTag(name)}$content${endTag(name)}"""
|
||||||
|
|
||||||
|
val result = """
|
||||||
|
|${startTag("dependency")}
|
||||||
|
| ${tag("groupId", dep.groupId)}
|
||||||
|
| ${tag("artifactId", dep.artifactId)}
|
||||||
|
| ${tag("version", dep.version.value)}
|
||||||
|
|${endTag("dependency")}
|
||||||
|
""".trimMargin()
|
||||||
|
|
||||||
|
return SafeString(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/main/kotlin/pebble/HasFeatureFilter.kt
Normal file
27
src/main/kotlin/pebble/HasFeatureFilter.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package pebble
|
||||||
|
|
||||||
|
import com.mitchellbosecke.pebble.template.EvaluationContext
|
||||||
|
import com.mitchellbosecke.pebble.template.PebbleTemplate
|
||||||
|
import starter.Feature
|
||||||
|
import starter.utils.PebbleFilter
|
||||||
|
|
||||||
|
class HasFeatureFilter : PebbleFilter {
|
||||||
|
override val name = "hasFeature"
|
||||||
|
|
||||||
|
override fun getArgumentNames() = listOf("name")
|
||||||
|
|
||||||
|
override fun apply(
|
||||||
|
input: Any,
|
||||||
|
args: MutableMap<String, Any>,
|
||||||
|
self: PebbleTemplate,
|
||||||
|
context: EvaluationContext,
|
||||||
|
lineNumber: Int,
|
||||||
|
): Boolean {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val features = input as List<Feature>
|
||||||
|
|
||||||
|
val name = args["name"] as String
|
||||||
|
|
||||||
|
return features.any { it.name == name }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,10 +24,13 @@ data class Repository(val name: String, val url: String)
|
|||||||
|
|
||||||
data class Input(val name: String, val display: String, val value: String? = null)
|
data class Input(val name: String, val display: String, val value: String? = null)
|
||||||
|
|
||||||
|
data class Feature(val name: String, val value: Boolean = false)
|
||||||
|
|
||||||
data class Project(
|
data class Project(
|
||||||
val name: String,
|
val name: String,
|
||||||
val basePackage: String,
|
val basePackage: String,
|
||||||
val inputs: List<Input>,
|
val inputs: List<Input>,
|
||||||
|
val features: List<Feature>,
|
||||||
val dependencies: List<Dependency>,
|
val dependencies: List<Dependency>,
|
||||||
val repositories: Collection<Repository>,
|
val repositories: Collection<Repository>,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import com.electronwill.nightconfig.core.Config as NightConfig
|
|||||||
data class StarterConfig(
|
data class StarterConfig(
|
||||||
val dependencies: List<Dependency>,
|
val dependencies: List<Dependency>,
|
||||||
val inputs: List<Input>,
|
val inputs: List<Input>,
|
||||||
|
val features: List<Feature>,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Config(private val cfg: NightConfig) {
|
class Config(private val cfg: NightConfig) {
|
||||||
@ -54,6 +55,11 @@ class Config(private val cfg: NightConfig) {
|
|||||||
Input(name, values["display"], values["default"])
|
Input(name, values["display"], values["default"])
|
||||||
}
|
}
|
||||||
|
|
||||||
return StarterConfig(dependencies, inputs)
|
val features = cfg.configMap("features")
|
||||||
|
.map { (name, values) ->
|
||||||
|
Feature(name, values["default"] ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return StarterConfig(dependencies, inputs, features)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,65 +1,23 @@
|
|||||||
package starter.modules
|
package starter.modules
|
||||||
|
|
||||||
import com.mitchellbosecke.pebble.extension.escaper.SafeString
|
|
||||||
import com.mitchellbosecke.pebble.template.EvaluationContext
|
|
||||||
import com.mitchellbosecke.pebble.template.PebbleTemplate
|
|
||||||
import org.intellij.lang.annotations.Language
|
|
||||||
import org.koin.dsl.bind
|
import org.koin.dsl.bind
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
import starter.Dependency
|
import pebble.DepAsXmlPebbleFunction
|
||||||
|
import pebble.HasFeatureFilter
|
||||||
import starter.utils.PebbleEngineBuilder
|
import starter.utils.PebbleEngineBuilder
|
||||||
import starter.utils.PebbleEngineBuilder.CacheType.ConcurrentMap
|
import starter.utils.PebbleEngineBuilder.CacheType.ConcurrentMap
|
||||||
|
import starter.utils.PebbleFilter
|
||||||
import starter.utils.PebbleFunction
|
import starter.utils.PebbleFunction
|
||||||
|
|
||||||
class DepAsXmlPebbleFunction : PebbleFunction {
|
|
||||||
override val name = "depAsXml"
|
|
||||||
override fun getArgumentNames() = listOf("dependency")
|
|
||||||
|
|
||||||
override fun execute(
|
|
||||||
args: Map<String, Any>,
|
|
||||||
self: PebbleTemplate,
|
|
||||||
context: EvaluationContext,
|
|
||||||
lineNumber: Int,
|
|
||||||
): Any {
|
|
||||||
val dep = args["dependency"] as Dependency
|
|
||||||
|
|
||||||
fun tagName(name: String) = """<span class="text-red-700">$name</span>"""
|
|
||||||
|
|
||||||
fun startTag(name: String): String {
|
|
||||||
@Language("html") @Suppress("UnnecessaryVariable")
|
|
||||||
val result = """<span class="text-gray-700"><</span>""" +
|
|
||||||
"""${tagName(name)}<span class="text-gray-700">></span>"""
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endTag(name: String): String {
|
|
||||||
@Language("html") @Suppress("UnnecessaryVariable")
|
|
||||||
val result = """<span class="text-gray-700"></</span>""" +
|
|
||||||
"""${tagName(name)}<span class="text-gray-700">></span>"""
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tag(name: String, content: String) = """${startTag(name)}$content${endTag(name)}"""
|
|
||||||
|
|
||||||
val result = """
|
|
||||||
|${startTag("dependency")}
|
|
||||||
| ${tag("groupId", dep.groupId)}
|
|
||||||
| ${tag("artifactId", dep.artifactId)}
|
|
||||||
| ${tag("version", dep.version.value)}
|
|
||||||
|${endTag("dependency")}
|
|
||||||
""".trimMargin()
|
|
||||||
|
|
||||||
return SafeString(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val pebbleModule = module {
|
val pebbleModule = module {
|
||||||
single { DepAsXmlPebbleFunction() } bind PebbleFunction::class
|
single { DepAsXmlPebbleFunction() } bind PebbleFunction::class
|
||||||
|
single { HasFeatureFilter() } bind PebbleFilter::class
|
||||||
|
|
||||||
single {
|
single {
|
||||||
PebbleEngineBuilder {
|
PebbleEngineBuilder {
|
||||||
cache = ConcurrentMap
|
cache = ConcurrentMap
|
||||||
functions(getAll())
|
functions(getAll())
|
||||||
|
filters(getAll())
|
||||||
classPath { suffix = ".twig" }
|
classPath { suffix = ".twig" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,21 @@ class ZipRouteSupplier(
|
|||||||
req.form(it.name) != null
|
req.form(it.name) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val formMap = req.formAsMap()
|
||||||
|
|
||||||
val inputKeys = conf.inputs.map { it.name }
|
val inputKeys = conf.inputs.map { it.name }
|
||||||
val inputs = req.formAsMap()
|
val inputs = formMap
|
||||||
.filter { it.key in inputKeys }
|
.filter { it.key in inputKeys }
|
||||||
.map { (name, value) ->
|
.map { (name, value) ->
|
||||||
conf.inputs.find { it.name == name }!!.copy(value = value.first())
|
conf.inputs.find { it.name == name }!!.copy(value = value.first())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val features = formMap
|
||||||
|
.filter { it.key in conf.features.map { it.name } }
|
||||||
|
.map { (name, _) ->
|
||||||
|
conf.features.find { it.name == name }!!.copy(value = true)
|
||||||
|
}
|
||||||
|
|
||||||
val projectName = inputs.find { it.name == "name" }!!.value!!
|
val projectName = inputs.find { it.name == "name" }!!.value!!
|
||||||
val basePackage = inputs.find { it.name == "basePackage" }!!.value!!
|
val basePackage = inputs.find { it.name == "basePackage" }!!.value!!
|
||||||
|
|
||||||
@ -39,7 +47,7 @@ class ZipRouteSupplier(
|
|||||||
Response.badRequest()
|
Response.badRequest()
|
||||||
} else {
|
} else {
|
||||||
val repositories = deps.mapNotNull { it.repository }.toSet()
|
val repositories = deps.mapNotNull { it.repository }.toSet()
|
||||||
val project = Project(projectName, basePackage, inputs, deps, repositories)
|
val project = Project(projectName, basePackage, inputs, features, deps, repositories)
|
||||||
val outputStream = projectZip.createZip(project)
|
val outputStream = projectZip.createZip(project)
|
||||||
|
|
||||||
Response.ok().with(
|
Response.ok().with(
|
||||||
|
|||||||
@ -13,6 +13,7 @@ class PomTemplate(private val engine: PebbleEngine) : Template {
|
|||||||
"dependencies" to project.dependencies.sortedBy { it.scope },
|
"dependencies" to project.dependencies.sortedBy { it.scope },
|
||||||
"repositories" to project.repositories,
|
"repositories" to project.repositories,
|
||||||
"kotlinxSerialization" to project.dependencies.any { it.name == "kotlinx-serialization" },
|
"kotlinxSerialization" to project.dependencies.any { it.name == "kotlinx-serialization" },
|
||||||
|
"features" to project.features,
|
||||||
"versions" to project.dependencies.map { it.version }.toSet()
|
"versions" to project.dependencies.map { it.version }.toSet()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ class PomTemplate(private val engine: PebbleEngine) : Template {
|
|||||||
args[it.name] = it.value
|
args[it.name] = it.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println(args.entries.joinToString("\n"))
|
||||||
|
|
||||||
val rendered = engine.render("starter/pom/index", args)
|
val rendered = engine.render("starter/pom/index", args)
|
||||||
return prettyPrintXml(rendered)
|
return prettyPrintXml(rendered)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import starter.utils.render
|
|||||||
class Views(private val engine: PebbleEngine, config: StarterConfig) {
|
class Views(private val engine: PebbleEngine, config: StarterConfig) {
|
||||||
private val args = mapOf(
|
private val args = mapOf(
|
||||||
"dependencies" to config.dependencies.groupBy { it.category }.toSortedMap(),
|
"dependencies" to config.dependencies.groupBy { it.category }.toSortedMap(),
|
||||||
"inputs" to config.inputs
|
"inputs" to config.inputs,
|
||||||
|
"features" to config.features,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun index() = engine.render("views/index", args)
|
fun index() = engine.render("views/index", args)
|
||||||
|
|||||||
@ -10,5 +10,7 @@
|
|||||||
|
|
||||||
{% include "starter/pom/plugins/@shade" %}
|
{% include "starter/pom/plugins/@shade" %}
|
||||||
|
|
||||||
|
{% include "starter/pom/plugins/@ktlint" %}
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<java.version>{{ javaVersion }}</java.version>
|
<java.version>{{ javaVersion }}</java.version>
|
||||||
<kotlin.version>{{ kotlinVersion }}</kotlin.version>
|
<kotlin.version>{{ kotlinVersion }}</kotlin.version>
|
||||||
|
<kotlin.code.style>official</kotlin.code.style>
|
||||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
46
src/main/resources/starter/pom/plugins/@ktlint.twig
Normal file
46
src/main/resources/starter/pom/plugins/@ktlint.twig
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{% if features | hasFeature("ktlint") %}
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>ktlint</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<configuration>
|
||||||
|
<target name="ktlint">
|
||||||
|
<java taskname="ktlint" dir="${basedir}" fork="true" failonerror="true"
|
||||||
|
classname="com.pinterest.ktlint.Main" classpathref="maven.plugin.classpath">
|
||||||
|
<arg value="src/**/*.kt"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>ktlint-format</id>
|
||||||
|
<configuration>
|
||||||
|
<target name="ktlint">
|
||||||
|
<java taskname="ktlint" dir="${basedir}" fork="true" failonerror="true"
|
||||||
|
classname="com.pinterest.ktlint.Main" classpathref="maven.plugin.classpath">
|
||||||
|
<arg value="-F"/>
|
||||||
|
<arg value="src/**/*.kt"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.pinterest</groupId>
|
||||||
|
<artifactId>ktlint</artifactId>
|
||||||
|
<version>0.39.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
{% endif %}
|
||||||
@ -10,6 +10,19 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
|
<section>
|
||||||
|
<h2 class="category">Features</h2>
|
||||||
|
<ul>
|
||||||
|
{% for feature in features %}
|
||||||
|
<label class="m-2">
|
||||||
|
<input name="{{ feature.name }}"
|
||||||
|
type="checkbox"{% if feature.value %} checked{% endif %}>
|
||||||
|
<span>{{ feature.name }}</span>
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
{% for category in dependencies %}
|
{% for category in dependencies %}
|
||||||
<section>
|
<section>
|
||||||
<h2 class="category">{{ category.key }}</h2>
|
<h2 class="category">{{ category.key }}</h2>
|
||||||
|
|||||||
@ -30,6 +30,7 @@ internal class PomTemplateTest {
|
|||||||
name = "Test",
|
name = "Test",
|
||||||
basePackage = "org.test",
|
basePackage = "org.test",
|
||||||
inputs = conf.inputs,
|
inputs = conf.inputs,
|
||||||
|
features = emptyList(),
|
||||||
dependencies = conf.dependencies,
|
dependencies = conf.dependencies,
|
||||||
repositories = conf.dependencies.mapNotNull { it.repository }.toSet()
|
repositories = conf.dependencies.mapNotNull { it.repository }.toSet()
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user