Commit 6d679476 authored by Matt Butcher's avatar Matt Butcher

Merge pull request #424 from technosophos/feat/helm-list

feat(cli): implement helm deployment list
parents faf62431 9a92f99d
...@@ -17,7 +17,11 @@ limitations under the License. ...@@ -17,7 +17,11 @@ limitations under the License.
package main package main
import ( import (
"errors"
"regexp"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/kubernetes/helm/pkg/format"
) )
func init() { func init() {
...@@ -28,6 +32,7 @@ func deploymentCommands() cli.Command { ...@@ -28,6 +32,7 @@ func deploymentCommands() cli.Command {
return cli.Command{ return cli.Command{
// Names following form prescribed here: http://is.gd/QUSEOF // Names following form prescribed here: http://is.gd/QUSEOF
Name: "deployment", Name: "deployment",
Aliases: []string{"dep"},
Usage: "Perform deployment-centered operations.", Usage: "Perform deployment-centered operations.",
Subcommands: []cli.Command{ Subcommands: []cli.Command{
{ {
...@@ -50,7 +55,38 @@ func deploymentCommands() cli.Command { ...@@ -50,7 +55,38 @@ func deploymentCommands() cli.Command {
Name: "list", Name: "list",
Usage: "list all deployments, or filter by an optional pattern", Usage: "list all deployments, or filter by an optional pattern",
ArgsUsage: "PATTERN", ArgsUsage: "PATTERN",
Action: func(c *cli.Context) { run(c, list) },
}, },
}, },
} }
} }
func list(c *cli.Context) error {
list, err := NewClient(c).ListDeployments()
if err != nil {
return err
}
args := c.Args()
if len(args) >= 1 {
pattern := args[0]
r, err := regexp.Compile(pattern)
if err != nil {
return err
}
newlist := []string{}
for _, i := range list {
if r.MatchString(i) {
newlist = append(newlist, i)
}
}
list = newlist
}
if len(list) == 0 {
return errors.New("no deployments found")
}
format.List(list)
return nil
}
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/kubernetes/helm/pkg/client" "github.com/kubernetes/helm/pkg/client"
"github.com/kubernetes/helm/pkg/format"
"github.com/kubernetes/helm/pkg/version" "github.com/kubernetes/helm/pkg/version"
) )
...@@ -30,6 +31,12 @@ func init() { ...@@ -30,6 +31,12 @@ func init() {
addCommands(cmds()...) addCommands(cmds()...)
} }
// debug indicates whether the process is in debug mode.
//
// This is set at app start-up time, based on the presence of the --debug
// flag.
var debug bool
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "helm" app.Name = "helm"
...@@ -55,6 +62,10 @@ func main() { ...@@ -55,6 +62,10 @@ func main() {
Usage: "Enable verbose debugging output", Usage: "Enable verbose debugging output",
}, },
} }
app.Before = func(c *cli.Context) error {
debug = c.GlobalBool("debug")
return nil
}
app.Run(os.Args) app.Run(os.Args)
} }
...@@ -72,7 +83,7 @@ func addCommands(cmds ...cli.Command) { ...@@ -72,7 +83,7 @@ func addCommands(cmds ...cli.Command) {
func run(c *cli.Context, f func(c *cli.Context) error) { func run(c *cli.Context, f func(c *cli.Context) error) {
if err := f(c); err != nil { if err := f(c); err != nil {
os.Stderr.Write([]byte(err.Error())) format.Err(err)
os.Exit(1) os.Exit(1)
} }
} }
...@@ -80,7 +91,6 @@ func run(c *cli.Context, f func(c *cli.Context) error) { ...@@ -80,7 +91,6 @@ func run(c *cli.Context, f func(c *cli.Context) error) {
// NewClient creates a new client instance preconfigured for CLI usage. // NewClient creates a new client instance preconfigured for CLI usage.
func NewClient(c *cli.Context) *client.Client { func NewClient(c *cli.Context) *client.Client {
host := c.GlobalString("host") host := c.GlobalString("host")
debug := c.GlobalBool("debug")
timeout := c.GlobalInt("timeout") timeout := c.GlobalInt("timeout")
return client.NewClient(host).SetDebug(debug).SetTimeout(timeout) return client.NewClient(host).SetDebug(debug).SetTimeout(timeout)
} }
...@@ -17,41 +17,77 @@ limitations under the License. ...@@ -17,41 +17,77 @@ limitations under the License.
package format package format
import ( import (
"bytes"
"fmt" "fmt"
"io"
"os" "os"
"reflect"
"sort"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
) )
// Stdout is the output this library will write to.
var Stdout io.Writer = os.Stdout
// Stderr is the error output this library will write to.
var Stderr io.Writer = os.Stderr
// This is all just placeholder. // This is all just placeholder.
// Err prints an error message to Stderr. // Err prints an error message to Stderr.
func Err(msg string, v ...interface{}) { func Err(message interface{}, v ...interface{}) {
var msg string
val := reflect.Indirect(reflect.ValueOf(message))
if val.Kind() == reflect.String {
msg = message.(string)
} else if z, ok := message.(fmt.Stringer); ok {
msg = z.String()
} else if z, ok := message.(error); ok {
msg = z.Error()
}
msg = "[ERROR] " + msg + "\n" msg = "[ERROR] " + msg + "\n"
fmt.Fprintf(os.Stderr, msg, v...) fmt.Fprintf(Stderr, msg, v...)
} }
// Info prints an informational message to Stdout. // Info prints an informational message to Stdout.
func Info(msg string, v ...interface{}) { func Info(msg string, v ...interface{}) {
msg = "[INFO] " + msg + "\n" msg = "[INFO] " + msg + "\n"
fmt.Fprintf(os.Stdout, msg, v...) fmt.Fprintf(Stdout, msg, v...)
} }
// Msg prints a raw message to Stdout. // Msg prints a raw message to Stdout.
func Msg(msg string, v ...interface{}) { func Msg(msg string, v ...interface{}) {
fmt.Fprintf(os.Stdout, msg, v...) fmt.Fprintf(Stdout, msg, v...)
} }
// Success is an achievement marked by pretty output. // Success is an achievement marked by pretty output.
func Success(msg string, v ...interface{}) { func Success(msg string, v ...interface{}) {
msg = "[Success] " + msg + "\n" msg = "[Success] " + msg + "\n"
fmt.Fprintf(os.Stdout, msg, v...) fmt.Fprintf(Stdout, msg, v...)
} }
// Warning emits a warning message. // Warning emits a warning message.
func Warning(msg string, v ...interface{}) { func Warning(msg string, v ...interface{}) {
msg = "[Warning] " + msg + "\n" msg = "[Warning] " + msg + "\n"
fmt.Fprintf(os.Stdout, msg, v...) fmt.Fprintf(Stdout, msg, v...)
}
// List prints a list of strings to Stdout.
//
// This sorts lexicographically.
func List(list []string) {
sort.Strings(list)
// Buffer and then flush all at once to avoid concurrency-based interleaving.
var b bytes.Buffer
for _, v := range list {
if v == "" {
v = "[empty]"
}
fmt.Fprintf(&b, "%s\n", v)
}
Stdout.Write(b.Bytes())
} }
// YAML prints an object in YAML format. // YAML prints an object in YAML format.
......
...@@ -14,29 +14,23 @@ See the License for the specific language governing permissions and ...@@ -14,29 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package main package format
import ( import (
"github.com/codegangsta/cli" "bytes"
"github.com/kubernetes/helm/pkg/format" "os"
"testing"
) )
func init() { func TestList(t *testing.T) {
addCommands(listCmd()) var b bytes.Buffer
} in := []string{"ddd", "ccc", "aaa", "bbb"}
expect := "aaa\nbbb\nccc\nddd\n"
func listCmd() cli.Command { Stdout = &b
return cli.Command{ defer func() { Stdout = os.Stdout }()
Name: "list",
Usage: "Lists the deployments in the cluster",
Action: func(c *cli.Context) { run(c, list) },
}
}
func list(c *cli.Context) error { List(in)
list, err := NewClient(c).ListDeployments() if b.String() != expect {
if err != nil { t.Errorf("Expected %q, got %q", expect, b.String())
return err
} }
return format.YAML(list)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment