Easy to use and concise yet powerful and robust command line argument parsing for Kotlin

Overview

Kotlin --argparser

Maven Central Build Status codebeat badge Awesome Kotlin Badge Javadocs License: LGPL 2.1

This is a library for parsing command-line arguments. It can parse both options and positional arguments. It aims to be easy to use and concise yet powerful and robust.

Overview

Defining options and positional arguments is as simple as:

import com.xenomachina.argparser.ArgParser

class MyArgs(parser: ArgParser) {
    val v by parser.flagging("enable verbose mode")

    val name by parser.storing("name of the user")

    val count by parser.storing("number of the widgets") { toInt() }

    val source by parser.positional("source filename")

    val destination by parser.positional("destination filename")
}

An instance of MyArgs will represent the set of parsed arguments. Each option and positional argument is declared as a property that delegates through a delegate factory method on an instance of ArgParser.

The name of an option is inferred from the name of the property it is bound to. The options above are named -v, --name and --count, respectively. There are also two positional arguments.

Direct control over an option's name is also possible, and for most types of options it is also possible to have multiple names, like a short and long name:

class MyArgs(parser: ArgParser) {
    val verbose by parser.flagging(
        "-v", "--verbose",
        help = "enable verbose mode")

    val name by parser.storing(
        "-N", "--name",
        help = "name of the user")

    val count by parser.storing(
        "-c", "--count",
        help = "number of widgets") { toInt() }

    val source by parser.positional(
        "SOURCE",
        help = "source filename")

    val destination by parser.positional(
        "DEST",
        help = "destination filename")
}

The unparsed command-line arguments are passed to the ArgParser instance at construction:

fun main(args: Array<String>) = mainBody {
    ArgParser(args).parseInto(::MyArgs).run {
        println("Hello, ${name}!")
        println("I'm going to move ${count} widgets from ${source} to ${destination}.")
        // TODO: move widgets
    }
}

See kotlin-argparser-example for a complete example project.

Nomenclature

Options, arguments, flags... what's the difference?

An application's main function is passed an array of strings. These are the unparsed command-line arguments, or unparsed arguments for short.

The unparsed arguments can then be parsed into options, which start with a hyphen ("-"), and positional arguments. For example, in the command ls -l /tmp/, the unparsed arguments would be "-l", "/tmp" where -l is an option, while /tmp/ is a positional argument.

Options can also have option arguments. In the command ls --time-style=iso, the option is --time-style and that options argument is iso. Note that in parsing a single unparsed argument can be split into an option and an option argument, or even into multiple options in some cases.

A flag is a boolean option which has no arguments and which is false if not provided, but true if provided. The -l option of ls is a flag.

Option Types

Boolean Flags

Boolean flags are created by asking the parser for a flagging delegate. One or more option names, may be provided:

val verbose by parser.flagging("-v", "--verbose",
                               help = "enable verbose mode")

Here the presence of either -v or --verbose options in the arguments will cause the Boolean property verbose to be true, otherwise it will be false.

Storing a Single Argument

Single argument options are created by asking the parser for a storing delegate.

val name by parser.storing("-N", "--name",
                           help = "name of the user")

Here either -N or --name with an argument will cause the name property to have that argument as its value.

A function can also be supplied to transform the argument into the desired type. Here the size property will be an Int rather than a String:

val size by parser.storing("-c", "--count",
                           help = "number of widgets") { toInt() }

Adding to a Collection

Options that add to a Collection each time they appear in the arguments are created with using the adding delegate. Just like storing delegates, a transform function may optionally be supplied:

val includeDirs by parser.adding(
        "-I", help = "directory to search for header files") { File(this) }

Now each time the -I option appears, its transformed argument is appended to includeDirs.

Mapping from an option to a fixed value

For choosing between a fixed set of values (typically, but not necessarily, from an enum), a mapping delegate can be used:

val mode by parser.mapping(
        "--fast" to Mode.FAST,
        "--small" to Mode.SMALL,
        "--quiet" to Mode.QUIET,
        help = "mode of operation")

Here the mode property will be set to the corresponding ArgParser.Mode value depending on which of --fast, --small, and --quiet appears (last) in the arguments.

mapping is one of the few cases where it is not possible to infer the option name from the property name.

More advanced options

For all other types of options, the option method should be used. The methods mentioned above are, in fact, convenience methods built on top of the option method.

