Sitelet https://github.com/kscripting/kscript/pull/374/files
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
17 changes: 8 additions & 9 deletions src/main/kotlin/kscript/app/KscriptHandler.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package kscript.app

import kscript.app.appdir.AppDir
import kscript.app.appdir.Cache
import kscript.app.code.Templates
import kscript.app.creator.*
import kscript.app.model.Config
Expand All @@ -24,13 +24,12 @@ class KscriptHandler(private val config: Config, private val docopt: DocOptWrapp
info(DebugInfoCreator().create(config, kscriptArgs, userArgs))
}

// create kscript dir if it does not yet exist
val appDir = AppDir(config.osConfig.kscriptConfigDir)
val cache = Cache(config.osConfig.kscriptCacheDir)

// optionally clear up the jar cache
if (docopt.getBoolean("clear-cache")) {
info("Cleaning up cache...")
appDir.clearCache()
cache.clear()
return
}

Expand All @@ -50,7 +49,7 @@ class KscriptHandler(private val config: Config, private val docopt: DocOptWrapp
add(config.scriptingConfig.customPreamble)
}

val inputOutputResolver = InputOutputResolver(config.osConfig, appDir.cache)
val inputOutputResolver = InputOutputResolver(config.osConfig, cache)
val sectionResolver = SectionResolver(inputOutputResolver, Parser(), config.scriptingConfig)
val scriptResolver = ScriptResolver(inputOutputResolver, sectionResolver, config.scriptingConfig)

Expand All @@ -61,14 +60,14 @@ class KscriptHandler(private val config: Config, private val docopt: DocOptWrapp
}

