@@ -3,188 +3,103 @@ package handler
3
3
import (
4
4
"bufio"
5
5
"bytes"
6
+ "encoding/json"
6
7
"io/ioutil"
7
8
"log"
8
9
"os"
9
10
"os/exec"
10
11
"path/filepath"
11
12
"strings"
12
13
14
+ "github.com/arduino/arduino-cli/arduino/libraries"
15
+ "github.com/arduino/arduino-cli/executils"
16
+ "github.com/arduino/go-paths-helper"
13
17
"github.com/arduino/go-properties-orderedmap"
14
18
"github.com/pkg/errors"
15
19
)
16
20
17
- func generateCpp (inoCode []byte , sourcePath , fqbn string ) (cppPath string , cppCode []byte , err error ) {
18
- // The CLI expects the `theSketchName.ino` file to be in `some/path/theSketchName` folder.
19
- // Expected folder structure: `/path/to/temp/ino2cpp-${random}/theSketchName/theSketchName.ino`.
20
- rawRootTempDir , err := ioutil .TempDir ("" , "ino2cpp-" )
21
- if err != nil {
22
- err = errors .Wrap (err , "Error while creating temporary directory." )
23
- return
24
- }
25
- rootTempDir , err := filepath .EvalSymlinks (rawRootTempDir )
26
- if err != nil {
27
- err = errors .Wrap (err , "Error while resolving symbolic links of temporary directory." )
28
- return
29
- }
30
-
31
- sketchName := filepath .Base (sourcePath )
32
- if strings .HasSuffix (sketchName , ".ino" ) {
33
- sketchName = sketchName [:len (sketchName )- len (".ino" )]
34
- }
35
- sketchTempPath := filepath .Join (rootTempDir , sketchName )
36
- createDirIfNotExist (sketchTempPath )
37
-
38
- // Write source file to temp dir
39
- sketchFileName := sketchName + ".ino"
40
- inoPath := filepath .Join (sketchTempPath , sketchFileName )
41
- err = ioutil .WriteFile (inoPath , inoCode , 0600 )
42
- if err != nil {
43
- err = errors .Wrap (err , "Error while writing source file to temporary directory." )
44
- return
45
- }
46
- if enableLogging {
47
- log .Println ("Source file written to" , inoPath )
48
- }
49
-
50
- // Copy all header files to temp dir
51
- err = copyHeaderFiles (filepath .Dir (sourcePath ), rootTempDir )
52
- if err != nil {
53
- return
54
- }
55
-
56
- // Generate compile_flags.txt
57
- cppPath = filepath .Join (sketchTempPath , sketchFileName + ".cpp" )
58
- flagsPath , err := generateCompileFlags (sketchTempPath , inoPath , sourcePath , fqbn )
59
- if err != nil {
60
- return
61
- }
62
- if enableLogging {
63
- log .Println ("Compile flags written to" , flagsPath )
64
- }
65
-
66
- // Generate target file
67
- cppCode , err = generateTargetFile (sketchTempPath , inoPath , cppPath , fqbn )
68
- return
69
- }
70
-
71
- func createDirIfNotExist (dir string ) {
72
- if _ , err := os .Stat (dir ); os .IsNotExist (err ) {
73
- err = os .MkdirAll (dir , os .ModePerm )
74
- if err != nil {
75
- panic (err )
76
- }
77
- }
78
- }
79
-
80
- func copyHeaderFiles (sourceDir string , destDir string ) error {
81
- fileInfos , err := ioutil .ReadDir (sourceDir )
82
- if err != nil {
83
- return err
84
- }
85
- for _ , fileInfo := range fileInfos {
86
- if ! fileInfo .IsDir () && strings .HasSuffix (fileInfo .Name (), ".h" ) {
87
- input , err := ioutil .ReadFile (filepath .Join (sourceDir , fileInfo .Name ()))
88
- if err != nil {
89
- return err
90
- }
91
-
92
- err = ioutil .WriteFile (filepath .Join (destDir , fileInfo .Name ()), input , 0644 )
93
- if err != nil {
94
- return err
95
- }
96
- }
97
- }
98
- return nil
99
- }
21
+ // func generateCpp(sourcePath, fqbn string) (*paths.Path, []byte, error) {
22
+ // // Generate target file
23
+ // if cppPath, err := generateBuildEnvironment(paths.New(sourcePath), fqbn); err != nil {
24
+ // return nil, nil, err
25
+ // } else if cppCode, err := cppPath.ReadFile(); err != nil {
26
+ // return nil, nil, err
27
+ // } else {
28
+ // return cppPath, cppCode, err
29
+ // }
30
+ // }
100
31
101
32
func updateCpp (inoCode []byte , sourcePath , fqbn string , fqbnChanged bool , cppPath string ) (cppCode []byte , err error ) {
102
- tempDir := filepath .Dir (cppPath )
103
- inoPath := strings .TrimSuffix (cppPath , ".cpp" )
104
- if inoCode != nil {
105
- // Write source file to temp dir
106
- err = ioutil .WriteFile (inoPath , inoCode , 0600 )
107
- if err != nil {
108
- err = errors .Wrap (err , "Error while writing source file to temporary directory." )
109
- return
110
- }
111
- if enableLogging {
112
- log .Println ("Source file written to" , inoPath )
113
- }
114
- }
33
+ // tempDir := filepath.Dir(cppPath)
34
+ // inoPath := strings.TrimSuffix(cppPath, ".cpp")
35
+ // if inoCode != nil {
36
+ // // Write source file to temp dir
37
+ // err = ioutil.WriteFile(inoPath, inoCode, 0600)
38
+ // if err != nil {
39
+ // err = errors.Wrap(err, "Error while writing source file to temporary directory.")
40
+ // return
41
+ // }
42
+ // if enableLogging {
43
+ // log.Println("Source file written to", inoPath)
44
+ // }
45
+ // }
115
46
116
- if fqbnChanged {
117
- // Generate compile_flags.txt
118
- var flagsPath string
119
- flagsPath , err = generateCompileFlags (tempDir , inoPath , sourcePath , fqbn )
120
- if err != nil {
121
- return
122
- }
123
- if enableLogging {
124
- log .Println ("Compile flags written to" , flagsPath )
125
- }
126
- }
47
+ // if fqbnChanged {
48
+ // // Generate compile_flags.txt
49
+ // var flagsPath string
50
+ // flagsPath, err = generateCompileFlags(tempDir, inoPath, sourcePath, fqbn)
51
+ // if err != nil {
52
+ // return
53
+ // }
54
+ // if enableLogging {
55
+ // log.Println("Compile flags written to", flagsPath)
56
+ // }
57
+ // }
127
58
128
- // Generate target file
129
- cppCode , err = generateTargetFile (tempDir , inoPath , cppPath , fqbn )
59
+ // // Generate target file
60
+ // cppCode, err = generateTargetFile(tempDir, inoPath, cppPath, fqbn)
130
61
return
131
62
}
132
63
133
- func generateCompileFlags (tempDir , inoPath , sourcePath , fqbn string ) (string , error ) {
134
- var cliArgs []string
135
- if len (fqbn ) > 0 {
136
- cliArgs = []string {"compile" , "--fqbn" , fqbn , "--show-properties" , inoPath }
137
- } else {
138
- cliArgs = []string {"compile" , "--show-properties" , inoPath }
139
- }
140
- propertiesCmd := exec .Command (globalCliPath , cliArgs ... )
141
- output , err := propertiesCmd .Output ()
142
- if err != nil {
143
- err = logCommandErr (propertiesCmd , output , err , errMsgFilter (tempDir ))
144
- return "" , err
145
- }
146
- buildProps , err := properties .LoadFromBytes (output )
64
+ func generateBuildEnvironment (sketchDir * paths.Path , fqbn string ) (* paths.Path , error ) {
65
+ // XXX: do this from IDE or via gRPC
66
+ args := []string {globalCliPath ,
67
+ "compile" ,
68
+ "--fqbn" , fqbn ,
69
+ "--only-compilation-database" ,
70
+ "--clean" ,
71
+ "--format" , "json" ,
72
+ sketchDir .String (),
73
+ }
74
+ cmd , err := executils .NewProcess (args ... )
147
75
if err != nil {
148
- return "" , errors .Wrap ( err , "Error while reading build properties." )
76
+ return nil , errors .Errorf ( "running %s: %s" , strings . Join ( args , " " ), err )
149
77
}
150
- flagsPath := filepath .Join (tempDir , "compile_flags.txt" )
151
- outFile , err := os .OpenFile (flagsPath , os .O_WRONLY | os .O_CREATE , 0600 )
152
- if err != nil {
153
- return flagsPath , errors .Wrap (err , "Error while creating output file for compile flags." )
78
+ cmdOutput := & bytes.Buffer {}
79
+ cmd .RedirectStdoutTo (cmdOutput )
80
+ cmd .SetDirFromPath (sketchDir )
81
+ log .Println ("running: " , strings .Join (args , " " ))
82
+ if err := cmd .Run (); err != nil {
83
+ return nil , errors .Errorf ("running %s: %s" , strings .Join (args , " " ), err )
154
84
}
155
- defer outFile .Close ()
156
85
157
- printer := Printer {Writer : bufio .NewWriter (outFile )}
158
- printCompileFlags (buildProps , & printer , fqbn )
159
- printLibraryPaths (sourcePath , & printer )
160
- printer .Flush ()
161
- return flagsPath , printer .Err
162
- }
163
-
164
- func generateTargetFile (tempDir , inoPath , cppPath , fqbn string ) (cppCode []byte , err error ) {
165
- var cliArgs []string
166
- if len (fqbn ) > 0 {
167
- cliArgs = []string {"compile" , "--fqbn" , fqbn , "--preprocess" , inoPath }
168
- } else {
169
- cliArgs = []string {"compile" , "--preprocess" , inoPath }
86
+ type cmdBuilderRes struct {
87
+ BuildPath * paths.Path `json:"build_path"`
88
+ UsedLibraries []* libraries.Library
170
89
}
171
- preprocessCmd := exec .Command (globalCliPath , cliArgs ... )
172
- cppCode , err = preprocessCmd .Output ()
173
- if err != nil {
174
- err = logCommandErr (preprocessCmd , cppCode , err , errMsgFilter (tempDir ))
175
- return
90
+ type cmdRes struct {
91
+ CompilerOut string `json:"compiler_out"`
92
+ CompilerErr string `json:"compiler_err"`
93
+ BuilderResult cmdBuilderRes `json:"builder_result"`
176
94
}
177
-
178
- // Filter lines beginning with ERROR or WARNING
179
- cppCode = []byte (filterErrorsAndWarnings (cppCode ))
180
-
181
- err = ioutil .WriteFile (cppPath , cppCode , 0600 )
182
- if err != nil {
183
- err = errors .Wrap (err , "Error while writing target file to temporary directory." )
184
- } else if enableLogging {
185
- log .Println ("Target file written to" , cppPath )
95
+ var res cmdRes
96
+ if err := json .Unmarshal (cmdOutput .Bytes (), & res ); err != nil {
97
+ return nil , errors .Errorf ("parsing arduino-cli output: %s" , err )
186
98
}
187
- return
99
+
100
+ // Return only the build path
101
+ log .Println ("arduino-cli output:" , cmdOutput )
102
+ return res .BuilderResult .BuildPath , nil
188
103
}
189
104
190
105
func filterErrorsAndWarnings (cppCode []byte ) string {
0 commit comments