Straightforward, type-safe argument parsing for Swift

Overview

Swift Argument Parser

Usage

Begin by declaring a type that defines the information that you need to collect from the command line. Decorate each stored property with one of ArgumentParser's property wrappers, declare conformance to ParsableCommand, and implement your command's logic in the run() method.

import ArgumentParser

struct Repeat: ParsableCommand {
    @Flag(help: "Include a counter with each repetition.")
    var includeCounter = false

    @Option(name: .shortAndLong, help: "The number of times to repeat 'phrase'.")
    var count: Int?

    @Argument(help: "The phrase to repeat.")
    var phrase: String

    mutating func run() throws {
        let repeatCount = count ?? .max

        for i in 1...repeatCount {
            if includeCounter {
                print("\(i): \(phrase)")
            } else {
                print(phrase)
            }
        }
    }
}

Repeat.main()

You kick off execution by calling your type's static main() method. The ArgumentParser library parses the command-line arguments, instantiates your command type, and then either executes your run() method or exits with a useful message.

ArgumentParser uses your properties' names and type information, along with the details you provide using property wrappers, to supply useful error messages and detailed help:

$ repeat hello --count 3
hello
hello
hello
$ repeat --count 3
Error: Missing expected argument 'phrase'.
Usage: repeat [--count ] [--include-counter] 
  See 'repeat --help' for more information.
$ repeat --help
USAGE: repeat [--count ] [--include-counter] 

ARGUMENTS:
                  The phrase to repeat.

OPTIONS:
  --include-counter       Include a counter with each repetition.
  -c, --count      The number of times to repeat 'phrase'.
  -h, --help              Show help for this command.

For more information and documentation about all supported options, see the Documentation folder at the root of the repository.

Examples

This repository includes a few examples of using the library:

  • repeat is the example shown above.
  • roll is a simple utility implemented as a straight-line script.
  • math is an annotated example of using nested commands and subcommands.

You can also see examples of ArgumentParser adoption among Swift project tools:

  • indexstore-db is a simple utility with two commands.
  • swift-format uses some advanced features, like custom option values and hidden flags.

Adding ArgumentParser as a Dependency

To use the ArgumentParser library in a SwiftPM project, add the following line to the dependencies in your Package.swift file:

.package(url: "https://github.com/apple/swift-argument-parser", from: "0.4.0"),

Because ArgumentParser is under active development, source-stability is only guaranteed within minor versions (e.g. between 0.0.3 and 0.0.4). If you don't want potentially source-breaking package updates, use this dependency specification instead:

.package(url: "https://github.com/apple/swift-argument-parser", .upToNextMinor(from: "0.4.0")),

Finally, include "ArgumentParser" as a dependency for your executable target:

