Skip to content

Commit 5b3b4f1

Browse files
committed
Fix loading of sketches with folder and main file mismatched casing
1 parent a9b0c9d commit 5b3b4f1

File tree

14 files changed

+274
-7
lines changed

14 files changed

+274
-7
lines changed

arduino/builder/sketch_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,17 @@ func TestCopyAdditionalFiles(t *testing.T) {
230230
info2, err := os.Stat(s2.AdditionalFiles[0].Path)
231231
require.Equal(t, info1.ModTime(), info2.ModTime())
232232
}
233+
234+
func TestLoadSketchCaseMismatch(t *testing.T) {
235+
// pass the path to the sketch folder
236+
sketchPath := filepath.Join("testdata", t.Name())
237+
mainFilePath := filepath.Join(sketchPath, t.Name()+".ino")
238+
s, err := builder.SketchLoad(sketchPath, "")
239+
require.Nil(t, s)
240+
require.Error(t, err)
241+
242+
// pass the path to the main file
243+
s, err = builder.SketchLoad(mainFilePath, "")
244+
require.Nil(t, s)
245+
require.Error(t, err)
246+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void setup() {
2+
3+
}
4+
5+
void loop() {
6+
7+
}

arduino/sketch/sketch.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323

2424
"github.com/arduino/arduino-cli/arduino/globals"
25+
"github.com/arduino/go-paths-helper"
2526
"github.com/pkg/errors"
2627
)
2728

@@ -116,10 +117,43 @@ func New(sketchFolderPath, mainFilePath, buildPath string, allFilesPaths []strin
116117
sort.Sort(ItemByPath(additionalFiles))
117118
sort.Sort(ItemByPath(otherSketchFiles))
118119

120+
if err := CheckSketchCasing(sketchFolderPath); err != nil {
121+
return nil, err
122+
}
123+
119124
return &Sketch{
120125
MainFile: mainFile,
121126
LocationPath: sketchFolderPath,
122127
OtherSketchFiles: otherSketchFiles,
123128
AdditionalFiles: additionalFiles,
124129
}, nil
125130
}
131+
132+
// CheckSketchCasing returns an error if the casing of the sketch folder and the main file are different.
133+
// Correct:
134+
// MySketch/MySketch.ino
135+
// Wrong:
136+
// MySketch/mysketch.ino
137+
// mysketch/MySketch.ino
138+
//
139+
// This is mostly necessary to avoid errors on Mac OS X.
140+
// For more info see: https://github.com/arduino/arduino-cli/issues/1174
141+
func CheckSketchCasing(sketchFolder string) error {
142+
sketchPath := paths.New(sketchFolder)
143+
files, err := sketchPath.ReadDir()
144+
if err != nil {
145+
return errors.Errorf("reading files: %v", err)
146+
}
147+
files.FilterOutDirs()
148+
149+
sketchName := sketchPath.Base()
150+
files.FilterPrefix(sketchName)
151+
152+
if files.Len() == 0 {
153+
sketchFolderPath := paths.New(sketchFolder)
154+
sketchFile := sketchFolderPath.Join(sketchFolderPath.Base() + globals.MainFileValidExtension)
155+
return errors.Errorf("no valid sketch found in %s: missing %s", sketchFolderPath, sketchFile)
156+
}
157+
158+
return nil
159+
}

arduino/sketch/sketch_test.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616
package sketch_test
1717

1818
import (
19+
"fmt"
1920
"path/filepath"
2021
"sort"
2122
"testing"
2223

2324
"github.com/arduino/arduino-cli/arduino/sketch"
25+
"github.com/arduino/go-paths-helper"
2426
"github.com/stretchr/testify/assert"
27+
"github.com/stretchr/testify/require"
2528
)
2629

