Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --status filter for get command #1325

Merged
merged 2 commits into from
May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a global variable, we should make this a local variable to NewGetCommand() instead, and pass the status filter down to printNode() through function arguments.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jessesuen

According to your comments, I change the code and pass param through function arguments.

Pls take a look. cc @sarabala1979

}

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