From b949d040d2d47f903040f1b48ac1a71c764a6ca9 Mon Sep 17 00:00:00 2001 From: David Liu Date: Tue, 17 Jan 2017 15:02:41 +0800 Subject: [PATCH] Add flag to sort listed entities by date. By default will sort by entity name alphabetically. Address issue #1569 for enhancement request. --- .../core/cli/test/WskBasicUsageTests.scala | 39 +++++++++++++++++++ tools/cli/go-whisk-cli/commands/flags.go | 5 +++ tools/cli/go-whisk-cli/commands/namespace.go | 2 + tools/cli/go-whisk-cli/commands/util.go | 16 ++++++++ tools/cli/go-whisk/whisk/action.go | 14 +++++++ tools/cli/go-whisk/whisk/package.go | 14 +++++++ tools/cli/go-whisk/whisk/rule.go | 14 +++++++ tools/cli/go-whisk/whisk/trigger.go | 14 +++++++ 8 files changed, 118 insertions(+) diff --git a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala index a7ae301e5d4..af13aa58f1f 100644 --- a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala +++ b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala @@ -1242,4 +1242,43 @@ class WskBasicUsageTests } tmpProps.delete() } + + behavior of "Wsk cli list" + + it should "wsk cli list entities by name alphabetically by default" in withAssetCleaner(wskprops) { + (wp, assetHelper) => + + val tmpwskprops = File.createTempFile("wskprops", ".tmp") + try { + val namespace = wsk.namespace.list().stdout.trim.split("\n").last + val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath()) + wsk.cli(Seq("property", "set", "-i", "--apihost", wskprops.apihost, "--auth", wskprops.authKey, + "--namespace", namespace), env = env) + val name1 = "helloTest" + val file1 = Some(TestUtils.getTestActionFilename("hello.js")) + + assetHelper.withCleaner(wsk.action, name1) { + (action, _) => + action.create(name1, file1, annotations = getValidJSONTestArgInput, + parameters = getValidJSONTestArgInput) + } + + val name2 = "echoTest" + val file2 = Some(TestUtils.getTestActionFilename("echo.js")) + + assetHelper.withCleaner(wsk.action, name2) { + (action, _) => + action.create(name2, file2, annotations = getValidJSONTestArgInput, + parameters = getValidJSONTestArgInput) + } + val stdout = wsk.cli(Seq("list", "-i", "--apihost", wskprops.apihost, "--auth", wskprops.authKey), env = env).stdout + + stdout should include regex ("echoTest") + stdout should include regex ("helloTest") + } finally { + tmpwskprops.delete() + } + + + } } diff --git a/tools/cli/go-whisk-cli/commands/flags.go b/tools/cli/go-whisk-cli/commands/flags.go index 23ae410d3ca..f5530de0014 100644 --- a/tools/cli/go-whisk-cli/commands/flags.go +++ b/tools/cli/go-whisk-cli/commands/flags.go @@ -104,6 +104,11 @@ var flags struct { summary bool } + // namespace + namespace struct { + date bool // sort by date flag + } + // api api struct { action string diff --git a/tools/cli/go-whisk-cli/commands/namespace.go b/tools/cli/go-whisk-cli/commands/namespace.go index cafed6f61c3..cf5dd57f11d 100644 --- a/tools/cli/go-whisk-cli/commands/namespace.go +++ b/tools/cli/go-whisk-cli/commands/namespace.go @@ -119,8 +119,10 @@ var listCmd = &cobra.Command{ } func init() { + listCmd.Flags().BoolVarP(&flags.namespace.date, "sort", "t", false, wski18n.T("sort by date")) namespaceCmd.AddCommand( namespaceListCmd, namespaceGetCmd, ) + } diff --git a/tools/cli/go-whisk-cli/commands/util.go b/tools/cli/go-whisk-cli/commands/util.go index ef3c8012f2a..57ee263baae 100644 --- a/tools/cli/go-whisk-cli/commands/util.go +++ b/tools/cli/go-whisk-cli/commands/util.go @@ -286,6 +286,10 @@ func printSummary(collection interface{}) { func printActionList(actions []whisk.Action) { fmt.Fprintf(color.Output, "%s\n", boldString("actions")) + if (!flags.namespace.date) { + sort.Sort(whisk.ActionArray(actions)) + } + for _, action := range actions { publishState := wski18n.T("private") kind := getValueString(action.Annotations, "exec") @@ -295,6 +299,10 @@ func printActionList(actions []whisk.Action) { func printTriggerList(triggers []whisk.Trigger) { fmt.Fprintf(color.Output, "%s\n", boldString("triggers")) + if (!flags.namespace.date) { + sort.Sort(whisk.TriggerArray(triggers)) + } + for _, trigger := range triggers { publishState := wski18n.T("private") fmt.Printf("%-70s %s\n", fmt.Sprintf("/%s/%s", trigger.Namespace, trigger.Name), publishState) @@ -303,6 +311,10 @@ func printTriggerList(triggers []whisk.Trigger) { func printPackageList(packages []whisk.Package) { fmt.Fprintf(color.Output, "%s\n", boldString("packages")) + if (!flags.namespace.date) { + sort.Sort(whisk.PackageArray(packages)) + } + for _, xPackage := range packages { publishState := wski18n.T("private") if xPackage.Publish != nil && *xPackage.Publish { @@ -314,6 +326,10 @@ func printPackageList(packages []whisk.Package) { func printRuleList(rules []whisk.Rule) { fmt.Fprintf(color.Output, "%s\n", boldString("rules")) + if (!flags.namespace.date) { + sort.Sort((whisk.RuleArray(rules))) + } + for _, rule := range rules { publishState := wski18n.T("private") fmt.Printf("%-70s %s\n", fmt.Sprintf("/%s/%s", rule.Namespace, rule.Name), publishState) diff --git a/tools/cli/go-whisk/whisk/action.go b/tools/cli/go-whisk/whisk/action.go index 90f1266a6c9..c11c6738420 100644 --- a/tools/cli/go-whisk/whisk/action.go +++ b/tools/cli/go-whisk/whisk/action.go @@ -57,6 +57,20 @@ type ActionListOptions struct { Docs bool `url:"docs,omitempty"` } +type ActionArray []Action + +func (aa ActionArray) Len() int { + return len(aa) +} + +func (aa ActionArray) Less(i int, j int) bool { + return aa[i].Name < aa[j].Name +} + +func (aa ActionArray) Swap(i int, j int) { + aa[i], aa[j] = aa[j], aa[i] +} + //////////////////// // Action Methods // //////////////////// diff --git a/tools/cli/go-whisk/whisk/package.go b/tools/cli/go-whisk/whisk/package.go index ad92e49123b..48337d29879 100644 --- a/tools/cli/go-whisk/whisk/package.go +++ b/tools/cli/go-whisk/whisk/package.go @@ -49,6 +49,20 @@ func (p *Package) GetName() string { return p.Name } +type PackageArray []Package + +func (pa PackageArray) Len() int { + return len(pa) +} + +func (pa PackageArray) Less(i int, j int) bool { + return pa[i].Name < pa[j].Name +} + +func (pa PackageArray) Swap(i int, j int) { + pa[i], pa[j] = pa[j], pa[i] +} + // Use this struct when creating a binding // Publish is NOT optional; Binding is a namespace/name object, not a bool type BindingPackage struct { diff --git a/tools/cli/go-whisk/whisk/rule.go b/tools/cli/go-whisk/whisk/rule.go index 6a4ee42082f..c69c68d5892 100644 --- a/tools/cli/go-whisk/whisk/rule.go +++ b/tools/cli/go-whisk/whisk/rule.go @@ -46,6 +46,20 @@ type RuleListOptions struct { Docs bool `url:"docs,omitempty"` } +type RuleArray []Rule + +func (ra RuleArray) Len() int { + return len(ra) +} + +func (ra RuleArray) Less(i int, j int) bool { + return ra[i].Name < ra[j].Name +} + +func (ta RuleArray) Swap(i int, j int) { + ta[i], ta[j] = ta[j], ta[i] +} + func (s *RuleService) List(options *RuleListOptions) ([]Rule, *http.Response, error) { route := "rules" routeUrl, err := addRouteOptions(route, options) diff --git a/tools/cli/go-whisk/whisk/trigger.go b/tools/cli/go-whisk/whisk/trigger.go index 86c1d5a0668..e02a90f1b79 100644 --- a/tools/cli/go-whisk/whisk/trigger.go +++ b/tools/cli/go-whisk/whisk/trigger.go @@ -46,6 +46,20 @@ type TriggerListOptions struct { Docs bool `url:"docs,omitempty"` } +type TriggerArray []Trigger + +func (ta TriggerArray) Len() int { + return len(ta) +} + +func (ta TriggerArray) Less(i int, j int) bool { + return ta[i].Name < ta[j].Name +} + +func (ta TriggerArray) Swap(i int, j int) { + ta[i], ta[j] = ta[j], ta[i] +} + func (s *TriggerService) List(options *TriggerListOptions) ([]Trigger, *http.Response, error) { route := "triggers" routeUrl, err := addRouteOptions(route, options)