Skip to content

Commit 105176e

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

File tree

14 files changed

+271
-7
lines changed

14 files changed

+271
-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: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"testing"
2222

2323
"github.com/arduino/arduino-cli/arduino/sketch"
24+
"github.com/arduino/go-paths-helper"
2425
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
2527
)
2628

2729
func TestNewItem(t *testing.T) {
@@ -43,9 +45,9 @@ func TestNewItem(t *testing.T) {
4345

4446
func TestSort(t *testing.T) {
4547
items := []*sketch.Item{
46-
&sketch.Item{"foo"},
47-
&sketch.Item{"baz"},
48-
&sketch.Item{"bar"},
48+
{"foo"},
49+
{"baz"},
50+
{"bar"},
4951
}
5052

5153
sort.Sort(sketch.ItemByPath(items))
@@ -71,3 +73,35 @@ func TestNew(t *testing.T) {
7173
assert.Len(t, sketch.OtherSketchFiles, 0)
7274
assert.Len(t, sketch.AdditionalFiles, 1)
7375
}
76+
77+
func TestNewSketchCasingWrong(t *testing.T) {
78+
sketchPath := paths.New("testdata", "SketchCasingWrong").String()
79+
mainFilePath := paths.New("testadata", "sketchcasingwrong.ino").String()
80+
sketch, err := sketch.New(sketchPath, mainFilePath, "", []string{mainFilePath})
81+
assert.Nil(t, sketch)
82+
assert.EqualError(t, err, "no valid sketch found in testdata/SketchCasingWrong: missing testdata/SketchCasingWrong/SketchCasingWrong.ino")
83+
}
84+
85+
func TestNewSketchCasingCorrect(t *testing.T) {
86+
sketchPath := paths.New("testdata", "SketchCasingCorrect").String()
87+
mainFilePath := paths.New("testadata", "SketchCasingCorrect.ino").String()
88+
sketch, err := sketch.New(sketchPath, mainFilePath, "", []string{mainFilePath})
89+
assert.NotNil(t, sketch)
90+
assert.NoError(t, err)
91+
assert.Equal(t, sketchPath, sketch.LocationPath)
92+
assert.Equal(t, mainFilePath, sketch.MainFile.Path)
93+
assert.Len(t, sketch.OtherSketchFiles, 0)
94+
assert.Len(t, sketch.AdditionalFiles, 0)
95+
}
96+
97+
func TestCheckSketchCasingWrong(t *testing.T) {
98+
sketchFolder := paths.New("testdata", "SketchCasingWrong").String()
99+
err := sketch.CheckSketchCasing(sketchFolder)
100+
assert.EqualError(t, err, "no valid sketch found in testdata/SketchCasingWrong: missing testdata/SketchCasingWrong/SketchCasingWrong.ino")
101+
}
102+
103+
func TestCheckSketchCasingCorrect(t *testing.T) {
104+
sketchFolder := paths.New("testdata", "SketchCasingCorrect").String()
105+
err := sketch.CheckSketchCasing(sketchFolder)
106+
require.NoError(t, err)
107+
}
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)