Scripting enhancements for Kotlin

Overview

kscript - Having fun with Kotlin scripting

GitHub release Build Status Gitter

Enhanced scripting support for Kotlin on *nix-based systems.

Kotlin has some built-in support for scripting already but it is not yet feature-rich enough to be a viable alternative in the shell.

In particular this wrapper around kotlinc adds

  • Compiled script caching (using md5 checksums)
  • Dependency declarations using gradle-style resource locators and automatic dependency resolution with jcabi-aether
  • More options to provide scripts including interpreter mode, reading from stdin, local files or URLs
  • Embedded configuration for Kotlin runtime options
  • Support library to ease the writing of Kotlin scriptlets
  • Deploy scripts as stand-alone binaries

Taken all these features together, kscript provides an easy-to-use, very flexible, and almost zero-overhead solution to write self-contained mini-applications with Kotlin.

Good News: Kotlin v1.4 finally ships with a much improved - and needed - scripting integration. See here for examples and documentation. Still, we think that kscript has various benefits compared this new platform-bundled improved toolstack, so we'll plan to support kscript until the kotlin platform will ship with an even more rich and versatile kotlin scripting interpreter.


kscript presentation from KotlinConf2017!


Installation

To use kscript just Kotlin and Maven are required. To install Kotlin we recommend sdkman:

curl -s "https://get.sdkman.io" | bash     # install sdkman
source "$HOME/.sdkman/bin/sdkman-init.sh"  # add sdkman to PATH

sdk install kotlin                         # install Kotlin

Once Kotlin is ready, you can install kscript with

sdk install kscript

To test your installation simply run

kscript --help

This will check and inform about updates. To update kscript simply install it again as described above.

Run with docker

We provide an executable docker container to run kscript

# using the latest version of kscript
docker run -i holgerbrandl/kscript 'println("Hello, world!")'

# or using versioned container
docker run -i holgerbrandl/kscript:2.9.3 'println("Hello, world!")'

To use a script file outside of the container as input, you could do

docker run -i holgerbrandl/kscript - < script.kts

This will make kscript read the code from stdin while piping the file. Beware that the -i flag is needed to have stdout redirected outside the container.

Please note, that currently @Include are not supported when using a dockerized kscript. Also, any resource outside the container context may not be resolved correctly. To overcome this limitation, you could use for instance bind mounts.

Installation without sdkman

If you have Kotlin and Maven already and you would like to install the latest kscript release without using sdkman you can do so by unzipping the latest binary release. Don't forget to update your $PATH accordingly.

Installation with Homebrew

On MacOS you can install kscript also with Homebrew

brew install holgerbrandl/tap/kscript

To upgrade to latest version

brew update
brew upgrade holgerbrandl/tap/kscript

Installation on Arch Linux

On Arch Linux, kscript is available through the Arch Linux User repository (AUR). Use your favorite AUR helper to install, e.g. yay:

yay -S kscript

Build it yourself

To build kscript yourself, simply clone the repo and do

./gradlew assemble

## Run kscript from output dir
./build/libs/kscript

Script Input Modes

The main mode of operation is kscript <script>.

The <script> can be a Kotlin *.kts script file , a script URL, - for stdin, a process substitution file handle, a *.kt source file with a main method, or some kotlin code.

Interpreter Usage

To use kscript as interpreter for a script just point to it in the shebang line of your Kotlin scripts:

#!/usr/bin/env kscript

println("Hello from Kotlin!")
for (arg in args) {
    println("arg: $arg")
}

Inlined Usage

To use kscript in a workflow without creating an additional script file, you can also use one of its supported modes for inlined usage. The following modes are supported:

  • Directly provide a Kotlin scriptlet as argument
kscript 'println("hello world")'
  • Pipe a Kotlin snippet into kscript and instruct it to read from stdin by using - as script argument
echo '
println("Hello Kotlin.")
' |  kscript -
  • Using heredoc (preferred solution for inlining) which gives you some more flexibility to also use single quotes in your script:
kscript - <<"EOF"
println("It's a beautiful day!")
EOF
  • Since the piped content is considered as a regular script it can also have dependencies
kscript - <<"EOF"
//DEPS com.offbytwo:docopt:0.6.0.20150202 log4j:log4j:1.2.14

import org.docopt.Docopt
val docopt = Docopt("Usage: jl <command> [options] [<joblist_file>]")

println("hello again")
EOF
  • Finally (for sake of completeness), it also works with process substitution and for sure you can always provide additional arguments (exposed as args : Array<String> within the script)
kscript <(echo 'println("k-onliner")') arg1 arg2 arg3 

Inlined kscripts are also cached based on md5 checksum, so running the same snippet again will use a cached jar (sitting in ~/.kscript).

