diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 5a21f50518c..8e58f480b0e 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -305,37 +305,35 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream return r, err } - var exportPath *paths.Path - if exportDir := req.GetExportDir(); exportDir != "" { - exportPath = paths.New(exportDir) - } else { + exportPath := paths.New(req.GetExportDir()) + if exportPath == nil { // Add FQBN (without configs part) to export path fqbnSuffix := strings.ReplaceAll(fqbn.StringWithoutConfig(), ":", ".") exportPath = sk.FullPath.Join("build", fqbnSuffix) } - logrus.WithField("path", exportPath).Trace("Saving sketch to export path.") - if err := exportPath.MkdirAll(); err != nil { - return r, &arduino.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err} - } // Copy all "sketch.ino.*" artifacts to the export directory - baseName, ok := sketchBuilder.GetBuildProperties().GetOk("build.project_name") // == "sketch.ino" - if !ok { - return r, &arduino.MissingPlatformPropertyError{Property: "build.project_name"} - } - buildFiles, err := sketchBuilder.GetBuildPath().ReadDir() - if err != nil { - return r, &arduino.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err} - } - buildFiles.FilterPrefix(baseName) - for _, buildFile := range buildFiles { - exportedFile := exportPath.Join(buildFile.Base()) - logrus. - WithField("src", buildFile). - WithField("dest", exportedFile). - Trace("Copying artifact.") - if err = buildFile.CopyTo(exportedFile); err != nil { - return r, &arduino.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err} + if !buildPath.EqualsTo(exportPath) { + logrus.WithField("path", exportPath).Trace("Saving sketch to export path.") + if err := exportPath.MkdirAll(); err != nil { + return r, &arduino.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err} + } + + baseName, ok := sketchBuilder.GetBuildProperties().GetOk("build.project_name") // == "sketch.ino" + if !ok { + return r, &arduino.MissingPlatformPropertyError{Property: "build.project_name"} + } + buildFiles, err := sketchBuilder.GetBuildPath().ReadDir() + if err != nil { + return r, &arduino.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err} + } + buildFiles.FilterPrefix(baseName) + for _, buildFile := range buildFiles { + exportedFile := exportPath.Join(buildFile.Base()) + logrus.WithField("src", buildFile).WithField("dest", exportedFile).Trace("Copying artifact.") + if err = buildFile.CopyTo(exportedFile); err != nil { + return r, &arduino.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err} + } } } diff --git a/internal/integrationtest/compile_1/compile_test.go b/internal/integrationtest/compile_1/compile_test.go index 2815afaabe6..b334e392cd3 100644 --- a/internal/integrationtest/compile_1/compile_test.go +++ b/internal/integrationtest/compile_1/compile_test.go @@ -73,6 +73,7 @@ func TestCompile(t *testing.T) { {"WithFakeSecureBootCore", compileWithFakeSecureBootCore}, {"PreprocessFlagDoNotMessUpWithOutput", preprocessFlagDoNotMessUpWithOutput}, {"WithCustomBuildPath", buildWithCustomBuildPath}, + {"WithCustomBuildPathAndOUtputDirFlag", buildWithCustomBuildPathAndOUtputDirFlag}, }.Run(t, env, cli) } @@ -1227,3 +1228,34 @@ func buildWithCustomBuildPath(t *testing.T, env *integrationtest.Environment, cl require.Error(t, err) }) } + +func buildWithCustomBuildPathAndOUtputDirFlag(t *testing.T, env *integrationtest.Environment, cli *integrationtest.ArduinoCLI) { + fqbn := "arduino:avr:uno" + sketchName := "bare_minimum" + sketchPath := cli.SketchbookDir().Join(sketchName) + defer sketchPath.RemoveAll() + + // Create a test sketch + _, _, err := cli.Run("sketch", "new", sketchPath.String()) + require.NoError(t, err) + + buildPath := cli.DataDir().Join("test_dir", "build_dir") + outputDirPath := buildPath + _, _, err = cli.Run("compile", "-b", fqbn, sketchPath.String(), "--build-path", buildPath.String(), "--output-dir", outputDirPath.String()) + require.NoError(t, err) + + // Verifies that output binaries are not empty. + require.DirExists(t, buildPath.String()) + files := []*paths.Path{ + buildPath.Join(sketchName + ".ino.eep"), + buildPath.Join(sketchName + ".ino.elf"), + buildPath.Join(sketchName + ".ino.hex"), + buildPath.Join(sketchName + ".ino.with_bootloader.bin"), + buildPath.Join(sketchName + ".ino.with_bootloader.hex"), + } + for _, file := range files { + content, err := file.ReadFile() + require.NoError(t, err) + require.NotEmpty(t, content) + } +}