Skip to content

Commit 6fb3d48

Browse files
committed
added dedicated package to sketch file wrapper
1 parent 8af70b5 commit 6fb3d48

File tree

6 files changed

+248
-0
lines changed

6 files changed

+248
-0
lines changed

Diff for: arduino/globals/globals.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to modify or
12+
// otherwise use the software for commercial activities involving the Arduino
13+
// software without disclosing the source code of your own applications. To purchase
14+
// a commercial license, send an email to [email protected].
15+
16+
package globals
17+
18+
var (
19+
empty struct{}
20+
21+
// MainFileValidExtensions lists valid extensions for a sketch file
22+
MainFileValidExtensions = map[string]struct{}{
23+
".ino": empty,
24+
".pde": empty,
25+
}
26+
27+
// AdditionalFileValidExtensions lists any file extension the builder considers as valid
28+
AdditionalFileValidExtensions = map[string]struct{}{
29+
".h": empty,
30+
".c": empty,
31+
".hpp": empty,
32+
".hh": empty,
33+
".cpp": empty,
34+
".s": empty,
35+
}
36+
37+
// SourceFilesValidExtensions lists valid extensions for source files (no headers)
38+
SourceFilesValidExtensions = map[string]struct{}{
39+
".c": empty,
40+
".cpp": empty,
41+
".s": empty,
42+
}
43+
)

Diff for: arduino/sketch/sketch.go

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to modify or
12+
// otherwise use the software for commercial activities involving the Arduino
13+
// software without disclosing the source code of your own applications. To purchase
14+
// a commercial license, send an email to [email protected].
15+
16+
package sketch
17+
18+
import (
19+
"io/ioutil"
20+
"path/filepath"
21+
"sort"
22+
"strings"
23+
24+
"github.com/arduino/arduino-cli/arduino/globals"
25+
"github.com/pkg/errors"
26+
)
27+
28+
// Item holds the source and the path for a single sketch file
29+
type Item struct {
30+
Path string
31+
Source []byte
32+
}
33+
34+
// NewItem reads the source code for a sketch item and returns an
35+
// Item instance
36+
func NewItem(itemPath string) (*Item, error) {
37+
// read the file
38+
source, err := ioutil.ReadFile(itemPath)
39+
if err != nil {
40+
return nil, errors.Wrap(err, "error reading source file")
41+
}
42+
43+
return &Item{itemPath, source}, nil
44+
}
45+
46+
// ItemByPath implements sort.Interface for []Item based on
47+
// lexicographic order of the path string.
48+
type ItemByPath []*Item
49+
50+
func (ibn ItemByPath) Len() int { return len(ibn) }
51+
func (ibn ItemByPath) Swap(i, j int) { ibn[i], ibn[j] = ibn[j], ibn[i] }
52+
func (ibn ItemByPath) Less(i, j int) bool { return ibn[i].Path < ibn[j].Path }
53+
54+
// Sketch holds all the files composing a sketch
55+
type Sketch struct {
56+
MainFile *Item
57+
OtherSketchFiles []*Item
58+
AdditionalFiles []*Item
59+
}
60+
61+
// New creates an Sketch instance by reading all the files composing a sketch and grouping them
62+
// by file type.
63+
func New(sketchFolderPath, mainFilePath, buildPath string, allFilesPaths []string) (*Sketch, error) {
64+
var mainFile *Item
65+
66+
// read all the sketch contents and create sketch Items
67+
pathToItem := make(map[string]*Item)
68+
for _, p := range allFilesPaths {
69+
// create an Item
70+
item, err := NewItem(p)
71+
if err != nil {
72+
return nil, errors.Wrap(err, "error creating the sketch")
73+
}
74+
75+
if p == mainFilePath {
76+
// store the main sketch file
77+
mainFile = item
78+
} else {
79+
// map the file path to sketch.Item
80+
pathToItem[p] = item
81+
}
82+
}
83+
84+
// organize the Items
85+
additionalFiles := []*Item{}
86+
otherSketchFiles := []*Item{}
87+
for p, item := range pathToItem {
88+
ext := strings.ToLower(filepath.Ext(p))
89+
if _, found := globals.MainFileValidExtensions[ext]; found {
90+
// item is a valid main file, see if it's stored at the
91+
// sketch root and ignore if it's not.
92+
if filepath.Dir(p) == sketchFolderPath {
93+
otherSketchFiles = append(otherSketchFiles, item)
94+
}
95+
} else if _, found := globals.AdditionalFileValidExtensions[ext]; found {
96+
// item is a valid sketch file, grab it only if the buildPath is empty
97+
// or the file is within the buildPath
98+
if buildPath == "" || !strings.Contains(filepath.Dir(p), buildPath) {
99+
additionalFiles = append(additionalFiles, item)
100+
}
101+
} else {
102+
return nil, errors.Errorf("unknown sketch file extension '%s'", ext)
103+
}
104+
}
105+
106+
sort.Sort(ItemByPath(additionalFiles))
107+
sort.Sort(ItemByPath(otherSketchFiles))
108+
109+
return &Sketch{
110+
MainFile: mainFile,
111+
OtherSketchFiles: otherSketchFiles,
112+
AdditionalFiles: additionalFiles,
113+
}, nil
114+
}

