diff --git a/arduino/utils/search.go b/arduino/utils/search.go new file mode 100644 index 00000000000..1ed942825ca --- /dev/null +++ b/arduino/utils/search.go @@ -0,0 +1,66 @@ +// This file is part of arduino-cli. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package utils + +import ( + "strings" + "unicode" + + "golang.org/x/text/runes" + "golang.org/x/text/transform" + "golang.org/x/text/unicode/norm" +) + +// removeDiatrics removes accents and similar diatrics from unicode characters. +// An empty string is returned in case of errors. +// This might not be the best solution but it works well enough for our usecase, +// in the future we might want to use the golang.org/x/text/secure/precis package +// when its API will be finalized. +// From https://stackoverflow.com/a/26722698 +func removeDiatrics(s string) (string, error) { + transformer := transform.Chain( + norm.NFD, + runes.Remove(runes.In(unicode.Mn)), + norm.NFC, + ) + s, _, err := transform.String(transformer, s) + if err != nil { + return "", err + } + return s, nil +} + +// Match returns true if all substrings are contained in str. +// Both str and substrings are transforms to lower case and have their +// accents and other unicode diatrics removed. +// If strings transformation fails an error is returned. +func Match(str string, substrings []string) (bool, error) { + str, err := removeDiatrics(strings.ToLower(str)) + if err != nil { + return false, err + } + + for _, sub := range substrings { + cleanSub, err := removeDiatrics(strings.ToLower(sub)) + if err != nil { + return false, err + } + if !strings.Contains(str, cleanSub) { + return false, nil + } + } + return true, nil +} diff --git a/cli/board/board.go b/cli/board/board.go index 29ab85b4243..45c6907105c 100644 --- a/cli/board/board.go +++ b/cli/board/board.go @@ -37,6 +37,7 @@ func NewCommand() *cobra.Command { boardCommand.AddCommand(initDetailsCommand()) boardCommand.AddCommand(initListCommand()) boardCommand.AddCommand(initListAllCommand()) + boardCommand.AddCommand(initSearchCommand()) return boardCommand } diff --git a/cli/board/search.go b/cli/board/search.go new file mode 100644 index 00000000000..8297993e3a1 --- /dev/null +++ b/cli/board/search.go @@ -0,0 +1,99 @@ +// This file is part of arduino-cli. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package board + +import ( + "context" + "os" + "sort" + "strings" + + "github.com/arduino/arduino-cli/cli/errorcodes" + "github.com/arduino/arduino-cli/cli/feedback" + "github.com/arduino/arduino-cli/cli/instance" + "github.com/arduino/arduino-cli/commands/board" + rpc "github.com/arduino/arduino-cli/rpc/commands" + "github.com/arduino/arduino-cli/table" + "github.com/spf13/cobra" +) + +func initSearchCommand() *cobra.Command { + var searchCommand = &cobra.Command{ + Use: "search [boardname]", + Short: "List all known boards and their corresponding FQBN.", + Long: "" + + "List all boards that have the support platform installed. You can search\n" + + "for a specific board if you specify the board name", + Example: "" + + " " + os.Args[0] + " board search\n" + + " " + os.Args[0] + " board search zero", + Args: cobra.ArbitraryArgs, + Run: runSearchCommand, + } + searchCommand.Flags().BoolVarP(&searchFlags.showHiddenBoard, "show-hidden", "a", false, "Show also boards marked as 'hidden' in the platform") + return searchCommand +} + +var searchFlags struct { + showHiddenBoard bool +} + +func runSearchCommand(cmd *cobra.Command, args []string) { + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error searching boards: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + + res, err := board.Search(context.Background(), &rpc.BoardSearchReq{ + Instance: inst, + SearchArgs: strings.Join(args, " "), + IncludeHiddenBoards: searchFlags.showHiddenBoard, + }) + if err != nil { + feedback.Errorf("Error searching boards: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + + feedback.PrintResult(searchResults{res.Boards}) +} + +// output from this command requires special formatting so we create a dedicated +// feedback.Result implementation +type searchResults struct { + boards []*rpc.BoardListItem +} + +func (r searchResults) Data() interface{} { + return r.boards +} + +func (r searchResults) String() string { + sort.Slice(r.boards, func(i, j int) bool { + return r.boards[i].GetName() < r.boards[j].GetName() + }) + + t := table.New() + t.SetHeader("Board Name", "FQBN", "Platform ID", "") + for _, item := range r.boards { + hidden := "" + if item.IsHidden { + hidden = "(hidden)" + } + t.AddRow(item.GetName(), item.GetFQBN(), item.Platform.ID, hidden) + } + return t.Render() +} diff --git a/client_example/go.sum b/client_example/go.sum index cf8628f1988..33bc6b179b7 100644 --- a/client_example/go.sum +++ b/client_example/go.sum @@ -1,8 +1,6 @@ -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= @@ -12,9 +10,7 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/arduino/board-discovery v0.0.0-20180823133458-1ba29327fb0c/go.mod h1:HK7SpkEax/3P+0w78iRQx1sz1vCDYYw9RXwHjQTB5i8= github.com/arduino/go-paths-helper v1.0.1/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck= github.com/arduino/go-paths-helper v1.2.0/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck= -github.com/arduino/go-paths-helper v1.3.2/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck= github.com/arduino/go-paths-helper v1.4.0/go.mod h1:V82BWgAAp4IbmlybxQdk9Bpkz8M4Qyx+RAFKaG9NuvU= -github.com/arduino/go-properties-orderedmap v0.0.0-20190828172252-05018b28ff6c/go.mod h1:kiSuHm7yz3chiy8rb2MphC7ECn3MlkQFAIe4SXmQg6o= github.com/arduino/go-properties-orderedmap v1.3.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk= github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b/go.mod h1:uwGy5PpN4lqW97FiLnbcx+xx8jly5YuPMJWfVwwjJiQ= github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b/go.mod h1:iIPnclBMYm1g32Q5kXoqng4jLhMStReIP7ZxaoUC2y8= @@ -26,18 +22,14 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmaglie/go.rice v1.0.3/go.mod h1:AF3bOWkvdOpp8/S3UL8qbQ4N7DiISIbJtj54GWFPAsc= -github.com/cmaglie/pb v1.0.27 h1:ynGj8vBXR+dtj4B7Q/W/qGt31771Ux5iFfRQBnwdQiA= github.com/cmaglie/pb v1.0.27/go.mod h1:GilkKZMXYjBA4NxItWFfO+lwkp59PLHQ+IOW/b/kmZI= github.com/codeclysm/cc v1.2.2/go.mod h1:XtW4ArCNgQwFphcRGG9+sPX5WM1J6/u0gMy5ZdV3obA= -github.com/codeclysm/extract v2.2.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks= github.com/codeclysm/extract/v3 v3.0.2/go.mod h1:NKsw+hqua9H+Rlwy/w/3Qgt9jDonYEgB6wJu+25eOKw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/goselect v0.1.1/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -71,10 +63,7 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -84,11 +73,11 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -98,7 +87,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/h2non/filetype v1.0.6/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU= github.com/h2non/filetype v1.0.8/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/imjasonmiller/godice v0.1.2/go.mod h1:8cTkdnVI+NglU2d6sv+ilYcNaJ5VSTBwvMbFULJd/QQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -110,7 +98,6 @@ github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0b github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/retry v0.0.0-20160928201858-1998d01ba1c3/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= -github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/juju/testing v0.0.0-20200510222523-6c8c298c77a0/go.mod h1:hpGvhGHPVbNBraRLZEhoQwFLMrjK8PSlO4D3nDjKYXo= github.com/juju/utils v0.0.0-20180808125547-9dfc6dbfb02b/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= @@ -126,13 +113,11 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leonelquinteros/gotext v1.4.0/go.mod h1:yZGXREmoGTtBvZHNcc+Yfug49G/2spuF/i/Qlsvz1Us= +github.com/lithammer/fuzzysearch v1.1.1/go.mod h1:H2bng+w5gsR7NlfIJM8ElGZI0sX6C/9uzGqicVXGU6c= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/marcinbor85/gohex v0.0.0-20200531163658-baab2527a9a2/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851/go.mod h1:EsbsAEUEs15qC1cosAwxgCWV0Qhd8TmkxnA9Kw1Vhl4= @@ -143,7 +128,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oleksandr/bonjour v0.0.0-20160508152359-5dcf00d8b228/go.mod h1:MGuVJ1+5TX1SCoO2Sx0eAnjpdRytYla2uC1YIZfkC9c= @@ -166,7 +150,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M= @@ -176,7 +159,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -184,11 +166,9 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.1-0.20200710201246-675ae5f5a98c/go.mod h1:aeNIJzz/GSSVlS+gpCpQWZ83BKbsoW57mr90+YthtkQ= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= @@ -202,20 +182,15 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.bug.st/cleanup v1.0.0/go.mod h1:EqVmTg2IBk4znLbPD28xne3abjsJftMdqqJEjhn70bk= -go.bug.st/downloader v1.1.0 h1:LipC9rqRCe8kwa+ah3ZDfCqneVaf34cB/TKjXZiZt54= -go.bug.st/downloader v1.1.0/go.mod h1:l+RPbNbrTB+MoAIp8nrZsP22nRPDy26XJZQqmm4gNT4= -go.bug.st/downloader/v2 v2.0.1/go.mod h1:VZW2V1iGKV8rJL2ZEGIDzzBeKowYv34AedJz13RzVII= go.bug.st/downloader/v2 v2.1.1/go.mod h1:VZW2V1iGKV8rJL2ZEGIDzzBeKowYv34AedJz13RzVII= go.bug.st/relaxed-semver v0.0.0-20190922224835-391e10178d18/go.mod h1:Cx1VqMtEhE9pIkEyUj3LVVVPkv89dgW8aCKrRPDR/uE= -go.bug.st/serial v1.0.0/go.mod h1:rpXPISGjuNjPTRTcMlxi9lN6LoIPxd1ixVjBd8aSk/Q= -go.bug.st/serial v1.1.1/go.mod h1:VmYBeyJWp5BnJ0tw2NUJHZdJTGl2ecBGABHlzRK1knY= +go.bug.st/serial v1.1.2/go.mod h1:VmYBeyJWp5BnJ0tw2NUJHZdJTGl2ecBGABHlzRK1knY= go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -223,7 +198,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -238,15 +212,12 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -258,23 +229,16 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU= -golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -287,18 +251,16 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90 h1:7THRSvPuzF1bql5kyFzX0JM0vpGhwuhskgJrJsbZ80Y= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= diff --git a/client_example/main.go b/client_example/main.go index 8401403e7f7..dd99be18c48 100644 --- a/client_example/main.go +++ b/client_example/main.go @@ -150,6 +150,9 @@ func main() { log.Println("calling BoardDetails(arduino:samd:mkr1000)") callBoardsDetails(client, instance) + log.Println("calling BoardSearch()") + callBoardSearch(client, instance) + // Attach a board to a sketch. // Uncomment if you do have an actual board connected. // log.Println("calling BoardAttach(serial:///dev/ttyACM0)") @@ -524,6 +527,22 @@ func callBoardsDetails(client rpc.ArduinoCoreClient, instance *rpc.Instance) { log.Printf("Config options: %s", details.GetConfigOptions()) } +func callBoardSearch(client rpc.ArduinoCoreClient, instance *rpc.Instance) { + res, err := client.BoardSearch(context.Background(), + &rpc.BoardSearchReq{ + Instance: instance, + SearchArgs: "", + }) + + if err != nil { + log.Fatalf("Error getting board data: %s\n", err) + } + + for _, board := range res.Boards { + log.Printf("Board Name: %s, Board Platform: %s\n", board.Name, board.Platform.ID) + } +} + func callBoardAttach(client rpc.ArduinoCoreClient, instance *rpc.Instance) { currDir, _ := os.Getwd() boardattachresp, err := client.BoardAttach(context.Background(), diff --git a/commands/board/search.go b/commands/board/search.go new file mode 100644 index 00000000000..c90d3e36ab7 --- /dev/null +++ b/commands/board/search.go @@ -0,0 +1,128 @@ +// This file is part of arduino-cli. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package board + +import ( + "context" + "errors" + "sort" + "strings" + + "github.com/arduino/arduino-cli/arduino/utils" + "github.com/arduino/arduino-cli/commands" + rpc "github.com/arduino/arduino-cli/rpc/commands" +) + +// Search returns all boards that match the search arg. +// Boards are searched in all platforms, including those in the index that are not yet +// installed. Note that platforms that are not installed don't include boards' FQBNs. +// If no search argument is used all boards are returned. +func Search(ctx context.Context, req *rpc.BoardSearchReq) (*rpc.BoardSearchResp, error) { + pm := commands.GetPackageManager(req.GetInstance().GetId()) + if pm == nil { + return nil, errors.New("invalid instance") + } + + searchArgs := strings.Split(strings.Trim(req.SearchArgs, " "), " ") + + match := func(toTest []string) (bool, error) { + if len(searchArgs) == 0 { + return true, nil + } + + for _, t := range toTest { + matches, err := utils.Match(t, searchArgs) + if err != nil { + return false, err + } + if matches { + return matches, nil + } + } + return false, nil + } + + res := &rpc.BoardSearchResp{Boards: []*rpc.BoardListItem{}} + for _, targetPackage := range pm.Packages { + for _, platform := range targetPackage.Platforms { + latestPlatformRelease := platform.GetLatestRelease() + if latestPlatformRelease == nil { + continue + } + installedVersion := "" + if installedPlatformRelease := pm.GetInstalledPlatformRelease(platform); installedPlatformRelease != nil { + installedVersion = installedPlatformRelease.Version.String() + } + + rpcPlatform := &rpc.Platform{ + ID: platform.String(), + Installed: installedVersion, + Latest: latestPlatformRelease.Version.String(), + Name: platform.Name, + Maintainer: platform.Package.Maintainer, + Website: platform.Package.WebsiteURL, + Email: platform.Package.Email, + ManuallyInstalled: platform.ManuallyInstalled, + } + + // Platforms that are not installed don't have a list of boards + // generated from their boards.txt file so we need two different + // ways of reading board data. + // The only boards information for platforms that are not installed + // is that found in the index, usually that's only a board name. + if len(latestPlatformRelease.Boards) != 0 { + for _, board := range latestPlatformRelease.Boards { + if !req.GetIncludeHiddenBoards() && board.IsHidden() { + continue + } + + toTest := append(strings.Split(board.Name(), " "), board.Name(), board.FQBN()) + if ok, err := match(toTest); err != nil { + return nil, err + } else if !ok { + continue + } + + res.Boards = append(res.Boards, &rpc.BoardListItem{ + Name: board.Name(), + FQBN: board.FQBN(), + IsHidden: board.IsHidden(), + Platform: rpcPlatform, + }) + } + } else { + for _, board := range latestPlatformRelease.BoardsManifest { + toTest := append(strings.Split(board.Name, " "), board.Name) + if ok, err := match(toTest); err != nil { + return nil, err + } else if !ok { + continue + } + + res.Boards = append(res.Boards, &rpc.BoardListItem{ + Name: strings.Trim(board.Name, " \n"), + Platform: rpcPlatform, + }) + } + } + } + } + + sort.Slice(res.Boards, func(i, j int) bool { + return res.Boards[i].Name < res.Boards[j].Name + }) + return res, nil +} diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index aa3a927343b..894acc39b17 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -59,6 +59,11 @@ func (s *ArduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.Board return board.ListAll(ctx, req) } +// BoardSearch exposes to the gRPC interface the board search command +func (s *ArduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchReq) (*rpc.BoardSearchResp, error) { + return board.Search(ctx, req) +} + // BoardListWatch FIXMEDOC func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCore_BoardListWatchServer) error { msg, err := stream.Recv() diff --git a/rpc/commands/board.pb.go b/rpc/commands/board.pb.go index 45372169c1d..93d2dd82a01 100644 --- a/rpc/commands/board.pb.go +++ b/rpc/commands/board.pb.go @@ -1530,6 +1530,120 @@ func (x *BoardListItem) GetPlatform() *Platform { return nil } +type BoardSearchReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Arduino Core Service instance from the `Init` response. + Instance *Instance `protobuf:"bytes,1,opt,name=instance,proto3" json:"instance,omitempty"` + // The search query to filter the board list by. + SearchArgs string `protobuf:"bytes,2,opt,name=search_args,json=searchArgs,proto3" json:"search_args,omitempty"` + // Set to true to get also the boards marked as "hidden" in installed platforms + IncludeHiddenBoards bool `protobuf:"varint,3,opt,name=include_hidden_boards,json=includeHiddenBoards,proto3" json:"include_hidden_boards,omitempty"` +} + +func (x *BoardSearchReq) Reset() { + *x = BoardSearchReq{} + if protoimpl.UnsafeEnabled { + mi := &file_commands_board_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BoardSearchReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BoardSearchReq) ProtoMessage() {} + +func (x *BoardSearchReq) ProtoReflect() protoreflect.Message { + mi := &file_commands_board_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BoardSearchReq.ProtoReflect.Descriptor instead. +func (*BoardSearchReq) Descriptor() ([]byte, []int) { + return file_commands_board_proto_rawDescGZIP(), []int{21} +} + +func (x *BoardSearchReq) GetInstance() *Instance { + if x != nil { + return x.Instance + } + return nil +} + +func (x *BoardSearchReq) GetSearchArgs() string { + if x != nil { + return x.SearchArgs + } + return "" +} + +func (x *BoardSearchReq) GetIncludeHiddenBoards() bool { + if x != nil { + return x.IncludeHiddenBoards + } + return false +} + +type BoardSearchResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of installed and installable boards. + Boards []*BoardListItem `protobuf:"bytes,1,rep,name=boards,proto3" json:"boards,omitempty"` +} + +func (x *BoardSearchResp) Reset() { + *x = BoardSearchResp{} + if protoimpl.UnsafeEnabled { + mi := &file_commands_board_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BoardSearchResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BoardSearchResp) ProtoMessage() {} + +func (x *BoardSearchResp) ProtoReflect() protoreflect.Message { + mi := &file_commands_board_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BoardSearchResp.ProtoReflect.Descriptor instead. +func (*BoardSearchResp) Descriptor() ([]byte, []int) { + return file_commands_board_proto_rawDescGZIP(), []int{22} +} + +func (x *BoardSearchResp) GetBoards() []*BoardListItem { + if x != nil { + return x.Boards + } + return nil +} + var File_commands_board_proto protoreflect.FileDescriptor var file_commands_board_proto_rawDesc = []byte{ @@ -1736,10 +1850,26 @@ var file_commands_board_proto_rawDesc = []byte{ 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, - 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, - 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xa4, 0x01, 0x0a, 0x0e, 0x42, 0x6f, + 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x08, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x72, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, + 0x22, 0x51, 0x0a, 0x0f, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x3e, 0x0a, 0x06, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, + 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x73, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, + 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1754,7 +1884,7 @@ func file_commands_board_proto_rawDescGZIP() []byte { return file_commands_board_proto_rawDescData } -var file_commands_board_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_commands_board_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_commands_board_proto_goTypes = []interface{}{ (*BoardDetailsReq)(nil), // 0: cc.arduino.cli.commands.BoardDetailsReq (*BoardDetailsResp)(nil), // 1: cc.arduino.cli.commands.BoardDetailsResp @@ -1777,38 +1907,42 @@ var file_commands_board_proto_goTypes = []interface{}{ (*BoardListWatchReq)(nil), // 18: cc.arduino.cli.commands.BoardListWatchReq (*BoardListWatchResp)(nil), // 19: cc.arduino.cli.commands.BoardListWatchResp (*BoardListItem)(nil), // 20: cc.arduino.cli.commands.BoardListItem - (*Instance)(nil), // 21: cc.arduino.cli.commands.Instance - (*Programmer)(nil), // 22: cc.arduino.cli.commands.Programmer - (*TaskProgress)(nil), // 23: cc.arduino.cli.commands.TaskProgress - (*Platform)(nil), // 24: cc.arduino.cli.commands.Platform + (*BoardSearchReq)(nil), // 21: cc.arduino.cli.commands.BoardSearchReq + (*BoardSearchResp)(nil), // 22: cc.arduino.cli.commands.BoardSearchResp + (*Instance)(nil), // 23: cc.arduino.cli.commands.Instance + (*Programmer)(nil), // 24: cc.arduino.cli.commands.Programmer + (*TaskProgress)(nil), // 25: cc.arduino.cli.commands.TaskProgress + (*Platform)(nil), // 26: cc.arduino.cli.commands.Platform } var file_commands_board_proto_depIdxs = []int32{ - 21, // 0: cc.arduino.cli.commands.BoardDetailsReq.instance:type_name -> cc.arduino.cli.commands.Instance + 23, // 0: cc.arduino.cli.commands.BoardDetailsReq.instance:type_name -> cc.arduino.cli.commands.Instance 4, // 1: cc.arduino.cli.commands.BoardDetailsResp.package:type_name -> cc.arduino.cli.commands.Package 6, // 2: cc.arduino.cli.commands.BoardDetailsResp.platform:type_name -> cc.arduino.cli.commands.BoardPlatform 7, // 3: cc.arduino.cli.commands.BoardDetailsResp.toolsDependencies:type_name -> cc.arduino.cli.commands.ToolsDependencies 9, // 4: cc.arduino.cli.commands.BoardDetailsResp.config_options:type_name -> cc.arduino.cli.commands.ConfigOption 2, // 5: cc.arduino.cli.commands.BoardDetailsResp.identification_pref:type_name -> cc.arduino.cli.commands.IdentificationPref - 22, // 6: cc.arduino.cli.commands.BoardDetailsResp.programmers:type_name -> cc.arduino.cli.commands.Programmer + 24, // 6: cc.arduino.cli.commands.BoardDetailsResp.programmers:type_name -> cc.arduino.cli.commands.Programmer 3, // 7: cc.arduino.cli.commands.IdentificationPref.usbID:type_name -> cc.arduino.cli.commands.USBID 5, // 8: cc.arduino.cli.commands.Package.help:type_name -> cc.arduino.cli.commands.Help 8, // 9: cc.arduino.cli.commands.ToolsDependencies.systems:type_name -> cc.arduino.cli.commands.Systems 10, // 10: cc.arduino.cli.commands.ConfigOption.values:type_name -> cc.arduino.cli.commands.ConfigValue - 21, // 11: cc.arduino.cli.commands.BoardAttachReq.instance:type_name -> cc.arduino.cli.commands.Instance - 23, // 12: cc.arduino.cli.commands.BoardAttachResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress - 21, // 13: cc.arduino.cli.commands.BoardListReq.instance:type_name -> cc.arduino.cli.commands.Instance + 23, // 11: cc.arduino.cli.commands.BoardAttachReq.instance:type_name -> cc.arduino.cli.commands.Instance + 25, // 12: cc.arduino.cli.commands.BoardAttachResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress + 23, // 13: cc.arduino.cli.commands.BoardListReq.instance:type_name -> cc.arduino.cli.commands.Instance 15, // 14: cc.arduino.cli.commands.BoardListResp.ports:type_name -> cc.arduino.cli.commands.DetectedPort 20, // 15: cc.arduino.cli.commands.DetectedPort.boards:type_name -> cc.arduino.cli.commands.BoardListItem - 21, // 16: cc.arduino.cli.commands.BoardListAllReq.instance:type_name -> cc.arduino.cli.commands.Instance + 23, // 16: cc.arduino.cli.commands.BoardListAllReq.instance:type_name -> cc.arduino.cli.commands.Instance 20, // 17: cc.arduino.cli.commands.BoardListAllResp.boards:type_name -> cc.arduino.cli.commands.BoardListItem - 21, // 18: cc.arduino.cli.commands.BoardListWatchReq.instance:type_name -> cc.arduino.cli.commands.Instance + 23, // 18: cc.arduino.cli.commands.BoardListWatchReq.instance:type_name -> cc.arduino.cli.commands.Instance 15, // 19: cc.arduino.cli.commands.BoardListWatchResp.port:type_name -> cc.arduino.cli.commands.DetectedPort - 24, // 20: cc.arduino.cli.commands.BoardListItem.platform:type_name -> cc.arduino.cli.commands.Platform - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 26, // 20: cc.arduino.cli.commands.BoardListItem.platform:type_name -> cc.arduino.cli.commands.Platform + 23, // 21: cc.arduino.cli.commands.BoardSearchReq.instance:type_name -> cc.arduino.cli.commands.Instance + 20, // 22: cc.arduino.cli.commands.BoardSearchResp.boards:type_name -> cc.arduino.cli.commands.BoardListItem + 23, // [23:23] is the sub-list for method output_type + 23, // [23:23] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name } func init() { file_commands_board_proto_init() } @@ -2070,6 +2204,30 @@ func file_commands_board_proto_init() { return nil } } + file_commands_board_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BoardSearchReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_commands_board_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BoardSearchResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2077,7 +2235,7 @@ func file_commands_board_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commands_board_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 23, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/commands/board.proto b/rpc/commands/board.proto index adc9d977367..bc93b646bb6 100644 --- a/rpc/commands/board.proto +++ b/rpc/commands/board.proto @@ -238,3 +238,17 @@ message BoardListItem { // Platform this board belongs to Platform platform = 6; } + +message BoardSearchReq { + // Arduino Core Service instance from the `Init` response. + Instance instance = 1; + // The search query to filter the board list by. + string search_args = 2; + // Set to true to get also the boards marked as "hidden" in installed platforms + bool include_hidden_boards = 3; +} + +message BoardSearchResp { + // List of installed and installable boards. + repeated BoardListItem boards = 1; +} diff --git a/rpc/commands/commands.pb.go b/rpc/commands/commands.pb.go index 375c34558fe..983c1cdf25d 100644 --- a/rpc/commands/commands.pb.go +++ b/rpc/commands/commands.pb.go @@ -1373,7 +1373,7 @@ var file_commands_commands_proto_rawDesc = []byte{ 0x75, 0x64, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x72, 0x22, 0x13, 0x0a, 0x11, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, - 0x6b, 0x65, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x32, 0xb8, 0x1e, 0x0a, 0x0b, 0x41, 0x72, + 0x6b, 0x65, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x32, 0x9a, 0x1f, 0x0a, 0x0b, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x43, 0x6f, 0x72, 0x65, 0x12, 0x4f, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x49, 0x6e, 0x69, 0x74, @@ -1467,160 +1467,166 @@ var file_commands_commands_proto_rawDesc = []byte{ 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x29, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, - 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6d, - 0x0a, 0x0e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x2a, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, - 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, - 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, - 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, - 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x28, 0x01, 0x30, 0x01, 0x12, 0x56, 0x0a, - 0x07, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x24, 0x2e, + 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x60, + 0x0a, 0x0b, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x27, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, - 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x71, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x6d, 0x0a, 0x0e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x2a, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, + 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2b, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x56, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x63, 0x63, 0x2e, + 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x1a, + 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2b, 0x2e, 0x63, 0x63, 0x2e, + 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, + 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x71, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2c, 0x2e, 0x63, 0x63, + 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x44, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2d, 0x2e, - 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, - 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, - 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x6e, - 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x12, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, - 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x2c, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, + 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x53, - 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x22, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x63, - 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x30, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, - 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x12, 0x31, 0x2e, - 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, - 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x1a, 0x32, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, - 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0xa2, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, - 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3d, 0x2e, 0x63, - 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x3e, 0x2e, 0x63, 0x63, - 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, - 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6b, 0x0a, 0x0e, 0x42, - 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2a, 0x2e, - 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, - 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, - 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x69, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x2a, 0x2e, 0x63, 0x63, 0x2e, - 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, - 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x63, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x6d, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, + 0x12, 0x6e, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x12, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x29, 0x2e, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, + 0x1a, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, + 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, + 0x12, 0x53, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x22, 0x2e, 0x63, 0x63, 0x2e, + 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x23, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x12, + 0x31, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x1a, 0x32, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0xa2, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3d, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x3e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6e, 0x0a, 0x0f, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2b, 0x2e, 0x63, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6b, 0x0a, + 0x0e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x2a, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, + 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x69, 0x0a, 0x0e, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x2a, 0x2e, 0x63, + 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x6b, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2a, 0x2e, 0x63, 0x63, 0x2e, - 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, - 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x5a, 0x69, 0x70, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2d, 0x2e, 0x63, 0x63, 0x2e, + 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x63, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, + 0x29, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6e, 0x0a, 0x0f, 0x4c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2b, 0x2e, + 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x5a, 0x69, 0x70, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, - 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x5a, 0x69, 0x70, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x47, - 0x69, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x12, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, - 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x47, 0x69, 0x74, 0x4c, 0x69, - 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, - 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x47, 0x69, 0x74, 0x4c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, - 0x01, 0x12, 0x71, 0x0a, 0x10, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x6b, 0x0a, 0x0e, 0x4c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2a, 0x2e, 0x63, + 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2b, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, + 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x5a, 0x69, 0x70, 0x4c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2d, 0x2e, 0x63, + 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x5a, 0x69, 0x70, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, + 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x5a, 0x69, 0x70, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, + 0x11, 0x47, 0x69, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x12, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x47, 0x69, 0x74, + 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x47, 0x69, 0x74, 0x4c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x30, 0x01, 0x12, 0x71, 0x0a, 0x10, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x6e, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, + 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x52, 0x65, 0x71, 0x1a, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, - 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, - 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, - 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x41, 0x6c, 0x6c, 0x12, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, - 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x70, 0x67, 0x72, 0x61, - 0x64, 0x65, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x8d, 0x01, 0x0a, 0x1a, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x44, 0x65, 0x70, - 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x63, 0x63, 0x2e, 0x61, - 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x1a, 0x37, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, - 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, - 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x66, 0x0a, 0x0d, 0x4c, 0x69, - 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x29, 0x2e, 0x63, 0x63, + 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x74, 0x0a, 0x11, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x79, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x41, 0x6c, 0x6c, 0x12, 0x2d, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2a, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, - 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x60, 0x0a, 0x0b, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x27, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, - 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x63, 0x63, 0x2e, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x70, 0x67, + 0x72, 0x61, 0x64, 0x65, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, - 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x55, 0x70, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x12, 0x8d, 0x01, 0x0a, + 0x1a, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x44, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x63, 0x63, + 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x1a, 0x37, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x44, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x66, 0x0a, 0x0d, + 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x29, 0x2e, + 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x2a, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, + 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x60, 0x0a, 0x0b, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x28, 0x2e, 0x63, + 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, + 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1668,52 +1674,54 @@ var file_commands_commands_proto_goTypes = []interface{}{ (*BoardAttachReq)(nil), // 28: cc.arduino.cli.commands.BoardAttachReq (*BoardListReq)(nil), // 29: cc.arduino.cli.commands.BoardListReq (*BoardListAllReq)(nil), // 30: cc.arduino.cli.commands.BoardListAllReq - (*BoardListWatchReq)(nil), // 31: cc.arduino.cli.commands.BoardListWatchReq - (*CompileReq)(nil), // 32: cc.arduino.cli.commands.CompileReq - (*PlatformInstallReq)(nil), // 33: cc.arduino.cli.commands.PlatformInstallReq - (*PlatformDownloadReq)(nil), // 34: cc.arduino.cli.commands.PlatformDownloadReq - (*PlatformUninstallReq)(nil), // 35: cc.arduino.cli.commands.PlatformUninstallReq - (*PlatformUpgradeReq)(nil), // 36: cc.arduino.cli.commands.PlatformUpgradeReq - (*UploadReq)(nil), // 37: cc.arduino.cli.commands.UploadReq - (*UploadUsingProgrammerReq)(nil), // 38: cc.arduino.cli.commands.UploadUsingProgrammerReq - (*ListProgrammersAvailableForUploadReq)(nil), // 39: cc.arduino.cli.commands.ListProgrammersAvailableForUploadReq - (*BurnBootloaderReq)(nil), // 40: cc.arduino.cli.commands.BurnBootloaderReq - (*PlatformSearchReq)(nil), // 41: cc.arduino.cli.commands.PlatformSearchReq - (*PlatformListReq)(nil), // 42: cc.arduino.cli.commands.PlatformListReq - (*LibraryDownloadReq)(nil), // 43: cc.arduino.cli.commands.LibraryDownloadReq - (*LibraryInstallReq)(nil), // 44: cc.arduino.cli.commands.LibraryInstallReq - (*ZipLibraryInstallReq)(nil), // 45: cc.arduino.cli.commands.ZipLibraryInstallReq - (*GitLibraryInstallReq)(nil), // 46: cc.arduino.cli.commands.GitLibraryInstallReq - (*LibraryUninstallReq)(nil), // 47: cc.arduino.cli.commands.LibraryUninstallReq - (*LibraryUpgradeAllReq)(nil), // 48: cc.arduino.cli.commands.LibraryUpgradeAllReq - (*LibraryResolveDependenciesReq)(nil), // 49: cc.arduino.cli.commands.LibraryResolveDependenciesReq - (*LibrarySearchReq)(nil), // 50: cc.arduino.cli.commands.LibrarySearchReq - (*LibraryListReq)(nil), // 51: cc.arduino.cli.commands.LibraryListReq - (*BoardDetailsResp)(nil), // 52: cc.arduino.cli.commands.BoardDetailsResp - (*BoardAttachResp)(nil), // 53: cc.arduino.cli.commands.BoardAttachResp - (*BoardListResp)(nil), // 54: cc.arduino.cli.commands.BoardListResp - (*BoardListAllResp)(nil), // 55: cc.arduino.cli.commands.BoardListAllResp - (*BoardListWatchResp)(nil), // 56: cc.arduino.cli.commands.BoardListWatchResp - (*CompileResp)(nil), // 57: cc.arduino.cli.commands.CompileResp - (*PlatformInstallResp)(nil), // 58: cc.arduino.cli.commands.PlatformInstallResp - (*PlatformDownloadResp)(nil), // 59: cc.arduino.cli.commands.PlatformDownloadResp - (*PlatformUninstallResp)(nil), // 60: cc.arduino.cli.commands.PlatformUninstallResp - (*PlatformUpgradeResp)(nil), // 61: cc.arduino.cli.commands.PlatformUpgradeResp - (*UploadResp)(nil), // 62: cc.arduino.cli.commands.UploadResp - (*UploadUsingProgrammerResp)(nil), // 63: cc.arduino.cli.commands.UploadUsingProgrammerResp - (*ListProgrammersAvailableForUploadResp)(nil), // 64: cc.arduino.cli.commands.ListProgrammersAvailableForUploadResp - (*BurnBootloaderResp)(nil), // 65: cc.arduino.cli.commands.BurnBootloaderResp - (*PlatformSearchResp)(nil), // 66: cc.arduino.cli.commands.PlatformSearchResp - (*PlatformListResp)(nil), // 67: cc.arduino.cli.commands.PlatformListResp - (*LibraryDownloadResp)(nil), // 68: cc.arduino.cli.commands.LibraryDownloadResp - (*LibraryInstallResp)(nil), // 69: cc.arduino.cli.commands.LibraryInstallResp - (*ZipLibraryInstallResp)(nil), // 70: cc.arduino.cli.commands.ZipLibraryInstallResp - (*GitLibraryInstallResp)(nil), // 71: cc.arduino.cli.commands.GitLibraryInstallResp - (*LibraryUninstallResp)(nil), // 72: cc.arduino.cli.commands.LibraryUninstallResp - (*LibraryUpgradeAllResp)(nil), // 73: cc.arduino.cli.commands.LibraryUpgradeAllResp - (*LibraryResolveDependenciesResp)(nil), // 74: cc.arduino.cli.commands.LibraryResolveDependenciesResp - (*LibrarySearchResp)(nil), // 75: cc.arduino.cli.commands.LibrarySearchResp - (*LibraryListResp)(nil), // 76: cc.arduino.cli.commands.LibraryListResp + (*BoardSearchReq)(nil), // 31: cc.arduino.cli.commands.BoardSearchReq + (*BoardListWatchReq)(nil), // 32: cc.arduino.cli.commands.BoardListWatchReq + (*CompileReq)(nil), // 33: cc.arduino.cli.commands.CompileReq + (*PlatformInstallReq)(nil), // 34: cc.arduino.cli.commands.PlatformInstallReq + (*PlatformDownloadReq)(nil), // 35: cc.arduino.cli.commands.PlatformDownloadReq + (*PlatformUninstallReq)(nil), // 36: cc.arduino.cli.commands.PlatformUninstallReq + (*PlatformUpgradeReq)(nil), // 37: cc.arduino.cli.commands.PlatformUpgradeReq + (*UploadReq)(nil), // 38: cc.arduino.cli.commands.UploadReq + (*UploadUsingProgrammerReq)(nil), // 39: cc.arduino.cli.commands.UploadUsingProgrammerReq + (*ListProgrammersAvailableForUploadReq)(nil), // 40: cc.arduino.cli.commands.ListProgrammersAvailableForUploadReq + (*BurnBootloaderReq)(nil), // 41: cc.arduino.cli.commands.BurnBootloaderReq + (*PlatformSearchReq)(nil), // 42: cc.arduino.cli.commands.PlatformSearchReq + (*PlatformListReq)(nil), // 43: cc.arduino.cli.commands.PlatformListReq + (*LibraryDownloadReq)(nil), // 44: cc.arduino.cli.commands.LibraryDownloadReq + (*LibraryInstallReq)(nil), // 45: cc.arduino.cli.commands.LibraryInstallReq + (*ZipLibraryInstallReq)(nil), // 46: cc.arduino.cli.commands.ZipLibraryInstallReq + (*GitLibraryInstallReq)(nil), // 47: cc.arduino.cli.commands.GitLibraryInstallReq + (*LibraryUninstallReq)(nil), // 48: cc.arduino.cli.commands.LibraryUninstallReq + (*LibraryUpgradeAllReq)(nil), // 49: cc.arduino.cli.commands.LibraryUpgradeAllReq + (*LibraryResolveDependenciesReq)(nil), // 50: cc.arduino.cli.commands.LibraryResolveDependenciesReq + (*LibrarySearchReq)(nil), // 51: cc.arduino.cli.commands.LibrarySearchReq + (*LibraryListReq)(nil), // 52: cc.arduino.cli.commands.LibraryListReq + (*BoardDetailsResp)(nil), // 53: cc.arduino.cli.commands.BoardDetailsResp + (*BoardAttachResp)(nil), // 54: cc.arduino.cli.commands.BoardAttachResp + (*BoardListResp)(nil), // 55: cc.arduino.cli.commands.BoardListResp + (*BoardListAllResp)(nil), // 56: cc.arduino.cli.commands.BoardListAllResp + (*BoardSearchResp)(nil), // 57: cc.arduino.cli.commands.BoardSearchResp + (*BoardListWatchResp)(nil), // 58: cc.arduino.cli.commands.BoardListWatchResp + (*CompileResp)(nil), // 59: cc.arduino.cli.commands.CompileResp + (*PlatformInstallResp)(nil), // 60: cc.arduino.cli.commands.PlatformInstallResp + (*PlatformDownloadResp)(nil), // 61: cc.arduino.cli.commands.PlatformDownloadResp + (*PlatformUninstallResp)(nil), // 62: cc.arduino.cli.commands.PlatformUninstallResp + (*PlatformUpgradeResp)(nil), // 63: cc.arduino.cli.commands.PlatformUpgradeResp + (*UploadResp)(nil), // 64: cc.arduino.cli.commands.UploadResp + (*UploadUsingProgrammerResp)(nil), // 65: cc.arduino.cli.commands.UploadUsingProgrammerResp + (*ListProgrammersAvailableForUploadResp)(nil), // 66: cc.arduino.cli.commands.ListProgrammersAvailableForUploadResp + (*BurnBootloaderResp)(nil), // 67: cc.arduino.cli.commands.BurnBootloaderResp + (*PlatformSearchResp)(nil), // 68: cc.arduino.cli.commands.PlatformSearchResp + (*PlatformListResp)(nil), // 69: cc.arduino.cli.commands.PlatformListResp + (*LibraryDownloadResp)(nil), // 70: cc.arduino.cli.commands.LibraryDownloadResp + (*LibraryInstallResp)(nil), // 71: cc.arduino.cli.commands.LibraryInstallResp + (*ZipLibraryInstallResp)(nil), // 72: cc.arduino.cli.commands.ZipLibraryInstallResp + (*GitLibraryInstallResp)(nil), // 73: cc.arduino.cli.commands.GitLibraryInstallResp + (*LibraryUninstallResp)(nil), // 74: cc.arduino.cli.commands.LibraryUninstallResp + (*LibraryUpgradeAllResp)(nil), // 75: cc.arduino.cli.commands.LibraryUpgradeAllResp + (*LibraryResolveDependenciesResp)(nil), // 76: cc.arduino.cli.commands.LibraryResolveDependenciesResp + (*LibrarySearchResp)(nil), // 77: cc.arduino.cli.commands.LibrarySearchResp + (*LibraryListResp)(nil), // 78: cc.arduino.cli.commands.LibraryListResp } var file_commands_commands_proto_depIdxs = []int32{ 22, // 0: cc.arduino.cli.commands.InitResp.instance:type_name -> cc.arduino.cli.commands.Instance @@ -1749,65 +1757,67 @@ var file_commands_commands_proto_depIdxs = []int32{ 28, // 30: cc.arduino.cli.commands.ArduinoCore.BoardAttach:input_type -> cc.arduino.cli.commands.BoardAttachReq 29, // 31: cc.arduino.cli.commands.ArduinoCore.BoardList:input_type -> cc.arduino.cli.commands.BoardListReq 30, // 32: cc.arduino.cli.commands.ArduinoCore.BoardListAll:input_type -> cc.arduino.cli.commands.BoardListAllReq - 31, // 33: cc.arduino.cli.commands.ArduinoCore.BoardListWatch:input_type -> cc.arduino.cli.commands.BoardListWatchReq - 32, // 34: cc.arduino.cli.commands.ArduinoCore.Compile:input_type -> cc.arduino.cli.commands.CompileReq - 33, // 35: cc.arduino.cli.commands.ArduinoCore.PlatformInstall:input_type -> cc.arduino.cli.commands.PlatformInstallReq - 34, // 36: cc.arduino.cli.commands.ArduinoCore.PlatformDownload:input_type -> cc.arduino.cli.commands.PlatformDownloadReq - 35, // 37: cc.arduino.cli.commands.ArduinoCore.PlatformUninstall:input_type -> cc.arduino.cli.commands.PlatformUninstallReq - 36, // 38: cc.arduino.cli.commands.ArduinoCore.PlatformUpgrade:input_type -> cc.arduino.cli.commands.PlatformUpgradeReq - 37, // 39: cc.arduino.cli.commands.ArduinoCore.Upload:input_type -> cc.arduino.cli.commands.UploadReq - 38, // 40: cc.arduino.cli.commands.ArduinoCore.UploadUsingProgrammer:input_type -> cc.arduino.cli.commands.UploadUsingProgrammerReq - 39, // 41: cc.arduino.cli.commands.ArduinoCore.ListProgrammersAvailableForUpload:input_type -> cc.arduino.cli.commands.ListProgrammersAvailableForUploadReq - 40, // 42: cc.arduino.cli.commands.ArduinoCore.BurnBootloader:input_type -> cc.arduino.cli.commands.BurnBootloaderReq - 41, // 43: cc.arduino.cli.commands.ArduinoCore.PlatformSearch:input_type -> cc.arduino.cli.commands.PlatformSearchReq - 42, // 44: cc.arduino.cli.commands.ArduinoCore.PlatformList:input_type -> cc.arduino.cli.commands.PlatformListReq - 43, // 45: cc.arduino.cli.commands.ArduinoCore.LibraryDownload:input_type -> cc.arduino.cli.commands.LibraryDownloadReq - 44, // 46: cc.arduino.cli.commands.ArduinoCore.LibraryInstall:input_type -> cc.arduino.cli.commands.LibraryInstallReq - 45, // 47: cc.arduino.cli.commands.ArduinoCore.ZipLibraryInstall:input_type -> cc.arduino.cli.commands.ZipLibraryInstallReq - 46, // 48: cc.arduino.cli.commands.ArduinoCore.GitLibraryInstall:input_type -> cc.arduino.cli.commands.GitLibraryInstallReq - 47, // 49: cc.arduino.cli.commands.ArduinoCore.LibraryUninstall:input_type -> cc.arduino.cli.commands.LibraryUninstallReq - 48, // 50: cc.arduino.cli.commands.ArduinoCore.LibraryUpgradeAll:input_type -> cc.arduino.cli.commands.LibraryUpgradeAllReq - 49, // 51: cc.arduino.cli.commands.ArduinoCore.LibraryResolveDependencies:input_type -> cc.arduino.cli.commands.LibraryResolveDependenciesReq - 50, // 52: cc.arduino.cli.commands.ArduinoCore.LibrarySearch:input_type -> cc.arduino.cli.commands.LibrarySearchReq - 51, // 53: cc.arduino.cli.commands.ArduinoCore.LibraryList:input_type -> cc.arduino.cli.commands.LibraryListReq - 1, // 54: cc.arduino.cli.commands.ArduinoCore.Init:output_type -> cc.arduino.cli.commands.InitResp - 3, // 55: cc.arduino.cli.commands.ArduinoCore.Destroy:output_type -> cc.arduino.cli.commands.DestroyResp - 5, // 56: cc.arduino.cli.commands.ArduinoCore.Rescan:output_type -> cc.arduino.cli.commands.RescanResp - 7, // 57: cc.arduino.cli.commands.ArduinoCore.UpdateIndex:output_type -> cc.arduino.cli.commands.UpdateIndexResp - 9, // 58: cc.arduino.cli.commands.ArduinoCore.UpdateLibrariesIndex:output_type -> cc.arduino.cli.commands.UpdateLibrariesIndexResp - 11, // 59: cc.arduino.cli.commands.ArduinoCore.UpdateCoreLibrariesIndex:output_type -> cc.arduino.cli.commands.UpdateCoreLibrariesIndexResp - 13, // 60: cc.arduino.cli.commands.ArduinoCore.Outdated:output_type -> cc.arduino.cli.commands.OutdatedResp - 15, // 61: cc.arduino.cli.commands.ArduinoCore.Upgrade:output_type -> cc.arduino.cli.commands.UpgradeResp - 17, // 62: cc.arduino.cli.commands.ArduinoCore.Version:output_type -> cc.arduino.cli.commands.VersionResp - 19, // 63: cc.arduino.cli.commands.ArduinoCore.LoadSketch:output_type -> cc.arduino.cli.commands.LoadSketchResp - 21, // 64: cc.arduino.cli.commands.ArduinoCore.ArchiveSketch:output_type -> cc.arduino.cli.commands.ArchiveSketchResp - 52, // 65: cc.arduino.cli.commands.ArduinoCore.BoardDetails:output_type -> cc.arduino.cli.commands.BoardDetailsResp - 53, // 66: cc.arduino.cli.commands.ArduinoCore.BoardAttach:output_type -> cc.arduino.cli.commands.BoardAttachResp - 54, // 67: cc.arduino.cli.commands.ArduinoCore.BoardList:output_type -> cc.arduino.cli.commands.BoardListResp - 55, // 68: cc.arduino.cli.commands.ArduinoCore.BoardListAll:output_type -> cc.arduino.cli.commands.BoardListAllResp - 56, // 69: cc.arduino.cli.commands.ArduinoCore.BoardListWatch:output_type -> cc.arduino.cli.commands.BoardListWatchResp - 57, // 70: cc.arduino.cli.commands.ArduinoCore.Compile:output_type -> cc.arduino.cli.commands.CompileResp - 58, // 71: cc.arduino.cli.commands.ArduinoCore.PlatformInstall:output_type -> cc.arduino.cli.commands.PlatformInstallResp - 59, // 72: cc.arduino.cli.commands.ArduinoCore.PlatformDownload:output_type -> cc.arduino.cli.commands.PlatformDownloadResp - 60, // 73: cc.arduino.cli.commands.ArduinoCore.PlatformUninstall:output_type -> cc.arduino.cli.commands.PlatformUninstallResp - 61, // 74: cc.arduino.cli.commands.ArduinoCore.PlatformUpgrade:output_type -> cc.arduino.cli.commands.PlatformUpgradeResp - 62, // 75: cc.arduino.cli.commands.ArduinoCore.Upload:output_type -> cc.arduino.cli.commands.UploadResp - 63, // 76: cc.arduino.cli.commands.ArduinoCore.UploadUsingProgrammer:output_type -> cc.arduino.cli.commands.UploadUsingProgrammerResp - 64, // 77: cc.arduino.cli.commands.ArduinoCore.ListProgrammersAvailableForUpload:output_type -> cc.arduino.cli.commands.ListProgrammersAvailableForUploadResp - 65, // 78: cc.arduino.cli.commands.ArduinoCore.BurnBootloader:output_type -> cc.arduino.cli.commands.BurnBootloaderResp - 66, // 79: cc.arduino.cli.commands.ArduinoCore.PlatformSearch:output_type -> cc.arduino.cli.commands.PlatformSearchResp - 67, // 80: cc.arduino.cli.commands.ArduinoCore.PlatformList:output_type -> cc.arduino.cli.commands.PlatformListResp - 68, // 81: cc.arduino.cli.commands.ArduinoCore.LibraryDownload:output_type -> cc.arduino.cli.commands.LibraryDownloadResp - 69, // 82: cc.arduino.cli.commands.ArduinoCore.LibraryInstall:output_type -> cc.arduino.cli.commands.LibraryInstallResp - 70, // 83: cc.arduino.cli.commands.ArduinoCore.ZipLibraryInstall:output_type -> cc.arduino.cli.commands.ZipLibraryInstallResp - 71, // 84: cc.arduino.cli.commands.ArduinoCore.GitLibraryInstall:output_type -> cc.arduino.cli.commands.GitLibraryInstallResp - 72, // 85: cc.arduino.cli.commands.ArduinoCore.LibraryUninstall:output_type -> cc.arduino.cli.commands.LibraryUninstallResp - 73, // 86: cc.arduino.cli.commands.ArduinoCore.LibraryUpgradeAll:output_type -> cc.arduino.cli.commands.LibraryUpgradeAllResp - 74, // 87: cc.arduino.cli.commands.ArduinoCore.LibraryResolveDependencies:output_type -> cc.arduino.cli.commands.LibraryResolveDependenciesResp - 75, // 88: cc.arduino.cli.commands.ArduinoCore.LibrarySearch:output_type -> cc.arduino.cli.commands.LibrarySearchResp - 76, // 89: cc.arduino.cli.commands.ArduinoCore.LibraryList:output_type -> cc.arduino.cli.commands.LibraryListResp - 54, // [54:90] is the sub-list for method output_type - 18, // [18:54] is the sub-list for method input_type + 31, // 33: cc.arduino.cli.commands.ArduinoCore.BoardSearch:input_type -> cc.arduino.cli.commands.BoardSearchReq + 32, // 34: cc.arduino.cli.commands.ArduinoCore.BoardListWatch:input_type -> cc.arduino.cli.commands.BoardListWatchReq + 33, // 35: cc.arduino.cli.commands.ArduinoCore.Compile:input_type -> cc.arduino.cli.commands.CompileReq + 34, // 36: cc.arduino.cli.commands.ArduinoCore.PlatformInstall:input_type -> cc.arduino.cli.commands.PlatformInstallReq + 35, // 37: cc.arduino.cli.commands.ArduinoCore.PlatformDownload:input_type -> cc.arduino.cli.commands.PlatformDownloadReq + 36, // 38: cc.arduino.cli.commands.ArduinoCore.PlatformUninstall:input_type -> cc.arduino.cli.commands.PlatformUninstallReq + 37, // 39: cc.arduino.cli.commands.ArduinoCore.PlatformUpgrade:input_type -> cc.arduino.cli.commands.PlatformUpgradeReq + 38, // 40: cc.arduino.cli.commands.ArduinoCore.Upload:input_type -> cc.arduino.cli.commands.UploadReq + 39, // 41: cc.arduino.cli.commands.ArduinoCore.UploadUsingProgrammer:input_type -> cc.arduino.cli.commands.UploadUsingProgrammerReq + 40, // 42: cc.arduino.cli.commands.ArduinoCore.ListProgrammersAvailableForUpload:input_type -> cc.arduino.cli.commands.ListProgrammersAvailableForUploadReq + 41, // 43: cc.arduino.cli.commands.ArduinoCore.BurnBootloader:input_type -> cc.arduino.cli.commands.BurnBootloaderReq + 42, // 44: cc.arduino.cli.commands.ArduinoCore.PlatformSearch:input_type -> cc.arduino.cli.commands.PlatformSearchReq + 43, // 45: cc.arduino.cli.commands.ArduinoCore.PlatformList:input_type -> cc.arduino.cli.commands.PlatformListReq + 44, // 46: cc.arduino.cli.commands.ArduinoCore.LibraryDownload:input_type -> cc.arduino.cli.commands.LibraryDownloadReq + 45, // 47: cc.arduino.cli.commands.ArduinoCore.LibraryInstall:input_type -> cc.arduino.cli.commands.LibraryInstallReq + 46, // 48: cc.arduino.cli.commands.ArduinoCore.ZipLibraryInstall:input_type -> cc.arduino.cli.commands.ZipLibraryInstallReq + 47, // 49: cc.arduino.cli.commands.ArduinoCore.GitLibraryInstall:input_type -> cc.arduino.cli.commands.GitLibraryInstallReq + 48, // 50: cc.arduino.cli.commands.ArduinoCore.LibraryUninstall:input_type -> cc.arduino.cli.commands.LibraryUninstallReq + 49, // 51: cc.arduino.cli.commands.ArduinoCore.LibraryUpgradeAll:input_type -> cc.arduino.cli.commands.LibraryUpgradeAllReq + 50, // 52: cc.arduino.cli.commands.ArduinoCore.LibraryResolveDependencies:input_type -> cc.arduino.cli.commands.LibraryResolveDependenciesReq + 51, // 53: cc.arduino.cli.commands.ArduinoCore.LibrarySearch:input_type -> cc.arduino.cli.commands.LibrarySearchReq + 52, // 54: cc.arduino.cli.commands.ArduinoCore.LibraryList:input_type -> cc.arduino.cli.commands.LibraryListReq + 1, // 55: cc.arduino.cli.commands.ArduinoCore.Init:output_type -> cc.arduino.cli.commands.InitResp + 3, // 56: cc.arduino.cli.commands.ArduinoCore.Destroy:output_type -> cc.arduino.cli.commands.DestroyResp + 5, // 57: cc.arduino.cli.commands.ArduinoCore.Rescan:output_type -> cc.arduino.cli.commands.RescanResp + 7, // 58: cc.arduino.cli.commands.ArduinoCore.UpdateIndex:output_type -> cc.arduino.cli.commands.UpdateIndexResp + 9, // 59: cc.arduino.cli.commands.ArduinoCore.UpdateLibrariesIndex:output_type -> cc.arduino.cli.commands.UpdateLibrariesIndexResp + 11, // 60: cc.arduino.cli.commands.ArduinoCore.UpdateCoreLibrariesIndex:output_type -> cc.arduino.cli.commands.UpdateCoreLibrariesIndexResp + 13, // 61: cc.arduino.cli.commands.ArduinoCore.Outdated:output_type -> cc.arduino.cli.commands.OutdatedResp + 15, // 62: cc.arduino.cli.commands.ArduinoCore.Upgrade:output_type -> cc.arduino.cli.commands.UpgradeResp + 17, // 63: cc.arduino.cli.commands.ArduinoCore.Version:output_type -> cc.arduino.cli.commands.VersionResp + 19, // 64: cc.arduino.cli.commands.ArduinoCore.LoadSketch:output_type -> cc.arduino.cli.commands.LoadSketchResp + 21, // 65: cc.arduino.cli.commands.ArduinoCore.ArchiveSketch:output_type -> cc.arduino.cli.commands.ArchiveSketchResp + 53, // 66: cc.arduino.cli.commands.ArduinoCore.BoardDetails:output_type -> cc.arduino.cli.commands.BoardDetailsResp + 54, // 67: cc.arduino.cli.commands.ArduinoCore.BoardAttach:output_type -> cc.arduino.cli.commands.BoardAttachResp + 55, // 68: cc.arduino.cli.commands.ArduinoCore.BoardList:output_type -> cc.arduino.cli.commands.BoardListResp + 56, // 69: cc.arduino.cli.commands.ArduinoCore.BoardListAll:output_type -> cc.arduino.cli.commands.BoardListAllResp + 57, // 70: cc.arduino.cli.commands.ArduinoCore.BoardSearch:output_type -> cc.arduino.cli.commands.BoardSearchResp + 58, // 71: cc.arduino.cli.commands.ArduinoCore.BoardListWatch:output_type -> cc.arduino.cli.commands.BoardListWatchResp + 59, // 72: cc.arduino.cli.commands.ArduinoCore.Compile:output_type -> cc.arduino.cli.commands.CompileResp + 60, // 73: cc.arduino.cli.commands.ArduinoCore.PlatformInstall:output_type -> cc.arduino.cli.commands.PlatformInstallResp + 61, // 74: cc.arduino.cli.commands.ArduinoCore.PlatformDownload:output_type -> cc.arduino.cli.commands.PlatformDownloadResp + 62, // 75: cc.arduino.cli.commands.ArduinoCore.PlatformUninstall:output_type -> cc.arduino.cli.commands.PlatformUninstallResp + 63, // 76: cc.arduino.cli.commands.ArduinoCore.PlatformUpgrade:output_type -> cc.arduino.cli.commands.PlatformUpgradeResp + 64, // 77: cc.arduino.cli.commands.ArduinoCore.Upload:output_type -> cc.arduino.cli.commands.UploadResp + 65, // 78: cc.arduino.cli.commands.ArduinoCore.UploadUsingProgrammer:output_type -> cc.arduino.cli.commands.UploadUsingProgrammerResp + 66, // 79: cc.arduino.cli.commands.ArduinoCore.ListProgrammersAvailableForUpload:output_type -> cc.arduino.cli.commands.ListProgrammersAvailableForUploadResp + 67, // 80: cc.arduino.cli.commands.ArduinoCore.BurnBootloader:output_type -> cc.arduino.cli.commands.BurnBootloaderResp + 68, // 81: cc.arduino.cli.commands.ArduinoCore.PlatformSearch:output_type -> cc.arduino.cli.commands.PlatformSearchResp + 69, // 82: cc.arduino.cli.commands.ArduinoCore.PlatformList:output_type -> cc.arduino.cli.commands.PlatformListResp + 70, // 83: cc.arduino.cli.commands.ArduinoCore.LibraryDownload:output_type -> cc.arduino.cli.commands.LibraryDownloadResp + 71, // 84: cc.arduino.cli.commands.ArduinoCore.LibraryInstall:output_type -> cc.arduino.cli.commands.LibraryInstallResp + 72, // 85: cc.arduino.cli.commands.ArduinoCore.ZipLibraryInstall:output_type -> cc.arduino.cli.commands.ZipLibraryInstallResp + 73, // 86: cc.arduino.cli.commands.ArduinoCore.GitLibraryInstall:output_type -> cc.arduino.cli.commands.GitLibraryInstallResp + 74, // 87: cc.arduino.cli.commands.ArduinoCore.LibraryUninstall:output_type -> cc.arduino.cli.commands.LibraryUninstallResp + 75, // 88: cc.arduino.cli.commands.ArduinoCore.LibraryUpgradeAll:output_type -> cc.arduino.cli.commands.LibraryUpgradeAllResp + 76, // 89: cc.arduino.cli.commands.ArduinoCore.LibraryResolveDependencies:output_type -> cc.arduino.cli.commands.LibraryResolveDependenciesResp + 77, // 90: cc.arduino.cli.commands.ArduinoCore.LibrarySearch:output_type -> cc.arduino.cli.commands.LibrarySearchResp + 78, // 91: cc.arduino.cli.commands.ArduinoCore.LibraryList:output_type -> cc.arduino.cli.commands.LibraryListResp + 55, // [55:92] is the sub-list for method output_type + 18, // [18:55] is the sub-list for method input_type 18, // [18:18] is the sub-list for extension type_name 18, // [18:18] is the sub-list for extension extendee 0, // [0:18] is the sub-list for field type_name @@ -2153,6 +2163,8 @@ type ArduinoCoreClient interface { BoardList(ctx context.Context, in *BoardListReq, opts ...grpc.CallOption) (*BoardListResp, error) // List all the boards provided by installed platforms. BoardListAll(ctx context.Context, in *BoardListAllReq, opts ...grpc.CallOption) (*BoardListAllResp, error) + // Search boards in installed and not installed Platforms. + BoardSearch(ctx context.Context, in *BoardSearchReq, opts ...grpc.CallOption) (*BoardSearchResp, error) // List boards connection and disconnected events. BoardListWatch(ctx context.Context, opts ...grpc.CallOption) (ArduinoCore_BoardListWatchClient, error) // Compile an Arduino sketch. @@ -2482,6 +2494,15 @@ func (c *arduinoCoreClient) BoardListAll(ctx context.Context, in *BoardListAllRe return out, nil } +func (c *arduinoCoreClient) BoardSearch(ctx context.Context, in *BoardSearchReq, opts ...grpc.CallOption) (*BoardSearchResp, error) { + out := new(BoardSearchResp) + err := c.cc.Invoke(ctx, "/cc.arduino.cli.commands.ArduinoCore/BoardSearch", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *arduinoCoreClient) BoardListWatch(ctx context.Context, opts ...grpc.CallOption) (ArduinoCore_BoardListWatchClient, error) { stream, err := c.cc.NewStream(ctx, &_ArduinoCore_serviceDesc.Streams[6], "/cc.arduino.cli.commands.ArduinoCore/BoardListWatch", opts...) if err != nil { @@ -3048,6 +3069,8 @@ type ArduinoCoreServer interface { BoardList(context.Context, *BoardListReq) (*BoardListResp, error) // List all the boards provided by installed platforms. BoardListAll(context.Context, *BoardListAllReq) (*BoardListAllResp, error) + // Search boards in installed and not installed Platforms. + BoardSearch(context.Context, *BoardSearchReq) (*BoardSearchResp, error) // List boards connection and disconnected events. BoardListWatch(ArduinoCore_BoardListWatchServer) error // Compile an Arduino sketch. @@ -3145,6 +3168,9 @@ func (*UnimplementedArduinoCoreServer) BoardList(context.Context, *BoardListReq) func (*UnimplementedArduinoCoreServer) BoardListAll(context.Context, *BoardListAllReq) (*BoardListAllResp, error) { return nil, status.Errorf(codes.Unimplemented, "method BoardListAll not implemented") } +func (*UnimplementedArduinoCoreServer) BoardSearch(context.Context, *BoardSearchReq) (*BoardSearchResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method BoardSearch not implemented") +} func (*UnimplementedArduinoCoreServer) BoardListWatch(ArduinoCore_BoardListWatchServer) error { return status.Errorf(codes.Unimplemented, "method BoardListWatch not implemented") } @@ -3501,6 +3527,24 @@ func _ArduinoCore_BoardListAll_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ArduinoCore_BoardSearch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BoardSearchReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArduinoCoreServer).BoardSearch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cc.arduino.cli.commands.ArduinoCore/BoardSearch", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArduinoCoreServer).BoardSearch(ctx, req.(*BoardSearchReq)) + } + return interceptor(ctx, in, info, handler) +} + func _ArduinoCore_BoardListWatch_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(ArduinoCoreServer).BoardListWatch(&arduinoCoreBoardListWatchServer{stream}) } @@ -3969,6 +4013,10 @@ var _ArduinoCore_serviceDesc = grpc.ServiceDesc{ MethodName: "BoardListAll", Handler: _ArduinoCore_BoardListAll_Handler, }, + { + MethodName: "BoardSearch", + Handler: _ArduinoCore_BoardSearch_Handler, + }, { MethodName: "ListProgrammersAvailableForUpload", Handler: _ArduinoCore_ListProgrammersAvailableForUpload_Handler, diff --git a/rpc/commands/commands.proto b/rpc/commands/commands.proto index 5851a8519e6..85b742ff1d1 100644 --- a/rpc/commands/commands.proto +++ b/rpc/commands/commands.proto @@ -80,6 +80,9 @@ service ArduinoCore { // List all the boards provided by installed platforms. rpc BoardListAll(BoardListAllReq) returns (BoardListAllResp); + // Search boards in installed and not installed Platforms. + rpc BoardSearch(BoardSearchReq) returns (BoardSearchResp); + // List boards connection and disconnected events. rpc BoardListWatch(stream BoardListWatchReq) returns (stream BoardListWatchResp); diff --git a/test/test_board.py b/test/test_board.py index 217064c83f4..526b5453214 100644 --- a/test/test_board.py +++ b/test/test_board.py @@ -587,3 +587,91 @@ def test_board_details_list_programmers_flag(run_command): assert "edbg Atmel EDBG" in lines assert "atmel_ice Atmel-ICE" in lines assert "sam_ice Atmel SAM-ICE" in lines + + +def test_board_search(run_command, data_dir): + assert run_command("update") + + res = run_command("board search --format json") + assert res.ok + data = json.loads(res.stdout) + # Verifies boards are returned + assert len(data) > 0 + # Verifies no board has FQBN set since no platform is installed + assert len([board["FQBN"] for board in data if "FQBN" in board]) == 0 + names = [board["name"] for board in data if "name" in board] + assert "Arduino Uno" in names + assert "Arduino Yún" in names + assert "Arduino Zero" in names + assert "Arduino Nano 33 BLE" in names + assert "Arduino Portenta H7" in names + + # Search in non installed boards + res = run_command("board search --format json nano 33") + assert res.ok + data = json.loads(res.stdout) + # Verifies boards are returned + assert len(data) > 0 + # Verifies no board has FQBN set since no platform is installed + assert len([board["FQBN"] for board in data if "FQBN" in board]) == 0 + names = [board["name"] for board in data if "name" in board] + assert "Arduino Nano 33 BLE" in names + assert "Arduino Nano 33 IoT" in names + + # Install a platform from index + assert run_command("core install arduino:avr@1.8.3") + + res = run_command("board search --format json") + assert res.ok + data = json.loads(res.stdout) + assert len(data) > 0 + # Verifies some FQBNs are now returned after installing a platform + assert len([board["FQBN"] for board in data if "FQBN" in board]) == 26 + installed_boards = {board["FQBN"]: board for board in data if "FQBN" in board} + assert "arduino:avr:uno" in installed_boards + assert "Arduino Uno" == installed_boards["arduino:avr:uno"]["name"] + assert "arduino:avr:yun" in installed_boards + assert "Arduino Yún" == installed_boards["arduino:avr:yun"]["name"] + + res = run_command("board search --format json arduino yun") + assert res.ok + data = json.loads(res.stdout) + assert len(data) > 0 + installed_boards = {board["FQBN"]: board for board in data if "FQBN" in board} + assert "arduino:avr:yun" in installed_boards + assert "Arduino Yún" == installed_boards["arduino:avr:yun"]["name"] + + # Manually installs a core in sketchbooks hardware folder + git_url = "https://github.com/arduino/ArduinoCore-samd.git" + repo_dir = Path(data_dir, "hardware", "arduino-beta-development", "samd") + assert Repo.clone_from(git_url, repo_dir, multi_options=["-b 1.8.11"]) + + res = run_command("board search --format json") + assert res.ok + data = json.loads(res.stdout) + assert len(data) > 0 + # Verifies some FQBNs are now returned after installing a platform + assert len([board["FQBN"] for board in data if "FQBN" in board]) == 43 + installed_boards = {board["FQBN"]: board for board in data if "FQBN" in board} + assert "arduino:avr:uno" in installed_boards + assert "Arduino Uno" == installed_boards["arduino:avr:uno"]["name"] + assert "arduino:avr:yun" in installed_boards + assert "Arduino Yún" == installed_boards["arduino:avr:yun"]["name"] + assert "arduino-beta-development:samd:mkrwifi1010" in installed_boards + assert "Arduino MKR WiFi 1010" == installed_boards["arduino-beta-development:samd:mkrwifi1010"]["name"] + assert "arduino-beta-development:samd:mkr1000" in installed_boards + assert "Arduino MKR1000" == installed_boards["arduino-beta-development:samd:mkr1000"]["name"] + assert "arduino-beta-development:samd:mkrzero" in installed_boards + assert "Arduino MKRZERO" == installed_boards["arduino-beta-development:samd:mkrzero"]["name"] + assert "arduino-beta-development:samd:nano_33_iot" in installed_boards + assert "Arduino NANO 33 IoT" == installed_boards["arduino-beta-development:samd:nano_33_iot"]["name"] + assert "arduino-beta-development:samd:arduino_zero_native" in installed_boards + + res = run_command("board search --format json mkr1000") + assert res.ok + data = json.loads(res.stdout) + assert len(data) > 0 + # Verifies some FQBNs are now returned after installing a platform + installed_boards = {board["FQBN"]: board for board in data if "FQBN" in board} + assert "arduino-beta-development:samd:mkr1000" in installed_boards + assert "Arduino MKR1000" == installed_boards["arduino-beta-development:samd:mkr1000"]["name"]