Skip to content

Instantly share code, notes, and snippets.

@jayd3e
Created March 23, 2014 17:43
Show Gist options
  • Save jayd3e/9726723 to your computer and use it in GitHub Desktop.
Save jayd3e/9726723 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"fmt"
"log"
"os"
"reflect"
)
type FlynnConfig struct {
Servers []server
}
type server struct {
GitHost string
ApiRoot string
ApiKey string
ApiTlsPin string
}
func NewFlynnConfig() *FlynnConfig {
return &FlynnConfig{
Servers: []server{},
}
}
func main() {
log.SetFlags(0)
var (
_ = flag.String("a", "", "Specific app to use")
)
flag.Parse()
// Create the main cli object
config := NewFlynnConfig()
cli := NewFlynnCli(config)
// Run the command
if err := cli.ParseCommands(flag.Args()...); err != nil {
log.Fatal(err)
}
}
func (cli *FlynnCli) getMethod(name string) (func(...string) error, bool) {
methodName := "Cmd" + capitalize(name)
method := reflect.ValueOf(cli).MethodByName(methodName)
if !method.IsValid() {
return nil, false
}
return method.Interface().(func(...string) error), true
}
func (cli *FlynnCli) ParseCommands(args ...string) error {
if len(args) > 0 {
method, exists := cli.getMethod(args[0])
if !exists {
fmt.Println("Error: Command not found:", args[0])
return cli.CmdHelp(args[1:]...)
}
return method(args[1:]...)
}
return cli.CmdHelp(args...)
}
func (cli *FlynnCli) CmdHelp(args ...string) error {
// If they have specified a specific command in the fashion `flynn help login`
if len(args) > 0 {
method, exists := cli.getMethod(args[0])
if !exists {
fmt.Printf("Error: Command not found: %s\n", args[0])
} else {
method("--help")
return nil
}
}
// Otherwise display some general usage information
help := fmt.Sprintf("Usage: [-a app] [command] [options] [arguments]\n\nA Flynn CLI client.\n\nCommands:\n")
for _, command := range [][]string{
{"login", "Attach to a running container"},
{"create", "Build a container from a Dockerfile"},
{"run", "Run a job"},
{"ps", "List jobs"},
{"logs", "Get job logs"},
{"scale", "Change formation"},
{"route", "Links a route to an app"},
{"api", "Make a single API request"},
} {
help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1])
}
fmt.Printf("%s\n", help)
return nil
}
func (cli *FlynnCli) CmdLogin(args ...string) error {
cmd := cli.Subcmd("login", "", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdCreate(args ...string) error {
cmd := cli.Subcmd("create", "GIT_HOST API_ROOT", "Creates a Flynn app.")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdRun(args ...string) error {
cmd := cli.Subcmd("run", "COMMAND", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdPs(args ...string) error {
cmd := cli.Subcmd("ps", "", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdLogs(args ...string) error {
cmd := cli.Subcmd("logs", "", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdScale(args ...string) error {
cmd := cli.Subcmd("scale", "PROCESS_TYPE=NUM,...", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdDomain(args ...string) error {
cmd := cli.Subcmd("domain", "DOMAIN", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) CmdApi(args ...string) error {
cmd := cli.Subcmd("api", "", "")
if err := cmd.Parse(args); err != nil {
return nil
}
return nil
}
func (cli *FlynnCli) Subcmd(name, signature, description string) *flag.FlagSet {
flags := flag.NewFlagSet(name, flag.ContinueOnError)
flags.Usage = func() {
fmt.Printf("\nUsage: flynn %s %s\n\n%s\n\n", name, signature, description)
flags.PrintDefaults()
os.Exit(2)
}
return flags
}
func NewFlynnCli(config *FlynnConfig) *FlynnCli {
return &FlynnCli{
config: config,
}
}
type FlynnCli struct {
config *FlynnConfig
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment