github.com/arduino/arduino-cloud-cli@v0.0.0-20240517070944-e7a449561083/cli/thing/list.go (about) 1 // This file is part of arduino-cloud-cli. 2 // 3 // Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published 7 // by the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 package thing 19 20 import ( 21 "context" 22 "fmt" 23 "os" 24 "strings" 25 26 "github.com/arduino/arduino-cli/cli/errorcodes" 27 "github.com/arduino/arduino-cli/cli/feedback" 28 "github.com/arduino/arduino-cli/table" 29 "github.com/arduino/arduino-cloud-cli/command/thing" 30 "github.com/arduino/arduino-cloud-cli/config" 31 "github.com/sirupsen/logrus" 32 "github.com/spf13/cobra" 33 ) 34 35 type listFlags struct { 36 ids []string 37 deviceID string 38 variables bool 39 tags map[string]string 40 } 41 42 func initListCommand() *cobra.Command { 43 flags := &listFlags{} 44 listCommand := &cobra.Command{ 45 Use: "list", 46 Short: "List things", 47 Long: "List things on Arduino IoT Cloud", 48 Run: func(cmd *cobra.Command, args []string) { 49 if err := runListCommand(flags); err != nil { 50 feedback.Errorf("Error during thing list: %v", err) 51 os.Exit(errorcodes.ErrGeneric) 52 } 53 }, 54 } 55 // list only the things corresponding to the passed ids 56 listCommand.Flags().StringSliceVarP(&flags.ids, "ids", "i", nil, "List of thing IDs to be retrieved") 57 // list only the thing associated to the passed device id 58 listCommand.Flags().StringVarP(&flags.deviceID, "device-id", "d", "", "ID of Device associated to the thing to be retrieved") 59 listCommand.Flags().BoolVarP(&flags.variables, "show-variables", "s", false, "Show thing variables") 60 listCommand.Flags().StringToStringVar( 61 &flags.tags, 62 "tags", 63 nil, 64 "Comma-separated list of tags with format <key>=<value>.\n"+ 65 "List only things that match the provided tags.", 66 ) 67 return listCommand 68 } 69 70 func runListCommand(flags *listFlags) error { 71 logrus.Info("Listing things") 72 73 cred, err := config.RetrieveCredentials() 74 if err != nil { 75 return fmt.Errorf("retrieving credentials: %w", err) 76 } 77 78 params := &thing.ListParams{ 79 IDs: flags.ids, 80 Variables: flags.variables, 81 Tags: flags.tags, 82 } 83 if flags.deviceID != "" { 84 params.DeviceID = &flags.deviceID 85 } 86 87 things, err := thing.List(context.TODO(), params, cred) 88 if err != nil { 89 return err 90 } 91 92 feedback.PrintResult(result{things: things, variables: flags.variables}) 93 return nil 94 } 95 96 type result struct { 97 things []thing.ThingInfo 98 variables bool 99 } 100 101 func (r result) Data() interface{} { 102 return r.things 103 } 104 105 func (r result) String() string { 106 if len(r.things) == 0 { 107 return "No things found." 108 } 109 t := table.New() 110 111 h := []interface{}{"Name", "ID", "Device", "Tags"} 112 if r.variables { 113 h = append(h, "Variables") 114 } 115 t.SetHeader(h...) 116 117 for _, thing := range r.things { 118 row := []interface{}{thing.Name, thing.ID, thing.DeviceID} 119 row = append(row, strings.Join(thing.Tags, ",")) 120 if r.variables { 121 row = append(row, strings.Join(thing.Variables, ", ")) 122 } 123 t.AddRow(row...) 124 } 125 return t.Render() 126 }