Diff for: arduino/sketch/sketch_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to modify or
12+
// otherwise use the software for commercial activities involving the Arduino
13+
// software without disclosing the source code of your own applications. To purchase
14+
// a commercial license, send an email to [email protected].
15+
16+
package sketch_test
17+
18+
import (
19+
"path/filepath"
20+
"sort"
21+
"testing"
22+
23+
"github.com/arduino/arduino-cli/arduino/sketch"
24+
"github.com/stretchr/testify/assert"
25+
)
26+
27+
func TestNewItem(t *testing.T) {
28+
sketchItem := filepath.Join("testdata", t.Name()+".ino")
29+
item, err := sketch.NewItem(sketchItem)
30+
assert.Nil(t, err)
31+
assert.Equal(t, sketchItem, item.Path)
32+
assert.Equal(t, []byte(`#include <testlib.h>`), item.Source)
33+
34+
item, err = sketch.NewItem("doesnt/exist")
35+
assert.Nil(t, item)
36+
assert.NotNil(t, err)
37+
}
38+
39+
func TestSort(t *testing.T) {
40+
items := []*sketch.Item{
41+
&sketch.Item{"foo", nil},
42+
&sketch.Item{"baz", nil},
43+
&sketch.Item{"bar", nil},
44+
}
45+
46+
sort.Sort(sketch.ItemByPath(items))
47+
48+
assert.Equal(t, "bar", items[0].Path)
49+
assert.Equal(t, "baz", items[1].Path)
50+
assert.Equal(t, "foo", items[2].Path)
51+
}
52+
53+
func TestNew(t *testing.T) {
54+
sketchFolderPath := filepath.Join("testdata", t.Name())
55+
mainFilePath := filepath.Join(sketchFolderPath, t.Name()+".ino")
56+
otherFile := filepath.Join(sketchFolderPath, "other.cpp")
57+
allFilesPaths := []string{
58+
mainFilePath,
59+
otherFile,
60+
}
61+
62+
sketch, err := sketch.New(sketchFolderPath, mainFilePath, "", allFilesPaths)
63+
assert.Nil(t, err)
64+
assert.Equal(t, mainFilePath, sketch.MainFile.Path)
65+
assert.Len(t, sketch.OtherSketchFiles, 0)
66+
assert.Len(t, sketch.AdditionalFiles, 1)
67+
}

Diff for: arduino/sketch/testdata/TestNew/TestNew.ino

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <testlib1.h>
2+
#include "subfolder/other.h"
3+
#include "src/subfolder/other.h"
4+
5+
MyClass myClass;
6+
7+
void setup() {
8+
myClass.init ( &Serial );
9+
}
10+
11+
void loop() {
12+
}

Diff for: arduino/sketch/testdata/TestNew/other.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <Arduino.h> // Arduino 1.0
2+
#include <testlib2.h>
3+
4+
#include "other.h"
5+
6+
MyClass::MyClass() {
7+
}
8+
9+
void MyClass::init ( Stream *stream ) {
10+
controllerStream = stream;
11+
}

Diff for: arduino/sketch/testdata/TestNewItem.ino

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include <testlib.h>

0 commit comments

Comments
 (0)