", dependencies: [ .product(name: "ArgumentParser", package: "swift-argument-parser"), ]), // other targets ] ) ">
let package = Package(
    // name, platforms, products, etc.
    dependencies: [
        .package(url: "https://github.com/apple/swift-argument-parser", from: "0.4.0"),
        // other dependencies
    ],
    targets: [
        .target(name: "", dependencies: [
            .product(name: "ArgumentParser", package: "swift-argument-parser"),
        ]),
        // other targets
    ]
)
Comments
  • Allow normal Swift default property initialization syntax

    Allow normal Swift default property initialization syntax

    This change allows the normal var foo = "blah" default initialization syntax for Options, as a parallel initialization method as using the default parameter.

    This syntax may feel more natural to some developers (myself included), but does not break any existing code using the original initialization method.

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [x] I've updated the documentation if necessary
    opened by MPLew-is 16
  • Improvements to `--dump-help`

    Improvements to `--dump-help`

    • Removes HelpInfo in favor of a recursively defined CommandInfo which contains more raw metadata about the source command. Additionally, introduces a top level ToolInfo type with a serialization version to aid future tooling.

    • Updates tests to match the new serialized format.

    • Renames DumpHelpInfoGenerator to DumpHelpGenerator to align the type with the --dump-help flag.

    enhancement 
    opened by rauhul 15
  • Make arrays with default values use their elements' defaultValueDescription

    Make arrays with default values use their elements' defaultValueDescription

    Makes default values for @Arguments and @Options whose values are arrays of ExpressibleByArgument use their elements' defaultValueDescription in the help text.

    Fixes #208.

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [x] I've updated the documentation if necessary
    opened by Wevah 15
  • Add --help-hidden for use with _hiddenFromHelp

    Add --help-hidden for use with _hiddenFromHelp

    Swift Package Manager adopted _hiddenFromHelp, the resulting help is much more approachable for basic usage, but leaves no way to view all the advanced options it accepts. This takes from swiftc's + clang's playbook and adds a hidden --help-hidden flag that prints all help, including those using _hiddenFromHelp

    Related: https://bugs.swift.org/browse/SR-15224

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [ ] I've updated the documentation if necessary
    opened by keith 14
  • Add experimental manual page generation

    Add experimental manual page generation

    • Adds a swift package manager command plugin called GenerateManualPlugin. The plugin can be invoked from the command line using swift package experimental-generate-manual. The plugin is prefixed for now with "experimental-" to indicate it is not mature and may see breaking changes to its CLI and output in the future. The plugin can be can be used to generate a manual in MDoc syntax for any swift-argument-parser tool that can be executed via tool --experimental-dump-info.
    • The plugin works by converting the ToolInfoV0 structure from the ArgumentParserToolInfo library into MDoc AST nodes using a custom (SwiftUI-esk) result builder DSL. The MDoc AST is then lowered to a string and written to disk.
    • The MDoc AST included is not general purpose and doesn't represent the true language exactly, so it is private to the underlying generate-manual tool. In the future it would be interesting to finish fleshing out this MDoc library and spin it out, however this is not a priority.
    • Next steps include:
      • Improving the command line interface for the plugin.
      • Adding support for "extended discussions" to Commands and exposing this information in manuals.
      • Further improve the escaping logic to properly escape MDoc macros that might happen to appear in user's help strings.
      • Ingesting external content a-la swift-docc so the entire tool documentation does not need to be included in the binary itself.
      • Bug fixes and addressing developer/user feedback.

    Built with love, @rauhul

    opened by rauhul 14
  • Add support for async/await where available

    Add support for async/await where available

    async/await is useful for writing clean and concise code for building small CLI tools, especially ones that interact with the network or the file system.

    Since @main now supports an async variant, I was able to add such support to a prototype with the following code:

    // entry.swift
    
    @available(macOS 12.0, *)
    protocol AsyncParsableCommand: ParsableCommand {
        mutating func runAsync() async throws
    }
    
    extension ParsableCommand {
        static func main(_ arguments: [String]? = nil) async {
            do {
                var command = try parseAsRoot(arguments)
                if #available(macOS 12.0, *), var asyncCommand = command as? AsyncParsableCommand {
                    try await asyncCommand.runAsync()
                } else {
                    try command.run()
                }
            } catch {
                exit(withError: error)
            }
        }
    }
    
    struct MainCommand: AsyncParsableCommand {
        @Option()
        var name: String = "Anon"
    
        func runAsync() async throws {
            print("Hello, \(name)")
            // await something...
        }
    }
    
    @main
    struct MainApp {
        static func main() async {
            await MainCommand.main()
        }
    }
    

    Having this be officially supported by swift-argument-parser would be ideal.

    opened by sergiocampama 14
  • Support an `async` entry point for commands

    Support an `async` entry point for commands

    Description

    Adds an AsyncParsableCommand type that sports an run() async method, allowing for asynchronous code in a command line tool.

    Detailed Design

    This includes the new AsyncParsableCommand protocol, which provides a static func main() async entry point and can call through to the root command's or a subcommand's asynchronous run() method. For this asynchronous execution, the root command must conform to AsyncParsableCommand, but its subcommands can be a mix of asynchronous and synchronous commands.

    /// A type that can be executed as part of a nested tree of commands.
    public protocol AsyncParsableCommand: ParsableCommand {
      mutating func run() async throws
    }
    
    extension AsyncParsableCommand {
      public static func main() async { ... }
    }
    

    Due to an issue in Swift 5.5, you can only use @main on an AsyncParsableCommand root command starting in Swift 5.6. This PR also includes a workaround for clients that are using Swift 5.5. Declare a separate type that conforms to AsyncMainProtocol and add the @main attribute to that type. For example:

    @main enum Main: AsyncMain {
        typealias Command = <#command#>
    }
    

    AsyncMainProtocol is deprecated for Swift 5.6.

    Documentation Plan

    There's a new example included (count-lines) that uses AsyncParsableCommand to read lines asynchronously, demonstrating the feature. A new guide for creating asynchronous commands is still TK.

    Test Plan

    As an entry point, this feature is tested by invoking the built executable via a new test in ArgumentParserExampleTests.

    Source Impact

    This change requires an upgrade in Swift versions to 5.5, but is otherwise source compatible.

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [ ] I've updated the documentation if necessary
    opened by natecook1000 13
  • Parsing strategy .optional

    Parsing strategy .optional

    I wanted to add a —draft option to my command but I wanted to be able to optionally specify the draft text i.e. —draft or —draft Entwurf. Unfortunately I couldn't think of a way to handle it.

    I think that there is a case for having optional arrays although I think there that specifying a minimum and maximum number of elements would be better.

    I don't think that there is a good way of handling this with standard types so maybe a custom type should be a requirement, one that could take an optional value as an argument.

    opened by msalmonse 12
  • Add Fish completion generator

    Add Fish completion generator

    Add fish completion script generation.

    The math example app generates the following fish script (swift run math --generate-completion-script fish).

    function __fish_math_using_command
        set cmd (commandline -opc)
        if [ (count $cmd) -eq (count $argv) ]
            for i in (seq (count $argv))
                if [ $cmd[$i] != $argv[$i] ]
                    return 1
                end
            end
            return 0
        end
        return 1
    end
    complete -c math -n '__fish_math_using_command math' -f -a 'add' -d 'Print the sum of the values.'
    complete -c math -n '__fish_math_using_command math' -f -a 'multiply' -d 'Print the product of the values.'
    complete -c math -n '__fish_math_using_command math' -f -a 'stats' -d 'Calculate descriptive statistics.'
    complete -c math -n '__fish_math_using_command math' -f -a 'help' -d 'Show subcommand help information.'
    complete -c math -n '__fish_math_using_command math add' -f -l hex-output -d 'Use hexadecimal notation for the result.'
    complete -c math -n '__fish_math_using_command math add' -f -l hex-output -s x -d 'Use hexadecimal notation for the result.'
    complete -c math -n '__fish_math_using_command math multiply' -f -l hex-output -d 'Use hexadecimal notation for the result.'
    complete -c math -n '__fish_math_using_command math multiply' -f -l hex-output -s x -d 'Use hexadecimal notation for the result.'
    complete -c math -n '__fish_math_using_command math stats' -f -a 'average' -d 'Print the average of the values.'
    complete -c math -n '__fish_math_using_command math stats' -f -a 'stdev' -d 'Print the standard deviation of the values.'
    complete -c math -n '__fish_math_using_command math stats' -f -a 'quantiles' -d 'Print the quantiles of the values (TBD).'
    complete -c math -n '__fish_math_using_command math stats' -f -a 'help' -d 'Show subcommand help information.'
    complete -c math -n '__fish_math_using_command math stats average' -f -r -l kind -d 'The kind of average to provide.'
    complete -c math -n '__fish_math_using_command math stats average --kind' -f -k -a 'mean median mode'
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -l test-success-exit-code
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -l test-failure-exit-code
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -l test-validation-exit-code
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -r -l test-custom-exit-code
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -r -l file
    complete -c math -n '__fish_math_using_command math stats quantiles --file' -f -a '(__fish_complete_path *.{txt,md})'
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -r -l directory
    complete -c math -n '__fish_math_using_command math stats quantiles --directory' -f -a '(__fish_complete_directories)'
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -r -l shell
    complete -c math -n '__fish_math_using_command math stats quantiles --shell' -f -a '(head -100 /usr/share/dict/words | tail -50)'
    complete -c math -n '__fish_math_using_command math stats quantiles' -f -r -l custom
    complete -c math -n '__fish_math_using_command math stats quantiles --custom' -f -a '(command math ---completion stats quantiles -- --custom (commandline -opc)[1..-1])'
    

    demo

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [x] I've updated the documentation if necessary
    opened by dduan 12
  • Simplify synopsis string generation

    Simplify synopsis string generation

    • Removes unused codepaths.
    • Simplifies synopsis string codepaths by removing optionality. This complexity is moved to the caller who is now responsible for filtering out hidden arguments and options. This change is desirable as it allows the caller to determine if the argument should be hidden. For example, while it makes sense to hide arguments in help text, it may not make sense to hide them when dumping the arguments for another tool to consume.

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [x] I've updated the documentation if necessary
    opened by rauhul 11
  • Remove LinuxMain.swift

    Remove LinuxMain.swift

    Swift 5.5+ Swift Package Manager warns that --enable-test-discovery is enabled by default. I assume for this project that should mean this isn't needed anymore on main.

    opened by keith 10
  • Unexpected “Asynchronous subcommand of a synchronous root”

    Unexpected “Asynchronous subcommand of a synchronous root”

    When attempting to create an application with a AsyncParsableCommand root and AsyncParsableCommand subcommands, a fatal error is thrown at runtime “Asynchronous subcommand of a synchronous root.”

    ArgumentParser version: 1.2.0 Swift version: swift-driver version: 1.62.8 Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50) Target: arm64-apple-macosx13.0

    Checklist

    • [ ] If possible, I've reproduced the issue using the main branch of this package
    • [x] I've searched for existing GitHub issues

    Steps to Reproduce

    source:

    import protocol ArgumentParser.AsyncParsableCommand
    import struct ArgumentParser.CommandConfiguration
    
    @main
    struct asyncissue: AsyncParsableCommand {
      static var configuration = CommandConfiguration(subcommands: [Cmd1.self])
    
      struct Cmd1: AsyncParsableCommand {
        mutating func run() async throws {
          print("Hello")
        }
      }
    }
    

    Expected behavior

    When resulting command is run, help with a subcommand would be displayed.

    Actual behavior

    ArgumentParser/ParsableCommand.swift:184: Fatal error: 
    --------------------------------------------------------------------
    Asynchronous subcommand of a synchronous root.
    
    The asynchronous command `Cmd1` is declared as a subcommand of the
    synchronous root command `asyncissue`.
    
    With this configuration, your asynchronous `run()` method will not be
    called. To fix this issue, change `asyncissue`'s `ParsableCommand`
    conformance to `AsyncParsableCommand`.
    --------------------------------------------------------------------
    
    zsh: trace trap  swift run
    
    good first issue 
    opened by fboundp 2
  • Improve fish completion (#376, #534)

    Improve fish completion (#376, #534)

    A generated fish script didn't complete an option after an argument.

    The cause is the generated fish script doesn't accept an input text which already has arguments. For example, when the input is repeat -, the script can complete --count, but when the text is repeat foo -, the script cannot complete repeat foo --count, because the input text already has the argument "foo".

    To fix the issue, I implemented the following steps.

    1. Preprocess for the subcommand. To support options of the root command like math --version add, --version is removed by _swift_{command name}_preprocessor.

    2. Decide a command. In a case when a command has some subcommands like math stats average 1 10 100 --kind mean, we need to decide the target command. (In the example case, the target command is average.) To decide it, the newly generated script receives expected command and subcommands. (e,g,)

      1. A case checking whether the target command is stats or not.
        • expected command = math stats
        • subcommands = average stdev quantiles help
      2. A case checking whether the target command is average or not.
        • expected command = math stats average
        • subcommands is empty (average doesn't have any subcommands.)`

      When the input has the expected command, and a text after the expected command is not the subcommand, the newly generated script decide the command is a target command, and suggest options for the target command.

    Related issues

    • #376
    • #534

    Checklist

    • [x] I've added at least one test that validates that my change is working, if appropriate
    • [x] I've followed the code style of the rest of the project
    • [x] I've read the Contribution Guidelines
    • [x] I've updated the documentation if necessary
    opened by mtj0928 0
  • A generated fish script doesn't complete an option after an argument.

    A generated fish script doesn't complete an option after an argument.

    A fish script that is generated by --generate-completion-script doesn't complete an option after an argument. For example, repeat command which is contained in the repository as an example can run the following command.

    $ repeat foo --count 10 
    

    However, --count is not completed even though $ repeat foo --c is input and a tab key is pressed.

    ArgumentParser version: main Swift version:

    swift-driver version: 1.62.15 Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)
    Target: arm64-apple-macosx13.0
    

    Checklist

    • [x] If possible, I've reproduced the issue using the main branch of this package
    • [x] I've searched for existing GitHub issues

    Steps to Reproduce

    1. Build this repository
    $ swift build -c release
    
    1. Add the release directory into your $PATH.
    $ set -x PATH (string join "" (pwd) "/.build/release/") $PATH  
    
    1. Generate a fish completion script.
    $ repeat --generate-completion-script fish >> ~/.config/fish/completions/repeat.fish
    
    1. Type repeat foo -- and press a tab key to try to complete options.

    Expected behavior

    Options that repeat supports are shown.

    Actual behavior

    Nothing is shown.

    opened by mtj0928 1
  • v 1.1.4 fails to build with SPM after xcode 14.1 update

    v 1.1.4 fails to build with SPM after xcode 14.1 update

    I have argument parser as a dependancy on a Library. After updating to xcode 14.1 swift build fails

    version 1.1.4 swift version 5.7

    Checklist

    • [ ] If possible, I've reproduced the issue using the main branch of this package
    • [X] I've searched for existing GitHub issues

    Steps to Reproduce

    using

    .package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0")
    

    tries to install version 1.1.4 fails with error.

    error: Couldn’t check out revision ‘9f39744e025c7d377987f30b03770805dcb0bcd1’:
        fatal: reference is not a tree: 9f39744e025c7d377987f30b03770805dcb0bcd1
    
    

    problem doesn't occur if I set the version

    .package(url: "https://github.com/apple/swift-argument-parser", .exact("1.1.3"))
    

    Expected behavior

    Library should build successfully without errors

    Actual behavior

    error: Couldn’t check out revision ‘9f39744e025c7d377987f30b03770805dcb0bcd1’:
        fatal: reference is not a tree: 9f39744e025c7d377987f30b03770805dcb0bcd1
    
    
    opened by sonic555gr 3
  • Allow parsing of -Dkey=value style options

    Allow parsing of -Dkey=value style options

    If I haven't overlooked something, it's currently not possible to define options in the style of make/gcc/clang definitions.

    In theory it should be possible to define it like this:

    @main
    struct Foo: ParsableCommand {
        @Option(name: .customShort("D", allowingJoined: true), parsing: .singleValue)
        var defines: [String] = []
    
        public func run() throws {
            print(defines)
        }
    }
    

    This works fine for calling the executable e.g. like so:

    $ foo -Dbar -Dbaz
    ["bar", "baz"]
    

    However, when the value of the option contains an =, this doesn't work anymore:

    $ foo -Dbar=baz
    Error: Unknown option '-Dbar'
    

    I'd guess that after seeing an equals sign the single "D" isn't considered anymore. It would be great, if that behaviour could be changed.

    Of course, it would be possible to go an extra step and fully parse such key-value pairs into a dictionary. I could imagine a syntax like this:

    @main
    struct Foo: ParsableCommand {
        @Option(name: [.customShort("D", allowingJoined: true), .customLong("define")])
        var defines: [String: String] = [:]
    
        public func run() throws {
            print(defines)
        }
    }
    

    Where Option gets a new specialized init for Value == [String: Element] that then would work like that:

    $ foo -Dbar=1 -D baz=2 --define qux=3
    ["bar": 1, "baz": 2, "qux": 3]
    
    enhancement 
    opened by Zollerboy1 0
Releases(1.2.0)
  • 1.2.0(Nov 8, 2022)

    Additions

    • You can now provide a title in an @OptionGroup declaration. Titled option groups are listed separately in the help screen under that title as a heading. (#492)

    • Two new parsing strategies have been added for @Argument array properties:

      • .allUnrecognized captures all unrecognized inputs after parsing known flags, options, and arguments.
      • .postTerminator collects any inputs that follow the -- terminator.

      See the ArgumentArrayParsingStrategy documentation for more. (#496)

    • Default values are now supported for @Argument or @Option properties with optional type, allowing you to initialize those properties with nil. Providing a non-nil default value results in a warning, since optional properties with non-nil defaults don't need to be declared as optionals. (#477, #480)

    Changes

    • The .unconditionalRemaining array parsing strategy has been deprecated and renamed to .captureForPassthrough, to better fit its semantic behavior and intended usage. See the ArgumentArrayParsingStrategy documentation for more. (#496)

    Fixes

    • Invalid init(from:) decoding initializers are now correctly diagnosed by ArgumentParser's validators. (#487)
    • Default values are now correctly displayed as flags for @Flag properties with inversions or EnumerableFlag types. (#486)
    • The help display for non-string-backed raw representable types has been corrected to not show raw Swift values. Instead, the help display uses the type's customized defaultValueDescription and allValues implementations. (#494)
    • Properties at different levels of a command hierarchy with the same Swift name but different argument names no longer collide. (#495)
    • The generate-manual plugin name is improved when used from within Xcode. (#505)
    • Documentation fixes and improvements.

    The 1.2.0 release includes contributions from @allevato, @clayellis, @compnerd, @d-ronnqvist, @natecook1000, @randomeizer, and @rauhul. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.1.4(Aug 27, 2022)

    Changes

    • The generate-manual plugin now defaults to creating single page manuals. The --single-page flag has been replaced with --multi-page to restore the previous default functionality. (#472)

      Migration: Update scripts that invoked generate-manual without --single-page to include --multi-page and update scripts that invoked generate-manual with --single-page to omit the flag.

    • The "experimental" prefix from the generate-manual plugin has been removed. (#475)

      Migration: Update scripts to invoke the generate-manual plugin via swift package generate-manual instead of swift package plugin experimental-generate-manual.

    Fixes

    • The generate-manual plugin is correctly declared as a product, making the plugin visible to clients. (#456)
    • The generate-manual plugin's --authors arguments are now correctly passed to the underlying generation tool. (#471)
    • Manuals generated by the generate-manual plugin now include the option's value names and do not include value names for flags. (#473)
    • Built-in flags such as --help and --version are now correctly marked as optional fixing some generated content which indicated the flags are always required. (#474)
    • Value descriptions are now correctly derived for types which are ExpressibleByArgument and RawRepresentable by String. Help menus will now display valid default values for such types. (#476)

    The 1.1.4 release includes contributions from @ian-twilightcoder, @MarcoEidinger, and @rauhul. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.1.3(Jun 23, 2022)

    Additions

    • ArgumentParser now includes a SwiftPM plugin for generating man pages. Explore the functionality and configuration by running swift package plugin experimental-generate-manual --help from your package root. (#332)

    Fixes

    • Hidden subcommands are now excluded from completion scripts. (#443)
    • When an invalid value is provided for a CaseIterable type, the error message now includes a list of valid inputs. (#445)
    • There's now a diagnostic when an AsyncParsableCommand is incorrectly placed under a non-async root command. (#436)

    The 1.1.3 release includes contributions from @keith, @KeithBird, @konomae, @LucianoPAlmeida, and @rauhul. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Apr 11, 2022)

    Changes

    • CMake builds now always statically link ArgumentParserToolInfo. (#424)

    Fixes

    • When a user provides an array-based option's key (e.g. --key) without any values, the error message now correctly describes the problem. (#435)

    The 1.1.2 release includes contributions from @compnerd and @KeithBird. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Mar 16, 2022)

    Fixes

    • Moves the platform requirement from the package level down to the new types and protocols with async members. This was a source-breaking change in 1.1.0. (#427)
    • Fixed issues in the CMake build configuration.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Mar 15, 2022)

    Additions

    • A command's run() method now supports async/await when the command conforms to AsyncParsableCommand. (#404)
    • New API for distinguishing between public, hidden, and private arguments and option groups, and a new extended help screen accessible via --help-hidden. (#366, #390, and #405 through #413)
    • You can now override the autogenerated usage string when configuring a command. (#400)

    Changes

    • ArgumentParser now requires Swift 5.5.

    Fixes

    • The auto-generated usage string now correctly hides all optional parameters when over the length limit. (#416)
    • One @Option initializer now has its parameters in the correct order; the incorrect initializer is deprecated. (#391)
    • Help flags are now correctly captured in .unconditionalRemaining argument arrays.
    • Documentation fixes and improvements.

    The 1.1.0 release includes contributions from @keith, @MartinP7r, @McNight, @natecook1000, @rauhul, and @zkiraly. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Feb 1, 2022)

    Changes

    • When a user provides an incorrect value for an option, an ArgumentParser-based program now includes the valid values when possible.

      $ example --format png
      Error: The value 'png' is invalid for '--format <format>'.
      Please provide one of 'text', 'json' or 'csv'.
      

    Fixes

    • Resolves an issue with zsh custom completions for command names that include a dash.
    • Improves the generated completions scripts for fish.
    • Resolves issues that prevented building ArgumentParser for WebAssembly using SwiftWasm toolchains.
    • Improved window size handling on Windows.
    • Fixed a crash when using --experimental-dump-help with commands that provide non-parsed values.
    • Fixes an issue where subcommands that declare array arguments with the .unconditionalRemaining parsing strategy unexpectedly miss arguments, extending the change in #333 to subcommands. (#397)
    • Corrects the order of an @Option initializer's parameters, deprecating the old version. (#391)
    • Expanded and corrected documentation.

    The 1.0.3 release includes contributions from @atierian, @CraigSiemens, @dduan, @floam, @KS1019, @McNight, @mdznr, @natecook1000, @rauhul, and @yonihemi. Thank you!

    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Nov 10, 2021)

  • 1.0.1(Sep 14, 2021)

  • 1.0.0(Sep 11, 2021)

    The 1.0 release marks an important milestone — ArgumentParser is now source stable!

    Changes

    • ArgumentParser now provides a DocC documentation catalog, so you can view rendered articles and symbol documentation directly within Xcode.

    Fixes

    • Parsing works as expected for options with single-dash names that are declared using the .upToNextOption parsing strategy.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Sep 3, 2021)

    Additions

    • When a user doesn't provide a required argument, the error message now includes that argument's help text. (#324)
    • Command-line tools built with ArgumentParser now include an experimental flag to dump command/argument/help information as JSON: --experimental-dump-help. (#310)

    Changes

    • All public enumerations are now structs with static properties, to make compatibility with future additions simpler.

    Fixes

    • Array properties defined as @Option with the .upToNextOption parsing strategy now include all provided values. (#304) In the example below, all four values are now included in the resulting array, where only the last two were included in previous releases:

      struct Example: ParsableCommand {
          @Option(parsing: .upToNextOption)
          var option: String
      }
      
      $ example --option one two --option three four
      
    • When a command defines an array property as an @Argument with the .unconditionalRemaining parsing strategy, option and flag parsing now stops at the first positional argument or unrecognized flag. (#333)

    • Completion scripts correctly use customized help flags. (#308)

    • Fixes errors with bash custom completion arguments and the executable path. (#320, #323)

    • Fixes the behavior when a user specifies both the help subcommand and a help flag. (#309)

    • A variety of internal improvements. (#315, #316, #321, #341)

    Source code(tar.gz)
    Source code(zip)
  • 0.4.4(Jul 30, 2021)

  • 0.4.3(Apr 28, 2021)

  • 0.4.2(Apr 21, 2021)

    Fixes

    • Both parts of a flag with an inversion are now hidden when specified.
    • Better support for building on OpenBSD.
    • Optional unparsed values are now always properly decoded. (#290)
    • Help information from super-commands is no longer unnecessarily injected into subcommand help screens.
    Source code(tar.gz)
    Source code(zip)
  • 0.4.1(Mar 8, 2021)

    Additions

    • When a user provides an invalid value as an argument or option, the error message now includes the help text for that argument.

    Fixes

    • Zsh completion scripts for commands that include a hyphen no longer cause errors.
    • Optional unparsed values are now decoded correctly in ParsableArguments types.
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Mar 4, 2021)

    Additions

    • Short options can now support "joined option" syntax, which lets users specify a value appended immediately after the option's short name. For example, in addition to calling this example command with -D debug and -D=debug, users can now write -Ddebug for the same parsed value. (#240)

      @main
      struct Example: ParsableCommand {
          @Option(name: .customShort("D", allowingJoined: true))
          var debugValue: String
      
          func run() {
              print(debugValue)
          }
      }
      

    Changes

    • The CommandConfiguration.helpNames property is now optional, to allow the overridden help flags of parent commands to flow down to their children. Most existing code should not be affected, but if you've customized a command's help flags you may see different behavior. (#251)

    • The errorCode property is no longer used as a command's exit code when CustomNSError types are thrown. (#276)

      Migration: Instead of throwing a CustomNSError type, print your error manually and throw an ExitCode error to customize your command's exit code.

    Removals

    • Old, deprecated property wrapper initializers have been removed.

    Fixes

    • Validation errors now show the correct help flags when help flags have been customized.
    • Options, flags, and arguments that are marked as hidden from the help screen are also suppressed from completion scripts.
    • Non-parsed variable properties are now allowed in parsable types.
    • Error messages produced when NSError types are thrown have been improved.
    • The usage line for commands with a large number of options includes more detail about required flags and positional arguments.
    • Support for CMake builds on Apple Silicon is improved.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.2(Jan 16, 2021)

    Fixes

    • Changes made to a command's properties in its validate method are now persisted.
    • The exit code defined by error types that conform to CustomNSError are now honored.
    • Improved error message when declaring a command type with an unadorned mutable property. (See #256 for more.)
    • Migrated from CRT to MSVCRT for Windows platforms.
    • Fixes and improvements for building with CMake for Windows and Apple Silicon.
    • Documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.1(Sep 2, 2020)

    Fixes

    • An option or flag can now declare a name with both single- and double- dash prefixes, such as -my-flag and --my-flag. Specify both names in the name parameter when declaring your property:

      @Flag(name: [.long, .customLong("my-flag", withSingleDash: true)])
      var myFlag = false
      
    • Parsing performance improvements.

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Aug 15, 2020)

    Additions

    • Shell completions scripts are now available for Fish.

    Changes

    • Array properties without a default value are now treated as required for the user of a command-line tool. In previous versions of the library, these properties defaulted to an empty array; a deprecation was introduced for this behavior in version 0.2.0.

      Migration: Specify an empty array as the default value for properties that should not require user input:

      // old
      @Option var names: [String]
      // new
      @Option var names: [String] = []
      
    Source code(tar.gz)
    Source code(zip)
  • 0.2.2(Aug 5, 2020)

    Fixes

    • Zsh completion scripts have improved documentation and better support multi-word completion strings, escaped characters, non-standard executable locations, and empty help strings.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.1(Jul 30, 2020)

    Additions

    • You can now generate Bash and Zsh shell completion scripts for commands, either by using the --generate-completion-script flag when running a command, or by calling the static completionScript(for:) method on a root ParsableCommand type. See the guide to completion scripts for information on customizing and installing the completion script for your command.

    Fixes

    • Property wrappers without parameters can now be written without parentheses — e.g. @Flag var verbose = false.
    • When displaying default values for array properties, the help screen now correctly uses the element type's ExpressibleByArgument conformance to generate the description.
    • Running a project that defines a command as its own subcommand now fails with a useful error message.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jun 23, 2020)

    Additions

    • You can now specify default values for array properties of parsable types. The default values are overridden if the user provides at least one value as part of the command-line arguments.

    Changes

    • This release of swift-argument-parser requires Swift 5.2.

    • Default values for all properties are now written using default initialization syntax, including some values that were previously implicit, such as empty arrays and false for Boolean flags.

      Migration: Specify default values using typical Swift default value syntax to remove the deprecation warnings:

      // old
      @Flag() var verbose: Bool
      // new
      @Flag() var verbose = false
      

      Important: There is a semantic change for flags with inversions that do not have a default value. In previous releases, these flags had a default value of false; starting in 0.2.0, these flags will have no default, and will therefore be required by the user. Specify a default value of false to retain the old behavior.

    Fixes

    • Options with multiple names now consistently show the first-declared name in usage and help screens.
    • Default subcommands are indicated in the help screen.
    • User errors with options are now shown before positional argument errors, eliminating some false negative reports.
    • CMake compatibility fixes.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jun 3, 2020)

    Additions

    • Error messages and help screens now include information about how to request more help.
    • CMake builds now support installation.

    Changes

    • The static func main() method on ParsableCommand no longer returns Never. This allows ParsableCommand types to be designated as the entry point for a Swift executable by using the @main attribute.

      Migration: For most uses, this change is source compatible. If you have used main() where a () -> Never function is explicitly required, you'll need to change your usage or capture the method in another function.

    • Optional no longer conforms to ExpressibleByArgument, to avoid some property declarations that don't make sense.

      Migration: This is source-compatible for all property declarations, with deprecations for optional properties that define an explicit default. If you're using optional values where an ExpressibleByArgument type is expected, such as a generic function, you will need to change your usage or provide an explicit override.

    • ParsableCommand's run() method requirement is now a mutating method, allowing mutations to a command's properties, such as sorting an array of arguments, without additional copying.

      Migration: No changes are required for commands that are executed through the main() method. If you manually parse a command and then call its run() method, you may need to change the command from a constant to a variable.

    Removals

    • The @Flag initializers that were deprecated in version 0.0.6 are now marked as unavailable.

    Fixes

    • @Option properties of an optional type that use a transform closure now correctly indicate their optionality in the usage string.
    • Correct wrapping and indentation are maintained for abstracts and discussions with short lines.
    • Empty abstracts no longer add extra blank lines to the help screen.
    • Help requests are still honored even when a parsed command fails validation.
    • The -- terminator isn't consumed when parsing a command, so that it can be parsed as a value when a subcommand includes an .unconditionalRemaining argument array.
    • CMake builds work correctly again.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.6(May 14, 2020)

    Additions

    • Command definition validation now checks for name collisions between options and flags.
    • ValidationError.message is now publicly accessible.
    • Added an EnumerableFlag protocol for CaseIterable types that are used to provide the names for flags. When declaring conformance to EnumerableFlag, you can override the name specification and help text for individual flags. See #65 for more detail.
    • When a command that requires arguments is called with no arguments at all, the error message includes the full help text instead of the short usage string. This is intended to provide a better experience for first-time users.
    • Added a helpMessage() method for generating the help text for a command or subcommand.

    Deprecations

    • @Flag properties that use CaseIterable/String types as their values are deprecated, and the related @Flag initializers will be removed in a future version.

      Migration: Add EnumerableFlag conformance to the type of these kinds of @Flag properties.

    Fixes

    • Errors thrown while parsing in a transform closure are printed correclty instead of a general Invalid state error.
    • Improvements to the guides and in the error message when attempting to access a value from an argument/option/flag definition.
    • Fixed issues in the CMake and Windows build configurations.
    • You can now use an = to join a value with an option's short name when calling a command. This previously only worked for long names.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.5(Apr 15, 2020)

    Additions

    • You can now specify a version string in a ParsableCommand's configuration. The generated tool will then automatically respond to a --version flag.
    • Command definitions are now validated at runtime in debug mode, to check issues that can't be detected during compilation.

    Fixes

    • Deprecation warnings during compilation on Linux have been removed.
    • The validate() method is now called on each command in the matched command stack, instead of only the last command in the stack.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.4(Mar 23, 2020)

  • 0.0.3(Mar 23, 2020)

    Additions

    • You can specify the .unconditionalRemaining parsing strategy for arrays of positional arguments to accept dash-prefixed input, like example --one two -three.
    • You can now provide a default value for a positional argument.
    • You can now customize the display of default values in the extended help for an ExpressibleByArgument type.
    • You can call the static exitCode(for:) method on any command to retrieve the exit code for a given error.

    Fixes

    • Supporting targets are now prefixed to prevent conflicts with other libraries.
    • The extension providing init?(argument:) to RawRepresentable types is now properly constrained.
    • The parser no longer treats passing the same exclusive flag more than once as an error.
    • ParsableArguments types that are declared as @OptionGroup() properties on commands can now also be declared on subcommands. Previosuly, the parent command's declaration would prevent subcommands from seeing the user-supplied arguments.
    • Default values are rendered correctly for properties with Optional types.
    • The output of help requests is now printed during the "exit" phase of execution, instead of during the "run" phase.
    • Usage strings now correctly show that optional positional arguments aren't required.
    • Extended help now omits extra line breaks when displaying arguments or commands with long names that don't provide help text.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.2(Mar 6, 2020)

    Additions

    • The EX_USAGE exit code is now used for validation errors.
    • The parser provides near-miss suggestions when a user provides an unknown option.
    • ArgumentParser now builds on Windows.
    • You can throw an ExitCode error to exit without printing any output.
    • You can now create optional Boolean flags with inversions that default to nil:
      @Flag(inversion: .prefixedNo) var takeMyShot: Bool?
      
    • You can now specify exclusivity for case-iterable flags and for Boolean flags with inversions.

    Fixes

    • Cleaned up a wide variety of documentation typos and shortcomings.
    • Improved different kinds of error messages:
      • Duplicate exclusive flags now show the duplicated arguments.
      • Subcommand validation errors print the correct usage string.
    • In the help screen:
      • Removed the extra space before the default value for arguments without descriptions.
      • Removed the default value note when the default value is an empty string.
      • Default values are now shown for Boolean options.
      • Case-iterable flags are now grouped correctly.
      • Case-iterable flags with default values now show the default value.
      • Arguments from parent commands that are included via @OptionGroup in subcommands are no longer duplicated.
    • Case-iterable flags created with the .chooseFirst exclusivity parameter now correctly ignore additional flags.
    Source code(tar.gz)
    Source code(zip)
  • 0.0.1(Feb 27, 2020)

Owner
Apple
Apple
Swift tool to generate Module Interfaces for Swift projects.

ModuleInterface Swift tool to generate Module Interfaces for Swift projects. What is a Module Interface A Module Interface is what we commonly get usi

Jorge Revuelta 75 Dec 21, 2022
Swift-cli - Example of building command-line tools in Swift

swift-cli Example of building command-line tools in Swift Step 1: Create CLI wit

Noah Gift 2 Jan 17, 2022
Compose beautiful command line interfaces in Swift

Commander is a small Swift framework allowing you to craft beautiful command line interfaces in a composable way. Usage Simple Hello World i

Kyle Fuller 1.5k Dec 29, 2022
CommandLineKit - A pure Swift library for creating command-line interfaces

CommandLineKit A pure Swift library for creating command-line interfaces. Note: This project is no longer maintained. It's preserved here for historic

Ben Gollmer 1.1k Dec 1, 2022
Guaka - Smart and beautiful POSIX compliant CLI framework for Swift.

Guaka - Smart and beautiful POSIX compliant CLI framework for Swift. It helps you create modern and familiar CLI apps in the vein of widely used proje

Omar Abdelhafith 1.1k Dec 24, 2022
Progress.swift ⌛ Add beautiful progress bars to your loops.

Progress.swift ⌛ Just wrap the SequenceType in your loop with the Progress SequenceType and you'll automatically get beautiful progress bars. Updating

Justus Kandzi 304 Dec 1, 2022
SwiftCLI - A powerful framework for developing CLIs in Swift

SwiftCLI A powerful framework for developing CLIs, from the simplest to the most complex, in Swift.

Jake Heiser 793 Jan 4, 2023
SwiftShell - A Swift framework for shell scripting.

Run shell commands | Parse command line arguments | Handle files and directories Swift 5.1 - 5.3 | Swift 4 | Swift 3 | Swift 2 SwiftShell A library fo

Kare Morstol 973 Jan 2, 2023
SwiftyTextTable - A lightweight Swift library for generating text tables

SwiftyTextTable A lightweight Swift library for generating text tables. Swift Language Support SwiftyTextTable is now Swift 4.0 compatible! The last r

Scott Hoyt 283 Dec 23, 2022
Shell scripting in Swift

Shwift Shell-scripting in Swift DISCLAIMER: Shwift depends on Swift's incoming concurrency features. As such, it requires a recent Swift toolchain, an

George Lyon 32 Sep 15, 2022
Swift utilities for running commands.

Swift Commands Swift utilities for running commands. The Commands module allows you to take a system command as a string and return the standard outpu

Phil 41 Jan 2, 2023
A CLI too powered by Swift to provision environments using an up.toml manifest file

tuist-up tuist up was originally a Tuist built-in command to provision environments by reading the requirements in a manifest file Setup.swift. Althou

Tuist 5 Mar 31, 2022
Terminal string styling for Swift.

Terminal string styling for Swift. Integration Swift Package Manager (SPM) You can use The Swift Package Manager to install ColorizeSwift by adding it

Michał Tynior 281 Dec 22, 2022
Simple & Elegant Command Line Interfaces in Swift

An elegant pure Swift library for building command line applications. Features Tons of class, but no classes. 100% organic pure value types. Auto gene

hypertalk 52 Nov 9, 2022
✏️Expressive styling on terminal string. (chalk for swift)

Chalk Expressive styling on terminal string. Highlights Expressive API 256/TrueColor support Nest styles Auto downgrading to terminal supported color

Luo Xiu 59 Jun 10, 2022
A starting point to create CLI utilities with swift

cli tuist template A starting point to create CLI utilities with swift Installation Just create a Tuist folder and a Templates folder inside it. Creat

humdrum 6 May 3, 2022
A Tuist Template to quickly create CLI apps in Swift

macOS CLI Template Motivation I'm writing more and more Swift CLI apps these days. And as I solve more problems with this litte tools, I find that I'm

Diego Freniche 21 Dec 28, 2022
A cli program written in swift (with async/await) that removes the unnecessary parts of xcframeworks.

xctrim A cli program written in swift (with async/await) that removes the unnecessary parts of xcframeworks. Usecase Say you downloaded firebase sdk a

Mustafa Yusuf 32 Jul 18, 2022
A library and CLI Utility to manage NVRAM Stuff, written in Swift.

NVRAMKit A Library and CLI Utility to manage NVRAM Stuff, written in Swift. Library Adding Library to Project Simply add this line to the dependencies

Serena 7 Sep 25, 2022