{"id":13804962,"url":"https://github.com/burner/argsd","last_synced_at":"2026-01-04T03:33:40.910Z","repository":{"id":47528267,"uuid":"91346123","full_name":"burner/argsd","owner":"burner","description":"A command line and config file parser for DLang","archived":false,"fork":false,"pushed_at":"2021-08-25T08:57:04.000Z","size":51,"stargazers_count":16,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-23T18:51:20.332Z","etag":null,"topics":["command-line-parser","configparser","configuration-file","dlang"],"latest_commit_sha":null,"homepage":null,"language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/burner.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}},"created_at":"2017-05-15T14:16:46.000Z","updated_at":"2024-07-28T01:59:13.000Z","dependencies_parsed_at":"2022-07-21T02:48:43.331Z","dependency_job_id":null,"html_url":"https://github.com/burner/argsd","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burner%2Fargsd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burner%2Fargsd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burner%2Fargsd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burner%2Fargsd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/burner","download_url":"https://codeload.github.com/burner/argsd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244006303,"owners_count":20382444,"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":["command-line-parser","configparser","configuration-file","dlang"],"created_at":"2024-08-04T01:00:55.724Z","updated_at":"2026-01-04T03:33:40.905Z","avatar_url":"https://github.com/burner.png","language":"D","readme":"# args\n\nA command line and config file parser for DLang\n\n\n## Quick Example\n\n### Parse command line options\n\n```d\nimport args : Arg, Optional, parseArgsWithConfigFile, printArgsHelp;\n\nstatic struct MyOptions {\n\t@Arg(\"the input file\", Optional.yes) string inputFilename;\n\t@Arg(\"test values\", 't') int[] testValues;\n\t@Arg(\"Enable feature\") bool enableFeature;\n}\n\nMyOptions getOptions(ref string[] args) {\n\tMyOptions options;\n\n\tbool helpWanted = parseArgsWithConfigFile(options, args);\n\n\tif (helpWanted) {\n\t\tprintArgsHelp(options, \"A text explaining the program\");\n\t}\n\treturn options;\n}\n\nvoid main(string[] args) {\n\tconst options = getOptions(args); // or args.dup to keep the original args\n\n\t// use options here....\n}\n```\n\nThis gives:\n```ps1\n❯ ./quick_example --help\nA text explaining the program\n     --inputFilename   Type: dchar[]   default:        Help: the input file\n-t   --testValues      Type: int[]     default: []     Help: test values\n     --enableFeature   Type: bool      default: false  Help: Enable feature\n\n```\n\n### Parse config file only\n\n```d\nimport std.stdio;\n\nimport args : Arg, Optional, parseArgsConfigFile, parseConfigFile;\n\nstatic struct Options {\n    @Arg(\"Path to some data dir\", Optional.no) string dataDir;\n    @Arg(\"Limit for something\", Optional.yes) int limit;\n    @Arg(\"Enable something\", Optional.yes) bool enable;\n}\n\nOptions getOptions(in string filePath) {\n    Options options;\n    auto data = parseArgsConfigFile(filePath);\n    parseConfigFile(options, data);\n\n    return options;\n}\n\nvoid main() {\n    string configPath = \"my.conf\";\n\n    Options options;\n    options = getOptions(configPath);\n\n    // use options here...\n\twriteln(\"Parsed options from file \", configPath, \" :\");\n    writeln(\"dataDir=\", options.dataDir);\n    writeln(\"limit=\", options.limit);\n    writeln(\"enable=\", options.enable);\n}\n```\n\nAssuming there is a file named \"my.conf\" with content\n```\ndataDir = \"/data/dir\"\nlimit = \"100\"\nenable = \"true\"\n```\n\nThe program output will be\n```\nParsed options from file my.conf :\ndataDir=/data/dir\nlimit=100\nenable=true\n```\n\n## Explanation\n\n`argsd` arguments are structures as shown below.\nEach argument that should be searched for needs to have `@Arg()`\nattached to it.\n\n`@Arg()` takes three kinds of parameter.\n1. A `string` which is used as the help message for that argument.\n2. A `char` which is used as the character for the short argument\nselector.\n3. A `Optional` value to make the argument as optional or not (default\nOptional.yes).\nThe order of the three parameter is not relevant.\n\nArguments can be nested, see the nested `NestedArgument struct` in\n`MyAppArguments`.\n\nArguments can be of all primitive types, arrays of primitive types and `D\nenum`s.\n\nAll arguments take the shape \"name value\". Equal sign syntax is not\nsupported.\n\nArray values can be given as a comma separated list.\n\nThe name of the argument will be derived from the name of the member in\nthe struct. The names are case sensitive.\n\nArguments in nested structs have the name of the struct prefixed (compare\n`--nested.someFloatValue`).\n\nShort names must be unique. If they are not unique an Exception will be\nthrown. Short names are used by prefixing the character with a single `-`.\nThe short name `-h` is reserved for requestion the help page.\n\nLong names are unique by definition. Long names are prefixed with `--`.\nThe long name \"--help\" is reserved for requestion the help page.\n\nIf `parseArgsWithConfigFile` is used two more long names are reserved,\n`--config`, and `--genConfig`. Both take a `string` as argument.\n`--config filename` will try to parse the file with name `filename` and\nassign the values in that file to the argument struct passed.\n\n`--genConfig filename` can be used to create a config file with\nthe default values of the argument struct. The name of the config file is\nagain `filename`.\n\n\n```d\n/** A enum used inside of NestedArguments */\nenum NestedEnumArgument {\n\tone,\n\ttwo,\n\tmany\n}\n\n/** A struct nested in MyAppArguments */\nstatic struct NestedArguments {\n\t@Arg(\"Important Help Message\") float someFloatValue;\n\n\t// D allows to assign default values to the arguments\n\t@Arg('z') NestedEnumArgument enumArg = NestedEnumArgument.two;\n\t@Arg() bool someBool;\n}\n\n/** The options to the created program. */\nstatic struct MyAppArguments {\n\t@Arg(Optional.no) string inputFilename;\n\t@Arg('b') int[] testValues;\n\n\t/** All options inside of nested need to be prefixed with\n\t  \"nested.\".\n\t*/\n\t@Arg() NestedArguments nested;\n}\n\nimport std.algorithm.comparison : equal;\nimport std.format : format;\nimport std.math : isClose;\n```\n\nIt is good practice to have the arguments write-protected by default.\nThe following three declarations show a possible implementation.\n\nIn order to look up a argument the developer would use the `config()`\nfunction, returning him a write-protected version of the arguments.\nIn order to populate the arguments the writable version returned from\n`configWriteable` is passed to `parseArgsWithConfigFile`.\nThis, and the option definitions is usually placed in a separate file and\nthe visibility of `MyAppArguments argument` is set to `D private`.\n\nMyAppArguments arguments;\n\n```d\nref MyAppArguments configWriteable() {\n\treturn arguments;\n}\n\nref const(MyAppArguments) config() {\n\treturn arguments;\n}\n```\n\nThis `string[]` serves as an example of what would be passed to the\n`main` function from the command line.\n\n```d\nstring[] args = [\"./executablename\",\n\t\"--nested.someBool\",\n\t\"--nested.someFloatValue\", \"12.34\",\n\t\"--testValues\", \"10\",\n\t\"-b\", \"11,12\",\n\t\"--nested.enumArg\", \"many\",\n\t\"--inputFilename\", \"nice.d\"];\n```\n\nPopulates the argument struct returned from configWriteable with the\nvalues passed in `args`.\n\n`true` is returned if the help page is requested with either `-h` or\n`--help`.\n`parseArgsWithConfigFile`, and `parseArgs` will remove all used\nstrings from `args`.\nAfter the unused strings and the application name are left in `args`.\n\nReplacing `parseArgsWithConfigFile` with `parseArgs` will disable\nthe config file parsing option.\n\n```d\nbool helpWanted = parseArgsWithConfigFile(configWriteable(), args);\n\nif(helpWanted) {\n\t/** If the help page is wanted by the user the printArgsHelp\n\tfunction can be used to print help page.\n\t*/\n\tprintArgsHelp(config(), \"A text explaining the program\");\n}\n\n/** Here it is tested if the parsing of args was successful. */\nassert(equal(config().testValues, [10,11,12]));\nassert(config().nested.enumArg == NestedEnumArgument.many);\nassert(isClose(config().nested.someFloatValue, 12.34));\nassert(config().nested.someBool);\nassert(config().inputFilename == \"nice.d\");\n```\n","funding_links":[],"categories":["Command Line"],"sub_categories":["XML"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburner%2Fargsd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fburner%2Fargsd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburner%2Fargsd/lists"}