For example, it is possible to create an option that has multiple arguments:

  fun ArgParser.putting(vararg names: String, help: String) =
          option<MutableMap<String, String>>(*names,
                  argNames = listOf("KEY", "VALUE"),
                  help = help) {
              value.orElse { mutableMapOf<String, String>() }.apply {
                  put(arguments.first(), arguments.last()) }
          }

Note that the option method does not have an auto-naming overload. If you need this capability, create a DelegateProvider that creates your Delegate:

  fun ArgParser.putting(help: String) =
          ArgParser.DelegateProvider { identifier ->
              putting(identifierToOptionName(identifier), help = help) }

Positional Arguments

Positional arguments are collected by using the positional and positionalList methods.

For a single positional argument:

val destination by parser.positional("destination filename")

An explicit name may also be specified:

val destination by parser.positional("DEST",
                                     help = "destination filename")

The name ("DEST", here) is used in error handling and help text.

For a list of positional arguments:

val sources by parser.positionalList("SOURCE", 1..Int.MAX_VALUE,
                                     help = "source filename")

The range indicates how many arguments should be collected, and defaults to the value shown in this example. As the name suggests, the resulting property will be a List.

Both of these methods accept an optional transform function for converting arguments from String to whatever type is actually desired:

val destination by parser.positional("DEST",
                                     help = "...") { File(this) }

val sources by parser.positionalList("SOURCE", 1..Int.MAX_VALUE,
                                     help = "...") { File(this) }

Modifying Delegates

The delegates returned by any of these methods also have a few methods for setting optional attributes:

Adding a Default Value

Certain types of delegates (notably storing, mapping, and positional) have no default value, and hence will be required options unless a default value is provided. This is done with the default method:

val name by parser.storing("-N", "--name", help = "...").default("John Doe")

Note that it is possible to use null for the default, though this may require specifying the type parameter for default explicitly:

val name by parser.storing("-N", "--name", help = "...").default<String?>(null)

The type of the resulting property be nullable (a String? in this case).

Adding a Validator

Sometimes it's easier to validate an option at the end of parsing, in which case the addValidator method can be used.

val percentages by parser.adding("--percentages", help = "...") { toInt() }
        .addValidator {
              if (value.sum() != 100)
                  throw InvalidArgumentException(
                          "Percentages must add up to 100%")
        }

Error Handling

If the parser determines that execution should not continue it will throw a SystemExitException which has a status code appropriate for passing to exitProcess as well as a message for the user.

These exceptions can be caused by user error, or even if the user requests help (eg: via the --help option).

It is recommended that transform functions (given to storing, positionalList, etc.) and post-parsing validation, including that performed via, addValidator also throw a SystemExitException on failure.

As a convenience, these exceptions can be handled by using the mainBody function:

class ParsedArgs(parser: ArgParser) {
    val name by positional("The user's name").default("world")
}

fun main(args: Array<String>) = mainBody {
    ArgParser(args).parseInto(::ParsedArgs).run {
        println("Hello, {name}!")
    }
}

Parsing

Parsing of command-line arguments is performed sequentially. So long as option-processing is enabled, each not-yet-processed command-line argument that starts with a hyphen (-) is treated as an option.

Short Options

Short options start with a single hyphen. If the option takes an argument, the argument can either be appended:

# "-o" with argument "ARGUMENT"
my_program -oARGUMENT

or can be the following command-line argument:

# "-o" with argument "ARGUMENT"
my_program -o ARGUMENT

Zero argument short options can also be appended to each other without intermediate hyphens:

# "-x", "-y" and "-z" options
my_program -xyz

An option that accepts arguments is also allowed at the end of such a chain:

# "-x", "-y" and "-z" options, with argument for "-z"
my_program -xyzARGUMENT

Long Options

Long options start with a double hyphen (--). An argument to a long option can either be delimited with an equal sign (=):

# "--foo" with argument "ARGUMENT"
my_program --foo=ARGUMENT

or can be the following command-line argument:

# "--foo" with argument "ARGUMENT"
my_program --foo ARGUMENT

Multi-argument Options

Multi-argument options are supported, though currently not by any of the convenience methods. Option-arguments after the first must be separate command-line arguments, for both an long and short forms of an option.

Positional Arguments

