diff --git a/arduino/builder/builder.go b/arduino/builder/builder.go new file mode 100644 index 00000000000..02f264c383a --- /dev/null +++ b/arduino/builder/builder.go @@ -0,0 +1,42 @@ +// This file is part of arduino-cli. +// +// Copyright 2019 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 builder + +import ( + "crypto/md5" + "encoding/hex" + "os" + "path/filepath" + "strings" + + "github.com/pkg/errors" +) + +// GenBuildPath generates a suitable name for the build folder +func GenBuildPath(sketchPath string) string { + md5SumBytes := md5.Sum([]byte(sketchPath)) + md5Sum := strings.ToUpper(hex.EncodeToString(md5SumBytes[:])) + + return filepath.Join(os.TempDir(), "arduino-sketch-"+md5Sum) +} + +// EnsureBuildPathExists creates the build path if doesn't already exists. +func EnsureBuildPathExists(path string) error { + if err := os.MkdirAll(path, os.FileMode(0755)); err != nil { + return errors.Wrap(err, "unable to create build path") + } + return nil +} diff --git a/arduino/builder/builder_test.go b/arduino/builder/builder_test.go new file mode 100644 index 00000000000..2048f75876d --- /dev/null +++ b/arduino/builder/builder_test.go @@ -0,0 +1,55 @@ +// This file is part of arduino-cli. +// +// Copyright 2019 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 builder_test + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/arduino/arduino-cli/arduino/builder" + "github.com/stretchr/testify/assert" +) + +func tmpDirOrDie() string { + dir, err := ioutil.TempDir(os.TempDir(), "builder_test") + if err != nil { + panic(fmt.Sprintf("error creating tmp dir: %v", err)) + } + return dir +} + +func TestGenBuildPath(t *testing.T) { + want := filepath.Join(os.TempDir(), "arduino-sketch-ACBD18DB4CC2F85CEDEF654FCCC4A4D8") + assert.Equal(t, want, builder.GenBuildPath("foo")) +} + +func TestEnsureBuildPathExists(t *testing.T) { + tmp := tmpDirOrDie() + defer os.RemoveAll(tmp) + bp := filepath.Join(tmp, "build_path") + + assert.Nil(t, builder.EnsureBuildPathExists(bp)) + _, err := os.Stat(bp) + assert.Nil(t, err) + + // run again over an existing folder + assert.Nil(t, builder.EnsureBuildPathExists(bp)) + _, err = os.Stat(bp) + assert.Nil(t, err) +} diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go index 67b3ca27430..e83beba8ae2 100644 --- a/legacy/builder/builder.go +++ b/legacy/builder/builder.go @@ -35,12 +35,14 @@ import ( "strconv" "time" + bldr "github.com/arduino/arduino-cli/arduino/builder" "github.com/arduino/arduino-cli/legacy/builder/builder_utils" "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/i18n" "github.com/arduino/arduino-cli/legacy/builder/phases" "github.com/arduino/arduino-cli/legacy/builder/types" "github.com/arduino/arduino-cli/legacy/builder/utils" + "github.com/arduino/go-paths-helper" ) var MAIN_FILE_VALID_EXTENSIONS = map[string]bool{".ino": true, ".pde": true} @@ -54,10 +56,15 @@ const DEFAULT_SOFTWARE = "ARDUINO" type Builder struct{} func (s *Builder) Run(ctx *types.Context) error { - commands := []types.Command{ - &GenerateBuildPathIfMissing{}, - &EnsureBuildPathExists{}, + if ctx.BuildPath == nil { + ctx.BuildPath = paths.New(bldr.GenBuildPath(ctx.SketchLocation.String())) + } + + if err := bldr.EnsureBuildPathExists(ctx.BuildPath.String()); err != nil { + return err + } + commands := []types.Command{ &ContainerSetupHardwareToolsLibsSketchAndProps{}, &ContainerBuildOptions{}, @@ -141,10 +148,15 @@ func (s *PreprocessSketch) Run(ctx *types.Context) error { type Preprocess struct{} func (s *Preprocess) Run(ctx *types.Context) error { - commands := []types.Command{ - &GenerateBuildPathIfMissing{}, - &EnsureBuildPathExists{}, + if ctx.BuildPath == nil { + ctx.BuildPath = paths.New(bldr.GenBuildPath(ctx.SketchLocation.String())) + } + if err := bldr.EnsureBuildPathExists(ctx.BuildPath.String()); err != nil { + return err + } + + commands := []types.Command{ &ContainerSetupHardwareToolsLibsSketchAndProps{}, &ContainerBuildOptions{}, @@ -168,9 +180,11 @@ func (s *Preprocess) Run(ctx *types.Context) error { type ParseHardwareAndDumpBuildProperties struct{} func (s *ParseHardwareAndDumpBuildProperties) Run(ctx *types.Context) error { - commands := []types.Command{ - &GenerateBuildPathIfMissing{}, + if ctx.BuildPath == nil { + ctx.BuildPath = paths.New(bldr.GenBuildPath(ctx.SketchLocation.String())) + } + commands := []types.Command{ &ContainerSetupHardwareToolsLibsSketchAndProps{}, &DumpBuildProperties{}, diff --git a/legacy/builder/ensure_buildpath_exists.go b/legacy/builder/ensure_buildpath_exists.go deleted file mode 100644 index 4760c47e747..00000000000 --- a/legacy/builder/ensure_buildpath_exists.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Arduino Builder. - * - * Arduino Builder is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - */ - -package builder - -import ( - "github.com/arduino/arduino-cli/legacy/builder/i18n" - "github.com/arduino/arduino-cli/legacy/builder/types" -) - -type EnsureBuildPathExists struct{} - -func (s *EnsureBuildPathExists) Run(ctx *types.Context) error { - if err := ctx.BuildPath.MkdirAll(); err != nil { - return i18n.WrapError(err) - } - return nil -} diff --git a/legacy/builder/generate_buildpath_if_missing.go b/legacy/builder/generate_buildpath_if_missing.go deleted file mode 100644 index 5078814efd7..00000000000 --- a/legacy/builder/generate_buildpath_if_missing.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Arduino Builder. - * - * Arduino Builder is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - */ - -package builder - -import ( - "os" - "strings" - - "github.com/arduino/arduino-cli/legacy/builder/constants" - "github.com/arduino/arduino-cli/legacy/builder/types" - "github.com/arduino/arduino-cli/legacy/builder/utils" - paths "github.com/arduino/go-paths-helper" -) - -type GenerateBuildPathIfMissing struct{} - -func (s *GenerateBuildPathIfMissing) Run(ctx *types.Context) error { - if ctx.BuildPath != nil { - return nil - } - - md5sum := utils.MD5Sum([]byte(ctx.SketchLocation.String())) - - buildPath := paths.TempDir().Join("arduino-sketch-" + strings.ToUpper(md5sum)) - - if ctx.DebugLevel > 5 { - logger := ctx.GetLogger() - logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_SETTING_BUILD_PATH, buildPath) - } - - ctx.BuildPath = buildPath - - return nil -} diff --git a/legacy/builder/test/generate_buildpath_if_missing_test.go b/legacy/builder/test/generate_buildpath_if_missing_test.go deleted file mode 100644 index b995866400e..00000000000 --- a/legacy/builder/test/generate_buildpath_if_missing_test.go +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Arduino Builder. - * - * Arduino Builder is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - */ - -package test - -import ( - "os" - "path/filepath" - "testing" - - "github.com/arduino/arduino-cli/legacy/builder" - "github.com/arduino/arduino-cli/legacy/builder/types" - paths "github.com/arduino/go-paths-helper" - "github.com/stretchr/testify/require" -) - -func TestGenerateBuildPathIfMissing(t *testing.T) { - ctx := &types.Context{ - SketchLocation: paths.New("test"), - } - - command := builder.GenerateBuildPathIfMissing{} - err := command.Run(ctx) - NoError(t, err) - - require.Equal(t, filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6"), ctx.BuildPath.String()) - _, err = os.Stat(filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6")) - require.True(t, os.IsNotExist(err)) -} - -func TestGenerateBuildPathIfEmpty(t *testing.T) { - ctx := &types.Context{ - SketchLocation: paths.New("test"), - } - - createBuildPathIfMissing := builder.GenerateBuildPathIfMissing{} - err := createBuildPathIfMissing.Run(ctx) - NoError(t, err) - - require.Equal(t, filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6"), ctx.BuildPath.String()) - _, err = os.Stat(filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6")) - require.True(t, os.IsNotExist(err)) -} - -func TestDontGenerateBuildPathIfPresent(t *testing.T) { - ctx := &types.Context{} - ctx.BuildPath = paths.New("test") - - createBuildPathIfMissing := builder.GenerateBuildPathIfMissing{} - err := createBuildPathIfMissing.Run(ctx) - NoError(t, err) - - require.Equal(t, ctx.BuildPath.String(), "test") -} - -func TestGenerateBuildPathAndEnsureItExists(t *testing.T) { - ctx := &types.Context{ - SketchLocation: paths.New("test"), - } - - commands := []types.Command{ - &builder.GenerateBuildPathIfMissing{}, - &builder.EnsureBuildPathExists{}, - } - - for _, command := range commands { - err := command.Run(ctx) - NoError(t, err) - } - - defer os.RemoveAll(filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6")) - - require.Equal(t, filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6"), ctx.BuildPath.String()) - _, err := os.Stat(filepath.Join(os.TempDir(), "arduino-sketch-098F6BCD4621D373CADE4E832627B4F6")) - NoError(t, err) -}