Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add board search command and gRPC interface function #1210

Merged
merged 3 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions arduino/utils/search.go
Original file line number Diff line number Diff line change
@@ -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 [email protected].

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
}
1 change: 1 addition & 0 deletions cli/board/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func NewCommand() *cobra.Command {
boardCommand.AddCommand(initDetailsCommand())
boardCommand.AddCommand(initListCommand())
boardCommand.AddCommand(initListAllCommand())
boardCommand.AddCommand(initSearchCommand())

return boardCommand
}
99 changes: 99 additions & 0 deletions cli/board/search.go
Original file line number Diff line number Diff line change
@@ -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 [email protected].

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()
}
Loading