This is an automated email from the ASF dual-hosted git repository. csantanapr pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git
commit 6aae54c1beb3b77cbfadb6783d5e67b11ce07b91 Author: Brandon Lee Underwood <[email protected]> AuthorDate: Thu Aug 10 21:47:07 2017 -0400 Allow CLI to sort entities by name (#2326) - Created interfaces `Printables` and `Sortables` - Made Actions, Triggers, Packages, Rules, APIs into Printables and Sortables - Made Activations into Printables and Sortables, Sort currently undefined - Made alphabetic sorting default, sort by last update time with --time flag - Changed sorting default back to last update time, --sort flag for alphabetical sorting - Updated flag name to "--name-sort"/"-n" - Updated Docs - Fixed rule status printing for `wsk list` and `wsk namespace get` --- commands/action.go | 4 +- commands/activation.go | 2 +- commands/api.go | 120 ++++++++++++++++++----------- commands/flags.go | 1 + commands/namespace.go | 25 ++++-- commands/package.go | 5 +- commands/rule.go | 5 +- commands/trigger.go | 4 +- commands/util.go | 162 ++++++++++++++++++++++----------------- commands/wsk.go | 2 + wski18n/i18n_resources.go | 22 +++--- wski18n/resources/en_US.all.json | 19 +++-- 12 files changed, 230 insertions(+), 141 deletions(-) diff --git a/commands/action.go b/commands/action.go index 83e89fa..f14cc9a 100644 --- a/commands/action.go +++ b/commands/action.go @@ -321,7 +321,8 @@ var actionListCmd = &cobra.Command{ return actionListError(qualifiedName.GetEntityName(), options, err) } - printList(actions) + sortByName := flags.common.nameSort + printList(actions, sortByName) return nil }, @@ -942,6 +943,7 @@ func init() { actionListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of actions from the result")) actionListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of actions from the collection")) + actionListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) actionCmd.AddCommand( actionCreateCmd, diff --git a/commands/activation.go b/commands/activation.go index 8273351..29f8f48 100644 --- a/commands/activation.go +++ b/commands/activation.go @@ -93,7 +93,7 @@ var activationListCmd = &cobra.Command{ if options.Docs == true { printFullActivationList(activations) } else { - printList(activations) + printList(activations, false) // Default sorting for Activations are by creation time, hence sortByName is always false } return nil diff --git a/commands/api.go b/commands/api.go index cec47eb..0f7f01c 100644 --- a/commands/api.go +++ b/commands/api.go @@ -93,7 +93,6 @@ func isValidRelpath(relpath string) (error, bool) { return nil, true } - /* * Pull the managedUrl (external API URL) from the API configuration */ @@ -445,6 +444,8 @@ var apiListCmd = &cobra.Command{ var retApiArray *whisk.RetApiArray var apiPath string var apiVerb string + var orderFilteredList []whisk.ApiFilteredList + var orderFilteredRow []whisk.ApiFilteredRow if whiskErr := checkArgs(args, 0, 3, "Api list", wski18n.T("Optional parameters are: API base path (or API name), API relative path and operation.")); whiskErr != nil { @@ -518,7 +519,8 @@ var apiListCmd = &cobra.Command{ // Cast to a common type to allow for code to print out apilist response or apiget response retApiArray = (*whisk.RetApiArray)(retApi) } - + //Checks for any order flags being passed + sortByName := flags.common.nameSort // Display the APIs - applying any specified filtering if (Flags.common.full) { fmt.Fprintf(color.Output, @@ -526,10 +528,10 @@ var apiListCmd = &cobra.Command{ map[string]interface{}{ "ok": color.GreenString("ok:"), })) - - for i:=0; i<len(retApiArray.Apis); i++ { - printFilteredListApi(retApiArray.Apis[i].ApiValue, apiPath, apiVerb) + for i := 0; i < len(retApiArray.Apis); i++ { + orderFilteredList = append(orderFilteredList, genFilteredList(retApiArray.Apis[i].ApiValue, apiPath, apiVerb)...) } + printList(orderFilteredList, sortByName) // Sends an array of structs that contains specifed variables that are not truncated } else { if (len(retApiArray.Apis) > 0) { // Dynamically create the output format string based on the maximum size of the @@ -542,17 +544,17 @@ var apiListCmd = &cobra.Command{ map[string]interface{}{ "ok": color.GreenString("ok:"), })) - fmt.Printf(fmtString, "Action", "Verb", "API Name", "URL") - for i:=0; i<len(retApiArray.Apis); i++ { - printFilteredListRow(retApiArray.Apis[i].ApiValue, apiPath, apiVerb, maxActionNameSize, maxApiNameSize) + for i := 0; i < len(retApiArray.Apis); i++ { + orderFilteredRow = append(orderFilteredRow, genFilteredRow(retApiArray.Apis[i].ApiValue, apiPath, apiVerb, maxActionNameSize, maxApiNameSize)...) } + printList(orderFilteredRow, sortByName) // Sends an array of structs that contains specifed variables that are truncated } else { fmt.Fprintf(color.Output, wski18n.T("{{.ok}} APIs\n", map[string]interface{}{ "ok": color.GreenString("ok:"), })) - fmt.Printf(fmtString, "Action", "Verb", "API Name", "URL") + printList(orderFilteredRow, sortByName) // Sends empty orderFilteredRow so that defaultHeader can be printed } } @@ -560,24 +562,25 @@ var apiListCmd = &cobra.Command{ }, } -/* - * Takes an API object (containing one more more single basepath/relpath/operation triplets) - * and some filtering configuration. For each API endpoint matching the filtering criteria, display - * each endpoint's configuration - one line per configuration property (action name, verb, api name, api gw url) - */ -func printFilteredListApi(resultApi *whisk.RetApi, apiPath string, apiVerb string) { +// genFilteredList(resultApi, api) generates an array of +// ApiFilteredLists for the purpose of ordering and printing in a list form. +// NOTE: genFilteredRow() generates entries with one line per configuration +// property (action name, verb, api name, api gw url) +func genFilteredList(resultApi *whisk.RetApi, apiPath string, apiVerb string) []whisk.ApiFilteredList{ + var orderInfo whisk.ApiFilteredList + var orderInfoArr []whisk.ApiFilteredList baseUrl := strings.TrimSuffix(resultApi.BaseUrl, "/") apiName := resultApi.Swagger.Info.Title basePath := resultApi.Swagger.BasePath if (resultApi.Swagger != nil && resultApi.Swagger.Paths != nil) { for path, _ := range resultApi.Swagger.Paths { - whisk.Debug(whisk.DbgInfo, "printFilteredListApi: comparing api relpath: %s\n", path) + whisk.Debug(whisk.DbgInfo, "genFilteredList: comparing api relpath: %s\n", path) if ( len(apiPath) == 0 || path == apiPath) { - whisk.Debug(whisk.DbgInfo, "printFilteredListApi: relpath matches\n") + whisk.Debug(whisk.DbgInfo, "genFilteredList: relpath matches\n") for op, opv := range resultApi.Swagger.Paths[path] { - whisk.Debug(whisk.DbgInfo, "printFilteredListApi: comparing operation: '%s'\n", op) + whisk.Debug(whisk.DbgInfo, "genFilteredList: comparing operation: '%s'\n", op) if ( len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb)) { - whisk.Debug(whisk.DbgInfo, "printFilteredListApi: operation matches: %#v\n", opv) + whisk.Debug(whisk.DbgInfo, "genFilteredList: operation matches: %#v\n", opv) var actionName string if (opv.XOpenWhisk == nil) { actionName = "" @@ -586,38 +589,36 @@ func printFilteredListApi(resultApi *whisk.RetApi, apiPath string, apiVerb strin } else { actionName = "/"+opv.XOpenWhisk.Namespace+"/"+opv.XOpenWhisk.ActionName } - fmt.Printf("%s: %s\n", wski18n.T("Action"), actionName) - fmt.Printf(" %s: %s\n", wski18n.T("API Name"), apiName) - fmt.Printf(" %s: %s\n", wski18n.T("Base path"), basePath) - fmt.Printf(" %s: %s\n", wski18n.T("Path"), path) - fmt.Printf(" %s: %s\n", wski18n.T("Verb"), op) - fmt.Printf(" %s: %s\n", wski18n.T("URL"), baseUrl+path) + orderInfo = AssignListInfo(actionName, op, apiName, basePath, path, baseUrl+path) + whisk.Debug(whisk.DbgInfo, "Appening to orderInfoArr: %s %s\n", orderInfo.RelPath) + orderInfoArr = append(orderInfoArr, orderInfo) } } } } } + return orderInfoArr } -/* - * Takes an API object (containing one more more single basepath/relpath/operation triplets) - * and some filtering configuration. For each API matching the filtering criteria, display the API - * on a single line (action name, verb, api name, api gw url). - * - * NOTE: Large action name and api name value will be truncated by their associated max size parameters. - */ -func printFilteredListRow(resultApi *whisk.RetApi, apiPath string, apiVerb string, maxActionNameSize int, maxApiNameSize int) { +// genFilteredRow(resultApi, api, maxApiNameSize, maxApiNameSize) generates an array of +// ApiFilteredRows for the purpose of ordering and printing in a list form by parsing and +// initializing vaules for each individual ApiFilteredRow struct. +// NOTE: Large action and api name values will be truncated by their associated max size parameters. +func genFilteredRow(resultApi *whisk.RetApi, apiPath string, apiVerb string, maxActionNameSize int, maxApiNameSize int) []whisk.ApiFilteredRow { + var orderInfo whisk.ApiFilteredRow + var orderInfoArr []whisk.ApiFilteredRow baseUrl := strings.TrimSuffix(resultApi.BaseUrl, "/") apiName := resultApi.Swagger.Info.Title + basePath := resultApi.Swagger.BasePath if (resultApi.Swagger != nil && resultApi.Swagger.Paths != nil) { for path, _ := range resultApi.Swagger.Paths { - whisk.Debug(whisk.DbgInfo, "printFilteredListRow: comparing api relpath: %s\n", path) + whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing api relpath: %s\n", path) if ( len(apiPath) == 0 || path == apiPath) { - whisk.Debug(whisk.DbgInfo, "printFilteredListRow: relpath matches\n") + whisk.Debug(whisk.DbgInfo, "genFilteredRow: relpath matches\n") for op, opv := range resultApi.Swagger.Paths[path] { - whisk.Debug(whisk.DbgInfo, "printFilteredListRow: comparing operation: '%s'\n", op) + whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing operation: '%s'\n", op) if ( len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb)) { - whisk.Debug(whisk.DbgInfo, "printFilteredListRow: operation matches: %#v\n", opv) + whisk.Debug(whisk.DbgInfo, "genFilteredRow: operation matches: %#v\n", opv) var actionName string if (opv.XOpenWhisk == nil) { actionName = "" @@ -626,21 +627,51 @@ func printFilteredListRow(resultApi *whisk.RetApi, apiPath string, apiVerb strin } else { actionName = "/"+opv.XOpenWhisk.Namespace+"/"+opv.XOpenWhisk.ActionName } - fmt.Printf(fmtString, - actionName[0 : min(len(actionName), maxActionNameSize)], - op, - apiName[0 : min(len(apiName), maxApiNameSize)], - baseUrl+path) + orderInfo = AssignRowInfo(actionName[0 : min(len(actionName), maxActionNameSize)], op, apiName[0 : min(len(apiName), maxApiNameSize)], basePath, path, baseUrl+path) + orderInfo.FmtString = fmtString + whisk.Debug(whisk.DbgInfo, "Appening to orderInfoArr: %s %s\n", orderInfo.RelPath) + orderInfoArr = append(orderInfoArr, orderInfo) } } } } } + return orderInfoArr +} + +// AssignRowInfo(actionName, verb, apiName, basePath, relPath, url) assigns +// the given vaules to and initializes an ApiFilteredRow struct, then returns it. +func AssignRowInfo(actionName string, verb string, apiName string, basePath string, relPath string, url string) whisk.ApiFilteredRow { + var orderInfo whisk.ApiFilteredRow + + orderInfo.ActionName = actionName + orderInfo.Verb = verb + orderInfo.ApiName = apiName + orderInfo.BasePath = basePath + orderInfo.RelPath = relPath + orderInfo.Url = url + + return orderInfo +} + +// AssignListInfo(actionName, verb, apiName, basePath, relPath, url) assigns +// the given vaules to and initializes an ApiFilteredList struct, then returns it. +func AssignListInfo(actionName string, verb string, apiName string, basePath string, relPath string, url string) whisk.ApiFilteredList { + var orderInfo whisk.ApiFilteredList + + orderInfo.ActionName = actionName + orderInfo.Verb = verb + orderInfo.ApiName = apiName + orderInfo.BasePath = basePath + orderInfo.RelPath = relPath + orderInfo.Url = url + + return orderInfo } func getLargestActionNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVerb string) int { var maxNameSize = 0 - for i:=0; i<len(retApiArray.Apis); i++ { + for i := 0; i < len(retApiArray.Apis); i++ { var resultApi = retApiArray.Apis[i].ApiValue if (resultApi.Swagger != nil && resultApi.Swagger.Paths != nil) { for path, _ := range resultApi.Swagger.Paths { @@ -673,7 +704,7 @@ func getLargestActionNameSize(retApiArray *whisk.RetApiArray, apiPath string, ap func getLargestApiNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVerb string) int { var maxNameSize = 0 - for i:=0; i<len(retApiArray.Apis); i++ { + for i := 0; i < len(retApiArray.Apis); i++ { var resultApi = retApiArray.Apis[i].ApiValue apiName := resultApi.Swagger.Info.Title if (resultApi.Swagger != nil && resultApi.Swagger.Paths != nil) { @@ -920,6 +951,7 @@ func init() { apiGetCmd.Flags().StringVarP(&Flags.common.format, "format", "", formatOptionJson, wski18n.T("Specify the API output `TYPE`, either json or yaml")) apiListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of actions from the result")) apiListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of actions from the collection")) + apiListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block")) apiListCmd.Flags().BoolVarP(&Flags.common.full, "full", "f", false, wski18n.T("display full description of each API")) apiCmd.AddCommand( apiCreateCmd, diff --git a/commands/flags.go b/commands/flags.go index 7ef23d6..9a3454f 100644 --- a/commands/flags.go +++ b/commands/flags.go @@ -61,6 +61,7 @@ type FlagsStruct struct { feed string // name of feed detail bool format string + nameSort bool // sorts list alphabetically by entity name } property struct { diff --git a/commands/namespace.go b/commands/namespace.go index a9f7bef..f7af0fc 100644 --- a/commands/namespace.go +++ b/commands/namespace.go @@ -55,7 +55,7 @@ var namespaceListCmd = &cobra.Command{ werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_NETWORK, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } - printList(namespaces) + printList(namespaces, false) // `-n` flag applies to `namespace get`, not list, so must pass value false for printList here return nil }, } @@ -99,16 +99,31 @@ var namespaceGetCmd = &cobra.Command{ fmt.Fprintf(color.Output, wski18n.T("Entities in namespace: {{.namespace}}\n", map[string]interface{}{"namespace": boldString(getClientNamespace())})) - printList(namespace.Contents.Packages) - printList(namespace.Contents.Actions) - printList(namespace.Contents.Triggers) - printList(namespace.Contents.Rules) + sortByName := flags.common.nameSort + printList(namespace.Contents.Packages, sortByName) + printList(namespace.Contents.Actions, sortByName) + printList(namespace.Contents.Triggers, sortByName) + //No errors, lets attempt to retrieve the status of each rule #312 + for index, rule := range namespace.Contents.Rules { + ruleStatus, _, err := client.Rules.Get(rule.Name) + if err != nil { + errStr := wski18n.T("Unable to get status of rule '{{.name}}': {{.err}}", + map[string]interface{}{"name": rule.Name, "err": err}) + fmt.Println(errStr) + werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) + return werr + } + namespace.Contents.Rules[index].Status = ruleStatus.Status + } + printList(namespace.Contents.Rules, sortByName) return nil }, } func init() { + namespaceGetCmd.Flags().BoolVarP(&flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) + namespaceCmd.AddCommand( namespaceListCmd, namespaceGetCmd, diff --git a/commands/package.go b/commands/package.go index fcf6652..9dff500 100644 --- a/commands/package.go +++ b/commands/package.go @@ -412,7 +412,8 @@ var packageListCmd = &cobra.Command{ return werr } - printList(packages) + sortByName := flags.common.nameSort + printList(packages, sortByName) return nil }, @@ -503,6 +504,7 @@ var packageRefreshCmd = &cobra.Command{ } func init() { +<<<<<<< HEAD packageCreateCmd.Flags().StringSliceVarP(&Flags.common.annotation, "annotation", "a", []string{}, wski18n.T("annotation values in `KEY VALUE` format")) packageCreateCmd.Flags().StringVarP(&Flags.common.annotFile, "annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in JSON format")) packageCreateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format")) @@ -524,6 +526,7 @@ func init() { packageListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of packages from the result")) packageListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of packages from the collection")) + packageListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) packageCmd.AddCommand( packageBindCmd, diff --git a/commands/rule.go b/commands/rule.go index 4d34af6..67cddf0 100644 --- a/commands/rule.go +++ b/commands/rule.go @@ -402,7 +402,9 @@ var ruleListCmd = &cobra.Command{ rules[index].Status = ruleStatus.Status } } - printList(rules) + + sortByName := flags.common.nameSort + printList(rules, sortByName) return nil }, } @@ -414,6 +416,7 @@ func init() { ruleListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of rules from the result")) ruleListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of rules from the collection")) + ruleListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) ruleCmd.AddCommand( ruleCreateCmd, diff --git a/commands/trigger.go b/commands/trigger.go index 4b1c2e9..0d85af7 100644 --- a/commands/trigger.go +++ b/commands/trigger.go @@ -457,7 +457,8 @@ var triggerListCmd = &cobra.Command{ werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } - printList(triggers) + sortByName := flags.common.nameSort + printList(triggers, sortByName) return nil }, } @@ -510,6 +511,7 @@ func init() { triggerListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of triggers from the result")) triggerListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of triggers from the collection")) + triggerListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) triggerCmd.AddCommand( triggerFireCmd, diff --git a/commands/util.go b/commands/util.go index 8bb5aae..de0b1f7 100644 --- a/commands/util.go +++ b/commands/util.go @@ -122,28 +122,99 @@ func getEscapedJSON(value string) (string) { func isValidJSON(value string) (bool) { var jsonInterface interface{} err := json.Unmarshal([]byte(value), &jsonInterface) + return err == nil } var boldString = color.New(color.Bold).SprintFunc() -func printList(collection interface{}) { - switch collection := collection.(type) { +type Sortables []whisk.Sortable +// Uses quickSort to sort commands based on their compare methods +// Param: Takes in a array of Sortable interfaces which contains a specific command +func Swap(sortables Sortables, i, j int) { sortables[i], sortables[j] = sortables[j], sortables[i] } + +func toPrintable(sortable []whisk.Sortable) []whisk.Printable{ + sortedPrintable := make([]whisk.Printable, len(sortable), len(sortable)) + for i := range sortable { + sortedPrintable[i] = sortable[i].(whisk.Printable) + } + return sortedPrintable +} + +// Prints the parameters/list for wsk xxxx list +// Identifies type and then copies array into an array of interfaces(Sortable) to be sorted and printed +// Param: Takes in an interace which contains an array of a command(Ex: []Action) +func printList(collection interface{}, sortByName bool) { + var commandToSort []whisk.Sortable + switch collection := collection.(type){ case []whisk.Action: - printActionList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } case []whisk.Trigger: - printTriggerList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } case []whisk.Package: - printPackageList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } case []whisk.Rule: - printRuleList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } case []whisk.Namespace: - printNamespaceList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } case []whisk.Activation: - printActivationList(collection) - case []whisk.Api: - printApiList(collection) + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } + case []whisk.ApiFilteredList: + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } + case []whisk.ApiFilteredRow: + for i := range collection { + commandToSort = append(commandToSort, collection[i]) + } + } + if sortByName && len(commandToSort) > 0 { + quickSort(commandToSort, 0, len(commandToSort)-1) } + printCommandsList(toPrintable(commandToSort), makeDefaultHeader(collection)) +} + +func quickSort(toSort Sortables, left int, right int) { + low := left + high := right + pivot := toSort[(left + right) / 2] + + for low <= high { + for toSort[low].Compare(pivot) { low++ } + for pivot.Compare(toSort[high]) { high-- } + if low <= high { + Swap(toSort, low, high) + low++ + high-- + } + } + if left < high { quickSort(toSort, left, high) } + if low < right { quickSort(toSort, low, right) } +} + +// makeDefaultHeader(collection) returns the default header to be used in case +// the list to be printed is empty. +func makeDefaultHeader(collection interface{}) string { + defaultHeader := reflect.TypeOf(collection).String() + defaultHeader = strings.ToLower(defaultHeader[8:] + "s") // Removes '[]whisk.' from `[]whisk.ENTITY_TYPE` + if defaultHeader == "apifilteredrows" { + defaultHeader = fmt.Sprintf("%-30s %7s %20s %s", "Action", "Verb", "API Name", "URL") + } else if defaultHeader == "apifilteredlists" { + defaultHeader = "" + } + return defaultHeader } func printFullList(collection interface{}) { @@ -179,53 +250,18 @@ func printSummary(collection interface{}) { } } -func printActionList(actions []whisk.Action) { - fmt.Fprintf(color.Output, "%s\n", boldString("actions")) - for _, action := range actions { - publishState := wski18n.T("private") - kind := getValueString(action.Annotations, "exec") - fmt.Printf("%-70s %s %s\n", fmt.Sprintf("/%s/%s", action.Namespace, action.Name), publishState, kind) - } -} - -func printTriggerList(triggers []whisk.Trigger) { - fmt.Fprintf(color.Output, "%s\n", boldString("triggers")) - for _, trigger := range triggers { - publishState := wski18n.T("private") - fmt.Printf("%-70s %s\n", fmt.Sprintf("/%s/%s", trigger.Namespace, trigger.Name), publishState) - } -} - -func printPackageList(packages []whisk.Package) { - fmt.Fprintf(color.Output, "%s\n", boldString("packages")) - for _, xPackage := range packages { - publishState := wski18n.T("private") - if xPackage.Publish != nil && *xPackage.Publish { - publishState = wski18n.T("shared") +// Used to print Action, Tigger, Package, and Rule lists +// Param: Takes in a array of Printable interface, and the name of the command +// being sent to it +// **Note**: The name sould be an empty string for APIs. +func printCommandsList(commands []whisk.Printable, defaultHeader string) { + if len(commands) != 0 { + fmt.Fprint(color.Output, boldString(commands[0].ToHeaderString())) + for i := range commands { + fmt.Print(commands[i].ToSummaryRowString()) } - fmt.Printf("%-70s %s\n", fmt.Sprintf("/%s/%s", xPackage.Namespace, xPackage.Name), publishState) - } -} - -func printRuleList(rules []whisk.Rule) { - fmt.Fprintf(color.Output, "%s\n", boldString("rules")) - for _, rule := range rules { - publishState := wski18n.T("private") - fmt.Printf("%-70s %-20s %s\n", fmt.Sprintf("/%s/%s", rule.Namespace, rule.Name), publishState, rule.Status) - } -} - -func printNamespaceList(namespaces []whisk.Namespace) { - fmt.Fprintf(color.Output, "%s\n", boldString("namespaces")) - for _, namespace := range namespaces { - fmt.Printf("%s\n", namespace.Name) - } -} - -func printActivationList(activations []whisk.Activation) { - fmt.Fprintf(color.Output, "%s\n", boldString("activations")) - for _, activation := range activations { - fmt.Printf("%s %-20s\n", activation.ActivationID, activation.Name) + } else { + fmt.Fprintf(color.Output, "%s\n", boldString(defaultHeader)) } } @@ -236,20 +272,6 @@ func printFullActivationList(activations []whisk.Activation) { } } -func printApiList(apis []whisk.Api) { - fmt.Fprintf(color.Output, "%s\n", boldString("apis")) - for _, api := range apis { - fmt.Printf("%s %20s %20s\n", api.ApiName, api.GatewayBasePath, api.GatewayFullPath) - } -} - -func printFullApiList(apis []whisk.Api) { - fmt.Fprintf(color.Output, "%s\n", boldString("apis")) - for _, api := range apis { - printJSON(api) - } -} - func printActivationLogs(logs []string) { for _, log := range logs { fmt.Printf("%s\n", log) diff --git a/commands/wsk.go b/commands/wsk.go index f7f209b..874e549 100644 --- a/commands/wsk.go +++ b/commands/wsk.go @@ -44,6 +44,8 @@ func init() { WskCmd.SetHelpTemplate(`{{with or .Long .Short }}{{.}} {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`) +listCmd.Flags().BoolVarP(&flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block")) + WskCmd.AddCommand( actionCmd, activationCmd, diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go index 0042ed4..0d90c6a 100644 --- a/wski18n/i18n_resources.go +++ b/wski18n/i18n_resources.go @@ -109,12 +109,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5d\x5f\x73\xdb\x38\x92\x7f\xcf\xa7\xe8\x9a\x17\x3b\x55\xb2\xb3\xfb\x74\x75\x99\x9a\x07\x4d\xec\xd9\x78\x93\xd8\xae\xc8\x99\xdd\xa9\x9b\xab\x11\x4c\x42\x12\xc6\x14\xc0\x01\x40\x2b\x4a\xd6\xdf\xfd\x0a\x00\x49\x91\x12\xfe\x92\x72\x72\x4f\x71\xc4\xee\x5f\x37\x80\x06\xd0\x68\x34\x80\xff\x79\x01\xf0\xf5\x05\x00\xc0\x0f\x24\xff\xe1\x35\xfc\x30\x2d\xcb\x82\x64\x48\x12\x46\x01\x7f\x26\x12\xe7\x50\x51\xfc\xb9 [...] +var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7d\x4f\x73\xdb\x38\xd2\xf7\x7d\x3e\x45\x57\x2e\x76\xde\x92\x9d\xdd\xd3\x5b\x4f\x52\x73\xd0\x24\x9e\x8d\x37\x89\xed\x8a\x9d\xd9\x9d\xda\x6c\x8d\x20\x12\x92\xb0\xa6\x00\x0e\x00\x5a\x51\xb2\xfe\xee\x4f\x01\x20\x29\x52\xc2\x5f\x52\x4e\x9e\x53\x1c\xb1\xfb\xd7\x0d\xa0\x01\x34\x1a\x0d\xe0\x5f\x3f\x01\x7c\xfb\x09\x00\xe0\x19\xc9\x9f\xbd\x84\x67\xd3\xb2\x2c\x48\x86\x24\x61\x14\xf0\x17\x22\x71\x0e\x15\xc5\x5f [...] func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) { return bindataRead( @@ -129,7 +129,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 49848, mode: os.FileMode(420), modTime: time.Unix(1502310784, 0)} + info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 50834, mode: os.FileMode(420), modTime: time.Unix(1502981211, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -149,7 +149,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -169,7 +169,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -189,7 +189,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -209,7 +209,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -229,7 +229,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -249,7 +249,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -269,7 +269,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -289,7 +289,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502310633, 0)} + info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1502980774, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json index 78acda0..39551d0 100644 --- a/wski18n/resources/en_US.all.json +++ b/wski18n/resources/en_US.all.json @@ -1400,8 +1400,8 @@ "translation": "display full description of each API" }, { - "id": "An API host must be provided.", - "translation": "An API host must be provided." + "id": "order API list by action name first followed by base-path/rel-path/verb", + "translation": "order API list by action name first followed by base-path/rel-path/verb." }, { "id": "Request accepted, but processing not completed yet.", @@ -1510,9 +1510,16 @@ { "id": "Unable to output bash command completion {{.err}}", "translation": "Unable to output bash command completion {{.err}}" -}, -{ + }, + { "id": "prints bash command completion script to stdout", "translation": "prints bash command completion script to stdout" -} -] + }, + { + "id": "sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block", + "translation": "sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block" + }, + { + "id": "sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block", + "translation": "sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block" + }] -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
