Type-safe Kotlin configuration by delegates

Overview

Maven Central Tests Pipelines Chat Awesome Kotlin Badge

Type-safe Kotlin configuration by delegates.

Supports the most common external configuration sources, including:

📦 Installation

Add Maven Central to your repositories and add Arkenv in Gradle:

repositories { mavenCentral() }
implementation "com.apurebase:arkenv:$arkenv_version"
implementation "com.apurebase:arkenv-yaml:$arkenv_version" // for yaml support

🔨 Usage

1. Define your arguments with the argument delegate.

object Arguments {
    val port: Int by argument()
}

or use constructor injection:

class Arguments(val port: Int)

2. Parse your arguments.

fun main(args: Array<String>) {
    Arkenv.parse(Arguments, args) // object or existing instance
    Arkenv.parse<Arguments>(args) // constructor injection 
}

You can specify additional custom names for each argument.

The property's name is used as a fallback.

By default, Arkenv supports parsing command line arguments, environment variables, and profiles.

In the case of port, you can parse it like this:

  • From command line with --port 443
  • As an environment variable PORT=80
  • In a profile, like application-dev.properties, add port=5000

To get started, we recommend reading about the basics for a quick tour of what's included.

📃 Documentation

Please visit https://arkenv.io/ for in-depth documentation.

🤝 Contributing PRs Welcome

Slack

Find the Arkenv channel in the official Kotlin Slack.

