Skip to content

Instantly share code, notes, and snippets.

@Mahoney
Mahoney / DatabaseMigrationSpec.groovy
Last active July 20, 2022 18:13
Test liquibase migration output
package mything.db
import com.zaxxer.hikari.HikariDataSource
import liquibase.Liquibase
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.resource.ClassLoaderResourceAccessor
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
@Mahoney
Mahoney / add_docker_alias.sh
Created June 1, 2022 13:53
Add a new alias to an existing container from a container running within a docker network
#! /bin/sh
# Requires curl, jq & /var/run/docker.sock to be mounted into the container
set -eu
main() {
alias=$1
container_id="$(hostname)"
@Mahoney
Mahoney / wildcard-cert.sh
Created April 28, 2022 16:16
Generate a wildcard cert using lets encrypt with route53 on macOS
#!/usr/bin/env bash
set -euo pipefail
domain_name=$1
brew install certbot
$( brew --prefix certbot )/libexec/bin/pip install certbot-dns-route53
@Mahoney
Mahoney / Integers.kt
Last active March 23, 2022 17:40
Type safe integer behaviour in Kotlin
sealed interface Integer {
operator fun plus(other: Integer): Integer
operator fun plus(other: NonZeroInteger): Integer
operator fun plus(other: NonNegativeInteger): Integer
operator fun plus(other: NonPositiveInteger): Integer
operator fun plus(other: PositiveInteger): Integer
operator fun plus(other: NegativeInteger): Integer
operator fun plus(other: Zero): Integer
operator fun div(other: NonZeroInteger): Integer
@Mahoney
Mahoney / Json.kt
Created March 4, 2022 09:18
Actual working JSON in Kotlin
sealed interface Json {
@JvmInline value class Boolean(val value: kotlin.Boolean) : Json
@JvmInline value class Number(val value: kotlin.Number) : Json
@JvmInline value class String(val value: kotlin.String) : Json
class Object(private val value: Map<kotlin.String, Json?>) : Map<kotlin.String, Json?> by value, Json
class Array(private val value: List<Json?>) : List<Json?> by value, Json
}
interface ToJson {
@Mahoney
Mahoney / MapGet.kt
Created March 2, 2022 16:19
Safe get from map as type
inline operator fun <reified T> Map<String, Any?>.get(key: String): Result<T> =
if (this.contains(key)) {
val value = this[key]
if (value is T) {
Result.success(value)
} else {
val message = if (value == null) {
"[$key] returned null, expected [${T::class}]"
} else {
"[$key] returned [$value] of type [${value::class}], expected type [${T::class}]"
@Mahoney
Mahoney / gist:0438153af917ab8cf13c2327e2c82205
Created February 18, 2022 23:21
Gradle JPMS: fantasy of multiple modules in a single sourceset
.
├── build.gradle.kts
└── src
├── app
│ ├── module-info.java
│ └── Main.kt
├── auction
│ ├── api
│ │ ├── module-info.java
│ │ └── AuctionHouse.kt
@Mahoney
Mahoney / gist:d81c82eae13eba7bb9b6298ebed625db
Created February 18, 2022 23:16
Gradle JPMS: project-per-module
.
├── build.gradle.kts
├── app
│ ├── build.gradle.kts
│ └── src
│ ├── module-info.java
│ └── Main.kt
├── auction
│ ├── api
│ │ ├── build.gradle.kts
@Mahoney
Mahoney / AgeSpec.kt
Created January 17, 2022 10:31
AgeSpec in Kotest
import io.kotest.core.spec.style.StringSpec
import io.kotest.data.headers
import io.kotest.data.row
import io.kotest.data.table
import io.kotest.matchers.shouldBe
import java.time.LocalDate
class AgeSpec : StringSpec({
ageScenarios.rows.forEach { (dateOfBirth, date, expectedAge) ->
@Mahoney
Mahoney / AgeSpec.groovy
Last active January 17, 2022 22:08
AgeSpec in Spock
import spock.lang.Specification
import spock.lang.Unroll
import java.time.LocalDate
class AgeSpec extends Specification {
@Unroll
def "A person born on #dateOfBirth will be #expectedAge on #date"() {