Giter Club home page Giter Club logo

clswift's Introduction

CLSwift

A Swift framework for writing commandline tools

Inspiration

There are a large number of really useful commandline tools that work on Linux, but were never ported to macOS. One of those was xdotool which is a UI automation tool for things like typing and moving a mouse around. Something similar doesn't exist on macOS so I started porting it over with the intent to make a drop in replacement and called it osxdotool. xdotool is a large and very mature tool so the complexity got to me early on and I knew I needed a way to orginize everything coherently, but nothing that achieved that well IMO for Swift. CLSwift was born.

Features

  • Ingest and parse commandline input into Commands, Options, and the parameters associated with each
  • Typecast parameters upfront according to expected input
  • Validate input by expected number and type of parameters
  • Built for modularity. Easily split up argument and flag definitions however you like
  • Highly testible. Built to take in example input
  • Generated help messages on command misuse

Examples

Options

Options are used to alter the functionality of an argument. This is done by getting a dictionary representing state from the argument and changing values within that dictionary. The closure parameter is executed when one of the triggers is found in the commandline input and parameters are validated. Flag is an Option that takes no parameters.

let flag = Flag(
    triggers: ["-f"],
    help: "Replaces foo value with baz",
    state: ["foo": "bar"]
) { (params, state)  -> State in
    var newState = state
    newState["foo"] = "baz"
    return newState
}

let legsOption = Option<Int>(
    triggers: ["-l"],
    help: "Sets leg number of legs",
    state: ["legs": 2],
    numParams: .number(1)
) { (params, state) -> State in
    var newState = state
    newState["legs"] = params[0]
    return newState
}

Commands

Just like Option, the closure parameter is executed when one of the triggers is found in the commandline input and parameters are validated. Options are attatched to an argument by passing them in on initialization. This is nice because if you have many arguments that use the same option, you can reuse the exact same Option instance.

let command = Command<Int>(
    triggers: ["hello"],
    help: "Takes foo, hello and legs and does foobar",
    numParams: .number(2),
    options: [flag, legsOption]
) { (vals, state) in
    if state["foo"] as? String == "baz" {
        print("-f flag used")
    }
    if state["legs"] as? Int != 2 {
        print("-l flag used")
    }
}

Command Center

The following is the typical use case in which CommandLine.arguments is used for input, but you can also supply your own input for testing purposes by simply replacing CommandLine.arguments with your own array of strings.

The first step is figuring out which of your commands was triggered if any. Then you call .execute() on that command which executes the closure supplied on initialization.

CommandCenter takes your input and breaks it up into more usable objects which are stored in commandCenter.input.

let commandCenter = CommandCenter(commands: [command], input: CommandLine.arguments)
let triggeredCommand = commandCenter.check()

if let triggeredCommand = triggeredCommand {
    triggeredCommand.execute(commandline: commandCenter.input)
}

Help message

The help message for the above looks like this

Usage: hello <Int, Int> [options]

Description:
Takes foo, hello and legs and does foobar

-f          Replaces foo value with baz
-l <Int>    Sets leg number of legs

This could be triggered if no parameters were supplied for -l for example which would look like this

$ ./example hello 1 2 -f -l

clswift's People

Contributors

basthomas avatar twof avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.