Skip to content

Commit

Permalink
feat(cli): implement list --shared argument (reanahub#153)
Browse files Browse the repository at this point in the history
Adds new `--shared`, `--shared-by`, and `--shared-with` arguments to the
`list` CLI command to display workflows along with their sharing
information.

Closes reanahub/reana-client#687
  • Loading branch information
DaanRosendal authored and mdonadoni committed Aug 19, 2024
1 parent 318bcf6 commit a568abd
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 7 deletions.
80 changes: 74 additions & 6 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,25 @@ criteria. Use --filter
<columm_name>=<column_value> pairs. Available
filters are 'name' and 'status'.`

const listDesc = `
List all workflows and sessions.
const listDesc = `List all workflows and sessions.
The ` + "``list``" + ` command lists workflows and sessions. By default, the list of
workflows is returned. If you would like to see the list of your open
The ` + "``list``" + ` command lists workflows and sessions. By default, a list of
owned workflows is returned. If you would like to see the list of your open
interactive sessions, you need to pass the ` + "``--sessions``" + ` command-line
option.
option. If you would like to see the list of all workflows, including those
shared with you, you need to pass the ` + "``--shared``" + ` command-line option.
Along with specific user emails, you can pass the following special
values to the ` + "``--shared-by``" + ` and ` + "``--shared-with``" + ` command-line options:
- ` + "``--shared-by anybody``" + `: list workflows shared with you by anybody.
- ` + "``--shared-with anybody``" + `: list your shared workflows exclusively.
- ` + "``--shared-with nobody``" + `: list your unshared workflows exclusively.
- ` + "``--shared-with [email protected],[email protected]``" + `: list workflows
shared with either [email protected] or [email protected]
Examples:
Expand All @@ -51,6 +63,12 @@ Examples:
$ reana-client list --sessions
$ reana-client list --verbose --bytes
$ reana-client list --shared
$ reana-client list --shared-by [email protected]
$ reana-client list --shared-with anybody
`

type listOptions struct {
Expand All @@ -71,6 +89,9 @@ type listOptions struct {
showDeletedRuns bool
page int64
size int64
shared bool
shared_by string
shared_with string
}

// newListCmd creates a new command for listing workflows and sessions.
Expand Down Expand Up @@ -139,8 +160,16 @@ In case a workflow is in progress, its duration as of now will be shown.`,
)
f.Int64Var(&o.page, "page", 1, "Results page number (to be used with --size).")
f.Int64Var(&o.size, "size", 0, "Number of results per page (to be used with --page).")
f.BoolVar(&o.shared, "shared", false, "List all shared (owned and unowned) workflows.")
f.StringVar(&o.shared_by, "shared-by", "", "List workflows shared by the specified user(s).")
f.StringVar(
&o.shared_with,
"shared-with",
"",
"List workflows shared with the specified user(s).",
)
// Remove -h shorthand
cmd.PersistentFlags().BoolP("help", "", false, "Help for du")
cmd.PersistentFlags().BoolP("help", "", false, "Help for list")

err := f.SetAnnotation("workflow", "properties", []string{"optional"})
if err != nil {
Expand All @@ -150,6 +179,17 @@ In case a workflow is in progress, its duration as of now will be shown.`,
}

func (o *listOptions) run(cmd *cobra.Command) error {
if o.shared_by != "" && o.shared_with != "" {
displayer.DisplayMessage(
"Please provide either --shared-by or --shared-with, not both.",
displayer.Error,
false,
cmd.OutOrStdout(),
)

return nil
}

var runType string
if o.listSessions {
runType = "interactive"
Expand Down Expand Up @@ -180,6 +220,15 @@ func (o *listOptions) run(cmd *cobra.Command) error {
if cmd.Flags().Changed("include-workspace-size") {
listParams.SetIncludeWorkspaceSize(&o.includeWorkspaceSize)
}
if cmd.Flags().Changed("shared") {
listParams.SetShared(&o.shared)
}
if cmd.Flags().Changed("shared-by") {
listParams.SetSharedBy(&o.shared_by)
}
if cmd.Flags().Changed("shared-with") {
listParams.SetSharedWith(&o.shared_with)
}

api, err := client.ApiClient()
if err != nil {
Expand All @@ -196,6 +245,9 @@ func (o *listOptions) run(cmd *cobra.Command) error {
o.includeWorkspaceSize,
o.includeProgress,
o.includeDuration,
o.shared,
o.shared_by,
o.shared_with,
)
parsedFormatFilters := formatter.ParseFormatParameters(o.formatFilters, true)
err = displayListPayload(
Expand Down Expand Up @@ -280,6 +332,10 @@ func displayListPayload(
}
case "session_status":
value = getOptionalStringField(&workflow.SessionStatus)
case "shared_by":
value = workflow.OwnerEmail
case "shared_with":
value = workflow.SharedWith
}

colSeries.Append(value)
Expand Down Expand Up @@ -315,6 +371,8 @@ func displayListPayload(
func buildListHeader(
runType string,
verbose, includeWorkspaceSize, includeProgress, includeDuration bool,
shared bool,
shared_by, shared_with string,
) []string {
headers := map[string][]string{
"batch": {"name", "run_number", "created", "started", "ended", "status"},
Expand All @@ -341,6 +399,16 @@ func buildListHeader(
if verbose || includeDuration {
header = append(header, "duration")
}
if shared {
header = append(header, "shared_with", "shared_by")
} else {
if shared_with != "" {
header = append(header, "shared_with")
}
if shared_by != "" {
header = append(header, "shared_by")
}
}

return header
}
Expand Down
78 changes: 78 additions & 0 deletions cmd/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,54 @@ func TestList(t *testing.T) {
"NAME", "RUN_NUMBER", "CREATED", "STARTED", "ENDED", "STATUS",
},
},
"include shared by others": {
serverResponses: map[string]ServerResponse{
listServerPath: {
statusCode: http.StatusOK,
responseFile: "list.json",
},
},
args: []string{"--shared"},
expected: []string{
"SHARED_BY", "SHARED_WITH",
},
},
"list shared with user": {
serverResponses: map[string]ServerResponse{
listServerPath: {
statusCode: http.StatusOK,
responseFile: "list.json",
},
},
args: []string{"--shared-with", "anybody"},
expected: []string{
"SHARED_WITH",
},
unwanted: []string{
"SHARED_BY",
},
},
"list shared by user": {
serverResponses: map[string]ServerResponse{
listServerPath: {
statusCode: http.StatusOK,
responseFile: "list.json",
},
},
args: []string{"--shared-by", "anybody"},
expected: []string{
"SHARED_BY",
},
unwanted: []string{
"SHARED_WITH",
},
},
"invalid: shared with and shared by in the same command": {
args: []string{"--shared-by", "anybody", "--shared-with", "anybody"},
expected: []string{
"Please provide either --shared-by or --shared-with, not both",
},
},
}

for name, params := range tests {
Expand All @@ -277,6 +325,9 @@ func TestBuildListHeader(t *testing.T) {
includeWorkspaceSize bool
includeProgress bool
includeDuration bool
shared bool
shared_by string
shared_with string
expected []string
}{
"batch run": {
Expand Down Expand Up @@ -322,6 +373,30 @@ func TestBuildListHeader(t *testing.T) {
"ended", "status", "duration",
},
},
"shared": {
runType: "batch",
shared: true,
expected: []string{
"name", "run_number", "created", "started",
"ended", "status", "shared_with", "shared_by",
},
},
"shared by": {
runType: "batch",
shared_by: "[email protected]",
expected: []string{
"name", "run_number", "created", "started",
"ended", "status", "shared_by",
},
},
"shared with": {
runType: "batch",
shared_with: "[email protected]",
expected: []string{
"name", "run_number", "created", "started",
"ended", "status", "shared_with",
},
},
}

for name, test := range tests {
Expand All @@ -332,6 +407,9 @@ func TestBuildListHeader(t *testing.T) {
test.includeWorkspaceSize,
test.includeProgress,
test.includeDuration,
test.shared,
test.shared_by,
test.shared_with,
)
if !slices.Equal(header, test.expected) {
t.Errorf("expected %v, got %v", test.expected, header)
Expand Down
2 changes: 1 addition & 1 deletion cmd/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func newLsCmd() *cobra.Command {
f.Int64Var(&o.page, "page", 1, "Results page number (to be used with --size).")
f.Int64Var(&o.size, "size", 0, "Number of results per page (to be used with --page).")
// Remove -h shorthand
cmd.PersistentFlags().BoolP("help", "", false, "Help for du")
cmd.PersistentFlags().BoolP("help", "", false, "Help for ls")

return cmd
}
Expand Down

0 comments on commit a568abd

Please sign in to comment.