In GNU mode (the default), options can be interspersed with positional arguments, but in POSIX mode the first positional argument that is encountered disables option processing for the remaining arguments. In either mode, if the argument "--" is encountered while option processing is enabled, then option processing is disabled for the rest of the command-line. Once the options and option-arguments have been eliminated, what remains are considered to be positional arguments.

Each positional argument delegate can specify a minimum and maximum number of arguments it is willing to collect.

The positional arguments are distributed to the delegates by allocating each positional delegate at least as many arguments as it requires. If more than the minimum number of positional arguments have been supplied then additional arguments will be allocated to the first delegate up to its maximum, then the second, and so on, until all arguments have been allocated to a delegate.

This makes it easy to create a program that behaves like grep:

class Args(parser: ArgParser) {
    // accept 1 regex followed by n filenames
    val regex by parser.positional("REGEX",
            help = "regular expression to search for")
    val files by parser.positionalList("FILE",
            help = "file to search in")
}

And equally easy to create a program that behaves like cp:

class Args(parser: ArgParser) {
    // accept n source files followed by 1 destination
    val sources by parser.positionalList("SOURCE",
            help = "source file")
    val destination by parser.positional("DEST",
            help = "destination file")
}

Forcing Parsing

Parsing normally does not begin until a delegate's value is accessed. Sometimes this is not desirable, so it is possible to enforce the parsing of arguments into a class of values. This ensures that all arguments that are required are provided, and all arguments provided are consumed.

Forcing can be done in a separate step using the force method:

val parser = ArgParser(args)
val parsedArgs = ParsedArgs(parser)
parser.force()
// now you can use parsedArgs

Alternatively, forcing can be done inline via the parseInto method:

val parsedArgs = ArgParser(args).parseInto(::ParsedArgs)
// now you can use parsedArgs

In both cases exceptions will be thrown where parsing or validation errors are found.

Help Formatting

By default, ArgParser will add a --help option (short name -h) for displaying usage information. If this option is present a ShowHelpException will be thrown. If the default exception handling is being used (see Error Handling) the program will halt and print a help message like the one below, based on the ArgParser configuration:

usage: program_name [-h] [-n] [-I INCLUDE]... -o OUTPUT
                    [-v]... SOURCE... DEST


This is the prologue. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Aliquam malesuada maximus eros. Fusce
luctus risus eget quam consectetur, eu auctor est
ullamcorper. Maecenas eget suscipit dui, sed sodales erat.
Phasellus.


required arguments:
  -o OUTPUT,          directory in which all output should
  --output OUTPUT     be generated


optional arguments:
  -h, --help          show this help message and exit

  -n, --dry-run       don't do anything

  -I INCLUDE,         search in this directory for header
  --include INCLUDE   files

  -v, --verbose       increase verbosity


positional arguments:
  SOURCE              source file

  DEST                destination file


This is the epilogue. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Donec vel tortor nunc. Sed eu
massa sed turpis auctor faucibus. Donec vel pellentesque
tortor. Ut ultrices tempus lectus fermentum vestibulum.
Phasellus.

The creation of the --help option can be disabled by passing null as the helpFormatter when constructing the ArgParser, or configured by manually constructing a HelpFormatter instance. In the above example a DefaultHelpFormatter was created with the prologue and epilogue.

Caveats

  • This library should be considered to be very beta. While there are no plans to make any breaking changes to the API, it's possible that there may be some until it is mature.

  • Upon reading the value any of the delegated properties created by an ArgParser, the arguments used to construct that ArgParser will be parsed. This means it's important that you don't attempt to create delegates on an ArgParser after any of its existing delegated properties have been read. Attempting to do so will cause an IllegalStateException. It would be nice if Kotlin had facilities for doing some of the work of ArgParser at compile time rather than run time, but so far the run time errors seem to be reasonably easy to avoid.

Configuring Your Build

Kotlin-argparser binaries are hosted on Maven Central and also Bintray's JCenter.

In Gradle, add something like this in your build.gradle:

// you probably already have this part
buildscript {
    repositories {
        mavenCentral() // or jcenter()
    }
}

dependencies {
    compile "com.xenomachina:kotlin-argparser:$kotlin_argparser_version"
}

In Maven add something like this to your pom.xml:

<dependency>
    <groupId>com.xenomachina</groupId>
    <artifactId>kotlin-argparser</artifactId>
    <version>VERSION</version>
</dependency>

Information on setting up other build systems, as well as the current version number, can be found on MVN Repository's page for Kotlin-argparser.