2730
func TestNewItem(t *testing.T) {
@@ -43,9 +46,9 @@ func TestNewItem(t *testing.T) {
4346

4447
func TestSort(t *testing.T) {
4548
items := []*sketch.Item{
46-
&sketch.Item{"foo"},
47-
&sketch.Item{"baz"},
48-
&sketch.Item{"bar"},
49+
{"foo"},
50+
{"baz"},
51+
{"bar"},
4952
}
5053

5154
sort.Sort(sketch.ItemByPath(items))
@@ -71,3 +74,37 @@ func TestNew(t *testing.T) {
7174
assert.Len(t, sketch.OtherSketchFiles, 0)
7275
assert.Len(t, sketch.AdditionalFiles, 1)
7376
}
77+
78+
func TestNewSketchCasingWrong(t *testing.T) {
79+
sketchPath := paths.New("testdata", "SketchCasingWrong")
80+
mainFilePath := paths.New("testadata", "sketchcasingwrong.ino").String()
81+
sketch, err := sketch.New(sketchPath.String(), mainFilePath, "", []string{mainFilePath})
82+
assert.Nil(t, sketch)
83+
expectedError := fmt.Sprintf("no valid sketch found in %s: missing %s", sketchPath.String(), sketchPath.Join(sketchPath.Base()+".ino"))
84+
assert.EqualError(t, err, expectedError)
85+
}
86+
87+
func TestNewSketchCasingCorrect(t *testing.T) {
88+
sketchPath := paths.New("testdata", "SketchCasingCorrect").String()
89+
mainFilePath := paths.New("testadata", "SketchCasingCorrect.ino").String()
90+
sketch, err := sketch.New(sketchPath, mainFilePath, "", []string{mainFilePath})
91+
assert.NotNil(t, sketch)
92+
assert.NoError(t, err)
93+
assert.Equal(t, sketchPath, sketch.LocationPath)
94+
assert.Equal(t, mainFilePath, sketch.MainFile.Path)
95+
assert.Len(t, sketch.OtherSketchFiles, 0)
96+
assert.Len(t, sketch.AdditionalFiles, 0)
97+
}
98+
99+
func TestCheckSketchCasingWrong(t *testing.T) {
100+
sketchFolder := paths.New("testdata", "SketchCasingWrong")
101+
err := sketch.CheckSketchCasing(sketchFolder.String())
102+
expectedError := fmt.Sprintf("no valid sketch found in %s: missing %s", sketchFolder, sketchFolder.Join(sketchFolder.Base()+".ino"))
103+
assert.EqualError(t, err, expectedError)
104+
}
105+
106+
func TestCheckSketchCasingCorrect(t *testing.T) {
107+
sketchFolder := paths.New("testdata", "SketchCasingCorrect").String()
108+
err := sketch.CheckSketchCasing(sketchFolder)
109+
require.NoError(t, err)
110+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void setup() {
2+
3+
}
4+
5+
void loop() {
6+
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void setup() {
2+
3+
}
4+
5+
void loop() {
6+
7+
}

arduino/sketches/sketches.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/arduino/arduino-cli/arduino/builder"
2323
"github.com/arduino/arduino-cli/arduino/globals"
24+
"github.com/arduino/arduino-cli/arduino/sketch"
2425
"github.com/arduino/go-paths-helper"
2526
"github.com/pkg/errors"
2627
)
@@ -70,19 +71,19 @@ func NewSketchFromPath(path *paths.Path) (*Sketch, error) {
7071
}
7172
}
7273

73-
if mainSketchFile == nil {
74+
if mainSketchFile == nil || sketch.CheckSketchCasing(path.String()) != nil {
7475
sketchFile := path.Join(path.Base() + globals.MainFileValidExtension)
7576
return nil, errors.Errorf("no valid sketch found in %s: missing %s", path, sketchFile)
7677
}
7778

78-
sketch := &Sketch{
79+
s := &Sketch{
7980
FullPath: path,
8081
MainFileExtension: mainSketchFile.Ext(),
8182
Name: path.Base(),
8283
Metadata: &Metadata{},
8384
}
84-
sketch.ImportMetadata()
85-
return sketch, nil
85+
s.ImportMetadata()
86+
return s, nil
8687
}
8788

8889
// ImportMetadata imports metadata into the sketch from a sketch.json file in the root

arduino/sketches/sketches_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,24 @@ func TestCheckForPdeFiles(t *testing.T) {
109109
require.Len(t, files, 1)
110110
require.Equal(t, sketchPath.Parent().Join("SketchMultipleMainFiles.pde"), files[0])
111111
}
112+
113+
func TestSketchLoadWithCasing(t *testing.T) {
114+
sketchFolder := paths.New("testdata", "SketchCasingWrong")
115+
116+
sketch, err := NewSketchFromPath(sketchFolder)
117+
require.Nil(t, sketch)
118+
119+
sketchFolderAbs, _ := sketchFolder.Abs()
120+
sketchMainFileAbs := sketchFolderAbs.Join("SketchCasingWrong.ino")
121+
expectedError := fmt.Sprintf("no valid sketch found in %s: missing %s", sketchFolderAbs, sketchMainFileAbs)
122+
require.EqualError(t, err, expectedError)
123+
}
124+
125+
func TestSketchLoadingCorrectCasing(t *testing.T) {
126+
sketchFolder := paths.New("testdata", "SketchCasingCorrect")
127+
sketch, err := NewSketchFromPath(sketchFolder)
128+
require.NotNil(t, sketch)
129+
require.NoError(t, err)
130+
require.Equal(t, sketch.Name, "SketchCasingCorrect")
131+
require.True(t, sketch.FullPath.EquivalentTo(sketchFolder))
132+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void setup() {
2+
3+
}
4+
5+
void loop() {
6+
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void setup() {
2+
3+
}
4+
5+
void loop() {
6+
7+
}

0 commit comments

Comments
 (0)