URL usage

To support remote scriplet repositories, kscript can also work with URLs. Consider the following hello-world-gist-scriptlet which is hosted on github (but any URL would work). To run it locally as a tool simply refer to it (here using the shortened raw-URL of the script for better readability)

kscript https://git.io/v1cG6 my argu ments 

To streamline the usage, the first part could be even aliased:

alias hello_kscript="kscript https://git.io/v1cG6"
hello_kscript my argu ments

Via this mechanism, kscript allows for easy integration of remotely hosted (mini) programs into data workflows.

URL-scripts are cached locally to speed up processing, and kscript --clear-cache can be used to wipe the cache if needed.

See this blogpost for a more extensive overview about URL support in kscript.

Script Configuration

The following directives supported by kscript to configure scripts:

  • //DEPS to declare dependencies with gradle-style locators
  • //KOTLIN_OPTS to configure the kotlin/java runtime environment
  • //INCLUDE to source kotlin files into the script
  • //ENTRY to declare the application entrypoint for kotlin *.kt applications

Declare dependencies with //DEPS

To specify dependencies simply use gradle-style locators. Here's an example using docopt and log4j

#!/usr/bin/env kscript
//DEPS com.offbytwo:docopt:0.6.0.20150202,log4j:log4j:1.2.14

import org.docopt.Docopt
import java.util.*


val usage = """
Use this cool tool to do cool stuff
Usage: cooltool.kts [options] <igenome> <fastq_files>...

Options:
 --gtf <gtfFile>     Custom gtf file instead of igenome bundled copy
 --pc-only           Use protein coding genes only for mapping and quantification
"""

val doArgs = Docopt(usage).parse(args.toList())

println("Hello from Kotlin!")
println("Parsed script arguments are: \n" + doArgs)

kscript will read dependencies from all lines in a script that start with //DEPS (if any). Multiple dependencies can be split by comma, space or semicolon.

Configure the runtime with //KOTLIN_OPTS

kscript allows to provide a //KOTLIN_OPTS directive followed by parameters passed on to kotlin similar to how dependencies are defined:

#!/usr/bin/env kscript
//KOTLIN_OPTS -J-Xmx5g  -J-server

println("Hello from Kotlin with 5g of heap memory running in server mode!")

Note: Similar to the runtime you can also tweak the compile step by providing //COMPILER_OPTS.

Ease prototyping with //INCLUDE

kscript supports an //INCLUDE directive to directly include other source files without prior compilation. Absolute and relative paths, as well as URLs are supported. Example:

//utils.kt
fun Array<Double>.median(): Double {
    val (lower, upper) = sorted().let { take(size / 2) to takeLast(size / 2) }
    return if (size % 2 == 0) (lower.last() + upper.first()) / 2.0 else upper.first()
}

Which can be now used using the //INCLUDE directive with

#!/usr/bin/env kscript

//INCLUDE utils.kt

val robustMean = listOf(1.3, 42.3, 7.).median()
println(robustMean)

The argument can be an URL, absolute or relative file path. Note that URLs used in include directives are cached locally to speed up processing, that is kscript won't fetch URLs again unless the user actively clears the cache with kscript --clear-cache.

For more examples see here.

Use //ENTRY to run applications with main method

kscript also supports running regular Kotlin kt files.

Example: ./examples/Foo.kt:

package examples

//ENTRY examples.Bar

class Bar{
    companion object {
        @JvmStatic fun main(args: Array<String>) {
            println("Foo was called")
        }
    }
}

fun main(args: Array<String>) = println("main was called")

To run top-level main instead we would use //ENTRY examples.FooKt

The latter is the default for kt files and could be omitted

Annotation driven script configuration

Using annotations instead of comment directives to configure scripts is cleaner and allow for better tooling.

// annotation-driven script configuration
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")

// comment directive
//DEPS com.github.holgerbrandl:kutils:0.12

To do so kscript supports annotations to be used instead of comment directives:

#!/usr/bin/env kscript

// Declare dependencies
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")
@file:DependsOn("com.beust:klaxon:0.24", "com.github.kittinunf.fuel:fuel:2.3.1")


// To use a custom maven repository you can declare it with
@file:MavenRepository("imagej-releases","http://maven.imagej.net/content/repositories/releases" )

// For compatibility with https://github.com/ligee/kotlin-jupyter kscript supports also
@file:DependsOnMaven("net.clearvolume:cleargl:2.0.1")
// Note that for compatibility reasons, only one locator argument is allowed for @DependsOnMaven