val script = scriptResolver.resolve(scriptSource, preambles)
val resolvedDependencies = appDir.cache.getOrCreateDependencies(script.digest) {
val resolvedDependencies = cache.getOrCreateDependencies(script.digest) {
DependencyResolver(script.repositories).resolve(script.dependencies)
}
val executor = Executor(CommandResolver(config.osConfig), config.osConfig)

// Create temporary dev environment
if (docopt.getBoolean("idea")) {
val path = appDir.cache.getOrCreateIdeaProject(script.digest) { basePath ->
val path = cache.getOrCreateIdeaProject(script.digest) { basePath ->
val uriLocalPathProvider = { uri: URI -> inputOutputResolver.resolveContent(uri).localPath }
IdeaProjectCreator().create(basePath, script, userArgs, uriLocalPathProvider)
}
Expand All @@ -92,13 +91,13 @@ class KscriptHandler(private val config: Config, private val docopt: DocOptWrapp
throw IllegalStateException("@Entry directive is just supported for kt class files")
}

val jar = appDir.cache.getOrCreateJar(script.digest) { basePath ->
val jar = cache.getOrCreateJar(script.digest) { basePath ->
JarArtifactCreator(executor).create(basePath, script, resolvedDependencies)
}

//if requested try to package the into a standalone binary
if (docopt.getBoolean("package")) {
val path = appDir.cache.getOrCreatePackage(script.digest, script.scriptName) { basePath, packagePath ->
val path = cache.getOrCreatePackage(script.digest, script.scriptName) { basePath, packagePath ->
PackageCreator(executor).packageKscript(basePath, packagePath, script, jar)
}

Expand Down
20 changes: 0 additions & 20 deletions src/main/kotlin/kscript/app/appdir/AppDir.kt

This file was deleted.

9 changes: 9 additions & 0 deletions src/main/kotlin/kscript/app/appdir/Cache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import kscript.app.model.Content
import kscript.app.model.ScriptType
import kscript.app.util.*
import org.apache.commons.codec.digest.DigestUtils
import org.apache.commons.io.FileUtils
import java.net.URI

class Cache(private val cacheBasePath: OsPath) {
init {
cacheBasePath.createDirectories()
}

fun getOrCreateIdeaProject(digest: String, creator: (OsPath) -> OsPath): OsPath {
val path = cacheBasePath.resolve("idea_$digest")

Expand Down Expand Up @@ -99,4 +104,8 @@ class Cache(private val cacheBasePath: OsPath) {

return dependencies
}

fun clear() {
FileUtils.cleanDirectory(cacheBasePath.toNativeFile())
}
}
5 changes: 3 additions & 2 deletions src/main/kotlin/kscript/app/model/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ data class OsConfig(
val intellijCommand: String,
val gradleCommand: String,
val userHomeDir: OsPath,
val kscriptConfigDir: OsPath,
val kscriptConfigFile: OsPath,
val kscriptCacheDir: OsPath,
val kotlinHomeDir: OsPath,
) {
override fun toString(): String {
Expand All @@ -37,7 +38,7 @@ data class OsConfig(
| intellijCommand: $intellijCommand
| gradleCommand: $gradleCommand
| userHomeDir: $userHomeDir
| kscriptConfigDir: $kscriptConfigDir
| kscriptConfigFile: $kscriptConfigFile
| kotlinHomeDir: $kotlinHomeDir
|}
""".trimMargin()
Expand Down
93 changes: 75 additions & 18 deletions src/main/kotlin/kscript/app/model/ConfigBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package kscript.app.model

import kscript.app.util.OsPath
import kscript.app.util.ShellUtils
import kscript.app.util.exists
import kscript.app.util.toNativePath
import java.util.*
import kotlin.io.path.reader

class ConfigBuilder internal constructor() {
var osType: String? = null
var selfName: String? = null
var kscriptDir: OsPath? = null
var configFile: OsPath? = null
var cacheDir: OsPath? = null
var customPreamble: String? = null
var intellijCommand: String? = null
var gradleCommand: String? = null
Expand All @@ -24,33 +29,85 @@ class ConfigBuilder internal constructor() {
val osType = OsType.findOrThrow(requireNotNull(osType))

val selfName = selfName ?: System.getenv("KSCRIPT_NAME") ?: "kscript"
val kscriptDir = kscriptDir ?: OsPath.createOrThrow(
OsType.native, System.getenv("KSCRIPT_DIR") ?: (System.getProperty("user.home")!! + "/.kscript")
)
val customPreamble = customPreamble ?: System.getenv("KSCRIPT_PREAMBLE") ?: ""
val intellijCommand = intellijCommand ?: System.getenv("KSCRIPT_COMMAND_IDEA") ?: "idea"
val gradleCommand = gradleCommand ?: System.getenv("KSCRIPT_COMMAND_GRADLE") ?: "gradle"

val kotlinHome = kotlinHome ?: (System.getenv("KOTLIN_HOME") ?: ShellUtils.guessKotlinHome(osType))?.let {
OsPath.createOrThrow(OsType.native, it)
} ?: throw IllegalStateException("KOTLIN_HOME is not set and could not be inferred from context.")
val kotlinHome = kotlinHome
?: (System.getenv("KOTLIN_HOME") ?: ShellUtils.guessKotlinHome(osType))?.let {
OsPath.createOrThrow(OsType.native, it)
}
?: throw IllegalStateException("KOTLIN_HOME is not set and could not be inferred from context.")

val homeDir = homeDir ?: OsPath.createOrThrow(OsType.native, System.getProperty("user.home")!!)
val providedKotlinOpts = providedKotlinOpts ?: System.getenv("KSCRIPT_KOTLIN_OPTS") ?: ""
val repositoryUrl = repositoryUrl ?: System.getenv("KSCRIPT_REPOSITORY_URL") ?: ""
val repositoryUser = repositoryUser ?: System.getenv("KSCRIPT_REPOSITORY_USER") ?: ""
val repositoryPassword = repositoryPassword ?: System.getenv("KSCRIPT_REPOSITORY_PASSWORD") ?: ""
val homeDir = homeDir ?: OsPath.createOrThrow(osType, System.getProperty("user.home"))
val kscriptDir = System.getenv("KSCRIPT_DIR")?.let { OsPath.createOrThrow(osType, it) }
val configFile = configFile
?: kscriptDir?.resolve("kscript.properties")
?: osType.configsDir.resolve("kscript.properties")
val cacheDir = cacheDir
?: kscriptDir?.resolve("cache")
?: osType.cachesDir.resolve("kscript")

val osConfig = OsConfig(
osType, selfName, intellijCommand, gradleCommand, homeDir, kscriptDir, kotlinHome
osType,
selfName,
intellijCommand,
gradleCommand,
homeDir,
configFile,
cacheDir,
kotlinHome,
)

val properties = Properties().apply {
if (configFile.exists()) {
load(configFile.toNativePath().reader())
}
}
val customPreamble = customPreamble
?: System.getenv("KSCRIPT_PREAMBLE")
?: properties.getProperty("scripting.preamble")
?: ""
val providedKotlinOpts = providedKotlinOpts
?: System.getenv("KSCRIPT_KOTLIN_OPTS")
?: properties.getProperty("scripting.kotlin.opts")
?: ""
val repositoryUrl = repositoryUrl
?: System.getenv("KSCRIPT_REPOSITORY_URL")
?: properties.getProperty("scripting.repository.url")
?: ""
val repositoryUser = repositoryUser
?: System.getenv("KSCRIPT_REPOSITORY_USER")
?: properties.getProperty("scripting.repository.user")
?: ""
val repositoryPassword = repositoryPassword
?: System.getenv("KSCRIPT_REPOSITORY_PASSWORD")
?: properties.getProperty("scripting.repository.password")
?: ""

val scriptingConfig = ScriptingConfig(
customPreamble, providedKotlinOpts, repositoryUrl, repositoryUser, repositoryPassword
customPreamble,
providedKotlinOpts,
repositoryUrl,
repositoryUser,
repositoryPassword,
)

return Config(
osConfig, scriptingConfig
)
return Config(osConfig, scriptingConfig)
}

companion object {
private val OsType.configsDir
get() = when {
isWindowsLike() -> path(System.getenv("LOCALAPPDATA"))
else -> path(System.getenv("XDG_CONFIG_DIR") ?: "${System.getProperty("user.home")}/.config")
}

private val OsType.cachesDir
get() = when {
isWindowsLike() -> path(System.getenv("TEMP"))
else -> path(System.getenv("XDG_CACHE_DIR") ?: "${System.getProperty("user.home")}/.cache")
}

private fun OsType.path(path: String) = OsPath.createOrThrow(this, path)
}
}
36 changes: 36 additions & 0 deletions src/test/kotlin/kscript/app/model/ConfigBuilderTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package kscript.app.model

import assertk.assertThat
import assertk.assertions.isEqualTo
import kscript.app.util.OsPath
import org.junit.jupiter.api.Test

internal class ConfigBuilderTest {
@Test
fun `Reads all properties of ScriptingConfig from given file`() {
val linux = OsType.LINUX
val config = ConfigBuilder().apply {
osType = linux.osName
configFile = OsPath.createOrThrow(linux, "test", "resources", "config", "kscript.properties")
}.build()

assertThat(config.scriptingConfig).isEqualTo(ScriptingConfig(
customPreamble = """
// declare dependencies
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")

// make sure to also support includes in here
// @file:Include("util.kt")
@file:Include("https://raw.githubusercontent.com/holgerbrandl/kscript/master/test/resources/custom_dsl/test_dsl_include.kt")


// define some important variables to be used throughout the dsl
val foo = "bar"
""".trimIndent(),
providedKotlinOpts = "-J-Xmx4g",
providedRepositoryUrl = "https://repository.example",
providedRepositoryUser = "user",
providedRepositoryPassword = "password",
))
}
}
3 changes: 2 additions & 1 deletion src/test/kotlin/kscript/app/resolver/CommandResolverTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class CommandResolverTest {
"idea",
"gradle",
homeDir,
homeDir.resolve("./.kscript/"),
homeDir.resolve("./.config/"),
homeDir.resolve("./.cache/"),
kotlinDir,
)

Expand Down
15 changes: 15 additions & 0 deletions test/resources/config/kscript.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
scripting.preamble=// declare dependencies\n\
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")\n\
\n\
// make sure to also support includes in here\n\
// @file:Include("util.kt")\n\
@file:Include("https://raw.githubusercontent.com/holgerbrandl/kscript/master/test/resources/custom_dsl/test_dsl_include.kt")\n\
\n\
\n\
// define some important variables to be used throughout the dsl\n\
val foo = "bar"

scripting.kotlin.opts=-J-Xmx4g
scripting.repository.url=https://repository.example
scripting.repository.user=user
scripting.repository.password=password