@@ -19,22 +19,104 @@ import (
1919 "io/ioutil"
2020 "os"
2121 "path/filepath"
22+ "strings"
23+
24+ "github.com/arduino/arduino-cli/arduino/globals"
25+ "github.com/arduino/arduino-cli/arduino/sketch"
2226
2327 "github.com/pkg/errors"
2428)
2529
26- // SaveSketch saves a preprocessed .cpp sketch file on disk
27- func SaveSketch (sketchName string , source string , buildPath string ) error {
30+ // SaveSketchItemCpp saves a preprocessed .cpp sketch file on disk
31+ func SaveSketchItemCpp (item * sketch.Item , buildPath string ) error {
32+
33+ sketchName := filepath .Base (item .Path )
2834
2935 if err := os .MkdirAll (buildPath , os .FileMode (0755 )); err != nil {
3036 return errors .Wrap (err , "unable to create a folder to save the sketch" )
3137 }
3238
3339 destFile := filepath .Join (buildPath , sketchName + ".cpp" )
3440
35- if err := ioutil .WriteFile (destFile , [] byte ( source ) , os .FileMode (0644 )); err != nil {
41+ if err := ioutil .WriteFile (destFile , item . Source , os .FileMode (0644 )); err != nil {
3642 return errors .Wrap (err , "unable to save the sketch on disk" )
3743 }
3844
3945 return nil
4046}
47+
48+ // LoadSketch collects all the files composing a sketch.
49+ // The parameter `sketchPath` holds a path pointing to a single sketch file or a sketch folder,
50+ // the path must be absolute.
51+ func LoadSketch (sketchPath , buildPath string ) (* sketch.Sketch , error ) {
52+ stat , err := os .Stat (sketchPath )
53+ if err != nil {
54+ return nil , errors .Wrap (err , "unable to stat Sketch location" )
55+ }
56+
57+ var sketchFolder , mainSketchFile string
58+
59+ // if a sketch folder was passed, save the parent and point sketchPath to the main .ino file
60+ if stat .IsDir () {
61+ sketchFolder = sketchPath
62+ mainSketchFile = filepath .Join (sketchPath , stat .Name ()+ ".ino" )
63+ // in the case a dir was passed, ensure the main file exists and is readable
64+ f , err := os .Open (mainSketchFile )
65+ if err != nil {
66+ return nil , errors .Wrap (err , "unable to find the main sketch file" )
67+ }
68+ f .Close ()
69+ } else {
70+ sketchFolder = filepath .Dir (sketchPath )
71+ mainSketchFile = sketchPath
72+ }
73+
74+ // collect all the sketch files
75+ var files []string
76+ err = filepath .Walk (sketchFolder , func (path string , info os.FileInfo , err error ) error {
77+ // ignore hidden files and skip hidden directories
78+ if strings .HasPrefix (info .Name (), "." ) {
79+ if info .IsDir () {
80+ return filepath .SkipDir
81+ }
82+ return nil
83+ }
84+
85+ // skip legacy SCM directories
86+ if info .IsDir () && strings .HasPrefix (info .Name (), "CVS" ) || strings .HasPrefix (info .Name (), "RCS" ) {
87+ return filepath .SkipDir
88+ }
89+
90+ // ignore directory entries
91+ if info .IsDir () {
92+ return nil
93+ }
94+
95+ // ignore if file extension doesn't match
96+ ext := strings .ToLower (filepath .Ext (path ))
97+ _ , isMain := globals .MainFileValidExtensions [ext ]
98+ _ , isAdditional := globals .AdditionalFileValidExtensions [ext ]
99+ if ! (isMain || isAdditional ) {
100+ return nil
101+ }
102+
103+ // check if file is readable
104+ f , err := os .Open (path )
105+ if err != nil {
106+ return nil
107+ }
108+ f .Close ()
109+
110+ // collect the file
111+ files = append (files , path )
112+
113+ // done
114+ return nil
115+ })
116+
117+ if err != nil {
118+ return nil , errors .Wrap (err , "there was an error while collecting the sketch files" )
119+ }
120+
121+ return sketch .New (sketchFolder , mainSketchFile , buildPath , files )
122+ }
0 commit comments