Code Monkey home page Code Monkey logo

commander's Introduction

Curassow

Build Status

Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn.

It exposes a Nest-compatible interface for your application, allowing you to use Curassow with any Nest compatible web frameworks of your choice.

Documentation

Full documentation can be found on the Curassow website: https://curassow.fuller.li

Usage

To use Curassow, you will need to install it via the Swift Package Manager, you can add it to the list of dependencies in your Package.swift:

import PackageDescription

let package = Package(
  name: "HelloWorld",
  dependencies: [
    .Package(url: "https://github.com/kylef/Curassow.git", majorVersion: 0, minor: 6),
  ]
)

Afterwards you can place your web application implementation in Sources and add the runner inside main.swift which exposes a command line tool to run your web application:

import Curassow
import Inquiline


serve { request in
  return Response(.ok, contentType: "text/plain", body: "Hello World")
}

Then build and run your application:

$ swift build --configuration release

Example Application

You can find a hello world example application that uses Curassow.

License

Curassow is licensed under the BSD license. See LICENSE for more info.

commander's People

Contributors

djbe avatar fwcd avatar hejki avatar hemet avatar iamdecode avatar keith avatar kylef avatar linusu avatar lvsti avatar mklbtz avatar neonichu avatar nicorichard avatar radex avatar readmecritic avatar sbarow avatar tannerdsilva avatar vi4m avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

commander's Issues

Unknown Arguments trigger displays garbled user input

Sorry for a possibly confusing title...

If I set a group and subsequent command similar to,

