Skip to content

Some small refactoring on legacy package #1064

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

Merged
merged 9 commits into from
Nov 12, 2020
3 changes: 1 addition & 2 deletions legacy/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package builder

import (
"fmt"
"os"
"reflect"
"strconv"
Expand Down Expand Up @@ -159,7 +158,7 @@ func (s *Preprocess) Run(ctx *types.Context) error {
}

// Output arduino-preprocessed source
fmt.Println(ctx.Source)
ctx.ExecStdout.Write([]byte(ctx.Source))
return nil
}

Expand Down
19 changes: 15 additions & 4 deletions legacy/builder/builder_utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,30 @@ func PrepareCommandForRecipe(ctx *types.Context, buildProperties *properties.Map
return nil, i18n.ErrorfWithLogger(logger, constants.MSG_PATTERN_MISSING, recipe)
}

var err error
commandLine := buildProperties.ExpandPropsInString(pattern)
if removeUnsetProperties {
commandLine = properties.DeleteUnexpandedPropsFromString(commandLine)
}

relativePath := ""
command, err := utils.PrepareCommand(commandLine)

// if the overall commandline is too long for the platform
// try reducing the length by making the filenames relative
// and changing working directory to build.path
if len(commandLine) > COMMANDLINE_LIMIT {
relativePath = buildProperties.Get("build.path")
relativePath := buildProperties.Get("build.path")
for i, arg := range command.Args {
if _, err := os.Stat(arg); os.IsNotExist(err) {
continue
}
rel, err := filepath.Rel(relativePath, arg)
if err == nil && !strings.Contains(rel, "..") && len(rel) < len(arg) {
command.Args[i] = rel
}
}
command.Dir = relativePath
}

command, err := utils.PrepareCommand(commandLine, logger, relativePath)
if err != nil {
return nil, errors.WithStack(err)
}
Expand Down
1 change: 0 additions & 1 deletion legacy/builder/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ const MSG_BUILD_OPTIONS_CHANGED = "Build options changed, rebuilding all"
const MSG_CANT_FIND_SKETCH_IN_PATH = "Unable to find {0} in {1}"
const MSG_FQBN_INVALID = "{0} is not a valid fully qualified board name. Required format is targetPackageName:targetPlatformName:targetBoardName."
const MSG_FIND_INCLUDES_FAILED = "Error while detecting libraries included by {0}"
const MSG_INVALID_QUOTING = "Invalid quoting: no closing [{0}] char found."
const MSG_LIB_LEGACY = "(legacy)"
const MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR = "Multiple libraries were found for \"{0}\""
const MSG_LIBRARIES_NOT_USED = " Not used: {0}"
Expand Down
2 changes: 1 addition & 1 deletion legacy/builder/ctags_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (s *CTagsRunner) Run(ctx *types.Context) error {
}

commandLine := properties.ExpandPropsInString(pattern)
command, err := utils.PrepareCommand(commandLine, logger, "")
command, err := utils.PrepareCommand(commandLine)
if err != nil {
return errors.WithStack(err)
}
Expand Down
2 changes: 1 addition & 1 deletion legacy/builder/preprocess_sketch.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (s *ArduinoPreprocessorRunner) Run(ctx *types.Context) error {
}

commandLine := properties.ExpandPropsInString(pattern)
command, err := utils.PrepareCommand(commandLine, logger, "")
command, err := utils.PrepareCommand(commandLine)
if err != nil {
return errors.WithStack(err)
}
Expand Down
46 changes: 3 additions & 43 deletions legacy/builder/test/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,12 @@
package test

import (
"github.com/arduino/arduino-cli/legacy/builder/i18n"
"github.com/arduino/arduino-cli/legacy/builder/utils"
"github.com/stretchr/testify/require"
"strings"
"testing"
)

func TestCommandLineParser(t *testing.T) {
command := "\"/home/federico/materiale/works_Arduino/Arduino/build/hardware/tools/coan\" source -m -E -P -kb -c -g -Os -w -ffunction-sections -fdata-sections -MMD -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=010600 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 '-DUSB_MANUFACTURER=' '-DUSB_PRODUCT=\"Arduino Leonardo\"' \"/tmp/sketch321469072.cpp\""

parts, err := utils.ParseCommandLine(command, i18n.HumanLogger{})
NoError(t, err)

require.Equal(t, 23, len(parts))

require.Equal(t, "/home/federico/materiale/works_Arduino/Arduino/build/hardware/tools/coan", parts[0])
require.Equal(t, "source", parts[1])
require.Equal(t, "-m", parts[2])
require.Equal(t, "-E", parts[3])
require.Equal(t, "-P", parts[4])
require.Equal(t, "-kb", parts[5])
require.Equal(t, "-c", parts[6])
require.Equal(t, "-g", parts[7])
require.Equal(t, "-Os", parts[8])
require.Equal(t, "-w", parts[9])
require.Equal(t, "-ffunction-sections", parts[10])
require.Equal(t, "-fdata-sections", parts[11])
require.Equal(t, "-MMD", parts[12])
require.Equal(t, "-mmcu=atmega32u4", parts[13])
require.Equal(t, "-DF_CPU=16000000L", parts[14])
require.Equal(t, "-DARDUINO=010600", parts[15])
require.Equal(t, "-DARDUINO_AVR_LEONARDO", parts[16])
require.Equal(t, "-DARDUINO_ARCH_AVR", parts[17])
require.Equal(t, "-DUSB_VID=0x2341", parts[18])
require.Equal(t, "-DUSB_PID=0x8036", parts[19])
require.Equal(t, "-DUSB_MANUFACTURER=", parts[20])
require.Equal(t, "-DUSB_PRODUCT=\"Arduino Leonardo\"", parts[21])
require.Equal(t, "/tmp/sketch321469072.cpp", parts[22])
}
"github.com/arduino/arduino-cli/legacy/builder/utils"
"github.com/stretchr/testify/require"
)