// also protected artifact repositories are supported, see <https://github.com/holgerbrandl/kscript/blob/master/test/TestsReadme.md#manual-testing>
// @file:MavenRepository("my-art", "http://localhost:8081/artifactory/authenticated_repo", user="auth_user", password="password")
// You can use environment variables for user and password when string surrounded by double {} brackets 
// @file:MavenRepository("my-art", "http://localhost:8081/artifactory/authenticated_repo", user="{{ARTIFACTORY_USER}}", password="{{ARTIFACTORY_PASSWORD}}")
// will be use 'ARTIFACTORY_USER' and 'ARTIFACTORY_PASSWORD' environment variables
// if the value doesn't found in the script environment  will fail

// Include helper scripts without deployment or prior compilation
@file:Include("util.kt")


// Define kotlin options
@file:KotlinOpts("-J-Xmx5g")
@file:KotlinOpts("-J-server")
@file:CompilerOpts("-jvm-target 1.8")

// declare application entry point (applies on for kt-files)
@file:EntryPoint("Foo.bar") 

print("1+1")

To enable the use of these annotations in Intellij, the user must add the following artifact to the project dependencies:

com.github.holgerbrandl:kscript-annotations:1.2

kscript will automatically detect an annotation-driven script, and if so will declare a dependency on this artifact internally.

Note, that if a script is located in a package other than the root package, you need to import the annotations with (e.g. import DependsOn).

Text Processing Mode

kscript can be used as a speedier and more flexible substitute for built-in terminal text tools such as awk or sed. Its text processing mode can be enabled with -t or --text. If so, kscript will

  • Declare com.github.holgerbrandl:kscript-support-api:1.2.5 as dependency for the script. This support library eases the writing of Kotlin scriptlets for text-processing. It includes solutions to common use-cases like argument parsing, data streaming, IO utilities, and various iterators to streamline the writing of scriptlets for text processing.
  • Import the kscript.* namespace
  • Define variable val lines = kscript.text.resolveArgFile(args) which returns an iterator over the lines in the first input argument of the script, or the standard input if no file arguments are provided to the script

This allows to to replace awkward constructs (or sed orperl) with kotlinesque solutions such as

cat some_file | kscript -t 'lines
    .filter { "^de0[-0]*".toRegex().matches(it) }
    .map { it + "foo:" }
    .print()
'

In this example, the extension method Iterable<String>.print() to print the lines to stdout comes from the support API. The rest is stdlib Kotlin.

For more examples using the support library see this blog post.

Treat yourself a REPL with --interactive

To create an interactive kotlin shell (aka REPL) with all script dependencies added to the classpath you can use --interactive.

For example, let's assume the following short script, named CountRecords.kts

#!/usr/bin/env kscript
@file:DependsOn("com.github.holgerbrandl:kutils:0.12")

import de.mpicbg.scicomp.bioinfo.openFasta

if (args.size != 1) {
    System.err.println("Usage: CountRecords <fasta>")
    kotlin.system.exitProcess(-1)
}

val records = openFasta(java.io.File(args[0]))
println(records.count())

To build a REPL that has the declared artifact in its classpath, we can just do

kscript --interactive CountRecords.kts

which will bring up the classpath-enhanced REPL:

Creating REPL from CountRecords.kts
Welcome to Kotlin version 1.1.51 (JRE 1.8.0_151-b12)
>>> import de.mpicbg.scicomp.bioinfo.openFasta
>>> 

Boostrap IDEA from a kscriptlet

Artifacts and versions will differ between scripts, so it is hard to maintain them all in a single project. To nevertheless provide optimal tooling when scripting with Kotlin kscript allows to create temporary projects for <script> arguments. .

kscript --idea CountRecords.kts

This will open IntelliJ IDEA with a minimalistic project containing just your (1) <script> and (2) a generated gradle.build file:

This assumes that you have the Intellij IDEA command line launcher idea in your PATH. It can be created in IntelliJ under Tools -> Create Command-line Launcher or you can set the command used to launch your intellij as KSCRIPT_IDEA_COMMAND env property

Deploy scripts as standalone binaries

To deploy a script simply do

kscript --package some_script.kts
./some_script --arg u ments

The created binary will contain a compiled copy of the script, as well as all declared dependencies (fatjar). Also runtime jvm parameters declared via @file:KotlinOpts are used to spin up the JVM.

Just java is required to run these binaries.

Embed kscript installer within your script

To make a script automatically install kscript and its dependencies on first run if necessary, run:

kscript --add-bootstrap-header some_script.kts

Now some_script.kts can be shared and run directly on any other machine that has bash, without having to go through the Installation steps first.

Note that unlike the --package option this doesn't produce a separate file, allowing the distributed script to be read and modified(including with kscript --idea) similar to what you might expect with bash/python/ruby scripts. On the other hand this doesn't embed dependencies within the script("fat jar"), so internet connection may be required on its first run.

