Skip to content

Instantly share code, notes, and snippets.

View mikehearn's full-sized avatar

Mike Hearn mikehearn

View GitHub Profile
#!/usr/bin/env bash
#
# To use, unpack a regular JDK somewhere and set JDK_HOME to point to it. The default here expects a JDK 15 early access
# in the same directory but you can set JDK_HOME to anything.
#
JDK_HOME=${JDK_HOME:-$PWD/jdk-15.jdk/Contents/Home}
#
@mikehearn
mikehearn / espresso-notes.md
Created January 20, 2021 13:56
Espresso architecture notes

Here are some rough notes on things observed in the codebase - not by the Espresso authors so may all be totally wrong.

Native components

Espresso is mostly written in Java but has some C components as well. These serve two purposes:

  1. The espresso engine can be compiled with native-image down to a shared library so it no longer needs hotspot and runs AOT. This is called “libespresso”
  2. Native code components from OpenJDK that use internal HotSpot APIs can be loaded. This allows a high degree of code re-use and means that unlike most JVM implementations, this one doesn’t need to implement the JDK class library, not even tricky parts in java.base or internal modules - in fact the classes you’d find in the java.base module in a regular OpenJDK should work as long as it’s of the right versions.

OpenJDK native code components include libjava, libjimage etc. These can be loaded as genuinely native components and also (it appears) via Sulong, which on GraalVM EE would give you sandboxing of these compon

package hydraulic.utils.config
import com.natpryce.hamkrest.isBlank
import com.typesafe.config.*
import com.typesafe.config.ConfigException.BadValue
import hydraulic.kotlin.utils.text.camelToKebabCase
import hydraulic.utils.app.UserInput
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.WildcardType
package hydraulic.utils.config
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.containsSubstring
import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigValueFactory
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
@mikehearn
mikehearn / teamcity.service
Created June 10, 2022 15:45
An example systemd service for TeamCity
[Unit]
After=postgresql.service
Description=JetBrains TeamCity
Requires=postgresql.service
Wants=network-online.target
# Can be included to allow a server to write to its own files.
[Service]
CacheDirectory=jetbrains/teamcity
ConfigurationDirectory=jetbrains/teamcity
// A server config for Conveyor: https://conveyor.hydraulic.dev/
// Import config from a Java build system (but you can get it from anywhere).
include required("#!gradle -q printConveyorConfig")
app {
vendor = Hydraulic
fsname = sample-server
machines = [linux.amd64.glibc] // Don't want packages for other platforms.
#!/usr/bin/env hshell
// -------------------- Dependencies and imports ------------------------------------------------
//
// You can depend on Maven coordinates, they will be downloaded and cached in ~/.m2 automatically.
@file:DependsOn("com.github.ricksbrown:cowsay:1.0.0")
import com.github.ajalt.mordant.table.table
import com.github.ricksbrown.cowsay.Cowsay
import hydraulic.utils.os.runningOnWindows
@mikehearn
mikehearn / conveyor.conf
Created December 4, 2022 13:19
Config for GH Desktop (using GH Actions to prepare the resources dir)
// A config for Conveyor (https://conveyor.hydraulic.dev/) that creates a download site for GitHub Desktop.
// Shows how to package a real-world and sophisticated Electron app.
include required("/stdlib/electron/electron.conf")
// Import package.json files so we can avoid duplicating config. There are two in this project.
package-json {
include required("app/package.json")
}
@mikehearn
mikehearn / Locker.kt
Created April 6, 2023 08:25
A class that makes it easy to wrap state such that it's only accessible when locked.
package hydraulic.kotlin.utils
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
/**
* A wrapper class that makes it harder to forget to take a lock before accessing some shared state.
*
* Simply define an anonymous object to hold the data that must be grouped under the same lock, and then pass it
@mikehearn
mikehearn / gist:fdcb2c3ef30c6a2970d089fd8f860216
Created May 1, 2023 16:26
IntelliJ plugin to register a custom Kotlin scripting host
package hydraulic.hshell.intellij
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.diagnostic.logger
import java.io.File
import java.io.IOException
import kotlin.script.experimental.intellij.ScriptDefinitionsProvider
private val LOG = logger<HShellDefinitionProvider>()