From e50ad1f127b834e001699ace45321688dd2e9931 Mon Sep 17 00:00:00 2001 From: Nicolas Kosinski Date: Wed, 10 Apr 2019 06:49:36 +0200 Subject: [PATCH 1/4] =?UTF-8?q?Cleanup=20Gradle=20conf=20since=20Ktor=20re?= =?UTF-8?q?moval=20=F0=9F=9A=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit b18ee18 missed this! --- build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index eab3cf0..6dcfa92 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,6 @@ repositories { } dependencies { - val ktorVersion = "1.1.2" compile("com.fasterxml.jackson.core:jackson-databind:2.9.8") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") testImplementation("org.jetbrains.kotlin:kotlin-test") From 918a291f956af6f7cce5bc2d8ecc1ccff624d829 Mon Sep 17 00:00:00 2001 From: Nicolas Kosinski Date: Wed, 10 Apr 2019 06:49:36 +0200 Subject: [PATCH 2/4] =?UTF-8?q?Upgrade=20Kotlin=20and=20dependencies=20to?= =?UTF-8?q?=20latest=20=F0=9F=99=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6dcfa92..f0292e3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,8 @@ plugins { - val kotlinVersion = "1.3.20" + val kotlinVersion = "1.3.21" id("org.jetbrains.kotlin.jvm").version(kotlinVersion) id("com.adarshr.test-logger").version("1.6.0") - id("se.patrikerdes.use-latest-versions") version "0.2.7" - id("com.github.ben-manes.versions") version "0.20.0" + id("se.patrikerdes.use-latest-versions") version "0.2.9" application } From 2978dadf57850e3caa677d21dc9c2c6a43d6cc9d Mon Sep 17 00:00:00 2001 From: Nicolas Kosinski Date: Wed, 10 Apr 2019 06:49:36 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Build=20a=20fat=20JAR=20#4=20=F0=9F=93=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fat JAR is needed to generate an executale via GraalVM. --- build.gradle.kts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f0292e3..8d221cb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,13 +3,14 @@ plugins { id("org.jetbrains.kotlin.jvm").version(kotlinVersion) id("com.adarshr.test-logger").version("1.6.0") id("se.patrikerdes.use-latest-versions") version "0.2.9" + id("com.github.ben-manes.versions") version "0.21.0" + id("com.github.johnrengelman.shadow") version "5.0.0" application } repositories { jcenter() - maven { url = uri("https://kotlin.bintray.com/ktor") } - maven { url = uri("https://kotlin.bintray.com/kotlinx") } // Required since 0.9.4 since ktor-client-gson includes ktor-client-json that depends on kotlinx-serialization + maven { url = uri("https://plugins.gradle.org/m2") } } dependencies { From f9ab3ed219b08e9c2b4e8c4739b44259ea61ff49 Mon Sep 17 00:00:00 2001 From: Nicolas Kosinski Date: Wed, 10 Apr 2019 06:49:36 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Generate=20an=20executable=20via=20GraalVM?= =?UTF-8?q?=20#4=20=E2=9A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Install GraalVM (https://www.graalvm.org/) via SDKMAN! (https://sdkman.io/). GraalVM is used to build a native image (executable) from the fat JAR. Note: 'libsunec' native library (Sun Elliptic Curve crypto) needs to be in java.library.path, it is copied in current directory). --- .gitignore | 2 ++ .idea/pullpitoK.iml | 9 ++++++ README.md | 10 +++++++ generate-executable.sh | 48 ++++++++++++++++++++++++++++++++ src/main/kotlin/pullpitok/App.kt | 34 +++++++++++++++------- 5 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 .idea/pullpitoK.iml create mode 100755 generate-executable.sh diff --git a/.gitignore b/.gitignore index 3b7a722..be84ec8 100644 --- a/.gitignore +++ b/.gitignore @@ -208,3 +208,5 @@ gradle-app.setting # End of https://www.gitignore.io/api/gradle,kotlin,eclipse,intellij,visualstudiocode /.idea/sonarIssues.xml +/pullpitoK +/libsunec.* diff --git a/.idea/pullpitoK.iml b/.idea/pullpitoK.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/pullpitoK.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 6dcaa63..46e5c39 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,16 @@ In order to show the 'usage': ./gradlew run --args "--help" +## Install + +In order to generate a *nix executable, run: + + ./generate-executable.sh + +An executable file named `pullpitoK` should be generated in the current directory. It can then be run: + + ./pullpitoK + ## Upgrade dependencies ./gradlew useLatestVersions \ No newline at end of file diff --git a/generate-executable.sh b/generate-executable.sh new file mode 100755 index 0000000..a76540d --- /dev/null +++ b/generate-executable.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Fail on error +set -e + +echo "Building JAR file:" +./gradlew shadowJar +echo "JAR file has been built! ✅" + +echo "Install GraalVM via SDKMAN!:" +curl --silent "https://get.sdkman.io" | bash || echo 'SDKMAN! already installed' +source "$HOME/.sdkman/bin/sdkman-init.sh" +GRAALVM_VERSION=1.0.0-rc-15-grl +sdkman_auto_answer=true sdk install java $GRAALVM_VERSION > /dev/null +sdk use java $GRAALVM_VERSION + +echo "Copying 'libsunec' shared library (Sun Elliptic Curve crypto):" +set +e +cp $JAVA_HOME/jre/lib/*/libsunec* . 2>/dev/null # Linux +linux_libsunec=$? +cp $JAVA_HOME/jre/lib/libsunec* . 2>/dev/null #macOS +macos_libsunec=$? +set -e +if [ $linux_libsunec -ne 0 ] && [ $macos_libsunec -ne 0 ]; then + echo "Cannot copy 'libsunec' shared library" + exit 1 +fi +echo "'libsunec' shared library has been copied! ✅" + +echo "Build executable from JAR via GraalVM:" +native-image \ + --no-server \ + --enable-https \ + -jar ./build/libs/pullpitoK-all.jar \ + pullpitoK && \ + echo ' => Check the executable: ' && ./pullpitoK +echo "Executable has been built! ✅" + +echo "\nExecutable has been generated in local directory, try it copy/pasting this command: + $> ./pullpitoK python/peps + +Executable can also be run from an other directory via a 'PULLPITOK_LIBSUNEC' +environment variable in order to load the 'libsunec' shared library (Sun +Elliptic Curve crypto) bundled in the Java Development Kit. +For instance, on Linux: + $> PULLPITOK_LIBSUNEC=$JAVA_HOME/jre/lib/amd64 ./pullpitoK python/peps +or on macOS: + $> PULLPITOK_LIBSUNEC=$JAVA_HOME/jre/lib ./pullpitoK python/peps" \ No newline at end of file diff --git a/src/main/kotlin/pullpitok/App.kt b/src/main/kotlin/pullpitok/App.kt index d3e7166..14063f8 100644 --- a/src/main/kotlin/pullpitok/App.kt +++ b/src/main/kotlin/pullpitok/App.kt @@ -6,6 +6,7 @@ import pullpitok.github.EventClient import pullpitok.github.Type fun main(args: Array) { + loadLibSunec() if (!checkArgs(args)) System.exit(0) val repo = args[0] @@ -18,17 +19,16 @@ fun main(args: Array) { if (events.isNotEmpty()) allEvents.addAll(events) else break } - println("""pull requests for "$repo" ->""") - val eventsPerAuthor = perAuthor(allEvents) - - val opened: (Event) -> Boolean = { it.type == Type.PullRequestEvent.name && it.payload.action == Action.opened.name } - println("\n" + counters("opened per author", eventsPerAuthor, opened)) - - val commented: (Event) -> Boolean = { it.type == Type.PullRequestReviewCommentEvent.name && it.payload.action == Action.created.name } - println("\n" + counters("commented per author", eventsPerAuthor, commented)) + displayEvents(repo, allEvents) +} - val closed: (Event) -> Boolean = { it.type == Type.PullRequestEvent.name && it.payload.action == Action.closed.name } - println("\n" + counters("closed per author", eventsPerAuthor, closed)) +private fun loadLibSunec() { + val libSunec = System.getenv("PULLPITOK_LIBSUNEC") + if (libSunec != null && !libSunec.isEmpty()) { + System.setProperty("java.library.path", libSunec) + } else { + System.setProperty("java.library.path", System.getenv("JAVA_HOME")) + } } fun checkArgs(args: Array): Boolean = @@ -44,6 +44,20 @@ A command line tool to display a summary of GitHub pull requests. false } else true +private fun displayEvents(repo: String, allEvents: MutableList) { + println("""pull requests for "$repo" ->""") + val eventsPerAuthor = perAuthor(allEvents) + + val opened: (Event) -> Boolean = { it.type == Type.PullRequestEvent.name && it.payload.action == Action.opened.name } + println("\n" + counters("opened per author", eventsPerAuthor, opened)) + + val commented: (Event) -> Boolean = { it.type == Type.PullRequestReviewCommentEvent.name && it.payload.action == Action.created.name } + println("\n" + counters("commented per author", eventsPerAuthor, commented)) + + val closed: (Event) -> Boolean = { it.type == Type.PullRequestEvent.name && it.payload.action == Action.closed.name } + println("\n" + counters("closed per author", eventsPerAuthor, closed)) +} + fun perAuthor(events: List): Map> = events .filter { it.type in Type.values().map(Type::name)