FAQ

Why is kscript not calling the main method in my .kts script?

There is no need for a main method in a Kotlin script. Kotlin *.kts scripts can be more simplistic compared to more common kotlin *.kt source files. The former work without a main method by directly running the provided code from top to bottom. E.g.

print("hello kotlin!")

is a valid Kotlin kts script. Plain and simple, no main, no companion, just a few bits of code.

Does kscript also work for regular kotlin .kt source files with a main as entry point?

Yes, (since v1.6) you can run kotlin source files through kscript. By default it will assume a top-level main method as entry-point.

However in case you're using a companion object to declare the entry point, you need to indicate this via the //ENTRY/@file:Entry directive:

Why does it fail to read my script file when using cygwin?

In order to use cygwin you need to use windows paths to provide your scripts. You can map cygwin paths using cygpath. Example

kscript $(cygpath -w /cygdrive/z/some/path/my_script.kts)

What are performance and resource usage difference between scripting with kotlin and python?

Kotlin is a compiled language, so there is a compilation overhead when you run a script/application written in Kotlin for the first time.

Kotlin runs (mainly) on the JVM which needs some time (~200ms) to start up. In contrast, the python interpreter has close to zero warmup time.

I think there is a consensus that JVM programs execute much faster than python equivalents. Still, python might be faster depending on your specific usecase. Also, with kotlin-native becoming more mature, you could compile into native binaries directly, which should bring it close to C/C++ performance.

Main motivations for using Kotlin over Python for scripting and development are

  • Kotlin is the better designed, more fluent language with much better tooling around it
  • The JVM dependency ecosystem allows for strict versioning. No more messing around with virtualenv, e.g. to run a short 10liner against a specific version of numpy.

Does kscript work with java?

The only language supported by kscript is kotlin. For a similar approach centering around Java scripting see jbang.

Can I use custom artifact repositories?

Yes, via the @MavenRepository annotation. See annotations section or custom_mvn_repo_annot for a complete example

Support

Feel welcome to post ideas and suggestions to our tracker.

More advanced use-cases are documented in the complementary user guide

How to contribute?

We always welcome pull requests and trouble tickets. :-)

Help to spread the word. Great community articles about kscript include

You could also show your support by upvoting kscript here on github, or by voting for issues in Intellij IDEA which impact kscripting. Here are our top 2 tickets/annoyances that we would love to see fixed:

  • KT-13347 Good code is red in injected kotlin language snippets

To allow for more interactive script development, you could also vote/comment on the most annoying REPL issues.

  • KT-24789 "Unresolved reference" when running a script which is a symlink to a script outside of source roots
  • KT-12583 IDE REPL should run in project root directory
  • KT-11409 Allow to "Send Selection To Kotlin Console"

Acknowledgements

The initial version of kscript was kindly contributed by Oscar Gonzalez.

Special thanks to Ilan Pillemer, Andrey Mischenko , Stephen Byrne, Eugene Susla, Eli Hart, Hwijae Lee and oshai for contributing PRs to this repo.

Thanks also to the Scionics Computer Innovation GmbH and the MPI-CBG for supporting this project.

kscript was inspired by kotlin-script which is another great way (now deprecated) to do scripting in Kotlin.

