SkillAgentSearch skills...

Commander

🚀The framework to write type-safe and structured command line program easily in Swift.

Install / Use

/learn @devedbox/Commander

README

<p align="center"> <img src="Resources/logo.svg"> </p> <p align="center"> <img src="https://travis-ci.com/devedbox/Commander.svg?branch=master"> <a href="https://codecov.io/gh/devedbox/Commander"> <img src="https://codecov.io/gh/devedbox/Commander/branch/master/graph/badge.svg"> </a> <a href="https://codeclimate.com/github/devedbox/Commander/maintainability"> <img src="https://api.codeclimate.com/v1/badges/83ff78d95f31412070e1/maintainability"> </a> <img src="https://img.shields.io/badge/license-MIT-blue.svg"> <img src="https://img.shields.io/badge/language-swift-orange.svg"> <img src="https://img.shields.io/github/tag-date/devedbox/Commander.svg?label=spm-ver&colorB=lightgray"> <a href="https://gitter.im/commander-swift/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link"> <img src="https://badges.gitter.im/devedbox/Commander.svg"> </a> </p> <p align="center"> <a href="https://github.com/devedbox/Commander/watchers"> <img src="https://img.shields.io/github/watchers/devedbox/Commander.svg?style=social&label=Watch"> </a> <a href="https://github.com/devedbox/Commander/stargazers"> <img src="https://img.shields.io/github/stars/devedbox/Commander.svg?style=social&label=Star"> </a> <a href="https://github.com/devedbox/Commander/fork"> <img src="https://img.shields.io/github/forks/devedbox/Commander.svg?style=social&label=Fork"> </a> <a href="https://twitter.com/intent/follow?screen_name=devedbox"> <img src="https://img.shields.io/twitter/follow/devedbox.svg?style=social&label=Follow%20%40devedbox"> </a> <a href="https://twitter.com/intent/tweet?text=Commander+makes+it+easy+to+build+type-safe+and+structured+command-line+interface+program+in+Swift!&url=https%3a%2f%2fgithub.com%2fdevedbox%2fCommander&hashtags=github,swiftlang,commandline,iosdev,commander&original_referer=http%3A%2F%2Fgithub.com%2F&tw_p=tweetbutton"> <img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a> </p> <p align='center'> <a href="https://996.icu"><img src="https://img.shields.io/badge/link-996.icu-red.svg" alt="996.icu"></a> </p>

Commander is a Swift framework for decoding command-line arguments by integrating with Swift standard library protocols Decodable & Decoder. Commander can help you to write structured cli program by declaring the structure of command and options of that command without writing any codes to parse the cli arguments. With Commander, you just need to focus on writing options structure of commands, the rest works will be handled by Commander automatically.

<p align="center"><img src="Resources/sample.png"></p>

Table Of Contents


<p align="center"> <a href="https://github.com/devedbox/Commander#features"><b>Features</b></a> <body> - </body> <a href="https://github.com/devedbox/Commander#example"><b>Example</b></a> </p>

Features

  • [x] Structured-CLI, commands and options are all structured by declaration of struct or class.
  • [x] Options types are type-safe by implementing Decodable protocol.
  • [x] Automatically generate help message for the commander or command.
  • [x] Shell <Tab> completion supported. Bash/Zsh <Tab> auto-complete scripts supported.
  • [x] Swift 4.x compatibility.
  • [x] Zero dependency and pure Swift.
  • [x] Supports Linux with swift build.

Example

With Commander, a command and its associated options could be defined as follows:

import Commander

public struct SampleCommand: CommandRepresentable {
  public struct Options: OptionsRepresentable {
    public typealias ArgumentsResolver = AnyArgumentsResolver<String>
    public enum CodingKeys: String, CodingKeysRepresentable {
      case verbose = "verbose"
      case stringValue = "string-value"
    }

    public static let keys: [Options.CodingKeys : Character] = [
      .verbose: "v",
      .stringValue: "s"
    ]

    public static let descriptions: [Options.CodingKeys : OptionDescription] = [
      .verbose: .usage("Prints the logs of the command"),
      .stringValue: .usage("Pass a value of String to the command")
    ]

    public var verbose: Bool = false
    public var stringValue: String = ""
  }

  public static let symbol: String = "sample"
  public static let usage: String = "Show sample usage of commander"