Thanks

Thanks to the creators of Python's argparse module, which provided the initial inspiration for this library.

Thanks also to the team behind Kotlin.

Finally, thanks to all of the people who have contributed code and/or issues.

Comments
  • ShowHelpException not caught

    ShowHelpException not caught

    Apologies if I'm misunderstanding something here, but from looking at the implementation it doesn't seem like anything is catching com.xenomachina.argparser.ShowHelpException: Help was requested and if I start my application with -h or --help, I see the exception stacktrace rather than the help text:

    Exception in thread "main" com.xenomachina.argparser.ShowHelpException: Help was requested
            at com.xenomachina.argparser.ArgParser$1.invoke(ArgParser.kt:590)
            at com.xenomachina.argparser.ArgParser$1.invoke(ArgParser.kt:38)
            at com.xenomachina.argparser.OptionDelegate.parseOption(OptionDelegate.kt:60)
            at com.xenomachina.argparser.ArgParser.parseShortOpts(ArgParser.kt:576)
            at com.xenomachina.argparser.ArgParser.access$parseShortOpts(ArgParser.kt:38)
            at com.xenomachina.argparser.ArgParser$parseOptions$2.invoke(ArgParser.kt:473)
            at com.xenomachina.argparser.ArgParser$parseOptions$2.invoke(ArgParser.kt:38)
            at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:130)
            at com.xenomachina.argparser.ArgParser.getParseOptions(ArgParser.kt)
            at com.xenomachina.argparser.ArgParser.force(ArgParser.kt:447)
            at com.xenomachina.argparser.ParsingDelegate.getValue(ParsingDelegate.kt:39)
            at com.xenomachina.argparser.ArgParser$Delegate.getValue(ArgParser.kt:340)
            at myapp.TestRunnerArgs.getTests(testRunner.kt)
    

    Is this expected? Do I need to catch this myself and delegate to the help formatter?

    opened by passy 7
  • Bind truly-optional nullable properties

    Bind truly-optional nullable properties

    I've been using sentinel values and default() to accomplish this, but it's gets awkward when using custom types. I would really like something like optional() which turned the property into a having a nullable type.

    opened by JakeWharton 7
  • Allow escaping strings

    Allow escaping strings

    Using positionalList or multi-argument flags is somehow inconvenient to bypass taking parameters containing spaces. There should ne support for various string escaping:

    • Enclosing a string with quotation marks should allow parsing a whole phrase as one argument:
    someCommand -s "This is one argument" -t something
    
    • Also, to use quotation marks within arguments without parsing them, escaping characters would be nice:
    someCommand -s \"Hello\"
    
    • Since escaping is also useful for other situations support for newlines or unicode escaping would also be nice:
    someCommand -n \n -u \u{2830}
    
    • Alternatively, spaces could also be escaped using the latter technique:
    someCommand -s This\ is\ one\ argument -t something
    
    opened by Cydhra 6
  • Maven not downloading .jar from bintray

    Maven not downloading .jar from bintray

    I've added the Bintray maven dependency but the argparse libraries are not in my path... only the xenocom ones are (xenomachina.text and .common)

    I'm not a Maven expert, but I had a look at the .pom on Bintray -- I see the Xenocom dependency in there -- maybe there's something misconfigured or not pointing to the argparse jar?

    opened by seanfdnn 6
  • parser.adding(...).default(...) does not work

    parser.adding(...).default(...) does not work

    As parser.adding(...) creates default delegate by itself (ArgParser.kt:137), nested default delegates are confused as to whose default value should be used, and it does not work.

    opened by ice-phoenix 4
  • .addValidator after .default removes default setting

    .addValidator after .default removes default setting

    The following code

    private val x by parser.storing(
    		"-x",
    		help = "",
    		transform = String::toInt
    ).addValidator {
    	// Validate here
    }.default(0)
    

    receives the default value of 0 and gets labeled as optional, while

    private val x by parser.storing(
    		"-x",
    		help = "",
    		transform = String::toInt
    ).default(0).addValidator {
    	// Validate here
    }
    

    does not, and gets labeled as required parameter.

    bug 
    opened by PvdBerg1998 4
  • Mechanism which combines 'adding' and 'positionalList' behavior

    Mechanism which combines 'adding' and 'positionalList' behavior

    I want to parse a command which takes a series of key/value pairs. From my experiments, adding gives me the ability to accumulate multiple arguments and positionalList gives me the ability to consume the next two arguments after a flag. There doesn't appear to be a way to combine these so that I can accomplish something like the following:

    ./whatever --kv hey there --kv these are --kv multiple values
    

    Which would somehow allow combining the positionalList and adding behavior into a List<List<String>>.

    enhancement 
    opened by JakeWharton 4
  • Make `mainBody` behavior the default when parsing args

    Make `mainBody` behavior the default when parsing args

    It took me quite a while (and frustration) to realize that my naive way of setting up a parser with

    val args = ArgParser(args).parseInto(::MyArgs) 
    
    

    wont give any help by default unless I wrap it with

    val args = mainBody { ArgParser(args).parseInto(::MyArgs) }
    

    Why can't parseInto catch the exception by default and print the help (similar to how mainBody works). Requiring a lambda here seems too much. A boolean parameter such as catchEx or similar (defaulting to to true) for parseInto seems more intuitive to me.

    opened by holgerbrandl 3
  • Exception in thread

    Exception in thread "main" com.xenomachina.argparser.ShowHelpException: Help was requested

    Hi, any ideas about this exception? I thought it would print the help automatically (I passed --help as an arg).

    Exception in thread "main" com.xenomachina.argparser.ShowHelpException: Help was requested
    	at com.xenomachina.argparser.ArgParser$1.invoke(ArgParser.kt:608)
    	at com.xenomachina.argparser.ArgParser$1.invoke(ArgParser.kt:38)
    	at com.xenomachina.argparser.OptionDelegate.parseOption(OptionDelegate.kt:61)
    	at com.xenomachina.argparser.ArgParser.parseLongOpt(ArgParser.kt:567)
    	at com.xenomachina.argparser.ArgParser.access$parseLongOpt(ArgParser.kt:38)
    	at com.xenomachina.argparser.ArgParser$parseOptions$2.invoke(ArgParser.kt:493)
    	at com.xenomachina.argparser.ArgParser$parseOptions$2.invoke(ArgParser.kt:38)
    	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
    	at com.xenomachina.argparser.ArgParser.getParseOptions(ArgParser.kt)
    	at com.xenomachina.argparser.ArgParser.force(ArgParser.kt:448)
    	at com.xenomachina.argparser.ArgParser.parseInto(ArgParser.kt:470)
    ...
    
    opened by sanity 3
  • NPE in constructor of DefaultHelpFormatter

    NPE in constructor of DefaultHelpFormatter

    Following line:

        var hf = DefaultHelpFormatter()
    

    leads to a NullPointerException:

    Exception in thread "main" kotlin.KotlinNullPointerException
    	at kotlin.coroutines.experimental.SequenceBuilderIterator.yield(SequenceBuilder.kt:163)
    	at com.xenomachina.text.TextKt$codePointSequence$1.doResume(Text.kt:33)
    	at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
    	at kotlin.coroutines.experimental.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:128)
    	at com.xenomachina.text.term.TextTermKt.codePointWidth(TextTerm.kt:180)
    	at com.xenomachina.argparser.DefaultHelpFormatter.<init>(DefaultHelpFormatter.kt:66)
    	at edu.kit.iti.formal.automation.rvt.HelloKt.main(Hello.kt:16)
    
    • kotlin-argparser version: com.xenomachina : kotlin-argparser : 2.0.1
      • version 2.0.0 also effected
      • version 1.1.0 not effected
    • Kotlin version: 1.1.2-4
    bug 
    opened by wadoon 3
  • Allow '.' as Separator in Options and Arguments

    Allow '.' as Separator in Options and Arguments

    The paradigm used for "advanced" options at my company uses namespace-qualified option names on the command line. A la:

    java -jar my-program.jar --com.foo.bar=100 --com.foo.baz=taco
    

    Specifying these as options will always throw IllegalArgumentException, as this does not pass the OPTION_NAME_RE pattern in ArgParser.kt. Is there any reason to prevent using '.' as part of an option or argument (sibling to the '_' and '-' characters)?

    opened by tgockel 2
  • Extend the optional delegate to accept a list of hardcoded acceptable values

    Extend the optional delegate to accept a list of hardcoded acceptable values

    I propose to add the following overloads to the ArgParser@option function, so that we can specify a list of valid values, and if the user specifies anything else, it'll throw. Example usage would be

    val mode by parser.option<Mode?>(
            "-m", "--mode",
            values = listOf("play", "search", "list"),
            help = "some very nice description, valid options are: [id, name, flags]",
        ) {
            when(this) {
                "play" -> Mode.Play
                "name" -> Mode.Search
                "tags" -> Mode.List
                else -> null
            }
        }.default(null)
    

    or with the latter overload

    val mode by parser.option(
            "-m", "--mode",
            values = listOf("play", "search", "list"),
            help = "some very nice description, valid options are: [play, search, list]",
        ).default<String?>(null)
    

    This would allow usage to be as follows:

    $ ./app --mode=play          // ok
    $ ./app -m play              // ok
    $ ./app -m hello             // error, "hello" was not a valid value
    $ ./app                      // ok, the option has a default value and isnt a required field
    

    It's technically already possible through the already existing overloads, but I can definitely see this to be a very common use, so I find it valuable enough to be included in the library.

    opened by NoakPalander 0
  • JCenter end of life

    JCenter end of life

    JFrog announced that they'll be shutting down JCenter: https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/

    Key dates:

    • March 31st 2021: No more submissions will be accepted to Bintray, JCenter
    • February 1st 2022: Bintray, JCenter services will no longer be available

    Hence kotlin-argparser should also be migrated to another maven repository like Maven central.

    opened by nbonbon 0
  • Support options of the form " (hyphen immediately followed by a number)">

    Support options of the form "-" (hyphen immediately followed by a number)

    Like the max-count option in git log:

    -<number>
    -n <number>
    --max-count=<number>
    

    Or the -n option in gnu head/tail

    Also it would be nice if the library had appropriate visibility of utility methods so a user can implement such behaviour himself (I don't think that's the case currently, e.g internal object PosixNaming).

    opened by amynbe 0
  • better handling of long parameter names in the default formatter

    better handling of long parameter names in the default formatter

    We have a case where we have some really long parameter names, which in the default formatting wraps all the descriptions into a single column. We work around this by specifying 120 columns, but a better solution would be if the formatter recognized that the names were over some threshold and then placed the description on the next line. So instead of the following:

    required arguments:
      --messaging-internal-format-uri MESSAGING_INTERNAL_FORMAT_URI                     Uri to publish messages in the
                                                                                        internal format. e.g.
                                                                                        rabbit://user:pass@localhost:5672
                                                                                        ?exchange=some-name
    
      --messaging-internal-format-with-raw-uri MESSAGING_INTERNAL_FORMAT_WITH_RAW_URI   Uri to publish messages in the
                                                                                        internal format plus the raw
                                                                                        message. e.g.
                                                                                        rabbit://user:pass@localhost:5672
                                                                                        ?exchange=some-other-name
    

    It could look like the following:

    required arguments:
      --messaging-internal-format-uri MESSAGING_INTERNAL_FORMAT_URI                     
            Uri to publish messages in the internal format. e.g.
            rabbit://user:pass@localhost:5672?exchange=some-name
    
      --messaging-internal-format-with-raw-uri MESSAGING_INTERNAL_FORMAT_WITH_RAW_URI   
            Uri to publish messages in the internal format plus the raw message. e.g.
            rabbit://user:pass@localhost:5672?exchange=some-other-name
    
    opened by stevenklassen8376 0
  • Influcence exit behaviour

    Influcence exit behaviour

    When using the mainBody, the system performs a exitProcess when e.h. --help is used. This brings down my whole unit test VM, so it would be nice to have the possibility to influence the exit behaviour like telling it that no exit should be performed.

    The default of course is, that the exitProcess is done.

    opened by guenhter 0
