Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a native executable via GraalVM #4 #11

Merged
merged 4 commits into from
Apr 13, 2019
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,5 @@ gradle-app.setting

# End of https://www.gitignore.io/api/gradle,kotlin,eclipse,intellij,visualstudiocode
/.idea/sonarIssues.xml
/pullpitoK
/libsunec.*
9 changes: 9 additions & 0 deletions .idea/pullpitoK.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 5 additions & 6 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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")
Expand Down
48 changes: 48 additions & 0 deletions generate-executable.sh
Original file line number Diff line number Diff line change
@@ -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"
34 changes: 24 additions & 10 deletions src/main/kotlin/pullpitok/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pullpitok.github.EventClient
import pullpitok.github.Type

fun main(args: Array<String>) {
loadLibSunec()

if (!checkArgs(args)) System.exit(0)
val repo = args[0]
Expand All @@ -18,17 +19,16 @@ fun main(args: Array<String>) {
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<String>): Boolean =
Expand All @@ -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<Event>) {
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<Event>): Map<String, List<Event>> = events
.filter {
it.type in Type.values().map(Type::name)
Expand Down