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/build.gradle.kts b/build.gradle.kts index eab3cf0..8d221cb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,20 +1,19 @@ 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" + 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 { - 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") 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)