{"id":21301744,"url":"https://github.com/funbox/optimus","last_synced_at":"2026-03-07T03:03:50.130Z","repository":{"id":43673865,"uuid":"74502815","full_name":"funbox/optimus","owner":"funbox","description":"Command line arguments parser for Elixir","archived":false,"fork":false,"pushed_at":"2023-06-19T18:55:28.000Z","size":316,"stargazers_count":184,"open_issues_count":2,"forks_count":14,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-08T21:16:24.373Z","etag":null,"topics":["argument-parser","elixir-library"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/funbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2016-11-22T18:43:27.000Z","updated_at":"2025-02-27T20:19:16.000Z","dependencies_parsed_at":"2025-01-09T20:39:10.041Z","dependency_job_id":null,"html_url":"https://github.com/funbox/optimus","commit_stats":{"total_commits":107,"total_committers":10,"mean_commits":10.7,"dds":"0.17757009345794394","last_synced_commit":"62595c03bc564a22365e5d4d5ffdb0351d1b74d3"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/funbox/optimus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funbox%2Foptimus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funbox%2Foptimus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funbox%2Foptimus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funbox%2Foptimus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funbox","download_url":"https://codeload.github.com/funbox/optimus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funbox%2Foptimus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30206341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"online","status_checked_at":"2026-03-07T02:00:06.765Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["argument-parser","elixir-library"],"created_at":"2024-11-21T15:50:40.313Z","updated_at":"2026-03-07T03:03:50.095Z","avatar_url":"https://github.com/funbox.png","language":"Elixir","readme":"# Optimus\n\n\u003cimg align=\"right\" width=\"192\" height=\"192\" alt=\"Optimus avatar: Transformer's head shaped as a letter “O”\" src=\"./assets/logo.png\"\u003e\n\n[![Build Status](https://travis-ci.org/funbox/optimus.svg?branch=master)](https://travis-ci.org/funbox/optimus)\n[![Coverage Status](https://coveralls.io/repos/github/funbox/optimus/badge.svg?branch=master)](https://coveralls.io/github/funbox/optimus?branch=master)\n[![Module Version](https://img.shields.io/hexpm/v/optimus.svg)](https://hex.pm/packages/optimus)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/optimus/)\n[![Total Download](https://img.shields.io/hexpm/dt/optimus.svg)](https://hex.pm/packages/optimus)\n[![License](https://img.shields.io/hexpm/l/optimus.svg)](https://github.com/funbox/optimus/blob/master/LICENSE.md)\n[![Last Updated](https://img.shields.io/github/last-commit/funbox/optimus.svg)](https://github.com/funbox/optimus/commits/master)\n\nA command line arguments parsing library for [Elixir](http://elixir-lang.org).\n\nIt's aim is to take off the maximum possible amount of manual argument handling.\nThe intended use case is to configure Optimus parser, run it against the\ncommand line and then do nothing but take completely validated\nready to use values.\n\nThe library was strongly inspired by the awesome [clap.rs](https://clap.rs/)\nlibrary. Optimus does not generally follow its design, but it tries to\nfollow the idea of zero manual manipulation with the values after the parser has\nreturned them.\n\n## Installation\n\nAdd `optimus` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:optimus, \"~\u003e 0.2\"}\n  ]\nend\n```\n\n## Example\n\nLet's configure a CLI interface to an imaginary utility which reads data from\na file of the following format:\n\n```\n# timestamp, value\n1481729245, 12.0\n1481729245, 13.0\n1481729246, 11.1\n...\n```\n\nand outputs some statistic metrics of the values.\nIt also has a subcommand which validates the source file integrity.\n\n```elixir\ndefmodule Statcalc do\n  def main(argv) do\n    Optimus.new!(\n      name: \"statcalc\",\n      description: \"Statistic metrics calculator\",\n      version: \"1.2.3\",\n      author: \"John Smith js@corp.com\",\n      about: \"Utility for calculating statistic metrics of values read from a file for a certain period of time\",\n      allow_unknown_args: false,\n      parse_double_dash: true,\n      args: [\n        infile: [\n          value_name: \"INPUT_FILE\",\n          help: \"File with raw data\",\n          required: true,\n          parser: :string\n        ],\n        outfile: [\n          value_name: \"OUTPUT_FILE\",\n          help: \"File to write statistics to\",\n          required: false,\n          parser: :string\n        ]\n      ],\n      flags: [\n        print_header: [\n          short: \"-h\",\n          long: \"--print-header\",\n          help: \"Specifies whether to print header before the outputs\",\n          multiple: false,\n        ],\n        verbosity: [\n          short: \"-v\",\n          help: \"Verbosity level\",\n          multiple: true,\n        ],\n      ],\n      options: [\n        date_from: [\n          value_name: \"DATE_FROM\",\n          short: \"-f\",\n          long: \"--from\",\n          help: \"Start date for the period\",\n          parser: fn(s) -\u003e\n            case Date.from_iso8601(s) do\n              {:error, _} -\u003e {:error, \"invalid date\"}\n              {:ok, _} = ok -\u003e ok\n            end\n          end,\n          required: true\n        ],\n        date_to: [\n          value_name: \"DATE_TO\",\n          short: \"-t\",\n          long: \"--to\",\n          help: \"End date for the period\",\n          parser: fn(s) -\u003e\n            case Date.from_iso8601(s) do\n              {:error, _} -\u003e {:error, \"invalid date\"}\n              {:ok, _} = ok -\u003e ok\n            end\n          end,\n          required: false,\n          default: \u0026Date.utc_today/0\n        ],\n      ],\n      subcommands: [\n        validate: [\n          name: \"validate\",\n          about: \"Validates the raw contents of a file\",\n          args: [\n            file: [\n              value_name: \"FILE\",\n              help: \"File with raw data to validate\",\n              required: true,\n              parser: :string\n            ]\n          ]\n        ]\n      ]\n    ) |\u003e Optimus.parse!(argv) |\u003e IO.inspect\n  end\nend\n```\n\n(The whole sample code can be found in\n[optimus_example](https://github.com/savonarola/optimus_example) repo.)\n\nNearly all of the configuration options above are not mandatory.\n\nAlso most configuration parameters are self-explanatory, except `parser`.\nFor options and positional arguments `parser` is a lambda which accepts a string argument and returns either\n`{:ok, parsed_value}` or `{:error, string_reason}`. There are also some predefined parsers which are denoted by atoms:\n`:string`, `:integer` and `:float`. No parser means that `:string` parser will be used.\n\nNot required `options` can have a `default` value. Both a term (string, number, etc.) or a lambda with zero arity can be used.\nIf the `option` accepts `multiple` values, the `default` value should be a list, for example `[1.0]` or `fn -\u003e [\"x\", \"y\"] end`.\n\nNow if we try to launch our compiled escript without any args we'll see the following:\n\n```\n\u003e./statcalc\nThe following errors occurred:\n- missing required arguments: INPUT_FILE\n- missing required options: --from(-f), --to(-t)\n\nTry\n    statcalc --help\n\nto see available options\n```\n\nThere are several things to note:\n* the script exited (in `Optimus.parse!`) since we haven't received a valid set\nof arguments;\n* a list of errors is displayed (and it's as full as possible);\n* a user is offered to launch `statcalc` with `--help` flag which is automatically\nhandled by Optimus.\n\nIf we launch `statcalc --help`, we'll see the following:\n\n```\n\u003e./statcalc --help\nStatistic metrics calculator 1.2.3\nJohn Smith js@corp.com\nUtility for calculating statistic metrics of values read from a file for a certain period of time\n\nUSAGE:\n    statcalc [--print-header] --from DATE_FROM --to DATE_TO INPUT_FILE [OUTPUT_FILE]\n    statcalc --version\n    statcalc --help\n    statcalc help subcommand\n\nARGS:\n\n    INPUT_FILE         File with raw data\n    OUTPUT_FILE        File to write statistics to\n\nFLAGS:\n\n    -h, --print-header        Specifies whether to print header before the\n                              outputs\n\nOPTIONS:\n\n    -f, --from        Start date for the period\n    -t, --to          End date for the period  (default: 2017-12-20)\n\nSUBCOMMANDS:\n\n    validate        Validates the raw contents of a file\n\n```\n\nThe things to note are:\n* Optimus formed a formatted help information and also exited;\n* it also offers some other autogenerated commands (`--version` and `help subcommand`).\n\nNow if we finally produce a valid list of args, we'll have our arguments parsed:\n\n```elixir\n\u003e./statcalc --print-header -f 2016-01-01 -t 2016-02-01 infile.raw outfile.dat\n%Optimus.ParseResult{\n  args: %{\n    infile: \"infile.raw\",\n    outfile: \"outfile.dat\"\n  },\n  flags: %{\n    print_header: true\n  },\n  options: %{\n    date_from: ~D[2016-01-01],\n    date_to: ~D[2016-02-01]\n  },\n  unknown: []\n}\n```\n\n`Optimus.ParseResult` is a struct with four fields: `args`, `flags`, `options`,\nwhich are maps, and `unknown`, which is a list. Things to note are:\n* `unknown` list is always empty if we set `allow_unknown_args: false` for our\n(sub)command;\n* values in `args`, `flags` and `options` maps are kept under keys specified in configuration;\n* for options with `multiple: true` the value is a list;\n* for flags without `multiple: true` the value is a boolean;\n* for flags with `multiple: true` the value is an integer (representing the\n  number of occurrences of a flag).\n\n## Credits\n\n* [José Valim](https://github.com/josevalim) and all other creators of [`Elixir`](http://elixir-lang.org)\n* [Kevin K.](https://github.com/kbknapp) and all other creators of [`clap.rs`](https://clap.rs)\n\nBrutal picture for the project was made by [Igor Garybaldi](http://pandabanda.com/).\n\n## Copyright and License\n\nCopyright (c) 2016 Ilya Averyanov\n\nThis work is free. You can redistribute it and/or modify it under the\nterms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details.\n\n[![Sponsored by FunBox](https://funbox.ru/badges/sponsored_by_funbox_centered.svg)](https://funbox.ru)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunbox%2Foptimus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunbox%2Foptimus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunbox%2Foptimus/lists"}