{"id":17053688,"url":"https://github.com/kareman/moderator","last_synced_at":"2025-04-12T16:46:05.804Z","repository":{"id":62447952,"uuid":"45646612","full_name":"kareman/Moderator","owner":"kareman","description":"A simple, modular command line argument parser in Swift.","archived":false,"fork":false,"pushed_at":"2019-03-30T20:02:17.000Z","size":16672,"stargazers_count":21,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-21T00:02:31.892Z","etag":null,"topics":["argument-parser","command-line","swift","swift-library"],"latest_commit_sha":null,"homepage":null,"language":"Swift","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/kareman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-05T23:33:29.000Z","updated_at":"2024-07-11T14:51:27.000Z","dependencies_parsed_at":"2022-11-01T23:17:50.176Z","dependency_job_id":null,"html_url":"https://github.com/kareman/Moderator","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kareman%2FModerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kareman%2FModerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kareman%2FModerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kareman%2FModerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kareman","download_url":"https://codeload.github.com/kareman/Moderator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248600732,"owners_count":21131536,"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":["argument-parser","command-line","swift","swift-library"],"created_at":"2024-10-14T10:12:59.220Z","updated_at":"2025-04-12T16:46:05.768Z","avatar_url":"https://github.com/kareman.png","language":"Swift","readme":" [Run shell commands](https://github.com/kareman/SwiftShell)    |    Parse command line arguments | [Handle files and directories](https://github.com/kareman/FileSmith)\n\n---\n\n[![Build Status](https://travis-ci.org/kareman/Moderator.svg?branch=master)](https://travis-ci.org/kareman/Moderator) ![Platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20Linux-lightgrey.svg) ![Version](https://img.shields.io/badge/Swift-3%20%7C%204%20%7C%205-orange.svg) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n# Moderator\n\nModerator is a simple Swift library for parsing commandline arguments.\n\n## Features\n\n- [x] Modular, easy to extend.\n- [x] Supports a [cross platform syntax](https://nottoobadsoftware.com/blog/uncategorized/cross-platform-command-line-arguments-syntax/).\n- [x] Generates help text automatically.\n- [x] Handles arguments of the type '--option=value'.\n- [x] Optional strict parsing, where an error is thrown if there are any unrecognised arguments.\n- [x] Any arguments after an \"\\--\" argument are taken literally, they are not parsed as options and any '=' are left untouched.\n\nSee also [why Moderator was created](https://nottoobadsoftware.com/blog/swift/moderator-parsing-commandline-arguments-in-swift/).\n\n## Example\n\nfrom [linuxmain-generator](https://github.com/kareman/linuxmain-generator):\n\n```Swift\nimport Moderator\nimport FileSmith\n\nlet arguments = Moderator(description: \"Automatically add code to Swift Package Manager projects to run unit tests on Linux.\")\nlet overwrite = arguments.add(.option(\"o\",\"overwrite\", description: \"Replace \u003ctest directory\u003e/LinuxMain.swift if it already exists.\"))\nlet testdirarg = arguments.add(Argument\u003cString?\u003e\n\t.optionWithValue(\"testdir\", name: \"test directory\", description: \"The path to the directory with the unit tests.\")\n\t.default(\"Tests\"))\n_ = arguments.add(Argument\u003cString?\u003e\n\t.singleArgument(name: \"directory\", description: \"The project root directory.\")\n\t.default(\"./\")\n\t.map { (projectpath: String) in\n\t\tlet projectdir = try Directory(open: projectpath)\n\t\ttry projectdir.verifyContains(\"Package.swift\")\n\t\tDirectory.current = projectdir\n\t})\n\ndo {\n\ttry arguments.parse()\n\n\tlet testdir = try Directory(open: testdirarg.value)\n\tif !overwrite.value \u0026\u0026 testdir.contains(\"LinuxMain.swift\") {\n\t\tthrow ArgumentError(errormessage: \"\\(testdir.path)/LinuxMain.swift already exists. Use -o/--overwrite to replace it.\")\n\t}\n\t...\n} catch {\n\tWritableFile.stderror.print(error)\n\texit(Int32(error._code))\n}\n```\n\nAutomatically generated help text: \n\n```text\nAutomatically add code to Swift Package Manager projects to run unit tests on Linux.\n\nUsage: linuxmain-generator\n  -o,--overwrite:\n      Replace \u003ctest directory\u003e/LinuxMain.swift if it already exists.\n  --testdir \u003ctest directory\u003e:\n      The path to the directory with the unit tests. Default = 'Tests'.\n  \u003cdirectory\u003e:\n      The project root directory. Default = './'.\n```\n\n## Introduction\n\nModerator works by having a single Moderator object which you add individual argument parsers to. When you start parsing it goes through each argument parser _in the order they were added_. Each parser takes the array of string arguments from the command line, finds the arguments it is responsible for, processes them and throws any errors if anything is wrong, _removes the arguments from the array_, returns its output (which for some parsers may be nil if the argument was not found) and passes the modified array to the next parser.\n\nThis keeps the code simple and each parser only has to take care of its own arguments. The built-in parsers can easily be customised, and you can create your own parsers from scratch.\n\n## Built-in parsers\n\n### Option\n\n```swift\nfunc option(_ names: String..., description: String? = nil) -\u003e Argument\u003cBool\u003e\n```\n\nHandles option arguments like `-h` and `--help`. Returns true if the argument is present and false otherwise.\n\n### Option with value\n\n```swift\nfunc optionWithValue(_ names: String..., name valuename: String? = nil, description: String? = nil)\n-\u003e Argument\u003cString?\u003e\n```\n\nHandles option arguments with a following value, like `--help \u003ctopic\u003e`. It returns the value as a String, or nil if the option is not present.\n\n### Single argument\n\n```swift\nfunc singleArgument(name: String, description: String? = nil) -\u003e Argument\u003cString?\u003e\n```\n\nReturns the next argument, or nil if there are no more arguments or the next argument is an option. Must be added after any option parsers.\n\n## Customise\n\n### `default`\n\nCan be used on parsers returning optionals, to replace nil with a default value.\n\n### `required`\n\nCan be used on parsers returning optionals, to throw an error on nil.\n\n### `map`\n\nTakes the output of any argument parser and converts it to something else.\n\n### `repeat`\n\nLooks for multiple occurrences of an argument, by repeating an optional parser until it returns nil.\n\n```swift\nlet m = Moderator()\nlet options = m.add(Argument\u003cString?\u003e.optionWithValue(\"b\").repeat())\nlet multiple = m.add(Argument\u003cString?\u003e.singleArgument(name: \"multiple\").repeat())\n\ntry m.parse([\"-b\", \"b1\", \"-b\", \"b2\", \"-b\", \"b3\", \"one\", \"two\", \"three\"])\n```\n\n`options.value` is now `[\"b1\", \"b2\", \"b3\"]` and `multiple.value` is `[\"one\", \"two\", \"three\"]`. \n\n### `count`\n\nCounts the number of times an option argument occurs.\n\n```swift\n\nlet m = Moderator()\nlet option = m.add(Argument\u003cBool\u003e.option(\"b\").count())\n\ntry m.parse([\"-b\", \"-b\", \"some\", \"other\", \"-b\", \"arguments\"])\n```\n\n`option.value` returns `3`\n \n## Add new parsers \n\nIf the built in parsers and customisations are not enough, you can easily create your own parsers. As an example here is the implementation of the singleArgument parser:\n\n```swift\nextension Argument {\n\tpublic static func singleArgument (name: String, description: String? = nil) -\u003e Argument\u003cString?\u003e {\n\t\treturn Argument\u003cString?\u003e(usage: description.map { (\"\u003c\"+name+\"\u003e\", $0) }) { args in\n\t\t\tlet index = args.first == \"--\" ? args.index(after: args.startIndex) : args.startIndex\n\t\t\tguard index != args.endIndex, !isOption(index: index, args: args) else { return (nil, args) }\n\t\t\tvar args = args\n\t\t\treturn (args.remove(at: index), args)\n\t\t}\n\t}\n}\n```\n\nIn the Argument initialiser you return a tuple with the output of the parser and the arguments array without the processed argument(s).\n\n## Installation\n\n### [Swift Package Manager](https://github.com/apple/swift-package-manager)\n\nAdd `.Package(url: \"https://github.com/kareman/Moderator\", \"0.5.0\")` to your Package.swift:\n\n```swift\nimport PackageDescription\n\nlet package = Package(\n\tname: \"somename\",\n\tdependencies: [\n\t\t.Package(url: \"https://github.com/kareman/Moderator\", \"0.5.0\")\n\t\t ]\n\t)\n```\n\nand run `swift build`.\n\n### [Carthage](https://github.com/Carthage/Carthage)\n\nAdd `github \"kareman/Moderator\"` to your Cartfile, then run `carthage update` and add the resulting framework to the \"Embedded Binaries\" section of the application. See [Carthage's README][carthage-installation] for further instructions.\n\n[carthage-installation]: https://github.com/Carthage/Carthage/blob/master/README.md#adding-frameworks-to-an-application\n\n### [CocoaPods](https://cocoapods.org/)\n\nAdd `Moderator` to your `Podfile`.\n\n```ruby\npod \"Moderator\", git: \"https://github.com/kareman/Moderator.git\"\n```\n\nThen run `pod install` to install it.\n\n## License\n\nReleased under the MIT License (MIT), http://opensource.org/licenses/MIT\n\nKåre Morstøl, [NotTooBad Software](https://nottoobadsoftware.com)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkareman%2Fmoderator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkareman%2Fmoderator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkareman%2Fmoderator/lists"}