forked from reanahub/reana-client-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): implement list --shared argument (reanahub#153)
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
1 parent
318bcf6
commit a568abd
Showing
3 changed files
with
153 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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: | ||
|
@@ -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 { | ||
|
@@ -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. | ||
|
@@ -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 { | ||
|
@@ -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" | ||
|
@@ -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 { | ||
|
@@ -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( | ||
|
@@ -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) | ||
|
@@ -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"}, | ||
|
@@ -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 | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 { | ||
|
@@ -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": { | ||
|
@@ -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 { | ||
|
@@ -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) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters