diff --git a/pom.xml b/pom.xml
index 28be0da..9a813da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,16 @@
javalin
3.10.1
+
+ org.apache.commons
+ commons-compress
+ 1.20
+
+
+ org.koin
+ koin-core
+ 2.1.6
+
diff --git a/src/main/kotlin/starter/KotlinStarter.kt b/src/main/kotlin/starter/KotlinStarter.kt
index 34f23fd..44f9494 100644
--- a/src/main/kotlin/starter/KotlinStarter.kt
+++ b/src/main/kotlin/starter/KotlinStarter.kt
@@ -1,8 +1,29 @@
package starter
+import org.koin.core.context.startKoin
+import org.koin.dsl.bind
+import org.koin.dsl.module
+import starter.templates.MainTemplate
+import starter.templates.PomTemplate
+import starter.templates.Template
+
+val mainModule = module {
+ single { Config().load() }
+ single { PebbleModule().engine() }
+ single { Server(get(), get(), get()) }
+ single { Views(get()) }
+ single { ProjectZip(getAll()) }
+}
+
+val templateModule = module {
+ single { PomTemplate(get()) } bind Template::class
+ single { MainTemplate(get()) } bind Template::class
+}
+
fun main() {
- val config = Config()
- val loaded = config.load()
- val server = Server(Views(PebbleModule().engine()),loaded)
+ val koin = startKoin {
+ modules(mainModule, templateModule)
+ }.koin
+ val server = koin.get()
server.run()
}
diff --git a/src/main/kotlin/starter/Models.kt b/src/main/kotlin/starter/Models.kt
index 0cb1836..672c6a7 100644
--- a/src/main/kotlin/starter/Models.kt
+++ b/src/main/kotlin/starter/Models.kt
@@ -18,4 +18,11 @@ data class Dependency(
val scope: Scope
)
-data class Input(val name: String, val display: String, val value: String? = null)
\ No newline at end of file
+data class Input(val name: String, val display: String, val value: String? = null)
+
+data class Project(
+ val name: String,
+ val basePackage: String,
+ val inputs: List,
+ val dependencies: List,
+)
diff --git a/src/main/kotlin/starter/ProjectZip.kt b/src/main/kotlin/starter/ProjectZip.kt
new file mode 100644
index 0000000..9a2db33
--- /dev/null
+++ b/src/main/kotlin/starter/ProjectZip.kt
@@ -0,0 +1,23 @@
+package starter
+
+import starter.templates.Template
+import starter.utils.ZipOutput
+import starter.utils.sanitizeFilename
+
+class ProjectZip(private val templates: List) {
+
+ fun createZip(project: Project): String {
+ val name: String
+
+ ZipOutput(sanitizeFilename(project.name)).use {
+ name = it.name
+
+ templates.forEach { template ->
+ it.write(template.path(project), template.render(project))
+ }
+ }
+
+ return name
+ }
+
+}
diff --git a/src/main/kotlin/starter/Server.kt b/src/main/kotlin/starter/Server.kt
index ba11bee..4a2cebc 100644
--- a/src/main/kotlin/starter/Server.kt
+++ b/src/main/kotlin/starter/Server.kt
@@ -1,8 +1,14 @@
package starter
import io.javalin.Javalin
+import starter.utils.sanitizeFilename
+import java.io.File
-class Server(private val views: Views, private val conf: StarterConfig) {
+class Server(
+ private val views: Views,
+ private val conf: StarterConfig,
+ private val projectZip: ProjectZip,
+) {
fun run() {
val app = Javalin.create {
it.addStaticFiles("/assets")
@@ -25,9 +31,14 @@ class Server(private val views: Views, private val conf: StarterConfig) {
conf.inputs.find { it.name == name }!!.copy(value = value.first())
}
- val generatedPom = views.pom(deps, inputs)
- ctx.result(prettyPrintXml(generatedPom))
- ctx.contentType("text/xml")
+ val projectName = inputs.find { it.name == "name" }!!.value!!
+ val basePackage = inputs.find { it.name == "basePackage" }!!.value!!
+ val project = Project(projectName, basePackage, inputs, deps)
+
+ ctx.contentType("application/zip")
+ ctx.header("Content-Disposition", "attachment; filename=\"${sanitizeFilename(projectName)}.zip\"")
+ val zipFile = projectZip.createZip(project)
+ ctx.result(File(zipFile).readBytes())
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/starter/Views.kt b/src/main/kotlin/starter/Views.kt
index e596a84..2999ad9 100644
--- a/src/main/kotlin/starter/Views.kt
+++ b/src/main/kotlin/starter/Views.kt
@@ -2,14 +2,7 @@ package starter
import com.mitchellbosecke.pebble.PebbleEngine
import org.slf4j.LoggerFactory
-import java.io.StringWriter
-
-private fun PebbleEngine.render(name: String, args: Map = mapOf()): String {
- val template = getTemplate(name)
- val writer = StringWriter()
- template.evaluate(writer, args)
- return writer.toString()
-}
+import starter.utils.render
class Views(private val engine: PebbleEngine) {
private val logger = LoggerFactory.getLogger(javaClass)
@@ -21,18 +14,4 @@ class Views(private val engine: PebbleEngine) {
)
}
- fun pom(dependencies: List, inputs: List): String {
-
- val args: MutableMap = mutableMapOf(
- "dependencies" to dependencies.sortedBy { it.scope },
- )
-
- inputs.forEach {
- args[it.name] = it.value
- }
-
- return engine.render("starter/pom",
- args
- )
- }
}
\ No newline at end of file
diff --git a/src/main/kotlin/starter/templates/MainTemplate.kt b/src/main/kotlin/starter/templates/MainTemplate.kt
new file mode 100644
index 0000000..4c26de4
--- /dev/null
+++ b/src/main/kotlin/starter/templates/MainTemplate.kt
@@ -0,0 +1,13 @@
+package starter.templates
+
+import com.mitchellbosecke.pebble.PebbleEngine
+import starter.Project
+import starter.utils.render
+
+class MainTemplate(private val engine: PebbleEngine) : Template {
+ override fun path(project: Project) =
+ project.basePackage.replace('.', '/') + "/" + project.name.toLowerCase().capitalize() + ".kt"
+
+ override fun render(project: Project) =
+ engine.render("starter/main/main", mapOf("basePackage" to project.basePackage))
+}
diff --git a/src/main/kotlin/starter/templates/PomTemplate.kt b/src/main/kotlin/starter/templates/PomTemplate.kt
new file mode 100644
index 0000000..01f5fdb
--- /dev/null
+++ b/src/main/kotlin/starter/templates/PomTemplate.kt
@@ -0,0 +1,23 @@
+package starter.templates
+
+import com.mitchellbosecke.pebble.PebbleEngine
+import starter.Project
+import starter.utils.prettyPrintXml
+import starter.utils.render
+
+class PomTemplate(private val engine: PebbleEngine) : Template {
+ override fun path(project: Project) = "pom.xml"
+
+ override fun render(project: Project): String {
+ val args: MutableMap = mutableMapOf(
+ "dependencies" to project.dependencies.sortedBy { it.scope },
+ )
+
+ project.inputs.forEach {
+ args[it.name] = it.value
+ }
+
+ val rendered = engine.render("starter/pom/pom", args)
+ return prettyPrintXml(rendered)
+ }
+}
diff --git a/src/main/kotlin/starter/templates/Template.kt b/src/main/kotlin/starter/templates/Template.kt
new file mode 100644
index 0000000..aca6a9c
--- /dev/null
+++ b/src/main/kotlin/starter/templates/Template.kt
@@ -0,0 +1,8 @@
+package starter.templates
+
+import starter.Project
+
+interface Template {
+ fun path(project: Project): String
+ fun render(project: Project): String
+}
diff --git a/src/main/kotlin/starter/utils/PathUtils.kt b/src/main/kotlin/starter/utils/PathUtils.kt
new file mode 100644
index 0000000..81eb342
--- /dev/null
+++ b/src/main/kotlin/starter/utils/PathUtils.kt
@@ -0,0 +1,3 @@
+package starter.utils
+
+fun sanitizeFilename(inputName: String): String = inputName.replace("[^a-zA-Z0-9-_.]".toRegex(), "_")
diff --git a/src/main/kotlin/starter/utils/PebbleUtils.kt b/src/main/kotlin/starter/utils/PebbleUtils.kt
new file mode 100644
index 0000000..6a52f56
--- /dev/null
+++ b/src/main/kotlin/starter/utils/PebbleUtils.kt
@@ -0,0 +1,11 @@
+package starter.utils
+
+import com.mitchellbosecke.pebble.PebbleEngine
+import java.io.StringWriter
+
+fun PebbleEngine.render(name: String, args: Map = mapOf()): String {
+ val template = getTemplate(name)
+ val writer = StringWriter()
+ template.evaluate(writer, args)
+ return writer.toString()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/starter/Utils.kt b/src/main/kotlin/starter/utils/XmlUtils.kt
similarity index 98%
rename from src/main/kotlin/starter/Utils.kt
rename to src/main/kotlin/starter/utils/XmlUtils.kt
index 9048e2c..7e1a7de 100644
--- a/src/main/kotlin/starter/Utils.kt
+++ b/src/main/kotlin/starter/utils/XmlUtils.kt
@@ -1,4 +1,4 @@
-package starter
+package starter.utils
import org.w3c.dom.Document
import org.w3c.dom.NodeList
diff --git a/src/main/kotlin/starter/utils/ZipOutput.kt b/src/main/kotlin/starter/utils/ZipOutput.kt
new file mode 100644
index 0000000..282bbd9
--- /dev/null
+++ b/src/main/kotlin/starter/utils/ZipOutput.kt
@@ -0,0 +1,29 @@
+package starter.utils
+
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import java.io.File
+import java.nio.file.Paths
+
+class ZipOutput(name: String) : AutoCloseable {
+ private val baseDir = File(".").canonicalFile
+ private val zipPath = Paths.get(baseDir.path, "$name.zip")
+ private val zipFile = zipPath.toAbsolutePath().normalize().toFile().apply {
+ createNewFile()
+ }
+ private val outputStream = ZipArchiveOutputStream(zipFile.outputStream())
+ val name: String
+ get() = zipFile.name
+
+ fun write(path: String, content: String) {
+ val entry = ZipArchiveEntry(path)
+ outputStream.putArchiveEntry(entry)
+ outputStream.write(content.toByteArray())
+ outputStream.closeArchiveEntry()
+ }
+
+ override fun close() {
+ outputStream.finish()
+ outputStream.close()
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/starter/main/main.twig b/src/main/resources/starter/main/main.twig
new file mode 100644
index 0000000..9a6893e
--- /dev/null
+++ b/src/main/resources/starter/main/main.twig
@@ -0,0 +1,6 @@
+package {{ basePackage }}
+
+
+fun main() {
+ println("Hello world!")
+}
diff --git a/src/main/resources/starter/@dependencies.twig b/src/main/resources/starter/pom/@dependencies.twig
similarity index 86%
rename from src/main/resources/starter/@dependencies.twig
rename to src/main/resources/starter/pom/@dependencies.twig
index d999ec8..e609248 100644
--- a/src/main/resources/starter/@dependencies.twig
+++ b/src/main/resources/starter/pom/@dependencies.twig
@@ -4,7 +4,7 @@
{{ dep.groupId }}
{{ dep.artifactId }}
{{ dep.version }}
- {% if dep.scope.toString == "Test" %}
+ {% if dep.scope == "Test" %}
test
{% endif %}
diff --git a/src/main/resources/starter/@plugins.twig b/src/main/resources/starter/pom/@plugins.twig
similarity index 56%
rename from src/main/resources/starter/@plugins.twig
rename to src/main/resources/starter/pom/@plugins.twig
index c27538b..a81ac19 100644
--- a/src/main/resources/starter/@plugins.twig
+++ b/src/main/resources/starter/pom/@plugins.twig
@@ -4,11 +4,11 @@
- {% include "starter/plugins/@default" %}
+ {% include "starter/pom/plugins/@default" %}
- {% include "starter/plugins/@kotlin" %}
+ {% include "starter/pom/plugins/@kotlin" %}
- {% include "starter/plugins/@shade" %}
+ {% include "starter/pom/plugins/@shade" %}
\ No newline at end of file
diff --git a/src/main/resources/starter/@repositories.twig b/src/main/resources/starter/pom/@repositories.twig
similarity index 100%
rename from src/main/resources/starter/@repositories.twig
rename to src/main/resources/starter/pom/@repositories.twig
diff --git a/src/main/resources/starter/plugins/@default.twig b/src/main/resources/starter/pom/plugins/@default.twig
similarity index 100%
rename from src/main/resources/starter/plugins/@default.twig
rename to src/main/resources/starter/pom/plugins/@default.twig
diff --git a/src/main/resources/starter/plugins/@kotlin.twig b/src/main/resources/starter/pom/plugins/@kotlin.twig
similarity index 100%
rename from src/main/resources/starter/plugins/@kotlin.twig
rename to src/main/resources/starter/pom/plugins/@kotlin.twig
diff --git a/src/main/resources/starter/plugins/@shade.twig b/src/main/resources/starter/pom/plugins/@shade.twig
similarity index 100%
rename from src/main/resources/starter/plugins/@shade.twig
rename to src/main/resources/starter/pom/plugins/@shade.twig
diff --git a/src/main/resources/starter/pom.twig b/src/main/resources/starter/pom/pom.twig
similarity index 82%
rename from src/main/resources/starter/pom.twig
rename to src/main/resources/starter/pom/pom.twig
index efe0813..092199e 100644
--- a/src/main/resources/starter/pom.twig
+++ b/src/main/resources/starter/pom/pom.twig
@@ -14,10 +14,10 @@
{{ basePackage }}/{{ name | lower | capitalize }}Kt
- {% include "starter/@dependencies" %}
+ {% include "starter/pom/@dependencies" %}
- {% include "starter/@repositories" %}
+ {% include "starter/pom/@repositories" %}
- {% include "starter/@plugins" %}
+ {% include "starter/pom/@plugins" %}
\ No newline at end of file