func TestPrintableCommand(t *testing.T) {
parts := []string{
Expand All @@ -75,13 +42,6 @@ func TestPrintableCommand(t *testing.T) {
require.Equal(t, correct, result)
}

func TestCommandLineParserError(t *testing.T) {
command := "\"command missing quote"

_, err := utils.ParseCommandLine(command, i18n.HumanLogger{})
require.Error(t, err)
}

func TestMapTrimSpace(t *testing.T) {
value := "hello, world , how are,you? "
parts := utils.Map(strings.Split(value, ","), utils.TrimSpace)
Expand Down
86 changes: 4 additions & 82 deletions legacy/builder/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,57 +29,15 @@ import (
"unicode"
"unicode/utf8"

"github.com/arduino/arduino-cli/legacy/builder/constants"
"github.com/arduino/arduino-cli/legacy/builder/gohasissues"
"github.com/arduino/arduino-cli/legacy/builder/i18n"
"github.com/arduino/arduino-cli/legacy/builder/types"
paths "github.com/arduino/go-paths-helper"
"github.com/arduino/go-properties-orderedmap"
"github.com/pkg/errors"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
)

func ParseCommandLine(input string, logger i18n.Logger) ([]string, error) {
var parts []string
escapingChar := constants.EMPTY_STRING
escapedArg := constants.EMPTY_STRING
for _, inputPart := range strings.Split(input, constants.SPACE) {
inputPart = strings.TrimSpace(inputPart)
if len(inputPart) == 0 {
continue
}

if escapingChar == constants.EMPTY_STRING {
if inputPart[0] != '"' && inputPart[0] != '\'' {
parts = append(parts, inputPart)
continue
}

escapingChar = string(inputPart[0])
inputPart = inputPart[1:]
escapedArg = constants.EMPTY_STRING
}

if inputPart[len(inputPart)-1] != '"' && inputPart[len(inputPart)-1] != '\'' {
escapedArg = escapedArg + inputPart + " "
continue
}

escapedArg = escapedArg + inputPart[:len(inputPart)-1]
escapedArg = strings.TrimSpace(escapedArg)
if len(escapedArg) > 0 {
parts = append(parts, escapedArg)
}
escapingChar = constants.EMPTY_STRING
}

if escapingChar != constants.EMPTY_STRING {
return nil, i18n.ErrorfWithLogger(logger, constants.MSG_INVALID_QUOTING, escapingChar)
}

return parts, nil
}

type filterFiles func([]os.FileInfo) []os.FileInfo

func ReadDirFiltered(folder string, fn filterFiles) ([]os.FileInfo, error) {
Expand Down Expand Up @@ -189,48 +147,12 @@ func TrimSpace(value string) string {
return strings.TrimSpace(value)
}

type argFilterFunc func(int, string, []string) bool

func PrepareCommandFilteredArgs(pattern string, filter argFilterFunc, logger i18n.Logger, relativePath string) (*exec.Cmd, error) {
parts, err := ParseCommandLine(pattern, logger)
func PrepareCommand(pattern string) (*exec.Cmd, error) {
parts, err := properties.SplitQuotedString(pattern, `"'`, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this change the behaviour of the compile command --build-property and --build-properties flags?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it should work exactly the same. This is code duplication that has never been removed.
(BTW a quick test would not be bad :-))

if err != nil {
return nil, errors.WithStack(err)
}
command := parts[0]
parts = parts[1:]
var args []string
for idx, part := range parts {
if filter(idx, part, parts) {
// if relativePath is specified, the overall commandline is too long for the platform
// try reducing the length by making the filenames relative
// and changing working directory to build.path
if relativePath != "" {
if _, err := os.Stat(part); !os.IsNotExist(err) {
tmp, err := filepath.Rel(relativePath, part)
if err == nil && !strings.Contains(tmp, "..") && len(tmp) < len(part) {
part = tmp
}
}
}
args = append(args, part)
}
}

cmd := exec.Command(command, args...)

if relativePath != "" {
cmd.Dir = relativePath
}

return cmd, nil
}

func filterEmptyArg(_ int, arg string, _ []string) bool {
return arg != constants.EMPTY_STRING
}

func PrepareCommand(pattern string, logger i18n.Logger, relativePath string) (*exec.Cmd, error) {
return PrepareCommandFilteredArgs(pattern, filterEmptyArg, logger, relativePath)
return exec.Command(parts[0], parts[1:]...), nil
}

func printableArgument(arg string) string {
Expand Down