Comments
  • Generic argument interface, allow arguments in plain classes.

    Generic argument interface, allow arguments in plain classes.

    Part one of #36

    This allows to define arguments in plain classes, i.e. without extending Arkenv.

    For example:

    object Arguments {
    
        val country: String by argument()
    
        val bool: Boolean by argument("-b")
    
        val port: Int by argument()
    }
    
    fun main(args: Array<String>) {
        Arkenv.parse(Arguments, args)
    }
    
    enhancement 
    opened by AndreasVolkmann 5
  • Env loading incorrect variable into field

    Env loading incorrect variable into field

    This example below is straight forward, but it fails as some how USER get's mapped into --db-user

    @Test fun `should only use fully qualified env name`() {
        MockSystem("USER" to "jeggy")
        object: Arkenv() {
            val user: String by argument("--db-user") {
                defaultValue = { "postgres" }
            }
        }.parse().user shouldBeEqualTo "postgres"
    }
    
    bug breaking 
    opened by jeggy 4
  • Publish to Maven Central

    Publish to Maven Central

    closes #45

    Tasks:

    • [x] Setup SonaType account and get com.apurebase approved there
    • [x] Gradle configuration for publishing to Maven Central
    • [x] Make sure it's using 1.8
    • [x] Setup Jupiter again
    • [x] Create GitHub action to publish to Maven Central
    • [x] Publish old versions to Maven Central
    opened by jeggy 4
  • Quoting values in CLI not possible

    Quoting values in CLI not possible

    When passing an argument via CLI that contains whitespace, it would be good if quoting was supported.

    data class Configuration(
        val notesFileName: String
    )
    

    --notes-file-name "My Clippings.txt"

    bug 
    opened by AndreasVolkmann 3
  • Parse without extending + parse directly to constructor

    Parse without extending + parse directly to constructor

    Explore options to support argument classes without inheritance.

    1. Class without inheritance / no class X : Arkenv()
    2. Class / data class with arguments in constructor class Ark(val port: Int, val host: String)
    enhancement 
    opened by AndreasVolkmann 3
  • Change default branch from master to main

    Change default branch from master to main

    As the current trend is to use main instead of master, I would suggest we will do the same.

    • [ ] Update github actions
    • [ ] Update default branch in git
    • [ ] (optional) Update gitlab badges
    wontfix 
    opened by jeggy 2
  • Nested Arkenv modules

    Nested Arkenv modules

    Allow nesting Arkenv instances, so that different parts of the configuration can be defined in separate classes.

    Proposed syntax:

    private inner class DatabaseConfig : Arkenv() {
    	val port: Int by argument()
    }
    
    private inner class Ark : Arkenv() {
    	val name: String by argument()
    	val database = module(DatabaseConfig())
    }
    
    @Test fun `modules should be parsed by root`() {
    	val myApp = "MyApp"
    	val port = 8080
    	Ark().parse("--name", myApp, "--port", port.toString())
    		.expectThat {
    			get { name }.isEqualTo(myApp)
    			get { database.port }.isEqualTo(port)
    		}
    }
    
    enhancement 
    opened by AndreasVolkmann 2
  • Parse automatically on first access

    Parse automatically on first access

    Instead of calling .parse() it could happen automatically on the first call to access any prop or get call.

    • isParsed Bool to indicate if it has been parsed. Can also be useful output for exceptions
    • provide lazy parsing on accessing first prop or ::get
    enhancement 
    opened by AndreasVolkmann 2
  • Add ProfileFeature to default installed

    Add ProfileFeature to default installed

    There is no reason to not have the ProfileFeature on by default.

    If you don't provide any configuration, nothing gets loaded.

    Once you decide to use profiles, it is automatically available without recompilation.

    As for the overall default order, follow Spring: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config

    1. CLI
    2. Properties
    3. SysEnv
    enhancement 
    opened by AndreasVolkmann 2
  • Create remote config guide

    Create remote config guide

    The remote config scenario needs a good guide with examples.

    I am thinking of walking through a light ktor app that uses Arkenv for remote config. Either refresh periodically, or via a web hook.

    enhancement documentation 
    opened by AndreasVolkmann 1
  • Optimize delegates for 1.4

    Optimize delegates for 1.4

    Upcoming optimization for delegates coming in 1.4: https://blog.jetbrains.com/kotlin/2019/12/what-to-expect-in-kotlin-1-4-and-beyond/ (Optimized delegated properties)

    enhancement 
    opened by AndreasVolkmann 1
  • Modules as constructor arguments

    Modules as constructor arguments

    Module support is more natural if we can just supply our nested modules via the constructor.

    Out of the box we get defaults and easy injection in tests.

    Either convention based, for example, all data classes are parsed as modules parameter.type.jvmErasure.isData.

    Or with annotation @Module

    enhancement 
    opened by AndreasVolkmann 0
  • Investigate merging property files from main and test modules

    Investigate merging property files from main and test modules

    A common setup is to have a application.* in main and one in test, where test adds or overwrites values specified in main. image

    Currently, it seems only one is loaded.

    Investigate the current behavior and see if we can enable a merging of both. How would we determine the order?

    enhancement 
    opened by AndreasVolkmann 0
  • Move fully away from GitLab

    Move fully away from GitLab

    I'm thinking we should remove our whole dependency to gitlab.com by removing our .gitlab-ci.yml and when finished with that we would update the https://apurebase.gitlab.io/arkenv/ website to just forward all requests to https://arkenv.io/

    Some tasks I can think of:

    • [ ] Create Code coverage badge via GitHub Actions [An idea how]
    • [x] Make sure all links work on the new arkenv.io webiste
    • [x] Change references in this GitHub repo to point to arkenv.io
    • [x] Update generated POM files to use new arkenv.io website
    • [x] Stop mirror settings on GitLab & Create 1 commit on GitLab that:
      • [ ] Will publish a new website, which only forwards the link directly over to the new site.
      • [ ] A small note in the README to say we are not using GitLab anymore and a link to this repo instead.
    enhancement documentation 
    opened by jeggy 0
  • --help doesn't include sub modules

    --help doesn't include sub modules

    class OtherArks: Arkenv() {
        val customConfig: String? by argument("--custom")
    }
    class Arks: Arkenv("My App") {
        val other = module(OtherArks())
        val port: Int by argument("--port") {
            defaultValue = { 8080 }
        }
    }
    
    fun main(args: Array<String>) {
        val arks = Arks().parse(args)
    
        if (arks.help) {
            println(arks.toString())
        }
    }
    

    outputs:

    My App: 
        [-h, --HELP]        
            help        true
        [--ARKENV_APPLICATION_NAME]        
            programName        My App
        [--PORT]        
            port        8080
    
    bug 
    opened by jeggy 0
Releases(v3.3.3)
Helper to upload Gradle Android Artifacts, Gradle Java Artifacts and Gradle Kotlin Artifacts to Maven repositories (JCenter, Maven Central, Corporate staging/snapshot servers and local Maven repositories).

