@@ -18,48 +18,50 @@ package phases
1818import (
1919 "encoding/json"
2020 "fmt"
21+ "io"
2122 "regexp"
2223 "strconv"
2324
25+ "github.com/arduino/arduino-cli/arduino/builder"
2426 "github.com/arduino/arduino-cli/arduino/builder/utils"
25- "github.com/arduino/arduino-cli/legacy/builder/types"
2627 "github.com/arduino/go-properties-orderedmap"
2728 "github.com/pkg/errors"
2829)
2930
30- type Sizer struct {
31- SketchError bool
32- }
33-
34- func (s * Sizer ) Run (ctx * types.Context ) error {
35- if ctx .OnlyUpdateCompilationDatabase {
36- return nil
31+ func Sizer (
32+ onlyUpdateCompilationDatabase , sketchError , verbose bool ,
33+ buildProperties * properties.Map ,
34+ stdoutWriter , stderrWriter io.Writer ,
35+ printInfoFn , printWarnFn func (msg string ),
36+ warningsLevel string ,
37+ ) (builder.ExecutablesFileSections , error ) {
38+ if onlyUpdateCompilationDatabase || sketchError {
39+ return nil , nil
3740 }
38- if s .SketchError {
39- return nil
40- }
41-
42- buildProperties := ctx .BuildProperties
4341
4442 if buildProperties .ContainsKey ("recipe.advanced_size.pattern" ) {
45- return checkSizeAdvanced (ctx , buildProperties )
43+ return checkSizeAdvanced (buildProperties , verbose , stdoutWriter , stderrWriter , printInfoFn , printWarnFn )
4644 }
4745
48- return checkSize (ctx , buildProperties )
46+ return checkSize (buildProperties , verbose , stdoutWriter , stderrWriter , printInfoFn , printWarnFn , warningsLevel )
4947}
5048
51- func checkSizeAdvanced (ctx * types.Context , properties * properties.Map ) error {
52- command , err := utils .PrepareCommandForRecipe (properties , "recipe.advanced_size.pattern" , false )
49+ func checkSizeAdvanced (buildProperties * properties.Map ,
50+ verbose bool ,
51+ stdoutWriter , stderrWriter io.Writer ,
52+ printInfoFn , printWarnFn func (msg string ),
53+ ) (builder.ExecutablesFileSections , error ) {
54+ command , err := utils .PrepareCommandForRecipe (buildProperties , "recipe.advanced_size.pattern" , false )
5355 if err != nil {
54- return errors .New (tr ("Error while determining sketch size: %s" , err ))
56+ return nil , errors .New (tr ("Error while determining sketch size: %s" , err ))
5557 }
5658
57- verboseInfo , out , _ , err := utils .ExecCommand (ctx . Verbose , ctx . Stdout , ctx . Stderr , command , utils .Capture /* stdout */ , utils .Show /* stderr */ )
58- if ctx . Verbose {
59- ctx . Info (string (verboseInfo ))
59+ verboseInfo , out , _ , err := utils .ExecCommand (verbose , stdoutWriter , stderrWriter , command , utils .Capture /* stdout */ , utils .Show /* stderr */ )
60+ if verbose {
61+ printInfoFn (string (verboseInfo ))
6062 }
6163 if err != nil {
62- return errors .New (tr ("Error while determining sketch size: %s" , err ))
64+ return nil , errors .New (tr ("Error while determining sketch size: %s" , err ))
6365 }
6466
6567 type AdvancedSizerResponse struct {
@@ -69,7 +71,7 @@ func checkSizeAdvanced(ctx *types.Context, properties *properties.Map) error {
6971 // likely be printed in red. Errors will stop build/upload.
7072 Severity string `json:"severity"`
7173 // Sections are the sections sizes for machine readable use
72- Sections []types .ExecutableSectionSize `json:"sections"`
74+ Sections []builder .ExecutableSectionSize `json:"sections"`
7375 // ErrorMessage is a one line error message like:
7476 // "text section exceeds available space in board"
7577 // it must be set when Severity is "error"
@@ -78,118 +80,127 @@ func checkSizeAdvanced(ctx *types.Context, properties *properties.Map) error {
7880
7981 var resp AdvancedSizerResponse
8082 if err := json .Unmarshal (out , & resp ); err != nil {
81- return errors .New (tr ("Error while determining sketch size: %s" , err ))
83+ return nil , errors .New (tr ("Error while determining sketch size: %s" , err ))
8284 }
8385
84- ctx . ExecutableSectionsSize = resp .Sections
86+ executableSectionsSize : = resp .Sections
8587 switch resp .Severity {
8688 case "error" :
87- ctx . Warn (resp .Output )
88- return errors .New (resp .ErrorMessage )
89+ printWarnFn (resp .Output )
90+ return executableSectionsSize , errors .New (resp .ErrorMessage )
8991 case "warning" :
90- ctx . Warn (resp .Output )
92+ printWarnFn (resp .Output )
9193 case "info" :
92- ctx . Info (resp .Output )
94+ printInfoFn (resp .Output )
9395 default :
94- return fmt .Errorf ("invalid '%s' severity from sketch sizer: it must be 'error', 'warning' or 'info'" , resp .Severity )
96+ return executableSectionsSize , fmt .Errorf ("invalid '%s' severity from sketch sizer: it must be 'error', 'warning' or 'info'" , resp .Severity )
9597 }
96- return nil
98+ return executableSectionsSize , nil
9799}
98100
99- func checkSize (ctx * types.Context , buildProperties * properties.Map ) error {
101+ func checkSize (buildProperties * properties.Map ,
102+ verbose bool ,
103+ stdoutWriter , stderrWriter io.Writer ,
104+ printInfoFn , printWarnFn func (msg string ),
105+ warningsLevel string ,
106+ ) (builder.ExecutablesFileSections , error ) {
100107 properties := buildProperties .Clone ()
101- properties .Set ("compiler.warning_flags" , properties .Get ("compiler.warning_flags." + ctx . WarningsLevel ))
108+ properties .Set ("compiler.warning_flags" , properties .Get ("compiler.warning_flags." + warningsLevel ))
102109
103110 maxTextSizeString := properties .Get ("upload.maximum_size" )
104111 maxDataSizeString := properties .Get ("upload.maximum_data_size" )
105112
106113 if maxTextSizeString == "" {
107- return nil
114+ return nil , nil
108115 }
109116
110117 maxTextSize , err := strconv .Atoi (maxTextSizeString )
111118 if err != nil {
112- return err
119+ return nil , err
113120 }
114121
115122 maxDataSize := - 1
116123 if maxDataSizeString != "" {
117124 maxDataSize , err = strconv .Atoi (maxDataSizeString )
118125 if err != nil {
119- return err
126+ return nil , err
120127 }
121128 }
122129
123- textSize , dataSize , _ , err := execSizeRecipe (ctx , properties )
130+ textSize , dataSize , _ , err := execSizeRecipe (properties , verbose , stdoutWriter , stderrWriter , printInfoFn )
124131 if err != nil {
125- ctx . Warn (tr ("Couldn't determine program size" ))
126- return nil
132+ printWarnFn (tr ("Couldn't determine program size" ))
133+ return nil , nil
127134 }
128135
129- ctx . Info (tr ("Sketch uses %[1]s bytes (%[3]s%%) of program storage space. Maximum is %[2]s bytes." ,
136+ printInfoFn (tr ("Sketch uses %[1]s bytes (%[3]s%%) of program storage space. Maximum is %[2]s bytes." ,
130137 strconv .Itoa (textSize ),
131138 strconv .Itoa (maxTextSize ),
132139 strconv .Itoa (textSize * 100 / maxTextSize )))
133140 if dataSize >= 0 {
134141 if maxDataSize > 0 {
135- ctx . Info (tr ("Global variables use %[1]s bytes (%[3]s%%) of dynamic memory, leaving %[4]s bytes for local variables. Maximum is %[2]s bytes." ,
142+ printInfoFn (tr ("Global variables use %[1]s bytes (%[3]s%%) of dynamic memory, leaving %[4]s bytes for local variables. Maximum is %[2]s bytes." ,
136143 strconv .Itoa (dataSize ),
137144 strconv .Itoa (maxDataSize ),
138145 strconv .Itoa (dataSize * 100 / maxDataSize ),
139146 strconv .Itoa (maxDataSize - dataSize )))
140147 } else {
141- ctx . Info (tr ("Global variables use %[1]s bytes of dynamic memory." , strconv .Itoa (dataSize )))
148+ printInfoFn (tr ("Global variables use %[1]s bytes of dynamic memory." , strconv .Itoa (dataSize )))
142149 }
143150 }
144151
145- ctx . ExecutableSectionsSize = []types .ExecutableSectionSize {
152+ executableSectionsSize : = []builder .ExecutableSectionSize {
146153 {
147154 Name : "text" ,
148155 Size : textSize ,
149156 MaxSize : maxTextSize ,
150157 },
151158 }
152159 if maxDataSize > 0 {
153- ctx . ExecutableSectionsSize = append (ctx . ExecutableSectionsSize , types .ExecutableSectionSize {
160+ executableSectionsSize = append (executableSectionsSize , builder .ExecutableSectionSize {
154161 Name : "data" ,
155162 Size : dataSize ,
156163 MaxSize : maxDataSize ,
157164 })
158165 }
159166
160167 if textSize > maxTextSize {
161- ctx . Warn (tr ("Sketch too big; see %[1]s for tips on reducing it." , "https://support.arduino.cc/hc/en-us/articles/360013825179" ))
162- return errors .New (tr ("text section exceeds available space in board" ))
168+ printWarnFn (tr ("Sketch too big; see %[1]s for tips on reducing it." , "https://support.arduino.cc/hc/en-us/articles/360013825179" ))
169+ return executableSectionsSize , errors .New (tr ("text section exceeds available space in board" ))
163170 }
164171
165172 if maxDataSize > 0 && dataSize > maxDataSize {
166- ctx . Warn (tr ("Not enough memory; see %[1]s for tips on reducing your footprint." , "https://support.arduino.cc/hc/en-us/articles/360013825179" ))
167- return errors .New (tr ("data section exceeds available space in board" ))
173+ printWarnFn (tr ("Not enough memory; see %[1]s for tips on reducing your footprint." , "https://support.arduino.cc/hc/en-us/articles/360013825179" ))
174+ return executableSectionsSize , errors .New (tr ("data section exceeds available space in board" ))
168175 }
169176
170177 if w := properties .Get ("build.warn_data_percentage" ); w != "" {
171178 warnDataPercentage , err := strconv .Atoi (w )
172179 if err != nil {
173- return err
180+ return executableSectionsSize , err
174181 }
175182 if maxDataSize > 0 && dataSize > maxDataSize * warnDataPercentage / 100 {
176- ctx . Warn (tr ("Low memory available, stability problems may occur." ))
183+ printWarnFn (tr ("Low memory available, stability problems may occur." ))
177184 }
178185 }
179186
180- return nil
187+ return executableSectionsSize , nil
181188}
182189
183- func execSizeRecipe (ctx * types.Context , properties * properties.Map ) (textSize int , dataSize int , eepromSize int , resErr error ) {
190+ func execSizeRecipe (properties * properties.Map ,
191+ verbose bool ,
192+ stdoutWriter , stderrWriter io.Writer ,
193+ printInfoFn func (msg string ),
194+ ) (textSize int , dataSize int , eepromSize int , resErr error ) {
184195 command , err := utils .PrepareCommandForRecipe (properties , "recipe.size.pattern" , false )
185196 if err != nil {
186197 resErr = fmt .Errorf (tr ("Error while determining sketch size: %s" ), err )
187198 return
188199 }
189200
190- verboseInfo , out , _ , err := utils .ExecCommand (ctx . Verbose , ctx . Stdout , ctx . Stderr , command , utils .Capture /* stdout */ , utils .Show /* stderr */ )
191- if ctx . Verbose {
192- ctx . Info (string (verboseInfo ))
201+ verboseInfo , out , _ , err := utils .ExecCommand (verbose , stdoutWriter , stderrWriter , command , utils .Capture /* stdout */ , utils .Show /* stderr */ )
202+ if verbose {
203+ printInfoFn (string (verboseInfo ))
193204 }
194205 if err != nil {
195206 resErr = fmt .Errorf (tr ("Error while determining sketch size: %s" ), err )
0 commit comments