diff --git a/build.gradle b/build.gradle
index c62c6fde7..d93d9dbd7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -44,7 +44,6 @@ allprojects {
project.getProperty('installPath') :
Paths.get(System.properties['user.home'].toString(), ".ipython", "kernels", "kotlin").toAbsolutePath().toString()
ext.debugPort = 1044
- ext.configFile = "config.json"
ext.debuggerConfig = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$debugPort"
}
@@ -69,6 +68,7 @@ dependencies {
compile "org.apache.maven:maven-core:3.0.3"
compile 'org.slf4j:slf4j-api:1.7.25'
+ compile "khttp:khttp:1.0.0"
compile 'org.zeromq:jeromq:0.3.5'
compile 'com.beust:klaxon:5.2'
runtime 'org.slf4j:slf4j-simple:1.7.25'
@@ -117,7 +117,7 @@ void createTaskForSpecs(Boolean debug) {
} .join(File.pathSeparator)
spec = substitute(spec, "RUNTIME_CLASSPATH", libsCp)
spec = substitute(spec, "DEBUGGER_CONFIG", debug ? "\"$debuggerConfig\"," : "")
- spec = substitute(spec, "LIBRARIES_PATH", "$installPath$sep$configFile")
+ spec = substitute(spec, "KERNEL_HOME", "$installPath")
File installDir = new File("$installPath")
if (!installDir.exists()) {
installDir.mkdirs();
@@ -138,9 +138,9 @@ static String substitute(String spec, String template, String val) {
return spec.replace("\${$template}", val.replace("\\", "\\\\"))
}
-task copyLibrariesConfig(type: Copy, dependsOn: cleanInstallDir) {
- from configFile
- into installPath
+task copyLibraries(type: Copy, dependsOn: cleanInstallDir) {
+ from "libraries"
+ into Paths.get(installPath, "libraries").toString()
}
createTaskForSpecs(true)
@@ -151,8 +151,8 @@ task installLibs(type: Copy, dependsOn: cleanInstallDir) {
from configurations.deploy
}
-task install(dependsOn: [installKernel, installLibs, createSpecs, copyLibrariesConfig]) {
+task install(dependsOn: [installKernel, installLibs, createSpecs, copyLibraries]) {
}
-task installDebug(dependsOn: [installKernel, installLibs, createDebugSpecs, copyLibrariesConfig]) {
+task installDebug(dependsOn: [installKernel, installLibs, createDebugSpecs, copyLibraries]) {
}
diff --git a/config.json b/config.json
deleted file mode 100644
index 46c31cee6..000000000
--- a/config.json
+++ /dev/null
@@ -1,184 +0,0 @@
-{
- "repositories": [
- "https://jcenter.bintray.com/",
- "https://repo.maven.apache.org/maven2/",
- "https://jitpack.io"
- ],
- "libraries": [
- {
- "name": "klaxon(v=5.2)",
- "dependencies": [
- "com.beust:klaxon:$v"
- ],
- "imports": [
- "com.beust.klaxon.*"
- ],
- "link": "https://github.com/cbeust/klaxon"
- },
- {
- "name": "lets-plot",
- "link": "https://github.com/JetBrains/lets-plot-kotlin",
- "repositories": [
- "https://jetbrains.bintray.com/lets-plot-maven"
- ],
- "dependencies": [
- "org.jetbrains.lets-plot:lets-plot-common:1.0.1-SNAPSHOT",
- "org.jetbrains.lets-plot:lets-plot-kotlin-api:0.0.8-SNAPSHOT",
- "org.jetbrains.lets-plot:kotlin-frontend-api:0.0.8-SNAPSHOT",
- "org.jetbrains.lets-plot:lets-plot-jfx:1.0.1-SNAPSHOT"
- ],
- "imports": [
- "jetbrains.letsPlot.*",
- "jetbrains.letsPlot.geom.*",
- "jetbrains.letsPlot.stat.*"
- ],
- "init": [
- "fun jetbrains.letsPlot.intern.Plot.getHtml() = jetbrains.letsPlot.intern.frontendContext.FrontendContextUtil.getHtml(this)",
- "DISPLAY(HTML(jetbrains.datalore.jupyter.configureScript()))"
- ],
- "renderers": [
- {
- "class": "jetbrains.letsPlot.intern.Plot",
- "result": "HTML(($it as jetbrains.letsPlot.intern.Plot).getHtml())"
- }
- ]
- },
- {
- "name": "krangl(v=-SNAPSHOT)",
- "dependencies": [
- "com.github.holgerbrandl:krangl:$v"
- ],
- "imports": [
- "krangl.*"
- ],
- "init": [
- "fun krangl.DataFrame.toHTML(limit: Int = 20, truncate: Int = 50) : String\n{val sb = StringBuilder()\nsb.append(\"
\")\nsb.append(\"\")\ncols.forEach { sb.append(\"| ${it.name} | \") }\nsb.append(\"
\")\nrows.take(limit).forEach {\n sb.append(\"\")\n it.values.map{it.toString()}.forEach { \n val truncated = if (truncate > 0 && it.length > truncate) {\n if (truncate < 4) it.substring(0, truncate)\n else it.substring(0, truncate - 3) + \"...\"\n } else {\n it\n }\n sb.append(\"\"\"| $truncated | \"\"\") \n }\n sb.append(\"
\")\n}\nsb.append(\"
\")\nif(limit < rows.count())\n sb.append(\"... only showing top $limit rows
\")\nsb.append(\"\")\nreturn sb.toString()}"
- ],
- "renderers": [
- {
- "class": "krangl.SimpleDataFrame",
- "result": "HTML($it.toHTML())"
- }
- ],
- "link": "https://github.com/holgerbrandl/krangl"
- },
- {
- "name": "kotlin-statistics(v=-SNAPSHOT)",
- "dependencies": [
- "com.github.thomasnield:kotlin-statistics:$v"
- ],
- "imports": [
- "org.nield.kotlinstatistics.*"
- ],
- "link": "https://github.com/thomasnield/kotlin-statistics"
- },
- {
- "name": "kravis(v=-SNAPSHOT)",
- "dependencies": [
- "com.github.holgerbrandl:kravis:$v"
- ],
- "imports": [
- "kravis.*"
- ],
- "renderers": [
- {
- "class": "kravis.GGPlot",
- "result": "$it.show()"
- }
- ],
- "link": "https://github.com/holgerbrandl/kravis"
- },
- {
- "name": "spark(scala=2.11.12,spark=2.4.4)",
- "dependencies": [
- "org.apache.spark:spark-mllib_2.11:$spark",
- "org.apache.spark:spark-sql_2.11:$spark",
- "org.apache.spark:spark-repl_2.11:$spark",
- "org.apache.spark:spark-streaming-flume-assembly_2.11:$spark",
- "org.apache.spark:spark-graphx_2.11:$spark",
- "org.apache.spark:spark-launcher_2.11:$spark",
- "org.apache.spark:spark-catalyst_2.11:$spark",
- "org.apache.spark:spark-streaming_2.11:$spark",
- "org.apache.spark:spark-core_2.11:$spark",
- "org.scala-lang:scala-library:$scala",
- "org.scala-lang:scala-reflect:$scala",
- "org.scala-lang:scala-compiler:$scala",
- "org.scala-lang.modules:scala-xml_2.11:1.2.0",
- "commons-io:commons-io:2.5"
- ],
- "imports": [
- "org.apache.spark.sql.*",
- "org.apache.spark.api.java.*",
- "org.apache.spark.ml.feature.*",
- "org.apache.spark.sql.functions.*"
- ],
- "init": [
- "org.apache.log4j.Logger.getLogger(\"org\").setLevel(org.apache.log4j.Level.OFF)",
- "org.apache.log4j.Logger.getLogger(\"akka\").setLevel(org.apache.log4j.Level.OFF)",
- "val spark = SparkSession\n .builder()\n .appName(\"Spark example\")\n .master(\"local\")\n .getOrCreate()",
- "val sc = spark.sparkContext()",
- "%dumpClassesForSpark",
- "fun Dataset.toHTML(limit: Int = 20, truncate: Int = 50): String {\n val sb = StringBuilder()\n\n sb.append(\"\")\n sb.append(\"\"\"\"\"\")\n sb.append(schema().fieldNames().map { \"| ${it} | \"}.joinToString(\"\"))\n sb.append(\"
\")\n\n limit(limit).collectAsList().forEach { row ->\n sb.append(\"\")\n (0 until row.size()).map {\n row[it].toString()\n }.forEach {\n val truncated = if (truncate > 0 && it.length > truncate) {\n if (truncate < 4) it.substring(0, truncate)\n else it.substring(0, truncate - 3) + \"...\"\n } else {\n it\n }\n sb.append(\"\"\"| $truncated | \"\"\")\n }\n sb.append(\"
\")\n }\n sb.append(\"
\")\n if(limit < count())\n sb.append(\"... only showing top $limit rows
\")\n sb.append(\"\")\n return sb.toString()\n}"
- ],
- "initCell": [
- "scala.Console.setOut(System.out)",
- "scala.Console.setErr(System.err)"
- ],
- "renderers": [
- {
- "class": "org.apache.spark.sql.Dataset",
- "result": "HTML($it.toHTML())"
- }
- ]
- },
- {
- "name": "gral(v=0.11)",
- "link": "https://github.com/eseifert/gral",
- "dependencies": [
- "de.erichseifert.gral:gral-core:$v"
- ],
- "imports": [
- "de.erichseifert.gral.data.*",
- "de.erichseifert.gral.data.filters.*",
- "de.erichseifert.gral.graphics.*",
- "de.erichseifert.gral.plots.*",
- "de.erichseifert.gral.plots.lines.*",
- "de.erichseifert.gral.plots.points.*",
- "de.erichseifert.gral.util.*"
- ],
- "init": [
- "fun T.show(sizeX: Double, sizeY: Double): Any {\n val writer = de.erichseifert.gral.io.plots.DrawableWriterFactory.getInstance().get(\"image/svg+xml\")\n\n val buf = java.io.ByteArrayOutputStream()\n\n writer.write(this, buf, sizeX, sizeY)\n\n return MIME(writer.mimeType to buf.toString())\n}"
- ]
- },
- {
- "name": "kmath(v=0.1.3)",
- "link": "https://github.com/mipt-npm/kmath",
- "repositories": [
- "https://dl.bintray.com/mipt-npm/scientifik"
- ],
- "dependencies": [
- "scientifik:kmath-core-jvm:$v"
- ],
- "imports": [
- "scientifik.kmath.linear.*",
- "scientifik.kmath.operations.*",
- "scientifik.kmath.structures.*"
- ]
- },
- {
- "name": "koma(v=0.12)",
- "link": "https://koma.kyonifer.com/index.html",
- "repositories": [
- "https://dl.bintray.com/kyonifer/maven"
- ],
- "dependencies": [
- "com.kyonifer:koma-core-ejml:$v",
- "com.kyonifer:koma-plotting:$v"
- ],
- "imports": [
- "koma.*",
- "koma.extensions.*"
- ]
- }
- ]
-}
diff --git a/kernelspec/kernel.json.template b/kernelspec/kernel.json.template
index 8660d2f16..fdf4a8922 100644
--- a/kernelspec/kernel.json.template
+++ b/kernelspec/kernel.json.template
@@ -1,5 +1,5 @@
{
- "argv": [ "java", "-jar", ${DEBUGGER_CONFIG} "${KERNEL_JAR_PATH}", "{connection_file}", "-cp=${RUNTIME_CLASSPATH}", "-libs=${LIBRARIES_PATH}"],
+ "argv": [ "java", "-jar", ${DEBUGGER_CONFIG} "${KERNEL_JAR_PATH}", "{connection_file}", "-cp=${RUNTIME_CLASSPATH}", "-home=${KERNEL_HOME}"],
"display_name": "Kotlin",
"language": "kotlin"
}
\ No newline at end of file
diff --git a/libraries/.properties b/libraries/.properties
new file mode 100644
index 000000000..045e6eae5
--- /dev/null
+++ b/libraries/.properties
@@ -0,0 +1 @@
+formatVersion=1
\ No newline at end of file
diff --git a/libraries/gral.json b/libraries/gral.json
new file mode 100644
index 000000000..83eeaf2d8
--- /dev/null
+++ b/libraries/gral.json
@@ -0,0 +1,21 @@
+{
+ "properties": {
+ "v": "0.11"
+ },
+ "link": "https://github.com/eseifert/gral",
+ "dependencies": [
+ "de.erichseifert.gral:gral-core:$v"
+ ],
+ "imports": [
+ "de.erichseifert.gral.data.*",
+ "de.erichseifert.gral.data.filters.*",
+ "de.erichseifert.gral.graphics.*",
+ "de.erichseifert.gral.plots.*",
+ "de.erichseifert.gral.plots.lines.*",
+ "de.erichseifert.gral.plots.points.*",
+ "de.erichseifert.gral.util.*"
+ ],
+ "init": [
+ "fun T.show(sizeX: Double, sizeY: Double): Any {\n val writer = de.erichseifert.gral.io.plots.DrawableWriterFactory.getInstance().get(\"image/svg+xml\")\n\n val buf = java.io.ByteArrayOutputStream()\n\n writer.write(this, buf, sizeX, sizeY)\n\n return MIME(writer.mimeType to buf.toString())\n}"
+ ]
+}
diff --git a/libraries/klaxon.json b/libraries/klaxon.json
new file mode 100644
index 000000000..f95a3d460
--- /dev/null
+++ b/libraries/klaxon.json
@@ -0,0 +1,12 @@
+{
+ "properties": {
+ "v": "5.2"
+ },
+ "link": "https://github.com/cbeust/klaxon",
+ "dependencies": [
+ "com.beust:klaxon:$v"
+ ],
+ "imports": [
+ "com.beust.klaxon.*"
+ ]
+}
diff --git a/libraries/kmath.json b/libraries/kmath.json
new file mode 100644
index 000000000..c3e9fe295
--- /dev/null
+++ b/libraries/kmath.json
@@ -0,0 +1,17 @@
+{
+ "properties": {
+ "v": "0.1.3"
+ },
+ "link": "https://github.com/mipt-npm/kmath",
+ "repositories": [
+ "https://dl.bintray.com/mipt-npm/scientifik"
+ ],
+ "dependencies": [
+ "scientifik:kmath-core-jvm:$v"
+ ],
+ "imports": [
+ "scientifik.kmath.linear.*",
+ "scientifik.kmath.operations.*",
+ "scientifik.kmath.structures.*"
+ ]
+}
diff --git a/libraries/koma.json b/libraries/koma.json
new file mode 100644
index 000000000..86ffbacc6
--- /dev/null
+++ b/libraries/koma.json
@@ -0,0 +1,17 @@
+{
+ "properties": {
+ "v": "0.13"
+ },
+ "link": "https://koma.kyonifer.com/index.html",
+ "repositories": [
+ "https://dl.bintray.com/kyonifer/maven"
+ ],
+ "dependencies": [
+ "com.kyonifer:koma-core-ejml:$v",
+ "com.kyonifer:koma-plotting:$v"
+ ],
+ "imports": [
+ "koma.*",
+ "koma.extensions.*"
+ ]
+}
diff --git a/libraries/kotlin-statistics.json b/libraries/kotlin-statistics.json
new file mode 100644
index 000000000..b2b34706a
--- /dev/null
+++ b/libraries/kotlin-statistics.json
@@ -0,0 +1,12 @@
+{
+ "properties": {
+ "v": "-SNAPSHOT"
+ },
+ "link": "https://github.com/thomasnield/kotlin-statistics",
+ "dependencies": [
+ "com.github.thomasnield:kotlin-statistics:$v"
+ ],
+ "imports": [
+ "org.nield.kotlinstatistics.*"
+ ]
+}
diff --git a/libraries/krangl.json b/libraries/krangl.json
new file mode 100644
index 000000000..0d0d77b08
--- /dev/null
+++ b/libraries/krangl.json
@@ -0,0 +1,21 @@
+{
+ "properties": {
+ "v": "-SNAPSHOT"
+ },
+ "link": "https://github.com/holgerbrandl/krangl",
+ "dependencies": [
+ "com.github.holgerbrandl:krangl:$v"
+ ],
+ "imports": [
+ "krangl.*"
+ ],
+ "init": [
+ "fun krangl.DataFrame.toHTML(limit: Int = 20, truncate: Int = 50) : String\n{val sb = StringBuilder()\nsb.append(\"\")\nsb.append(\"\")\ncols.forEach { sb.append(\"| ${it.name} | \") }\nsb.append(\"
\")\nrows.take(limit).forEach {\n sb.append(\"\")\n it.values.map{it.toString()}.forEach { \n val truncated = if (truncate > 0 && it.length > truncate) {\n if (truncate < 4) it.substring(0, truncate)\n else it.substring(0, truncate - 3) + \"...\"\n } else {\n it\n }\n sb.append(\"\"\"| $truncated | \"\"\") \n }\n sb.append(\"
\")\n}\nsb.append(\"
\")\nif(limit < rows.count())\n sb.append(\"... only showing top $limit rows
\")\nsb.append(\"\")\nreturn sb.toString()}"
+ ],
+ "renderers": [
+ {
+ "class": "krangl.SimpleDataFrame",
+ "result": "HTML($it.toHTML())"
+ }
+ ]
+}
diff --git a/libraries/kravis.json b/libraries/kravis.json
new file mode 100644
index 000000000..c13301f4b
--- /dev/null
+++ b/libraries/kravis.json
@@ -0,0 +1,18 @@
+{
+ "properties": {
+ "v": "-SNAPSHOT"
+ },
+ "link": "https://github.com/holgerbrandl/kravis",
+ "dependencies": [
+ "com.github.holgerbrandl:kravis:$v"
+ ],
+ "imports": [
+ "kravis.*"
+ ],
+ "renderers": [
+ {
+ "class": "kravis.GGPlot",
+ "result": "$it.show()"
+ }
+ ]
+}
diff --git a/libraries/lets-plot.json b/libraries/lets-plot.json
new file mode 100644
index 000000000..a5ae93ee2
--- /dev/null
+++ b/libraries/lets-plot.json
@@ -0,0 +1,31 @@
+{
+ "properties": {
+ "core": "1.0.1-SNAPSHOT",
+ "kotlin": "0.0.8-SNAPSHOT"
+ },
+ "link": "https://github.com/JetBrains/lets-plot-kotlin",
+ "repositories": [
+ "https://jetbrains.bintray.com/lets-plot-maven"
+ ],
+ "dependencies": [
+ "org.jetbrains.lets-plot:lets-plot-common:$core",
+ "org.jetbrains.lets-plot:lets-plot-kotlin-api:$kotlin",
+ "org.jetbrains.lets-plot:kotlin-frontend-api:$kotlin",
+ "org.jetbrains.lets-plot:lets-plot-jfx:$core"
+ ],
+ "imports": [
+ "jetbrains.letsPlot.*",
+ "jetbrains.letsPlot.geom.*",
+ "jetbrains.letsPlot.stat.*"
+ ],
+ "init": [
+ "fun jetbrains.letsPlot.intern.Plot.getHtml() = jetbrains.letsPlot.intern.frontendContext.FrontendContextUtil.getHtml(this)",
+ "DISPLAY(HTML(jetbrains.datalore.jupyter.configureScript()))"
+ ],
+ "renderers": [
+ {
+ "class": "jetbrains.letsPlot.intern.Plot",
+ "result": "HTML(($it as jetbrains.letsPlot.intern.Plot).getHtml())"
+ }
+ ]
+}
diff --git a/libraries/spark.json b/libraries/spark.json
new file mode 100644
index 000000000..488a42f27
--- /dev/null
+++ b/libraries/spark.json
@@ -0,0 +1,46 @@
+{
+ "properties": {
+ "scala": "2.11.12",
+ "spark": "2.4.4"
+ },
+ "dependencies": [
+ "org.apache.spark:spark-mllib_2.11:$spark",
+ "org.apache.spark:spark-sql_2.11:$spark",
+ "org.apache.spark:spark-repl_2.11:$spark",
+ "org.apache.spark:spark-streaming-flume-assembly_2.11:$spark",
+ "org.apache.spark:spark-graphx_2.11:$spark",
+ "org.apache.spark:spark-launcher_2.11:$spark",
+ "org.apache.spark:spark-catalyst_2.11:$spark",
+ "org.apache.spark:spark-streaming_2.11:$spark",
+ "org.apache.spark:spark-core_2.11:$spark",
+ "org.scala-lang:scala-library:$scala",
+ "org.scala-lang:scala-reflect:$scala",
+ "org.scala-lang:scala-compiler:$scala",
+ "org.scala-lang.modules:scala-xml_2.11:1.2.0",
+ "commons-io:commons-io:2.5"
+ ],
+ "imports": [
+ "org.apache.spark.sql.*",
+ "org.apache.spark.api.java.*",
+ "org.apache.spark.ml.feature.*",
+ "org.apache.spark.sql.functions.*"
+ ],
+ "init": [
+ "org.apache.log4j.Logger.getLogger(\"org\").setLevel(org.apache.log4j.Level.OFF)",
+ "org.apache.log4j.Logger.getLogger(\"akka\").setLevel(org.apache.log4j.Level.OFF)",
+ "val spark = SparkSession\n .builder()\n .appName(\"Spark example\")\n .master(\"local\")\n .getOrCreate()",
+ "val sc = spark.sparkContext()",
+ "%dumpClassesForSpark",
+ "fun Dataset.toHTML(limit: Int = 20, truncate: Int = 50): String {\n val sb = StringBuilder()\n\n sb.append(\"\")\n sb.append(\"\"\"\"\"\")\n sb.append(schema().fieldNames().map { \"| ${it} | \"}.joinToString(\"\"))\n sb.append(\"
\")\n\n limit(limit).collectAsList().forEach { row ->\n sb.append(\"\")\n (0 until row.size()).map {\n row[it].toString()\n }.forEach {\n val truncated = if (truncate > 0 && it.length > truncate) {\n if (truncate < 4) it.substring(0, truncate)\n else it.substring(0, truncate - 3) + \"...\"\n } else {\n it\n }\n sb.append(\"\"\"| $truncated | \"\"\")\n }\n sb.append(\"
\")\n }\n sb.append(\"
\")\n if(limit < count())\n sb.append(\"... only showing top $limit rows
\")\n sb.append(\"\")\n return sb.toString()\n}"
+ ],
+ "initCell": [
+ "scala.Console.setOut(System.out)",
+ "scala.Console.setErr(System.err)"
+ ],
+ "renderers": [
+ {
+ "class": "org.apache.spark.sql.Dataset",
+ "result": "HTML($it.toHTML())"
+ }
+ ]
+}
diff --git a/readme.md b/readme.md
index 2e991374b..1980acfd2 100644
--- a/readme.md
+++ b/readme.md
@@ -88,7 +88,7 @@ List of supported libraries:
- [koma](https://koma.kyonifer.com/index.html) - Scientific computing library
- [kmath](https://github.com/mipt-npm/kmath) - Kotlin mathematical library analogous to NumPy
-*The list of all supported libraries can be found in [config file](config.json)*
+*The list of all supported libraries can be found in ['libraries' directory](libraries)*
A definition of supported library may have a list of optional arguments that can be overriden when library is included.
The major use case for library arguments is to specify particular version of library. Most library definitions default to `-SNAPSHOT` version that may be overriden in `%use` magic.
@@ -127,14 +127,14 @@ Press `TAB` to get the list of suggested items for completion.
2. Run `jupyter-notebook`
3. Attach remote debugger to JVM with specified port
-## Contributing
+## Adding new libraries
-### Support new libraries
+To support new `JVM` library and make it available via `%use` magic command you need to create a library descriptor for it.
-You are welcome to add support for new `Kotlin` libraries by contributing to [config.json](config.json) file.
+Check ['libraries'](libraries) directory to see examples of library descriptors.
-Library descriptor has the following fields:
-- `name`: short name of the library with optional arguments. All library arguments must have default value specified. Syntax: `(=, =)`
+Library descriptor is a `.json` file with the following fields:
+- `properties`: a dictionary of properties that are used within library descriptor
- `link`: a link to library homepage. This link will be displayed in `:help` command
- `repositories`: a list of maven or ivy repositories to search for dependencies
- `dependencies`: a list of library dependencies
@@ -143,8 +143,26 @@ Library descriptor has the following fields:
- `initCell`: a list of code snippets to be executed before execution of any cell
- `renderers`: a list of type converters for special rendering of particular types
+*All fields are optional
+
Fields for type renderer:
- `class`: fully-qualified class name for the type to be rendered
-- `result`: expression to produce output value. Source object is referenced as `$it`
+- `result`: expression that produces output value. Source object is referenced as `$it`
+
+Name of the file is a library name that is passed to '%use' command
+
+Library properties can be used in any parts of library descriptor as `$property`
+
+To register new library descriptor:
+1. For private usage - add it to local settings folder `/.jupyter_kotlin/libraries`
+2. For sharing with community - commit it to ['libraries'](libraries) directory and create pull request.
+
+If you are maintaining some library and want to update your library descriptor, just create pull request with your update. After your request is accepted,
+new version of your library will be available to all Kotlin Jupyter users immediately on next kernel startup (no kernel update is needed).
+
+If a library descriptor with the same name is found in several locations, the following resolution priority is used:
+1. Local settings folder (highest priority)
+2. ['libraries'](libraries) folder at the latest master branch of `https://github.com/Kotlin/kotlin-jupyter` repository
+3. Kernel installation directory
-Library arguments can be referenced in any parts of library descriptor as `$arg`
\ No newline at end of file
+If you don't want some library to be updated automatically, put fixed version of its library descriptor into local settings folder.
\ No newline at end of file
diff --git a/src/main/kotlin/org/jetbrains/kotlin/jupyter/commands.kt b/src/main/kotlin/org/jetbrains/kotlin/jupyter/commands.kt
index a5f7b847b..a84dc77fa 100644
--- a/src/main/kotlin/org/jetbrains/kotlin/jupyter/commands.kt
+++ b/src/main/kotlin/org/jetbrains/kotlin/jupyter/commands.kt
@@ -32,7 +32,7 @@ fun runCommand(code: String, repl: ReplForJupyter?): ResponseWithMessage {
if (it.argumentsUsage != null) s += "\n Usage: %${it.name} ${it.argumentsUsage}"
s
}
- val libraries = repl?.config?.libraries?.toList()?.joinToStringIndented {
+ val libraries = repl?.config?.libraries?.awaitBlocking()?.toList()?.joinToStringIndented {
"${it.first} ${it.second.link ?: ""}"
}
ResponseWithMessage(ResponseState.Ok, textResult("Commands:\n$commands\n\nMagics\n$magics\n\nSupported libraries:\n$libraries"))
diff --git a/src/main/kotlin/org/jetbrains/kotlin/jupyter/config.kt b/src/main/kotlin/org/jetbrains/kotlin/jupyter/config.kt
index 974eec1ab..e2fe9e0fa 100644
--- a/src/main/kotlin/org/jetbrains/kotlin/jupyter/config.kt
+++ b/src/main/kotlin/org/jetbrains/kotlin/jupyter/config.kt
@@ -1,9 +1,36 @@
package org.jetbrains.kotlin.jupyter
+import com.beust.klaxon.JsonObject
+import com.beust.klaxon.Parser
+import khttp.responses.Response
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.async
+import org.apache.commons.io.FileUtils
+import org.jetbrains.kotlin.konan.parseKonanVersion
+import org.json.JSONObject
import org.slf4j.LoggerFactory
import java.io.File
+import java.nio.file.Files
+import java.nio.file.Paths
import kotlin.script.experimental.dependencies.RepositoryCoordinates
+val LibrariesDir = "libraries"
+val LocalCacheDir = "cache"
+val CachedLibrariesFootprintFile = "libsCommit"
+
+val LocalSettingsPath = Paths.get(System.getProperty("user.home"), ".jupyter_kotlin").toString()
+
+val GitHubApiHost = "api.github.com"
+val GitHubRepoOwner = "kotlin"
+val GitHubRepoName = "kotlin-jupyter"
+val GitHubBranchName = "master"
+val GitHubApiPrefix = "https://$GitHubApiHost/repos/$GitHubRepoOwner/$GitHubRepoName"
+
+val LibraryDescriptorExt = "json"
+val LibraryPropertiesFile = ".properties"
+val libraryDescriptorFormatVersion = 1
+
internal val log by lazy { LoggerFactory.getLogger("ikotlin") }
enum class JupyterSockets {
@@ -14,9 +41,21 @@ enum class JupyterSockets {
iopub
}
+data class KernelConfig(
+ val ports: Array,
+ val transport: String,
+ val signatureScheme: String,
+ val signatureKey: String,
+ val pollingIntervalMillis: Long = 100,
+ val scriptClasspath: List = emptyList(),
+ val resolverConfig: ResolverConfig?
+)
+
+val protocolVersion = "5.3"
+
data class TypeRenderer(val className: String, val displayCode: String?, val resultCode: String?)
-data class Variable(val name: String?, val value: String?)
+data class Variable(val name: String, val value: String)
class LibraryDefinition(val dependencies: List,
val variables: List,
@@ -27,16 +66,197 @@ class LibraryDefinition(val dependencies: List,
val renderers: List,
val link: String?)
-data class ResolverConfig(val repositories: List, val libraries: Map)
+data class ResolverConfig(val repositories: List,
+ val libraries: Deferred