{"id":13801027,"url":"https://github.com/com-lihaoyi/mainargs","last_synced_at":"2025-05-15T12:00:21.213Z","repository":{"id":40404598,"uuid":"312781000","full_name":"com-lihaoyi/mainargs","owner":"com-lihaoyi","description":"A small, convenient, dependency-free library for command-line argument parsing in Scala","archived":false,"fork":false,"pushed_at":"2025-03-10T09:47:03.000Z","size":330,"stargazers_count":196,"open_issues_count":30,"forks_count":25,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-14T19:59:14.920Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/com-lihaoyi.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-14T09:00:48.000Z","updated_at":"2025-04-09T20:25:01.000Z","dependencies_parsed_at":"2023-01-25T20:46:18.340Z","dependency_job_id":"9220601e-ad3f-4d64-8260-2a0eaf60e5e4","html_url":"https://github.com/com-lihaoyi/mainargs","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/com-lihaoyi%2Fmainargs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/com-lihaoyi%2Fmainargs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/com-lihaoyi%2Fmainargs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/com-lihaoyi%2Fmainargs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/com-lihaoyi","download_url":"https://codeload.github.com/com-lihaoyi/mainargs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:18.734Z","updated_at":"2025-05-15T12:00:21.133Z","avatar_url":"https://github.com/com-lihaoyi.png","language":"Scala","funding_links":[],"categories":["Table of Contents","Console"],"sub_categories":["Command Line Interfaces"],"readme":"# mainargs 0.7.6\n\nMainArgs is a small, dependency-free library for command line argument parsing\nin Scala.\n\nMainArgs is used for command-line parsing of the\n[Ammonite Scala REPL](http://ammonite.io/) and for user-defined `@main` methods\nin its scripts, as well as for command-line parsing for the\n[Mill Build Tool](https://github.com/lihaoyi/mill) and for user-defined\n`T.command`s.\n\n- [mainargs](#mainargs)\n- [Usage](#usage)\n  - [Parsing Main Method Parameters](#parsing-main-method-parameters)\n    - [runOrExit](#runorexit)\n    - [runOrThrow](#runorthrow)\n    - [runEither](#runeither)\n    - [runRaw](#runraw)\n  - [Multiple Main Methods](#multiple-main-methods)\n  - [Parsing Case Class Parameters](#parsing-case-class-parameters)\n  - [Re-using Argument Sets](#re-using-argument-sets)\n  - [Option or Sequence parameters](#option-or-sequence-parameters)\n  - [Short Arguments](#short-arguments)\n  - [Annotations](#annotations)\n    - [@main](#main)\n    - [@arg](#arg)\n  - [Customization](#customization)\n  - [Custom Argument Parsers](#custom-argument-parsers)\n  - [Handlings Leftover Arguments](#handlings-leftover-arguments)\n    - [Varargs Parameters](#varargs-parameters)\n- [Prior Art](#prior-art)\n  - [Ammonite \u0026 Mill](#ammonite--mill)\n  - [Case App](#case-app)\n  - [Scopt](#scopt)\n- [Changelog](#changelog)\n- [Scaladoc](https://javadoc.io/doc/com.lihaoyi/mainargs_2.13/latest/mainargs/index.html)\n\n# Usage\n\n```scala\nivy\"com.lihaoyi::mainargs:0.7.6\"\n```\n\n## Parsing Main Method Parameters\n\nYou can parse command line arguments and use them to call a main method via\n`ParserForMethods(...)`:\n\n```scala\npackage testhello\nimport mainargs.{main, arg, ParserForMethods, Flag}\n\nobject Main{\n  @main\n  def run(@arg(short = 'f', doc = \"String to print repeatedly\")\n          foo: String,\n          @arg(doc = \"How many times to print string\")\n          myNum: Int = 2,\n          @arg(doc = \"Example flag, can be passed without any value to become true\")\n          bool: Flag) = {\n    println(foo * myNum + \" \" + bool.value)\n  }\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n$ ./mill example.hello -f hello # short name\nhellohello false\n\n$ ./mill example.hello --foo hello # long name\nhellohello false\n\n$ ./mill example.hello --foo=hello # gflags-style\nhellohello false\n\n$ ./mill example.hello --foo \"\" # set to empty value\n false\n\n$ ./mill example.hello --foo= # gflags-style empty value\n false\n\n$ ./mill example.hello -f x --my-num 3 # camelCase automatically converted to kebab-case\nxxx false\n\n$ ./mill example.hello -f hello --my-num 3 --bool # flags\nhellohellohello true\n\n$ ./mill example.hello --wrong-flag\nMissing argument: --foo \u003cstr\u003e\nUnknown argument: \"--wrong-flag\"\nExpected Signature: run\n  -f --foo \u003cstr\u003e  String to print repeatedly\n  --my-num \u003cint\u003e  How many times to print string\n  --bool          Example flag\n```\n\nSetting default values for the method arguments makes them optional, with the\ndefault value being used if an explicit value was not passed in from the\ncommand-line arguments list.\n\nAfter calling `ParserForMethods(...)` on the `object` containing your `@main`\nmethods, you can call the following methods to perform the argument parsing and\ndispatch:\n\n### runOrExit\n\nRuns the given main method if argument parsing succeeds, otherwise prints out\nthe help text to standard error and calls `System.exit(1)` to exit the process\n\n### runOrThrow\n\nRuns the given main method if argument parsing succeeds, otherwise throws an\nexception with the help text\n\n### runEither\n\nRuns the given main method if argument parsing succeeds, returning `Right(v: Any)` containing the return value of the main method if it succeeds, or `Left(s: String)` containing the error message if it fails.\n\n### runRaw\n\nRuns the given main method if argument parsing succeeds, returning\n`mainargs.Result.Success(v: Any)` containing the return value of the main method\nif it succeeds, or `mainargs.Result.Error` if it fails. This gives you the\ngreatest flexibility to handle the error cases with custom logic, e.g. if you do\nnot like the default CLI error reporting and would like to write your own.\n\n## Multiple Main Methods\n\nPrograms with multiple entrypoints are supported by annotating multiple `def`s\nwith `@main`. Each entrypoint can have their own set of arguments:\n\n```scala\npackage testhello2\nimport mainargs.{main, arg, ParserForMethods, Flag}\n\nobject Main{\n  @main\n  def foo(@arg(short = 'f', doc = \"String to print repeatedly\")\n          foo: String,\n          @arg(doc = \"How many times to print string\")\n          myNum: Int = 2,\n          @arg(doc = \"Example flag\")\n          bool: Flag) = {\n    println(foo * myNum + \" \" + bool.value)\n  }\n  @main\n  def bar(i: Int,\n          @arg(doc = \"Pass in a custom `s` to override it\")\n          s: String  = \"lols\") = {\n    println(s * i)\n  }\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n$ ./mill example.hello2\nNeed to specify a sub command: foo, bar\n\n$ ./mill example.hello2 foo -f hello\nhellohello false\n\n$ ./mill example.hello2 bar -i 10\nlolslolslolslolslolslolslolslolslolslols\n```\n\n## Parsing Case Class Parameters\n\nIf you want to construct a configuration object instead of directly calling a\nmethod, you can do so via `ParserForClass[T]` and `constructOrExit:\n\n```scala\npackage testclass\nimport mainargs.{main, arg, ParserForClass, Flag}\n\nobject Main{\n  @main\n  case class Config(@arg(short = 'f', doc = \"String to print repeatedly\")\n                    foo: String,\n                    @arg(doc = \"How many times to print string\")\n                    myNum: Int = 2,\n                    @arg(doc = \"Example flag\")\n                    bool: Flag)\n  def main(args: Array[String]): Unit = {\n    val config = ParserForClass[Config].constructOrExit(args)\n    println(config)\n  }\n}\n```\n\n```bash\n$ ./mill example.caseclass --foo \"hello\"\nConfig(hello,2,Flag(false))\n\n$ ./mill example.caseclass\nMissing argument: --foo \u003cstr\u003e\nExpected Signature: apply\n  -f --foo \u003cstr\u003e  String to print repeatedly\n  --my-num \u003cint\u003e  How many times to print string\n  --bool          Example flag\n```\n\n`ParserForClass[T]` also provides corresponding `constructOrThrow`,\n`constructEither`, or `constructRaw` methods for you to handle the error cases\nin whichever style you prefer.\n\n## Re-using Argument Sets\n\nYou can share arguments between different `@main` methods by defining them in a\n`@main case class` configuration object with an implicit `ParserForClass[T]`\ndefined:\n\n```scala\npackage testclassarg\nimport mainargs.{main, arg, ParserForMethods, ParserForClass, Flag}\n\nobject Main{\n  @main\n  case class Config(@arg(short = 'f', doc = \"String to print repeatedly\")\n                    foo: String,\n                    @arg(doc = \"How many times to print string\")\n                    myNum: Int = 2,\n                    @arg(doc = \"Example flag\")\n                    bool: Flag)\n  implicit def configParser = ParserForClass[Config]\n\n  @main\n  def bar(config: Config,\n          @arg(name = \"extra-message\")\n          extraMessage: String) = {\n    println(config.foo * config.myNum + \" \" + config.bool.value + \" \" + extraMessage)\n  }\n  @main\n  def qux(config: Config,\n          n: Int) = {\n    println((config.foo * config.myNum + \" \" + config.bool.value + \"\\n\") * n)\n  }\n\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n\n$ ./mill example.classarg bar --foo cow --extra-message \"hello world\"\ncowcow false hello world\n\n$ ./mill example.classarg qux --foo cow --n 5\ncowcow false\ncowcow false\ncowcow false\ncowcow false\ncowcow false\n```\n\nThis allows you to re-use common command-line parsing configuration without\nneeding to duplicate it in every `@main` method in which it is needed. A `@main def` can make use of multiple `@main case class`es, and `@main case class`es can\nbe nested arbitrarily deeply.\n\n## Option or Sequence parameters\n\n`@main` method parameters can be `Option[T]` or `Seq[T]` types, representing\noptional parameters without defaults or repeatable parameters\n\n```scala\npackage testoptseq\nimport mainargs.{main, arg, ParserForMethods}\n\nobject Main{\n  @main\n  def runOpt(opt: Option[Int]) = println(opt)\n\n  @main\n  def runSeq(seq: Seq[Int]) = println(seq)\n\n  @main\n  def runVec(seq: Vector[Int]) = println(seq)\n\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n$ ./mill example.optseq runOpt\nNone\n\n$ ./mill example.optseq runOpt --opt 123\nSome(123)\n\n$ ./mill example.optseq runSeq --seq 123 --seq 456 --seq 789\nList(123, 456, 789)\n```\n\n\n## Short Arguments\n\n`@main` method arguments that have single-character names are automatically converted\nto short arguments, invoked with a single `-` instead of double `--`. The short version\nof an argument can also be given explicitly via the `@arg(short = '...')`: \n\n```scala\nobject Base {\n  @main\n  def bools(a: Flag, b: Boolean = false) = println(Seq(a.value, b, c.value))\n  \n  @main\n  def strs(a: Flag, b: String) = println(Seq(a.value, b))\n}\n```\n\nThese can be invoked as normal, for `Flag`s like `-a` or normal arguments that take \na value like `-b` below:\n\n```bash\n$ ./mill example.short bools -a\nSeq(true, false)\n\n$ ./mill example.short bools -b true\nSeq(false, true)\n```\n\nMultiple short arguments can be combined into one `-ab` call:\n\n$ ./mill example.short bools -ab true\nSeq(true, true)\n```\n\nShort arguments can be combined with their value:\n\n```scala\n$ ./mill example.short bools -btrue\nSeq(false, true)\n```\n\nAnd you can combine both multiple short arguments as well as the resulting value:\n\n```scala\n$ ./mill example.short bools -abtrue\nSeq(true, true)\n```\n\nNote that when multiple short arguments are combined, whether via `-ab true` or via `-abtrue`,\nonly the last short argument (in this case `b`) can take a value.\n\nIf an `=` is present in the short argument group after the first character, the short\nargument group is treated as a key-value pair with the remaining characters after the `=`\npassed as the value to the first short argument:\n\n```scala\n$ ./mill example.short strs -b=value\nSeq(false, value)\n\n$ ./mill example.short strs -a -b=value\nSeq(true, value)\n```\n\nYou can use `-b=` as a shorthand to set the value of `b` to an empty string:\n\n```scala\n$ ./mill example.short strs -a -b=\n  Seq(true, )\n```\n\nIf an `=` is present in the short argument group after subsequent character, all characters\nexcept the first are passed to the first short argument. This can be useful for concisely\npassing key-value pairs to a short argument:\n\n```scala\n$ ./mill example.short strs -a -bkey=value\nSeq(true, key=value)\n```\n\n```scala\nThese can also be combined into a single token, with the first non-`Flag` short argument in the\ntoken consuming the subsequent characters as a string (unless the subsequent characters start with\nan `=`, which is skipped):\n\n```scala\n$ ./mill example.short strs -ab=value\nSeq(true, value)\n\n$ ./mill example.short strs -abkey=value \nSeq(true, key=value)\n```\n\n## Annotations\n\nThe library's annotations and methods support the following parameters to\ncustomize your usage:\n\n### @main\n\n- `name: String`: lets you specify the top-level name of `@main` method you are\n  defining. If multiple `@main` methods are provided, this name controls the\n  sub-command name in the CLI. If an explicit `name` is not passed, both the\n  (typically) `camelCase` name of the Scala `def` as well as its `kebab-case` \n  equivalents will be accepted\n\n- `doc: String`: a documentation string used to provide additional information\n  about the command. Normally printed below the command name in the help message\n\n### @arg\n\n- `name: String`: lets you specify the long name of a CLI parameter, e.g.\n  `--foo`. If an explicit `name` is not passed, both the (typically) `camelCase`\n  name of the Scala method parameter as well as its `kebab-case`\n  equivalents will be accepted\n\n- `short: Char`: lets you specify the short name of a CLI parameter, e.g. `-f`.\n  If not given, the argument can only be provided via its long name\n\n- `doc: String`: a documentation string used to provide additional information\n  about the command\n\n- `noDefaultName: Boolean`: if `true` this arg (e.g `fooBar`) can only be called by its mangled name `--foo-bar` and not by the original name `--fooBar`. Defaults to `false`\n\n- `positional: Boolean`: if `true` this arg can be passed \"positionally\" without\n  the `--name` of the parameter being provided, e.g. `./mill example.hello hello 3 --bool`. Defaults to `false`\n\n- `hidden: Boolean`: if `true` this arg will not be included in the rendered help text.\n\n## Customization\n\nApart from taking the name of the main `object` or config `case class`,\n`ParserForMethods` and `ParserForClass` both have methods that support a number\nof useful configuration values:\n\n- `allowPositional: Boolean`: allows you to pass CLI arguments \"positionally\"\n  without the `--name` of the parameter being provided, e.g. `./mill example.hello -f hello --my-num 3 --bool` could be called via `./mill example.hello hello 3 --bool`. Defaults to `false`\n\n- `allowRepeats: Boolean`: allows you to pass in a flag multiple times, and\n  using the last provided value rather than raising an error. Defaults to\n  `false`\n\n- `totalWidth: Int`: how wide to re-format the `doc` strings to when printing\n  the help text. Defaults to `100`\n\n- `printHelpOnExit: Boolean`: whether or not to print the full help text when\n  argument parsing fails. This can be convenient, but potentially very verbose\n  if the list of arguments is long. Defaults to `true`\n\n- `docsOnNewLine: Boolean`: whether to print argument doc-strings on a new line\n  below the name of the argument; this may make things easier to read, but at a\n  cost of taking up much more vertical space. Defaults to `false`\n\n- `autoprintHelpAndExit: Option[(Int, PrintStream)]`: whether to detect `--help`\n  being passed in automatically, and if so where to print the help message and\n  what exit code to exit the process with. Defaults t, `Some((0, System.out))`,\n  but can be disabled by passing in `None` if you want to handle help text\n  manually (e.g. by calling `.helpText` on the parser object)\n\n- `customName`/`customNames` and `customDoc`/`customDocs`: allows you to\n  override the main method names and documentation strings at runtime. This\n  allows you to work around limitations in the use of the `@main(name = \"...\", doc = \"...\")` annotation that only allows simple static strings.\n\n- `sorted: Boolean`: whether to sort the arguments alphabetically in the help text. Defaults to `true`\n\n- `nameMapper: String =\u003e Option[String]`: how Scala `camelCase` names are mapping\n  to CLI command and flag names. Defaults to translation to `kebab-case`, but\n  you can pass in `mainargs.Util.snakeCaseNameMapper` for `snake_case` CLI names\n  or `mainargs.Util.nullNameMapper` to disable mapping.\n\n## Custom Argument Parsers\n\nIf you want to parse arguments into types that are not provided by the library,\nyou can do so by defining an implicit `TokensReader[T]` for that type:\n\n```scala\npackage testcustom\nimport mainargs.{main, arg, ParserForMethods, TokensReader}\n\nobject Main{\n  implicit object PathRead extends TokensReader.Simple[os.Path]{\n    def shortName = \"path\"\n    def read(strs: Seq[String]) = Right(os.Path(strs.head, os.pwd))\n  }\n\n  @main\n  def run(from: os.Path, to: os.Path) = {\n    println(\"from: \" + from)\n    println(\"to:   \" + to)\n  }\n\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n$ ./mill example.custom --from mainargs --to out\nfrom: /Users/lihaoyi/Github/mainargs/mainargs\nto:   /Users/lihaoyi/Github/mainargs/out\n```\n\nIn this example, we define an implicit `PathRead` to teach MainArgs how to parse\n`os.Path`s from the [OS-Lib](https://github.com/lihaoyi/os-lib) library.\n\nNote that `read` takes all tokens that were passed to a particular parameter.\nNormally this is a `Seq` of length `1`, but if `allowEmpty` is `true` it could\nbe an empty `Seq`, and if `alwaysRepeatable` is `true` then it could be\narbitrarily long.\n\nYou can see the Scaladoc for `TokenReaders.Simple` for other things you can override:\n\n- [mainargs.TokenReaders.Simple](https://javadoc.io/doc/com.lihaoyi/mainargs_2.13/latest/mainargs/TokensReader$$Simple.html)\n\n\n## Handlings Leftover Arguments\n\nYou can use the special `Leftover[T]` type to store any tokens that are\nnot consumed by other parsers:\n\n```scala\npackage testvararg\nimport mainargs.{main, arg, ParserForMethods, Leftover}\n\nobject Main{\n  @main\n  def run(foo: String,\n          myNum: Int = 2,\n          rest: Leftover[String]) = {\n    println(foo * myNum + \" \" + rest.value)\n  }\n\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\n```bash\n$ ./mill example.vararg --foo bar i am cow\nbarbar List(i, am, cow)\n```\n\nThis also works with `ParserForClass`:\n\n```scala\npackage testvararg2\nimport mainargs.{main, arg, ParserForClass, Leftover}\n\nobject Main{\n  @main\n  case class Config(foo: String,\n                    myNum: Int = 2,\n                    rest: Leftover[String])\n\n  def main(args: Array[String]): Unit = {\n    val config = ParserForClass[Config].constructOrExit(args)\n    println(config)\n  }\n}\n```\n\n```bash\n$ ./mill example.vararg2 --foo bar i am cow\nConfig(bar,2,Leftover(List(i, am, cow)))\n```\n\nYou can also pass in a different type to `Leftover`, e.g. `Leftover[Int]` or\n`Leftover[Boolean]`, if you want to specify that leftover tokens all parse to a\nparticular type. Any tokens that do not conform to that type will result in an\nargument parsing error.\n\n### Varargs Parameters\n\nYou can also use `*` \"varargs\" to define a parameter that takes in the remainder\nof the tokens passed to the CLI:\n\n```scala\npackage testvararg\nimport mainargs.{main, arg, ParserForMethods, Leftover}\n\nobject Main{\n  @main\n  def run(foo: String,\n          myNum: Int,\n          rest: String*) = {\n    println(foo * myNum + \" \" + rest.value)\n  }\n\n  def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)\n}\n```\n\nNote that this has a limitation that you cannot then assign default values to\nthe other parameters of the function, and hence using `Leftover[T]` is\npreferable for those cases.\n\n# Prior Art\n\n## Ammonite \u0026 Mill\n\nMainArgs grew out of the user-defined `@main` method feature supported by\nAmmonite Scala Scripts:\n\n- http://ammonite.io/#ScriptArguments\n\nThis implementation was largely copy-pasted into the Mill build tool, to use for\nits user-defined `T.command`s. A parallel implementation was used to parse\ncommand-line parameters for Ammonite and Mill themselves.\n\nNow all four implementations have been unified in the MainArgs library, which\nboth Ammonite and Mill rely heavily upon. MainArgs also provides some additional\nfeatures, such as making it easy to define short versions of flags like `-c` via\nthe `short = '...'` parameter, or re-naming the command line flags via `name = \"...\"`.\n\n## Case App\n\nMainArgs' support for parsing Scala `case class`es was inspired by Alex\nArchambault's `case-app` library:\n\n- https://github.com/alexarchambault/case-app\n\nMainArgs has the following differentiators over `case-app`:\n\n- Support for directly dispatching to `@main` method(s), rather than only\n  parsing into `case class`es\n- A dependency-free implementation, without pulling in the heavyweight Shapeless\n  library.\n\n## Scopt\n\nMainArgs takes a lot of inspiration from the old Scala Scopt library:\n\n- https://github.com/scopt/scopt\n\nUnlike Scopt, MainArgs lets you call `@main` methods or instantiate `case class`es directly, without needing to separately define a `case class` and\nparser. This makes it usable with much less boilerplate than Scopt: a single\nmethod annotated with `@main` is all you need to turn your program into a\ncommand-line friendly tool.\n\n# Changelog\n\n## 0.7.6\n\n-  add support for Scala 2 varargs in scala 3 macro [#167](http://github.com/com-lihaoyi/mainargs/pull/167)\n\n## 0.7.5\n\n- Fix reporting of incomplete short args [#162](https://github.com/com-lihaoyi/mainargs/pull/162)\n- Add BigDecimal TokensReader [#152](https://github.com/com-lihaoyi/mainargs/pull/152)\n\n## 0.7.4\n\n- Fix issue with binary infinite recursion in binary compatibility forwarders [#156](https://github.com/com-lihaoyi/mainargs/pull/156)\n\n## 0.7.3\n\n- Add missing `nameMapper` argument to `.runOrExit`, make `sort` param on `runEither` return\n  `true` for consistency with the docs [#155](https://github.com/com-lihaoyi/mainargs/pull/155)\n\n## 0.7.2\n\n- Various improvements to Scala 3 macros to match Scala 2 implementation [#148](https://github.com/com-lihaoyi/mainargs/pull/148)\n\n## 0.7.1\n\n- Fix detection of `@main` methods inherited from `trait`s in Scala 3.x [#142](https://github.com/com-lihaoyi/mainargs/pull/142)\n\n## 0.7.0\n\n- Support for Scala-Native 0.5.0\n- Minimum version of Scala 3.x raised to 3.3.1\n\n## 0.6.3\n\n- Fix usage of `ParserForClass` for `case class`es with more than 22 parameters in Scala 2.x\n\n## 0.6.2\n\n- Make combine short args that fail to parse go through normal leftover-token code paths\n  [#112](https://github.com/com-lihaoyi/mainargs/pull/112)\n\n## 0.6.1\n\n- Fix stackoverflow from incorrect binary compatibility shim\n  [#107](https://github.com/com-lihaoyi/mainargs/pull/107)\n\n## 0.6.0\n\n- Automatically map `camelCase` Scala method and argument names to `kebab-case`\n  CLI commands and flag names, with configurability by passing in custom\n  `nameMappers` [#101](https://github.com/com-lihaoyi/mainargs/pull/101)\n\n- Allow short arguments and their values to be combined into a single token \n  [#102](https://github.com/com-lihaoyi/mainargs/pull/102)\n\n## 0.5.4\n\n- Remove unnecessary PPrint dependency\n\n## 0.5.3\n\n- Support GFlags-style `--foo=bar` syntax [#98](https://github.com/com-lihaoyi/mainargs/pull/98)\n\n## 0.5.1\n\n- Fix handling of case class main method parameter default parameters and\n  annotations in Scala 3 [#88](https://github.com/com-lihaoyi/mainargs/pull/88)\n\n## 0.5.0\n\n- Remove hard-code support for mainargs.Leftover/Flag/Subparser to support\n  alternate implementations [#62](https://github.com/com-lihaoyi/mainargs/pull/62).\n  Note that this is a binary-incompatible change, and any custom \n  `mainargs.TokenReader`s you may implement will need to be updated to implement\n  the `mainargs.TokenReader.Simple` trait \n  \n- Fix argument parsing of flags in the presence of `allowPositional=true`\n  [#66](https://github.com/com-lihaoyi/mainargs/pull/66)\n\n## 0.4.0\n\n- Support sorting to args in help text and sort by default\n- Various dependency updates\n- This release is binary compatible with mainargs 0.3.0\n\n## 0.3.0\n\n- Update all dependencies to latest\n- Support for Scala Native on Scala 3\n\n## 0.2.5\n\n- Backport of *Fix usage of `ParserForClass` for `case class`es with more than\n  22 parameters with some default values in Scala 2.x (#123)* on top of 0.2.3\n\n## 0.2.3\n\n- Support Scala 3 [#18](https://github.com/com-lihaoyi/mainargs/pull/18)\n\n## 0.2.2\n\n- Fix hygiene of macros [#12](https://github.com/com-lihaoyi/mainargs/pull/12)\n- Allow special characters in method names and argument names [#13](https://github.com/com-lihaoyi/mainargs/pull/13)\n\n## 0.2.1\n\n- Scala-Native 0.4.0 support\n\n## 0.1.7\n\n- Add support for `positional=true` flag in `mainargs.arg`, to specify a\n  specific argument can only be passed positionally regardless of whether\n  `allowPositional` is enabled for the entire parser\n\n- Allow `-` and `--` to be passed as argument values without being treated as\n  flags\n\n## 0.1.4\n\n- First release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcom-lihaoyi%2Fmainargs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcom-lihaoyi%2Fmainargs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcom-lihaoyi%2Fmainargs/lists"}