Releases(2.0.7)
Owner
Laurence Gonsalves
Founder of @Niphtio. Formerly @Google (Google Reader, GXP, AdWords, AdSense, and more)
Laurence Gonsalves
kraskaska-runner: This application allows you to automatically restart specific command. Initially made for minecraft servers.

kraskaska-runner This application allows you to automatically restart specific command. Initially made for minecraft servers. Usage: Usage: kraskaska-

Kraskaska 2 Aug 30, 2022
Powerful, elegant and flexible test framework for Kotlin with additional assertions, property testing and data driven testing

Kotest is a flexible and comprehensive testing tool for Kotlin with multiplatform support. To learn more about Kotest, visit kotest.io or see our quic

Kotest 3.8k Jan 3, 2023
A powerful test framework for Android

Cafe A powerful test framework for Android named Case Automated Framework for Everyone. Home Page http://baiduqa.github.com/Cafe/ How to make Cafe dow

Baidu 367 Nov 22, 2022
A powerful test framework for Android

Cafe A powerful test framework for Android named Case Automated Framework for Everyone. Home Page http://baiduqa.github.com/Cafe/ How to make Cafe dow

Baidu 367 Nov 22, 2022
Strikt is an assertion library for Kotlin intended for use with a test runner such as JUnit, Minutest, Spek, or KotlinTest.