let test = Group {
        
        $0.command("get",
                   Option("user", default: "", description: "The user to get."),
                   description: "Get User Information")

But I call the program as so:
$ test get -user myuser

Notice how "-user" should have an extra "-", this causes the "Unknown Arguments" error to print out:

Unknown Arguments: -usre myuser

Options:
    --user [default: ] - The user to get.

Notice "-usre" is garbled. Upon further runs, this word seems to rotate through it's order of letters. Very strange.

`command` should be a type, not a function

I think command should be made a type, so we'd write Command instead.

This is more consistent with Option and Command.

I also think with how it is now, it's not very clear that this block of code:

command {

}

does not actually execute anything.

Commander doesn't... parse arguments?

With the following swift file called main:

#! /usr/bin/env cato 2.1
import Commander


Group {
    $0.command("init") { (name: String) in
        print("Initializing \(name)")
    }
}.run()

As expected, running:

$ chmod +x main
$ ./main

results in

Usage:

    $ ./main

Commands:

    + init

Which is great! However, when I run the following command, I get the same result:

$ ./main init test
Usage:

    $ ./main

Commands:

    + init

instead of the expected:

$ ./main init test
Creating test

Is this an error on my part or is it broken?

By the way, I'm on OS X El Capitan running Xcode 7.1 Beta 2, if it matters.

Flag constructor arguments order isn't consistent with Option

The Flag constructor takes default as the last argument where as Option takes it as the second argument.

When using both in a single command it's a bit weird to have:

Flag("web", description: "Whether or not to search the web", default: false),
Option("remote", "cocoapods.org", description: "Custom remote host"),

How to add shortflag option?

Say I have an option call count - xxx count 10
and I want to add a short flag option so I can call it xxx -c 10
Is there any way to do this?

Are optional options available?

I just started using Commander and it is awesome. I just had one question. Are options with optional values available? What I would like is to have an option that if the user did not specify that option with a value on the command line, I would like to receive nil for that option's value.

I see that the default parameter for the Option class is not optional. In my use case, there is no possible default value. If the user specifies a value, I add it to the service call's query parameter, if not, it is omitted. When I try something like this:

Option<String?>("campaign", default: nil, description: "The campaign identifier used to narrow the search."),

I get the following error:

Type 'String?' does not conform to protocol 'ArgumentConvertible'

Is there currently anyway to do this using Commander?

Deprecation warning: ++ is deprecated

There are some deprecation warnings received when compiling the Commander package with the latest version of Swift 2.2-dev Feb 3, 2016.

warning: '++' is deprecated: it will be removed in Swift 3

Sources/ArgumentParser.swift:121:9
Sources/ArgumentParser.swift:163:7
Sources/ArgumentParser.swift:189:7
Sources/ArgumentParser.swift:214:9

Why dropped support for Carthage?

I noticed that the xcodeproj along with the shared schemes are deleted in a recent commit(9926257), but the current Readme still says Carthage is supported. Is it an accident or do we have to give up Carthage if we would like to get the latest version from now on?

I'm currently developing a command line tool and I personally prefer the submodule way of managing dependencies, which is provided by Carthage.

Conche is good, but it is not the right choice for me since I'm using a Xcode project and packed all resources into an app bundle. Using Cocoapods & Carthage together is definitely a mess, so I really hope you could bring back the xcodeproj along with the shared schemes. Otherwise it should be painful in case Swift's next update breaks Commander and I have to constantly sync all the new commits from this repo to my fork.

Thank you.

add Flag.flag to help text

Currently, the help text shows only the long flags, suche as e.g. --verbose, but not the short flag -f which can be configured via

let main = command(
    Flag("verbose", flag: "v")
) {
    // ...
}

Arguments not printing

Maybe I'm missing something, but still cannot get arguments to print as part of the "help" menu.


Usage:

$ .build/x86_64-apple-macosx10.10/debug/Mothership-CLI testflight

Commands:

+ login

import Commander
import Mothership

let mothership = Mothership()
let testFlight = TestFlight()

let group = Group {
  
  $0.command("help") {}
  
  $0.command("login") { (username:String, password:String) in
    
    print("logging \(username) into Mothership")
    
    let credentials = LoginCredentials(accountName: username, password:password)
    
    mothership.login(with: credentials)
    
  }
  
  $0.group("testflight") {
    
    $0.command(
      "login",
      Argument<String>("username", description: "iTunes Connect Email"),
      Argument<String>("password", description: "iTunes Connect Password")
               ) { (username:String, password:String) in
      
      print("logging \(username) in to Testflight")
      
      let credentials = LoginCredentials(accountName: username, password:password)
      
      testFlight.login(with: credentials)
      
    }
    
  }
  
}

group.run()

PromiseKit extension

Hey 👋

I'm currently using the following overload for command in order to be able to return a Promise from PromiseKit directly from my command. This, I think, makes it very easy to write asynchronous CLI apps (e.g. performing multiple tasks in parallel).

This example is only for the very specific "two argument descriptor and an executor" overload, but could easily be written for every already existing overload.

import Foundation

import Commander
import PromiseKit

public func command<A:ArgumentDescriptor, A1:ArgumentDescriptor>(_ descriptor: A, _ descriptor1:A1, _ closure:@escaping (A.ValueType, A1.ValueType) throws -> Promise<Void>) -> CommandType {
    return command(descriptor, descriptor1) { (value0: A.ValueType, value1: A1.ValueType) throws -> () in
        firstly {
            try closure(value0, value1)
        }.done { _ in
            exit(0)
        }.catch { err in
            command({ throw err }).run()
        }

        CFRunLoopRun()
    }
}

How would you feel about a pull request that would add these overloads? (probably as a new target, so that it's opt-in for consumers)

I would also like to improve the error handling (command({ throw err }).run()), how would you feel about extracting out the following lines to a separate function?

} catch let error as Help {
let help = error.reraise("$ \(executableName)")
help.print()
exit(1)
} catch GroupError.noCommand(let path, let group) {
var usage = "$ \(executableName)"
if let path = path {
usage += " \(path)"
}
let help = Help([], command: usage, group: group)
help.print()
exit(1)
} catch let error as ANSIConvertible {
error.print()
exit(1)
} catch let error as CustomStringConvertible {
ANSI.red.print(error.description, to: stderr)
exit(1)
} catch {
ANSI.red.print("Unknown error occurred.", to: stderr)
exit(1)
}

Thanks for a great library 🍻

Printing the default value of a string enum?

I am using the following enum as an argument:

enum SyncSource: String, ArgumentConvertible {
	case finder
	case iptc
	case both

	public init(parser: ArgumentParser) throws {
    if let value = parser.shift() {
		if let value = SyncSource(rawValue: value) {
			self.init(rawValue: value.rawValue)!
		} else {
			throw ArgumentError.invalidType(value: value, type:"SyncSource", argument: nil)
		}
    } else {
		throw ArgumentError.missingValue(argument: nil)
    }
  }
  public var description: String {
	  return self.rawValue
  }
}

Even though I did implement description I do not get a default value printed for a SyncSource option declared like this:

	Option("source", default: SyncSource.both, description: "Sync attributes source \([SyncSource.finder.rawValue, SyncSource.iptc.rawValue, SyncSource.both.rawValue])"),

Package -> Product -> Library

In version 0.7.0, Package.swift needs the products to be defined.

Without, it is not possible to link, and therefore to import, Commander into any project.

Xcode console not supporting colors

When running the application in Xcode the Framework incorrectly detects that the Xcode debug console supports colors:

Sample output

Unknown Arguments: -DnuvMSbNcReotdimsg

Arguments:

    �[34mmode�[0m - The mode in which the app will run

Cannot define an argument named `version`

Defining a version argument appears to conflict with some internal definition.

Given the argument:

Option<String?>(
    "version",
    default: nil,
    description: "The version number of the build"),

Commander always fails to parse the value:

$ mytool mycmd --version 123
Unknown Arguments: 123

Commander as stati library

Hello thanks for this package! Is there a way to make commander be a static library? It would benice to just be able to copy the cli executable arround without worring about the libraries being in the same folder.
Thanks

Issue when trying to run CLI tool

Whenever I try to run a CLI (my own or the playground) I get this error:

dyld: Library not loaded: @rpath/libswiftAppKit.dylib
  Referenced from: /Users/justinmakaila/Library/Developer/Xcode/DerivedData/HLSKit-cli-hajfgtnswuxgqkgwgdfrmsdooeoc/Build/Products/Debug/CLIKit.framework/Versions/A/CLIKit
  Reason: image not found

I've added CLIKit as a target dependency, is there anything else I should be aware of?

Also, Integration instructions in the README would be excellent.

The one-character Options flag does not seem to work anymore

Given an option defined like this:

let outputOption = Option("output", OutputDestination.Console, flag: "o", description: "The path to the file to generate (Omit to generate to stdout)")

Using -o doesn't work, while using --output does.
(The -o doesn't show up in the help either btw, not sure that's expected)

$ swiftgen images -o out.swift share/swiftgen/fixtures/Images.xcassets
Unknown Arguments: -o

Options:
    --output - The path to the file to generate (Omit to generate to stdout)
    --template - The name of the template to use for code generation (without the "images" prefix nor extension).
    --templatePath - The path of the template to use for code generation. Overrides -t.
    --enumName - The name of the enum to generate

$ swiftgen images --output out.swift share/swiftgen/fixtures/Images.xcassets
File written: out.swift

Was working in Commander 0.2.2, stopped working on 3.0.0

SPM: dependency graph is unresolvable

Tried to add Commander to a SPM project with the following Package.swift:

// swift-tools-version:4.0

import PackageDescription

let package = Package(
	name: "LocalizableCheck",
	dependencies: [
		.package(url: "https://github.com/kylef/Commander.git", from: "0.8.0"),
		.package(url: "https://github.com/kylef/PathKit.git", from: "0.8.0"),
		.package(url: "https://github.com/sharplet/Regex.git", from: "1.1.0"),
	],
	targets: [
		.target(
			name: "LocalizableCheck",
			dependencies: [
				"PathKit",
				"Regex"
			]
		)
	]
)

When I try swift package update, I get the following error:

error: dependency graph is unresolvable; found these conflicting requirements:

Dependencies:
https://github.com/kylef/PathKit.git @ 0.8.0..<1.0.0

Note that it complains about PathKit, but it happens when I add Commander to the project. Without Commander there's no issue. I have no clue why this is, but I'm guessing this is because of the common dependency on Spectre, with different version requirements from: "0.8.0" and .upToNextMinor(from:"0.8.0").

Bad help description for options with nil default value

Commander shows bad help text for Option where type is Optional and default value is nil.

Example

Option<String?>("name", default: nil, description: "The name")

shows

Options:
    --name [default: ] - The name

instead of

Options:
    --name - The name

Maximum number of arguments increase?

Apologies if I just missed a step in setup or so, but I'm using Commander as part of Sourcery and am running out of command line arguments. It seems there is a limit of about 16 arguments in Commander.

Am I missing some script I need to run to re-generate the templated classes to be able to specify more arguments (Sourcery has many options, and I need to add some new ones)?

I couldn't find anything about this limit or avoiding it in Github issues, the Readme, nor the Wiki on Github.

0.9.0 broke positional argument passing

I haven't had time to investigate this too much yet, but updating from 0.8.0 to 0.9.0 broke RasterizeXCAssets, even though my understanding was that the only breaking change should be requiring a more recent version of Swift?

When positional arguments is missing, it correctly prints that it's missing those arguments. But when they are given it prints an "Unknown Arguments" error:

$ swift run rasterizexcassets                                                                      
[0/0] Build complete!
An error occurred: Missing value for `source`

$ swift run rasterizexcassets a
[0/0] Build complete!
An error occurred: Missing value for `output`

$ swift run rasterizexcassets a b
[0/0] Build complete!
Unknown Arguments: a b

Here is the code used to set up the command:

func main(source: String, output: String, size: Size) throws {
    // ...
}

command(
    Argument<String>("source", description: "Source SVG file"),
    Argument<String>("output", description: "Output path for resulting asset"),
    Option<Size>("size", default: Size(width: 64, height: 64), description: "Size (in points) of the output asset (e.g. 120x120)"),
    main
).run()

Add badges

Below the title please add badges this help a lot.

If your component is compatible:

  • with carthage add Carthage compatible
  • with SwiftPM add SwiftPM compatible

Indicated:

  • the Swift version Swift Version
  • Platforms supported Plaforms
  • License License MIT

Commander Package.swift --> targets error

Hi, wtf?

i got error when try using in terminal

go to folder with project, adding repo to Package.swift
go to terminal --> swift build and got error

Desktop:cryptpwd username$ swift build warning: refname '0.8.0' is ambiguous. warning: refname '0.8.0' is ambiguous. HEAD is now at e5b50ad chore: Release 0.8.0 Resolved version: 0.8.0 /Users/username/Desktop/cryptpwd/Packages/Commander/Package.swift:13:3: error: argument 'targets' must precede argument 'dependencies' targets: [ ^ Can't parse Package.swift manifest file because it contains invalid format. Fix Package.swift file format and try again. error: The package at/Users/username/Desktop/cryptpwd/Packages/Commander' has no Package.swift for the specific version: 0.8.0
`

Not-returning CLI and passing commands to command.run()

Hi there!

I'm writing a cli to interact through serial with a robot.

The cli should not return unless the quit command is called and thus would be waiting for user input.

Would it be possible to do that with Commander? Waiting for user input with readline() and pass the string to Commander?

Thank you for your help!

Rendered Help doesn't show default value for Options

This is marked as a TODO in the source, willing to submit a PR do we want it rendered just as:

--<name> - <description> (Default: <default>)

Flags should also probably be updated to --[no-]<name> - <description> (Default: false)

Option without default value

Is it possible to specify an option without default value?
I might be missing something, but it seems that the default value is mandatory. While I can set it to some magic value, the problem is that it is printed using the "[default: XXX]" in help.

noobie question!

Hi, i'm trying to use your project in my console app, i'm noobie in swift but i have problem using
listing of commands in class

for example i got a class and inside i got Group with commands when i try to call a method where this group i got error `
import Commander

class MainController {
private var result = false
func auth() {
Group {
$0.command("login") { (name:String) in
print("Hello (name)")
self.result = true
}
$0.command("logout") {
print("Goodbye.")
}
}
}

func getInfo() {
    self.auth()
    if self.result {
        print("login confirmed!")
    } else {
        print("login not confirmed!")
    }
}

}
var doing = MainController()
doing.getInfo()`

Using the argument parser

Hi,

I'm trying to determine if the command is receiving a specific command.
I saw this example in README, Is this still valid?

command { (name:String, parser:ArgumentParser) in
  if parser.hasOption("verbose") {
    print("Verbose mode enabled")
  }

  print("Hello \(name)")
}

Probably I'm missing something here, but as far I can understand looking to Command.swift the parser is never passed to the closure as parameter.
Is there another way to do what I'm trying to achieve without accessing the parser?

Impossible to pass a negative number as the value for an option

If you configure an option to accept a number, it seems it's impossible to pass a negative number for the value of the option since it's interpreted as a flag instead.

I'm not 100% sure what the right way to resolve this would be without making a mess of things, but I figure it's something that should at least have a workaround.

Group {
    $0.command("submit", Option<Double>("nice", default: 0, flag: "n")) { niceValue in
        print(niceValue)
    }
}.run()

Attempts to use that flag:

$ swiftmatrix submit --nice 123
123.0

$ swiftmatrix submit --nice -123
An error occurred: Unexpected flag `-123` as a value for `--nice`

$ swiftmatrix submit --nice -0.123
An error occurred: Unexpected flag `-0.123` as a value for `--nice`

$ swiftmatrix submit --nice=-123
Unknown Arguments: --nice=-123

Options:
    --nice [default: 0.0]

$ swiftmatrix submit --nice=123
Unknown Arguments: --nice=123

Options:
    --nice [default: 0.0]

Adding commands in multiple places

I'm struggling with using Curassow, because it's using Commander for input arguments. I'd like to add my own arguments and parse my app's specific ones only, and leave Curassow to parse its own as well. Unfortunately currently Commander errors out if any command is unused, making this usecase impossible.

Assuming I'm not missing anything, I'd like there to be an option to not error out when unrecognized arguments are passed, instead they'd be ignored, making multi-layer argument parsing possible.

Rendered Help doesn't display descriptions for Argument's

Given an example app like:

if CommandLine.arguments.count == 1 {
    CommandLine.arguments += [
        "create",
        "--help"
    ]
}

let app = Group { app in

    app.command("create",
                Argument<String>("First Name", description: "The user's first name"),
                Argument<String>("Last Name", description: "The user's last name"), { fn, ln in
                    print("fn: \(fn), ln: \(ln)")
                })

}


app.run()

The help printed is just:

Usage:

    $ ./App <First Name> <Last Name>

I think it's weird that the Argument constructor takes a description yet it never gets displayed.

I think maybe it should instead:

Usage:

    $ ./App create <First Name> <Last Name>

Arguments:
    <First Name> - The user's first name.
    <Last Name> - The user's last name.

Would you be willing to accept a PR on this?

Cannot use Commander & Stencil in the same project

Hi Kyle,

Thanks for your contributions to OSS, Stencil is incredibly useful for something that I'm working on!

I'm attempting to use both Commander and Stencil in the same project, however when attempting to run swift package fetch it's returning an error, as both libraries require Spectre.

It appears to be an issue with Swift PM not resolving the dependency correctly. What do you think?

I've attached a small project to demonstrate.

error: rename error: Directory not empty (66): 
/Users/kramer_max/Desktop/CommanderStencil/Packages/Spectre.git ->    /Users/kramer_max/Desktop/CommanderStencil/Packages/Spectre-0.7.2

Package.swift:

let package = Package(
    name: "cerberus",
    dependencies: [
        .Package(url: "https://github.com/kylef/Stencil.git", majorVersion: 0, minor: 7),
        .Package(url: "https://github.com/kylef/Commander.git", majorVersion: 0)
    ]
)

Cheers,
Max.

CommanderStencil.zip

Please release 0.4.1

I encountered the crash fixed in #18. Instead of reporting an unknown command, Commander crashes.

Repeated arguments for options

I want to do something like:

command --set x --set y --set z ARG1 ARG2

which would parse out as an array of strings for set. I don't think this is currently possible because the Options object takes a specific count and expects all the arguments to immediately follow the --set option. Is that right? Is this a good thing to add if so?

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.