Skip to content

Commit

Permalink
Merge pull request #12 from pressly/tabwriter
Browse files Browse the repository at this point in the history
Use tabwriter & refactor usage
  • Loading branch information
VojtechVitek committed Nov 25, 2015
2 parents 1e19143 + d62fe19 commit 8fb86db
Showing 1 changed file with 74 additions and 54 deletions.
128 changes: 74 additions & 54 deletions cmd/sup/main.go
Original file line number Diff line number Diff line change
@@ -1,107 +1,124 @@
package main

import (
"errors"
"flag"
"fmt"
"log"
"os"
"strings"
"text/tabwriter"

"github.com/pressly/sup"
)

var (
supfile = flag.String("f", "./Supfile", "custom path to Supfile")
supfile = flag.String("f", "./Supfile", "custom path to Supfile")
ErrCmd = errors.New("Usage: sup [-f <Supfile>] <network> <target/command>")
ErrUnknownNetwork = errors.New("Unknown network")
ErrNetworkNoHosts = errors.New("No hosts for a given network")
ErrTarget = errors.New("Unknown target")
ErrTargetNoCommands = errors.New("No commands for a given target")
)

// usage prints help for an arg and exits.
func usage(conf *sup.Supfile, arg int) {
log.Println("Usage: sup <network> <target/command>\n")
switch arg {
case 1:
// <network> missing, print available hosts.
log.Println("Available networks (from ./Supfile):")
for name, network := range conf.Networks {
log.Printf("- %v\n", name)
for _, host := range network.Hosts {
log.Printf(" - %v\n", host)
}
}
case 2:
// <target/command> not found or missing,
// print available targets/commands.
log.Println("Available targets (from Supfile):")
for name, commands := range conf.Targets {
log.Printf("- %v", name)
for _, cmd := range commands {
log.Printf("\t%v\n", cmd)
}
}
log.Println()
log.Println("Available commands (from Supfile):")
for name, cmd := range conf.Commands {
log.Printf("- %v\t%v", name, cmd.Desc)
func networkUsage(conf *sup.Supfile) {
w := &tabwriter.Writer{}
w.Init(os.Stderr, 4, 4, 2, ' ', 0)
defer w.Flush()

// <network> missing, print available hosts.
fmt.Fprintln(w, "Networks:\t")
for name, network := range conf.Networks {
fmt.Fprintf(w, "- %v\n", name)
for _, host := range network.Hosts {
fmt.Fprintf(w, "\t- %v\n", host)
}
}
os.Exit(1)
fmt.Fprintln(w)
}

func targetUsage(conf *sup.Supfile) {
w := &tabwriter.Writer{}
w.Init(os.Stderr, 4, 4, 2, ' ', 0)
defer w.Flush()

// <target/command> not found or missing,
// print available targets/commands.
fmt.Fprintln(w, "Targets:\t")
for name, commands := range conf.Targets {
fmt.Fprintf(w, "- %v\t%v\n", name, strings.Join(commands, ", "))
}
fmt.Fprintln(w, "\t")
fmt.Fprintln(w, "Commands:\t")
for name, cmd := range conf.Commands {
fmt.Fprintf(w, "- %v\t%v\n", name, cmd.Desc)
}
fmt.Fprintln(w)
}

// parseArgs parses os.Args and returns network and commands to be run.
// parseArgs parses args and returns network and commands to be run.
// On error, it prints usage and exits.
func parseArgsOrDie(conf *sup.Supfile) (*sup.Network, []*sup.Command) {
func parseArgs(conf *sup.Supfile) (*sup.Network, []*sup.Command, error) {
var commands []*sup.Command

// Check for the first argument first
if len(os.Args) < 2 {
usage(conf, len(os.Args))
args := flag.Args()

if len(args) < 1 {
networkUsage(conf)
return nil, nil, ErrCmd
}

// Does the <network> exist?
network, ok := conf.Networks[os.Args[1]]
network, ok := conf.Networks[args[0]]
if !ok {
log.Printf("Unknown network \"%v\"\n\n", os.Args[1])
usage(conf, 1)
networkUsage(conf)
return nil, nil, ErrUnknownNetwork
}

// Does <network> have any hosts?
if len(network.Hosts) == 0 {
log.Printf("No hosts specified for network \"%v\"", os.Args[1])
usage(conf, 1)
networkUsage(conf)
return nil, nil, ErrNetworkNoHosts
}

// Check for the second argument
if len(os.Args) < 3 {
usage(conf, len(os.Args))
if len(args) < 2 {
targetUsage(conf)
return nil, nil, ErrCmd
}

// Does the <target/command> exist?
target, isTarget := conf.Targets[os.Args[2]]
target, isTarget := conf.Targets[args[1]]
if isTarget {
// It's the target. Loop over its commands.
for _, cmd := range target {
// Does the target's command exist?
command, isCommand := conf.Commands[cmd]
if !isCommand {
log.Printf("Unknown command \"%v\" (from target \"%v\": %v)\n\n", cmd, os.Args[2], target)
usage(conf, 2)
targetUsage(conf)
return nil, nil, ErrTargetNoCommands
}
command.Name = cmd
commands = append(commands, &command)
}
} else {
// It's probably a command. Does it exist?
command, isCommand := conf.Commands[os.Args[2]]
command, isCommand := conf.Commands[args[1]]
if !isCommand {
// Not a target, nor command.
log.Printf("Unknown target/command \"%v\"\n\n", os.Args[2])
usage(conf, 2)
targetUsage(conf)
return nil, nil, ErrTargetNoCommands
}
command.Name = os.Args[2]
command.Name = args[1]
commands = append(commands, &command)
}

// Check for extra arguments
if len(os.Args) != 3 {
usage(conf, len(os.Args))
// TODO: Do we want to use extra args?
if len(args) > 2 {
return nil, nil, ErrCmd
}

return &network, commands
return &network, commands, nil
}

func main() {
Expand All @@ -112,8 +129,11 @@ func main() {
log.Fatal(err)
}

// Parse network and commands to be run from os.Args.
network, commands := parseArgsOrDie(conf)
// Parse network and commands to be run from args.
network, commands, err := parseArgs(conf)
if err != nil {
log.Fatal(err)
}

// Create new Stackup app.
app, err := sup.New(conf)
Expand Down

0 comments on commit 8fb86db

Please sign in to comment.