Strikt is an assertion library for Kotlin intended for use with a test runner such as JUnit, Minutest, Spek, or KotlinTest.

Rob Fletcher 447 Dec 26, 2022
A collection of tests and easy to reuse pieces of code for bdk-jvm and bdk-android

Readme This repo is a collection of tests and easy to reuse pieces of code for bdk-jvm and bdk-android. Note that they don't aim to provide a full cov

thunderbiscuit 1 Jun 28, 2022
Easy Response Mocking for Retrofit using annotations

Response Mocking for Retrofit using annotations. Assume Provides safe and easy way to mock API responses for retrofit-okhttp3.

Aniket Bhoite 25 Nov 16, 2021
Kotlin wrapper for React Test Renderer, which can be used to unit test React components in a Kotlin/JS project.

Kotlin API for React Test Renderer Kotlin wrapper for React Test Renderer, which can be used to unit test React components in a Kotlin/JS project. How

Xavier Cho 7 Jun 8, 2022
A multiplatform assertion library for Kotlin

Atrium is an open-source multiplatform assertion library for Kotlin with support for JVM, JS and Android. It is designed to support multiple APIs, dif

Robert Stoll 439 Dec 29, 2022
Portable validations for Kotlin

Portable validations for Kotlin ✅ Type-safe DSL ?? Multi-platform support (JVM, JS) ?? Zero dependencies Installation For multiplatform projects: kotl