  public static func main(_ options: Options) throws {
    print(options)
    print("arguments: \(options.arguments)")
    print("\n\n\(Options.CodingKeys.stringValue.stringValue)")
  }
}

Then, configuring the available commands would like this:

import Commander

Commander.commands = [
  SampleCommand.self,
  NoArgsCommand.self
]
Commander.usage = "The sample usage command of 'Commander'"
Commander().dispatch() // Call this to dispatch and run the command

After which, arguments can be resolved by declaration of ArgumentsResolver:

public typealias ArgumentsResolver = AnyArgumentsResolver<T> // T must be Decodable

And you can fetch the arguments by:

public static func main(_ options: Options) throws {
  print("arguments: \(options.arguments)") // 'arguments' is being declared in OptionsRepresentable 
}

At last, run from shell:

commander-sample sample --verbose --string-value String arg1 arg2
# 
# Options(verbose: true, stringValue: "String")
# arguments: ["arg1", "arg2"]
#
#
# string-value

It's easy and fun!!!


<p align="center"> <a href="https://github.com/devedbox/Commander#requirements"><b>Requirements</b></a> <body> - </body> <a href="https://github.com/devedbox/Commander#test-coverage-graph"><b>Test Coverage Graph</b></a> <body> - </body> <a href="https://github.com/devedbox/Commander#installation"><b>Installation</b></a> </p>

Requirements

  • Mac OS X 10.10+ / Ubuntu 14.10
  • Xcode 10
  • Swift 4.2

Test Coverage Graph

<p align="center"> <img src="https://codecov.io/gh/devedbox/Commander/commit/1a15f7be4db03125027641205529e0e5d5050b21/graphs/sunburst.svg"> </p>

Installation

With SPM

// swift-tools-version:4.2
dependencies: [
  .package(url: "https://github.com/devedbox/Commander.git", "0.5.6..<100.0.0")
]

<p align="center"> <a href="https://github.com/devedbox/Commander#features"><b>Patterns</b></a> <body> - </body> <a href="https://github.com/devedbox/Commander#value-types"><b>Value Types</b></a> </p>

Patterns

Key-Value Pairs

Single Value

commander command --key value --key1=value1
commander command --bool
commander command -k value -K=value1
commander command -z=value # {"z": "value"}
commander command -z # {"z": true}
commander command -zop # {"z": true, "o": true, "p": true}

Multiple Values

commander command --array val1,val2,val3
commander command -a val1,val2,val3
commander command --dict key1=val1,key2=val2,key3=val3
commander command -d key1=val1,key2=val2,key3=val3
commander command --array val1 --array val2 --array val3
commander command -a val1 -a val2 -a val3
commander command --dict key1=val1 --dict key2=val2 --dict key3=val3
commander command -d key1=val1 -d key2=val2 -d key3=val3

Argument

In Commander,The position of arguments is not settled, they can be arywhere but the arguments must be continuous:

commander command args... --options                   # before options
commander command --options args...                   # after options
commander command --options args... --options         # between options
commander command arg0... --options arg1... --options # Error

Use -- to mark the ends of options and begins of arguments, but, this is normally optional in Commander:

commander command --options -- args...

Value Types

As we all know, all the arguments from CommandLine.arguments is String type, in Commander, the available value types are:

  • Bool: commander command --verbose
  • Int(8, 16, 32, 64...): commander command --int 100
  • String: commander command --string "this is a string value"
  • Array: commander command --array val1,val2,val3
  • Dictionary: commander command --dict key1=val1,key2=val2,key3=val3

Array object is delimited by character , and Dict object is delimited by character = and ,.


<p align="center"> <a href="https://github.com/devedbox/Commander#usage"><b>Advanced Usage</b></a> <body> - </body> <a href="https://github.com/devedbox/Commander#license"><b>License</b></a> </p>

Usage

Commander supports a main commander alongwith the commands of that commander, and each command has its own subcommands and options.

Using a Commander is simple, you just need to declare the commands, usage of the commander, and then call Commander().dispatch(), the Commander will automatically decode the command line arguments and dispatch the decoded options t

Related Skills

View on GitHub
GitHub Stars169
CategoryDevelopment
Updated1mo ago
Forks1

Languages

Swift

Security Score

100/100

Audited on Feb 17, 2026

No findings