Comments
  • Dependencies are working only with jdk8

    Dependencies are working only with jdk8

    Using >8 JDK everything is working except dependency resolution:

    [kscript] Resolving dependencies...
    [kscript]     Resolving "org.openjsse:openjsse:1.1.0"...Exception in thread "main" java.lang.NoClassDefFoundError: org/ietf/jgss/GSSException
    	at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.<clinit>(NettyAsyncHttpProvider.java:177)
    	at org.sonatype.aether.connector.async.AsyncRepositoryConnector.getDefaultProvider(AsyncRepositoryConnector.java:246)
    	at org.sonatype.aether.connector.async.AsyncRepositoryConnector.getProvider(AsyncRepositoryConnector.java:241)
    	at org.sonatype.aether.connector.async.AsyncRepositoryConnector.<init>(AsyncRepositoryConnector.java:154)
    	at org.sonatype.aether.connector.async.AsyncRepositoryConnectorFactory.newInstance(AsyncRepositoryConnectorFactory.java:106)
    	at org.sonatype.aether.impl.internal.DefaultRemoteRepositoryManager.getRepositoryConnector(DefaultRemoteRepositoryManager.java:346)
    	at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:453)
    	at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:216)
    	at org.sonatype.aether.impl.internal.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:193)
    	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:281)
    	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:186)
    	at org.sonatype.aether.impl.internal.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:191)
    	at org.sonatype.aether.impl.internal.DefaultRepositorySystem.resolveDependencies(DefaultRepositorySystem.java:333)
    	at com.jcabi.aether.Aether.fetch(Aether.java:228)
    	at com.jcabi.aether.Aether.resolve_aroundBody2(Aether.java:180)
    	at com.jcabi.aether.Aether$AjcClosure3.run(Aether.java:1)
    	at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149)
    	at com.jcabi.aspects.aj.MethodLogger.wrap(MethodLogger.java:208)
    	at com.jcabi.aspects.aj.MethodLogger.ajc$inlineAccessMethod$com_jcabi_aspects_aj_MethodLogger$com_jcabi_aspects_aj_MethodLogger$wrap(MethodLogger.java:1)
    	at com.jcabi.aspects.aj.MethodLogger.wrapClass(MethodLogger.java:136)
    	at com.jcabi.aether.Aether.resolve(Aether.java:177)
    	at com.jcabi.aether.Aether.resolve_aroundBody0(Aether.java:163)
    	at com.jcabi.aether.Aether$AjcClosure1.run(Aether.java:1)
    	at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149)
    	at com.jcabi.aspects.aj.MethodLogger.wrap(MethodLogger.java:208)
    	at com.jcabi.aspects.aj.MethodLogger.ajc$inlineAccessMethod$com_jcabi_aspects_aj_MethodLogger$com_jcabi_aspects_aj_MethodLogger$wrap(MethodLogger.java:1)
    	at com.jcabi.aspects.aj.MethodLogger.wrapClass(MethodLogger.java:136)
    	at com.jcabi.aether.Aether.resolve(Aether.java:156)
    	at kscript.app.DependencyUtilKt.resolveDependenciesViaAether(DependencyUtil.kt:86)
    	at kscript.app.DependencyUtilKt.resolveDependencies(DependencyUtil.kt:53)
    	at kscript.app.KscriptKt.main(Kscript.kt:158)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    	at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:61)
    	at org.jetbrains.kotlin.runner.Main.run(Main.kt:110)
    	at org.jetbrains.kotlin.runner.Main.main(Main.kt:120)
    Caused by: java.lang.ClassNotFoundException: org.ietf.jgss.GSSException
    	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:436)
    	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    	... 38 more
    

    A first bug was reported #233

    jdk8 is 5 years old and some people prefer to use newer versions of jdk.

    bug help wanted 
    opened by neworld 49
  • the released 4.0.0 version can not download dependency from maven repo, back to 3.1.0 runs ok

    the released 4.0.0 version can not download dependency from maven repo, back to 3.1.0 runs ok

    [kscript] Resolving wu.seal:kscript-tool:1.0.13... [kscript] Resolving com.google.code.gson:gson:2.8.9... [kscript] [ERROR] Failed while connecting to the server. Check the connection (http/https, port, proxy, credentials, etc.) of your maven dependency locators. If you suspect this is a bug, you can create an issue on https://github.com/holgerbrandl/kscriptFile 'wu.seal:kscript-tool:1.0.13' not found [kscript] [ERROR] org.eclipse.aether.resolution.DependencyResolutionException: Failed to read artifact descriptor for wu.seal:kscript-tool:jar:1.0.13 [kscript] [ERROR] org.eclipse.aether.resolution.DependencyResolutionException: Failed to read artifact descriptor for wu.seal:kscript-tool:jar:1.0.13

    bug 
    opened by Nvsleep 24
  • kscript doesn't appear to work with Clikt and Kotlin 1.4.10

    kscript doesn't appear to work with Clikt and Kotlin 1.4.10

    I get this cryptic NoSuchMethodError with Kotlin 1.4.10...works fine if I back down to 1.3.72

    Exception in thread "main" java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    	at Main_Scriptlet_a9f5a3bb1e4ba312$Companion.main(Main_Scriptlet_a9f5a3bb1e4ba312.kt:6)
    	at Main_Scriptlet_a9f5a3bb1e4ba312.main(Main_Scriptlet_a9f5a3bb1e4ba312.kt)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:64)
    	at org.jetbrains.kotlin.runner.Main.run(Main.kt:149)
    	at org.jetbrains.kotlin.runner.Main.main(Main.kt:159)
    Caused by: java.lang.NoSuchMethodError: kotlin.jvm.internal.PropertyReference1Impl.<init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
    	at Scriptlet_a9f5a3bb1e4ba312$SonarqubeAnalyzer.<clinit>(scriptlet.a9f5a3bb1e4ba312.kts)
    
    bug 
    opened by kenyee 24
  • Updating to 2.7 breaks dependency resolution

    Updating to 2.7 breaks dependency resolution

    It looks like the update to 2.7 (with the new dependency resolution mechanism) is not working. The example script here worked just fine in 2.5, but in 2.7 I get some java.lang.NoClassDefFoundError errors.

    Here's the full output:

    [kscript] Resolving dependencies...
    [kscript]     Resolving io.github.javaeden.orchid:OrchidAll:0.16.1...Done
    [kscript]     Resolving com.github.holgerbrandl:kscript-annotations:1.2...Done
    [kscript] Dependencies resolved
    Using the following modules:
    --------------------
     * com.eden.orchid.StandardModule
    
    Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at Main_Start$Companion.main(Main_Start.kt:6)
        at Main_Start.main(Main_Start.kt)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:61)
        at org.jetbrains.kotlin.runner.Main.run(Main.kt:109)
        at org.jetbrains.kotlin.runner.Main.main(Main.kt:119)
    Caused by: java.lang.NoClassDefFoundError: com/vladsch/flexmark/ext/aside/AsideExtension
        at com.eden.orchid.impl.compilers.markdown.FlexmarkModule.configure(FlexmarkModule.kt:19)
        at com.google.inject.AbstractModule.configure(AbstractModule.java:61)
        at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
        at com.google.inject.AbstractModule.install(AbstractModule.java:103)
        at com.eden.orchid.api.registration.ClasspathModuleInstaller.lambda$configure$0(ClasspathModuleInstaller.java:28)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at com.eden.orchid.api.registration.ClasspathModuleInstaller.configure(ClasspathModuleInstaller.java:23)
        at com.google.inject.AbstractModule.configure(AbstractModule.java:61)
        at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
        at com.google.inject.AbstractModule.install(AbstractModule.java:103)
        at com.eden.orchid.StandardModule.configure(StandardModule.kt:34)
        at com.google.inject.AbstractModule.configure(AbstractModule.java:61)
        at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
        at com.google.inject.spi.Elements.getElements(Elements.java:103)
        at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:137)
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
        at com.google.inject.Guice.createInjector(Guice.java:87)
        at com.google.inject.Guice.createInjector(Guice.java:69)
        at com.eden.orchid.Orchid.start(Orchid.java:83)
        at Start.<init>(start.kts:45)
        ... 13 more
    Caused by: java.lang.ClassNotFoundException: com.vladsch.flexmark.ext.aside.AsideExtension
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 33 more
    

    This issue was initially discussed on the Orchid Gitter chat.

    bug 
    opened by cjbrooks12 24
  • dependency notation does not support maven version range syntax containing `)` and `,`

    dependency notation does not support maven version range syntax containing `)` and `,`

    EDIT: Maven supports version ranges natively: examples: http://www.mojohaus.org/versions-maven-plugin/examples/resolve-ranges.html an it works in kscript once the annotation and comment parsing is not messing up on , and )

    old issue content:

    i am writing a library and tool that i try to make compatilble / consumable by kscript the versions are pushed to maven by jenkins , each git commit increments the build number

    ideally i would like to use

    @file:DependsOnMaven("moe.nikky.voodoo:dsl:0.4.0+")
    

    instead of

    @file:DependsOnMaven("moe.nikky.voodoo:dsl:0.4.0-132")
    
    opened by NikkyAI 24
  • Redesign of kscript

    Redesign of kscript

    Hi!

    This is a redesign of kscript. The main goal is to split kscript into smaller pieces based on object-oriented design to allow easier modifications of kscript in the future.

    This rewrite is not yet finished (since draft PR), but most of the cases are already working correctly. I will prepare a detailed changelog later, but for now, it would be nice if you can review the changes.

    Currently, only the new UT do not work, but the whole test_suite is working as previously (packaging and idea tests are failing).

    This is a huge refactor, but please have a look - I believe it is worthy to apply it as it will make modifications much, much easier. Not yet finished as I mentioned before, but if you like it I am able to devote some more time to accomplish changes.

    Probably a candidate for version 4.0-beta because of the scope of changes.

    opened by aartiPl 22
  • Unable to pull dependencies

    Unable to pull dependencies

    I wrote a simple script with a simple dependency to 'com.opencsv:opencsv:4.6'. I get the following error message:

    [kscript] Resolving dependencies...
    [kscript]     Resolving com.opencsv:opencsv:4.6...[kscript] [ERROR] Failed while connecting to the server. 
        Check the connection (http/https, port, proxy, credentials, etc.) of your maven dependency locators. 
        If you suspect this is a bug, you can create an issue on https://github.com/holgerbrandl/kscript
    [kscript] [ERROR] Exception: org.sonatype.aether.resolution.DependencyResolutionException: 
        failed to load 'com.opencsv:opencsv:jar:4.6 (runtime)' from 
            [
                "maven (https://maven.<company>.net/content/groups/public, releases+snapshots) without authentication", 
                "maven (https://maven.<company>.net/content/groups/public, releases+snapshots) without authentication"
            ] into /Users/<my_user>/.m2/repository
    

    Is it possible to have a clearer error message on what could be causing this, the repository urls work perfectly on maven and gradle, and I can't seem to find a reason for kscript to fail on resolving the dependencies.

    bug enhancement help wanted 
    opened by andrealexandre 22
  • #49 use jcabi-aether for dependency resolving

    #49 use jcabi-aether for dependency resolving

    Sample output:

    $ kscript /home/neonew/Schreibtisch/kscript/test/resources/depends_on_with_type.kts
    [kscript] Resolving dependencies...
    [kscript]     Resolving org.javamoney:moneta:[email protected]
    [kscript]     Resolving com.github.holgerbrandl:kscript-annotations:1.2...Done
    [kscript] Dependencies resolved
    getBigDecimal(1L): 1
    
    • Updated shadow plugin to 2.0.4 (otherwise the build is extremely slow)
    • Resulting kscript.jar went from 122kb -> 18.5mb :(
    • I've excluded some (unused?) dependencies to strip it down to 5.1mb
    • No requirement for mvn anymore

    Some excludes were even needed, otherwise we would see: Sep 07, 2018 4:03:24 AM org.hibernate.validator.internal.util.Version INFO: HV000001: Hibernate Validator 5.1.2.Final SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

    Feedback is welcomed.

    opened by andreas-mausch 21
  • Kscript is broken on ArchLinux

    Kscript is broken on ArchLinux

    Installed from the AUR.

    Error message:

    $ kscript 'println("Hello world")'
    /usr/bin/kscript: line 49: /usr/share/kotlin/bin/kotlin: No such file or directory
    

    Correct path to the Kotlin binary:

    $ command -v kotlin
    /usr/bin/kotlin
    

    I don't really know what information could be of use, don't hesitate to ask for specific information you need.

    help wanted 
    opened by CLOVIS-AI 19
  • Compile native version using graal, reducing startup time to almost 0

    Compile native version using graal, reducing startup time to almost 0

    Without this, kscript --help takes 0.6 to 0.9 seconds. With this, it takes 0.02 seconds 🎉

    This still needs to be integrated into the release script, but for now you can use it by running ./gradlew nativeImage, then using the binary at ./build/graal/kscript-native.

    help wanted 
    opened by russelldavis 18
  • Windows support with scoop installer without bash

    Windows support with scoop installer without bash

    I tried to use this from windows. Unfortunately it needs a bash environment. I know that this is the intended purpose for this project.

    I created a simple scoop installer but with a jar created from https://github.com/hj-lee/kscript (thanks @hj-lee ).

    scoop add bucket raisercostin https://github.com/raisercostin/raiser-scoop-bucket
    scoop install kscript
    
    

    After that I was able to execute scripts with dependencies from windows without any bash help via a simple kscript hello.ks.

    How can I help to have an official release with the merge from @hj-lee fork?

    opened by raisercostin 17
  • Kscript-release.sh: Create symlinks in PKGBUILD

    Kscript-release.sh: Create symlinks in PKGBUILD

    Create symlinks, if kotlin binary files installed in /usr/bin and not in /usr/share/kotlin/bin (it's true with official kotlin package).

    This should fix #371

    opened by DareFox 0
  • KScript release process

    KScript release process

    Maybe we can create a GitHub organization named: kotlin-scripting and transfer kscript to that organization? Then we could build a release process around a new organization (user names/passwords).

    I have also an idea for yet another project - Kotlin wrapper around bash commands. It will allow to finally get rid of bash from user space. At least I hope for that ;-)

    'kotlin-scripting' organization could be hosting place for that project also.

    Please comment with your suggestions/ideas.

    opened by aartiPl 2
  • Publish to Maven

    Publish to Maven

    Would it be possible to publish the jar to maven?

    I would like to create a Python wrapper as mentioned on https://github.com/holgerbrandl/kscript/issues/362 , and ideally want to be able to fetch and run the latest jar using https://github.com/scijava/jgo .

    I see a bunch of stuff in https://search.maven.org/search?q=g:com.github.holgerbrandl , including some kscript artifact, but they dont look like the main jar.

    opened by jayvdb 6
  • Kotlin options in script don't make it into packaging

    Kotlin options in script don't make it into packaging

    This line https://github.com/holgerbrandl/kscript/blob/dc827753adf707cf31cd220716e85139cae2d9cd/src/main/kotlin/kscript/app/code/GradleTemplates.kt#L44 fails to pick up Kotlin options declared like this: https://github.com/holgerbrandl/kscript/blob/dc827753adf707cf31cd220716e85139cae2d9cd/test/resources/package_example.kts#L1

    I see that the Script has these two fields: https://github.com/holgerbrandl/kscript/blob/dc827753adf707cf31cd220716e85139cae2d9cd/src/main/kotlin/kscript/app/model/Script.kt#L21-L22 However the kotlinOpts seems not to be used, at least in the Gradle template generation, How come?

    opened by vsajip 3
Releases(v4.2.0-RC1)
Owner
Holger Brandl
machine learning & data science enthusiast.
Holger Brandl
A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

common sense OSS 0 Jan 20, 2022
Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in Kotlin with Jetpack Compose and a backed in Kotlin hosted on AppEngine.

Conferences4Hall Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in K

Gérard Paligot 98 Dec 15, 2022
Android + Kotlin + Github Actions + ktlint + Detekt + Gradle Kotlin DSL + buildSrc = ❤️

kotlin-android-template ?? A simple Github template that lets you create an Android/Kotlin project and be up and running in a few seconds. This templa

Nicola Corti 1.5k Jan 3, 2023
LifecycleMvp 1.2 0.0 Kotlin is MVP architecture implementation with Android Architecture Components and Kotlin language features

MinSDK 14+ Download Gradle Add to project level build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' }

Robert 20 Nov 9, 2021
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
👋 A common toolkit (utils) ⚒️ built to help you further reduce Kotlin boilerplate code and improve development efficiency. Do you think 'kotlin-stdlib' or 'android-ktx' is not sweet enough? You need this! 🍭

Toolkit [ ?? Work in progress ⛏ ?? ??️ ?? ] Snapshot version: repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") }

凛 35 Jul 23, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022
Provides Kotlin libs and some features for building Kotlin plugins

Kotlin Plugin Provides Kotlin libs and some features for building awesome Kotlin plugins. Can be used instead of CreeperFace's KotlinLib (don't use to

null 3 Dec 24, 2021
Notes-App-Kotlin - Notes App Built Using Kotlin

Notes-App-Kotlin Splash Screen Home Page Adding New Notes Filter Feature Search

Priyanka 4 Oct 2, 2022
Kotlin-client-dsl - A kotlin-based dsl project for a (Client) -> (Plugin) styled program

kotlin-client-dsl a kotlin-based dsl project for a (Client) -> (Plugin) styled p

jackson 3 Dec 10, 2022
A Kotlin Native program to show the time since a date, using Kotlin LibUI

TimeSince A Kotlin Native program to show the time since a date, using Kotlin LibUI Report Bug . Request Feature About The Project TimeSince is a Kotl

Russell Banks 2 May 6, 2022
RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

Alex 27 Jan 1, 2023
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Practical Kotlin Multiplatform on the Web 본 저장소는 코틀린 멀티플랫폼 기반 웹 프로그래밍 워크숍(강좌)을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 워크숍 과정에서 코틀린 멀티플랫폼을 기반으로 프론트엔드(front-end)는 Ko

SpringRunner 14 Nov 5, 2022
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Building a Full Stack Web App with Kotlin Multiplatform 본 저장소는 INFCON 2022에서 코틀린 멀티플랫폼 기반 웹 프로그래밍 핸즈온랩을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 핸즈온 과정에서 코틀린 멀티플랫폼을

Arawn Park 19 Sep 8, 2022
Kotlin library for Android

KAndroid Kotlin library for Android providing useful extensions to eliminate boilerplate code in Android SDK and focus on productivity. Download Downl

Paweł Gajda 890 Nov 13, 2022
Type-safe time calculations in Kotlin, powered by generics.

Time This library is made for you if you have ever written something like this: val duration = 10 * 1000 to represent a duration of 10 seconds(in mill

Kizito Nwose 958 Dec 10, 2022
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.

NotyKT ??️ NotyKT is the complete Kotlin-stack note taking ??️ application ?? built to demonstrate a use of Kotlin programming language in server-side

Shreyas Patil 1.4k Jan 4, 2023
A Kotlin DSL wrapper around the mikepenz/MaterialDrawer library.

MaterialDrawerKt Create navigation drawers in your Activities and Fragments without having to write any XML, in pure Kotlin code, with access to all t

Márton Braun 517 Nov 19, 2022
Kotlin-based modern RecyclerView rendering weapon

Read this in other languages: 中文, English, Changelog Yasha Item introduction: Kotlin-based modern RecyclerView rendering weapon Item Features: No Adap

Season 514 Dec 21, 2022