null 509 Dec 18, 2022
mocking library for Kotlin

Kotlin Academy articles Check the series of articles "Mocking is not rocket science" at Kt. Academy describing MockK from the very basics of mocking u

MockK 4.8k Jan 3, 2023
Fixtures for Kotlin providing generated values for unit testing

A tool to generate well-defined, but essentially random, input following the idea of constrained non-determinism.

Appmattus Limited 191 Dec 21, 2022
A Kotlin Android library for heuristics evasion that prevents your code from being tested.

EvadeMe An Android library for heuristics evasion that prevents your code from being tested. User Instructions Add the maven repository to your projec

Chris Basinger 29 Dec 26, 2022
Lightweight service for creating standalone mock, written in pure Kotlin with Netty container.

MockService The lightweight service for creating a standalone mock, written in pure Kotlin with Netty container. The service allows getting config fil

null 2 Oct 28, 2021
Proyecto de Kotlin y JPA sobre Hibernate, con algunos test usando JUnit 5 y Mockito.

Contactos Kotlin JPA Ejemplos de una aplicación de manejo de contactos con Kotlin y JPA. Usando para testear la aplicación JUnit 5 y Mockito. Almacena

José Luis González Sánchez 3 Sep 13, 2022
This is a sample API project for Rest Assured with Maven Kotlin DSL & JUnit 5

Kotlin-RestAssured Test Automation This is a sample API project for Rest Assured with Maven Kotlin DSL & JUnit 5 Introduction All the Test Cases kept

Dilshan Fernando 0 Dec 9, 2021
Android Sample Kotlin+ MVVM + Coroutines + Retrofit +Hilt+ Junit + Mockito

NTimes AppSample NY Times Most Popular Articles simple app to hit the NY Times Most Popular Articles API and show a list of articles, that shows detai

Amer Elsayed 0 Dec 27, 2021
Snapshot Testing framework for Kotlin.

KotlinSnapshot Snapshot Testing framework for Kotlin. What is this? Snapshot testing is an assertion strategy based on the comparision of the instance

Pedro Gómez 157 Nov 13, 2022
Automated tests using Rest-assured with Kotlin lang

Testes de API em Kotlin Pré-requisitos Instalar o Kotlin Ambiente Para executar os testes localmente, estou utilizando o ServeRest Link do Repo: https

Rafael Berçam 15 Dec 23, 2022