[Editor] Enable packaging compiled *.class files to *.jar package

This commit is contained in:
2021-02-25 19:33:38 +01:00
parent bfd073b42b
commit e355be81ed
10 changed files with 103 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
package com.bartlomiejpluta.base.editor.code.compiler
package com.bartlomiejpluta.base.editor.code.build.compiler
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
import com.bartlomiejpluta.base.editor.event.UpdateCompilationLogEvent
@@ -38,12 +38,6 @@ class JaninoCompiler : ScriptCompiler {
}
private fun moveClassFilesToTargetDirectory(sourceDirectory: File, targetDirectory: File) {
if (targetDirectory.exists() && !targetDirectory.isDirectory) {
throw IllegalStateException("Target directory is actually a file")
}
targetDirectory.mkdirs()
val files = Files.walk(sourceDirectory.toPath())
.filter(Files::isRegularFile)
.map(Path::toFile)

View File

@@ -1,4 +1,4 @@
package com.bartlomiejpluta.base.editor.code.compiler
package com.bartlomiejpluta.base.editor.code.build.compiler
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
import java.io.File

View File

@@ -0,0 +1,7 @@
package com.bartlomiejpluta.base.editor.code.build.packager
import java.io.File
interface JarPackager {
fun pack(sourceDirectory: File, targetJar: File, root: String = ".")
}

View File

@@ -0,0 +1,30 @@
package com.bartlomiejpluta.base.editor.code.build.packager
import org.springframework.stereotype.Component
import java.io.File
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
@Component
class ZipBasedJarPackager : JarPackager {
override fun pack(sourceDirectory: File, targetJar: File, root: String) {
val env = mapOf("create" to "true")
val zip = targetJar.toPath()
val uri = URI.create("jar:" + zip.toUri())
val source = sourceDirectory.toPath()
FileSystems.newFileSystem(uri, env).use { jar ->
Files.walk(source)
.filter(Files::isRegularFile)
.forEach {
val path = jar.getPath(Paths.get(root, source.relativize(it).toString()).normalize().toString())
Files.createDirectories(path.parent)
Files.copy(it, path, StandardCopyOption.REPLACE_EXISTING)
}
}
}
}

View File

@@ -0,0 +1,5 @@
package com.bartlomiejpluta.base.editor.code.build.pipeline
interface BuildPipelineService {
fun build()
}

View File

@@ -0,0 +1,42 @@
package com.bartlomiejpluta.base.editor.code.build.pipeline
import com.bartlomiejpluta.base.editor.code.build.compiler.ScriptCompiler
import com.bartlomiejpluta.base.editor.code.build.packager.JarPackager
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.io.File
@Component
class DefaultBuildPipelineService : BuildPipelineService {
@Autowired
private lateinit var compiler: ScriptCompiler
@Autowired
private lateinit var packager: JarPackager
@Autowired
private lateinit var projectContext: ProjectContext
override fun build() {
projectContext.project?.let {
prepareBuildDirectory(it)
compiler.compile(it.codeFSNode, it.buildClassesDirectory)
packager.pack(it.buildClassesDirectory, File(it.buildOutDirectory, OUTPUT_JAR_NAME))
}
}
private fun prepareBuildDirectory(project: Project) {
project.buildDirectory.delete()
project.buildClassesDirectory.mkdirs()
project.buildOutDirectory.mkdirs()
}
companion object {
private const val OUTPUT_JAR_NAME = "game.jar"
}
}

View File

@@ -1,5 +0,0 @@
package com.bartlomiejpluta.base.editor.code.compiler
interface CompilingService {
fun compile()
}

View File

@@ -1,21 +0,0 @@
package com.bartlomiejpluta.base.editor.code.compiler
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
class DefaultCompilingService : CompilingService {
@Autowired
private lateinit var compiler: ScriptCompiler
@Autowired
private lateinit var projectContext: ProjectContext
override fun compile() {
projectContext.project?.let {
compiler.compile(it.codeFSNode, it.buildClassesDirectory)
}
}
}

View File

@@ -1,6 +1,6 @@
package com.bartlomiejpluta.base.editor.main.view
import com.bartlomiejpluta.base.editor.code.compiler.CompilingService
import com.bartlomiejpluta.base.editor.code.build.pipeline.BuildPipelineService
import com.bartlomiejpluta.base.editor.main.controller.MainController
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import tornadofx.*
@@ -8,7 +8,7 @@ import tornadofx.*
class MainMenuView : View() {
private val mainController: MainController by di()
private val projectContext: ProjectContext by di()
private val compilingService: CompilingService by di()
private val buildPipelineService: BuildPipelineService by di()
override val root = menubar {
menu("File") {
@@ -57,7 +57,7 @@ class MainMenuView : View() {
item("Compile") {
action {
compilingService.compile()
buildPipelineService.build()
}
}
}

View File

@@ -43,10 +43,19 @@ class Project {
val codeFSNodeProperty = Bindings.createObjectBinding({ FileSystemNode(codeDirectory) }, codeDirectoryProperty)
val codeFSNode by codeFSNodeProperty
// Build directories
val buildDirectoryProperty = SimpleObjectProperty<File>()
var buildDirectory by buildDirectoryProperty
private set
val buildClassesDirectoryProperty = SimpleObjectProperty<File>()
var buildClassesDirectory by buildClassesDirectoryProperty
private set
val buildOutDirectoryProperty = SimpleObjectProperty<File>()
var buildOutDirectory by buildOutDirectoryProperty
private set
init {
sourceDirectoryProperty.addListener { _, _, dir ->
dir?.let {
@@ -54,7 +63,9 @@ class Project {
tileSetsDirectory = File(it, TILESETS_DIR)
imagesDirectory = File(it, IMAGES_DIR)
codeDirectory = File(it, CODE_DIR)
buildDirectory = File(it, BUILD_DIR)
buildClassesDirectory = File(it, BUILD_CLASSES_DIR)
buildOutDirectory = File(it, BUILD_OUT_DIR)
}
}
}
@@ -72,6 +83,8 @@ class Project {
const val TILESETS_DIR = "tilesets"
const val IMAGES_DIR = "images"
const val CODE_DIR = "code"
const val BUILD_CLASSES_DIR = "build/classes"
const val BUILD_DIR = "build"
const val BUILD_CLASSES_DIR = "$BUILD_DIR/classes"
const val BUILD_OUT_DIR = "$BUILD_DIR/out"
}
}