Skip to content

Commit

Permalink
Add --status filter for get command (#1325)
Browse files Browse the repository at this point in the history
  • Loading branch information
xianlubird authored and jessesuen committed May 10, 2019
1 parent 3f6ac9c commit 8bf7578
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 28 deletions.
3 changes: 3 additions & 0 deletions cmd/argo/commands/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const (
FgDefault = 39
)

// Default status for printWorkflow
const DefaultStatus = ""

func initializeSession() {
jobStatusIconMap = map[wfv1.NodePhase]string{
wfv1.NodePending: ansiFormat("◷", FgYellow),
Expand Down
61 changes: 37 additions & 24 deletions cmd/argo/commands/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ import (

const onExitSuffix = "onExit"

type getFlags struct {
output string
status string
}

func NewGetCommand() *cobra.Command {
var (
output string
getArgs getFlags
)

var command = &cobra.Command{
Expand All @@ -40,17 +45,22 @@ func NewGetCommand() *cobra.Command {
if err != nil {
log.Fatal(err)
}
printWorkflow(wf, output)
printWorkflow(wf, getArgs.output, getArgs.status)
},
}

command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: json|yaml|wide")
command.Flags().StringVarP(&getArgs.output, "output", "o", "", "Output format. One of: json|yaml|wide")
command.Flags().BoolVar(&noColor, "no-color", false, "Disable colorized output")
command.Flags().StringVar(&getArgs.status, "status", "", "Filter by status (Pending, Running, Succeeded, Skipped, Failed, Error)")
return command
}

func printWorkflow(wf *wfv1.Workflow, outFmt string) {
switch outFmt {
func printWorkflow(wf *wfv1.Workflow, output, status string) {
getArgs := getFlags{
output: output,
status: status,
}
switch getArgs.output {
case "name":
fmt.Println(wf.ObjectMeta.Name)
case "json":
Expand All @@ -60,13 +70,13 @@ func printWorkflow(wf *wfv1.Workflow, outFmt string) {
outBytes, _ := yaml.Marshal(wf)
fmt.Print(string(outBytes))
case "wide", "":
printWorkflowHelper(wf, outFmt)
printWorkflowHelper(wf, getArgs)
default:
log.Fatalf("Unknown output format: %s", outFmt)
log.Fatalf("Unknown output format: %s", getArgs.output)
}
}

func printWorkflowHelper(wf *wfv1.Workflow, outFmt string) {
func printWorkflowHelper(wf *wfv1.Workflow, getArgs getFlags) {
const fmtStr = "%-20s %v\n"
fmt.Printf(fmtStr, "Name:", wf.ObjectMeta.Name)
fmt.Printf(fmtStr, "Namespace:", wf.ObjectMeta.Namespace)
Expand Down Expand Up @@ -128,7 +138,7 @@ func printWorkflowHelper(wf *wfv1.Workflow, outFmt string) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Println()
// apply a dummy FgDefault format to align tabwriter with the rest of the columns
if outFmt == "wide" {
if getArgs.output == "wide" {
fmt.Fprintf(w, "%s\tPODNAME\tDURATION\tARTIFACTS\tMESSAGE\n", ansiFormat("STEP", FgDefault))
} else {
fmt.Fprintf(w, "%s\tPODNAME\tDURATION\tMESSAGE\n", ansiFormat("STEP", FgDefault))
Expand All @@ -139,12 +149,12 @@ func printWorkflowHelper(wf *wfv1.Workflow, outFmt string) {

// Print main and onExit Trees
mainRoot := roots[wf.ObjectMeta.Name]
mainRoot.renderNodes(w, wf, 0, " ", " ", outFmt)
mainRoot.renderNodes(w, wf, 0, " ", " ", getArgs)

onExitID := wf.NodeID(wf.ObjectMeta.Name + "." + onExitSuffix)
if onExitRoot, ok := roots[onExitID]; ok {
fmt.Fprintf(w, "\t\t\t\t\t\n")
onExitRoot.renderNodes(w, wf, 0, " ", " ", outFmt)
onExitRoot.renderNodes(w, wf, 0, " ", " ", getArgs)
}
_ = w.Flush()
}
Expand Down Expand Up @@ -175,7 +185,7 @@ func (n *nodeInfo) getStartTime(wf *wfv1.Workflow) metav1.Time {
// Interface to represent Nodes in render form types
type renderNode interface {
// Render this renderNode and its children
renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, outFmt string)
renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, getArgs getFlags)
nodeInfoInterface
}

Expand Down Expand Up @@ -364,7 +374,7 @@ func filterNode(node wfv1.NodeStatus) (bool, bool) {
// whether it was filtered and does this child need special indent
func renderChild(w *tabwriter.Writer, wf *wfv1.Workflow, nInfo renderNode, depth int,
nodePrefix string, childPrefix string, parentFiltered bool,
childIndex int, maxIndex int, childIndent bool, outFmt string) {
childIndex int, maxIndex int, childIndent bool, getArgs getFlags) {
var part, subp string
if parentFiltered && childIndent {
if maxIndex == 0 {
Expand Down Expand Up @@ -402,11 +412,14 @@ func renderChild(w *tabwriter.Writer, wf *wfv1.Workflow, nInfo renderNode, depth
}
childChldPrefix = childPrefix + subp
}
nInfo.renderNodes(w, wf, depth, childNodePrefix, childChldPrefix, outFmt)
nInfo.renderNodes(w, wf, depth, childNodePrefix, childChldPrefix, getArgs)
}

// Main method to print information of node in get
func printNode(w *tabwriter.Writer, wf *wfv1.Workflow, node wfv1.NodeStatus, depth int, nodePrefix string, childPrefix string, outFmt string) {
func printNode(w *tabwriter.Writer, wf *wfv1.Workflow, node wfv1.NodeStatus, depth int, nodePrefix string, childPrefix string, getArgs getFlags) {
if getArgs.status != "" && string(node.Phase) != getArgs.status {
return
}
nodeName := fmt.Sprintf("%s %s", jobStatusIconMap[node.Phase], node.DisplayName)
var args []interface{}
duration := humanize.RelativeDurationShort(node.StartedAt.Time, node.FinishedAt.Time)
Expand All @@ -415,7 +428,7 @@ func printNode(w *tabwriter.Writer, wf *wfv1.Workflow, node wfv1.NodeStatus, dep
} else {
args = []interface{}{nodePrefix, nodeName, "", "", node.Message}
}
if outFmt == "wide" {
if getArgs.output == "wide" {
msg := args[len(args)-1]
args[len(args)-1] = getArtifactsString(node)
args = append(args, msg)
Expand All @@ -427,36 +440,36 @@ func printNode(w *tabwriter.Writer, wf *wfv1.Workflow, node wfv1.NodeStatus, dep

// renderNodes for each renderNode Type
// boundaryNode
func (nodeInfo *boundaryNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, outFmt string) {
func (nodeInfo *boundaryNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, getArgs getFlags) {
filtered, childIndent := filterNode(nodeInfo.getNodeStatus(wf))
if !filtered {
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, outFmt)
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, getArgs)
}

for i, nInfo := range nodeInfo.boundaryContained {
renderChild(w, wf, nInfo, depth, nodePrefix, childPrefix, filtered, i,
len(nodeInfo.boundaryContained)-1, childIndent, outFmt)
len(nodeInfo.boundaryContained)-1, childIndent, getArgs)
}
}

// nonBoundaryParentNode
func (nodeInfo *nonBoundaryParentNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, outFmt string) {
func (nodeInfo *nonBoundaryParentNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, getArgs getFlags) {
filtered, childIndent := filterNode(nodeInfo.getNodeStatus(wf))
if !filtered {
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, outFmt)
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, getArgs)
}

for i, nInfo := range nodeInfo.children {
renderChild(w, wf, nInfo, depth, nodePrefix, childPrefix, filtered, i,
len(nodeInfo.children)-1, childIndent, outFmt)
len(nodeInfo.children)-1, childIndent, getArgs)
}
}

// executionNode
func (nodeInfo *executionNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, outFmt string) {
func (nodeInfo *executionNode) renderNodes(w *tabwriter.Writer, wf *wfv1.Workflow, depth int, nodePrefix string, childPrefix string, getArgs getFlags) {
filtered, _ := filterNode(nodeInfo.getNodeStatus(wf))
if !filtered {
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, outFmt)
printNode(w, wf, nodeInfo.getNodeStatus(wf), depth, nodePrefix, childPrefix, getArgs)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/resubmit.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewResubmitCommand() *cobra.Command {
errors.CheckError(err)
created, err := util.SubmitWorkflow(wfClient, newWF, nil)
errors.CheckError(err)
printWorkflow(created, cliSubmitOpts.output)
printWorkflow(created, cliSubmitOpts.output, DefaultStatus)
waitOrWatch([]string{created.Name}, cliSubmitOpts)
},
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewRetryCommand() *cobra.Command {
if err != nil {
log.Fatal(err)
}
printWorkflow(wf, cliSubmitOpts.output)
printWorkflow(wf, cliSubmitOpts.output, DefaultStatus)
waitOrWatch([]string{wf.Name}, cliSubmitOpts)
},
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func SubmitWorkflows(filePaths []string, submitOpts *util.SubmitOpts, cliOpts *c
if err != nil {
log.Fatalf("Failed to submit workflow: %v", err)
}
printWorkflow(created, cliOpts.output)
printWorkflow(created, cliOpts.output, DefaultStatus)
workflowNames = append(workflowNames, created.Name)
}
waitOrWatch(workflowNames, *cliOpts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func watchWorkflow(name string) {
errors.CheckError(err)
print("\033[H\033[2J")
print("\033[0;0H")
printWorkflowHelper(wf, "")
printWorkflowHelper(wf, getFlags{})
if !wf.Status.FinishedAt.IsZero() {
break
}
Expand Down

0 comments on commit 8bf7578

Please sign in to comment.