GradleMavenPush Helper to upload Gradle Android Artifacts, Gradle Java Artifacts and Gradle Kotlin Artifacts to Maven repositories (JCenter, Maven Cen

 Vorlonsoft LLC 21 Oct 3, 2022
A Kotlin compiler plugin implementation of AutoService

auto-service-kt A Kotlin compiler plugin implementation of AutoService. Usage Simply add the auto-service-kt Gradle Plugin. plugins { id("dev.zacswe

Zac Sweers 5 Dec 29, 2022
Kotlin Multiplatform (pending KSP support) snapshot (klip) manager for tests

KLIP Kotlin Multiplatform (pending KSP support) snapshot (klip) manager for tests Modules core - runtime library processor - ksp-based annotation proc

Martynas Petuška 23 Nov 25, 2022
CKlib is a gradle plugin that will build and package C/C++/Objective-C code for Kotlin/Native.

C Klib CKlib is a gradle plugin that will build and package C/C++/Objective-C code for Kotlin/Native. The Problem When you want to access C-etc code f

Touchlab 73 Nov 8, 2022
Kotlin Native's Clang Compiler Plugin

Kotlin Native's Clang Compiler Plugin This plugin makes possible to use konon clang compiler. Support targets: Target Name Host compatibility linux_x6

null 3 May 8, 2022
🤹 Common Kotlin utilities made for my personal usage, comes with SLF4J utilities, common extensions, common Gradle utilities, and more.

?? common-utils Common Kotlin utilities made for my personal usage, comes with SLF4J utilities, common extensions, ansi-colours, common Gradle utiliti

Noel ʕ •ᴥ•ʔ 6 Dec 2, 2022
Aqui você encontra os projetos Kotlin atualizados do curso do Professor Marco Maddo.

Fundamentos-da-Programacao-Kotlin-para-Leigos-IntelliJ Aqui você encontra os projetos Kotlin atualizados do curso do Professor Marco Maddo. Visite a p

Marco Maddo (TSSTI Tecnologia) 11 Dec 27, 2022
Wiroforce godot plugin for kotlin

Wiroforce Godot Plugin The purpose of this project is the creation of a plugin f

Fernando Castellanos 3 Dec 25, 2021
BuildPlots-Plugin - PaperMC-Plugin for build contests written in Kotlin.

BuildPlotsPlugin PaperMC-Plugin for build contests. This is my first time using Kotlin and the first plugin I've written after a long time. It is stil

Lukas Heinzl 0 Jan 1, 2022
HH Synthetic -- plugin for automated migration from Kotlin synthetics to View Binding.

HH Synthetic -- plugin for automated migration from Kotlin synthetics to View Binding.

HeadHunter 17 Dec 22, 2022
Kotlin compiler plugin generates support synthetic methods for use SaveStateHandle without constants and string variables.

SavedState Compiler Plugin Kotlin compiler plugin generates support methods for use SaveStateHandle without constants and string variables. Example If

Anton Nazarov 3 Sep 20, 2022
This project provides declarative camunda delegates for Spring based application

camunda-delegator-lib Features Declarative style for delegate code Generated delegates documentation and templates for camunda modeler(this feature is

Tinkoff.ru 27 Aug 12, 2022
Type-safe time calculations in Kotlin, powered by generics.

Time This library is made for you if you have ever written something like this: val duration = 10 * 1000 to represent a duration of 10 seconds(in mill

Kizito Nwose 958 Dec 10, 2022
typedmap is an implementation of heterogeneous type-safe map pattern in Kotlin

Typedmap typedmap is an implementation of heterogeneous type-safe map pattern in Kotlin. It is a data structure similar to a regular map, but with two

Ryszard Wiśniewski 34 Nov 7, 2022
Kotlin code generation for commercetools platform type-safe product-types, reference expansion and custom fields

Kotlin code generation for commercetools platform type-safe product-types, reference expansion and custom fields

null 8 Dec 15, 2022
A type-safe HTTP client for Android and the JVM

Retrofit A type-safe HTTP client for Android and Java. For more information please see the website. Download Download the latest JAR or grab from Mave

Square 41k Jan 5, 2023
Type safe intent building for services and activities

#IntentBuilder Type safe intent building for services and activities. IntentBuilder is a type safe way of creating intents and populating them with ex

Emil Sjölander 348 Oct 10, 2022
The sample App implements type safe SQL by JOOQ & DB version control by Flyway

The sample App implements type safe SQL by JOOQ & DB version control by Flyway Setup DB(PostgreSQL) $ docker compose up -d Migration $ ./gradlew flywa

t-kurihara 3 Jan 1, 2022
Type-safe arguments for JetPack Navigation Compose using Kotlinx.Serialization

Navigation Compose Typed Compile-time type-safe arguments for JetPack Navigation Compose library. Based on KotlinX.Serialization. Major features: Comp

Kiwi.com 32 Jan 4, 2023