Skip to content

Commit 1f6da96

Browse files
refactor Sizer in a function
1 parent 592f46e commit 1f6da96

File tree

4 files changed

+105
-80
lines changed

4 files changed

+105
-80
lines changed

Diff for: arduino/builder/sizer.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package builder
2+
3+
import rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
4+
5+
// ExecutableSectionSize represents a section of the executable output file
6+
type ExecutableSectionSize struct {
7+
Name string `json:"name"`
8+
Size int `json:"size"`
9+
MaxSize int `json:"max_size"`
10+
}
11+
12+
// ExecutablesFileSections is an array of ExecutablesFileSection
13+
type ExecutablesFileSections []ExecutableSectionSize
14+
15+
// ToRPCExecutableSectionSizeArray transforms this array into a []*rpc.ExecutableSectionSize
16+
func (s ExecutablesFileSections) ToRPCExecutableSectionSizeArray() []*rpc.ExecutableSectionSize {
17+
res := []*rpc.ExecutableSectionSize{}
18+
for _, section := range s {
19+
res = append(res, &rpc.ExecutableSectionSize{
20+
Name: section.Name,
21+
Size: int64(section.Size),
22+
MaxSize: int64(section.MaxSize),
23+
})
24+
}
25+
return res
26+
}

Diff for: legacy/builder/builder.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,18 @@ func (s *Builder) Run(ctx *types.Context) error {
204204

205205
&ExportProjectCMake{SketchError: mainErr != nil},
206206

207-
&phases.Sizer{SketchError: mainErr != nil},
207+
types.BareCommand(func(ctx *types.Context) error {
208+
executableSectionsSize, err := phases.Sizer(
209+
ctx.OnlyUpdateCompilationDatabase, mainErr != nil, ctx.Verbose,
210+
ctx.BuildProperties,
211+
ctx.Stdout, ctx.Stderr,
212+
func(msg string) { ctx.Info(msg) },
213+
func(msg string) { ctx.Warn(msg) },
214+
ctx.WarningsLevel,
215+
)
216+
ctx.ExecutableSectionsSize = executableSectionsSize
217+
return err
218+
}),
208219
}
209220
for _, command := range commands {
210221
PrintRingNameIfDebug(ctx, command)

Diff for: legacy/builder/phases/sizer.go

+66-55
Original file line numberDiff line numberDiff line change
@@ -18,48 +18,50 @@ package phases
1818
import (
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)

Diff for: legacy/builder/types/context.go

+1-24
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ type Context struct {
9393
stdLock sync.Mutex
9494

9595
// Sizer results
96-
ExecutableSectionsSize ExecutablesFileSections
96+
ExecutableSectionsSize builder.ExecutablesFileSections
9797

9898
// Compilation Database to build/update
9999
CompilationDatabase *builder.CompilationDatabase
@@ -106,29 +106,6 @@ type Context struct {
106106
SourceOverride map[string]string
107107
}
108108

109-
// ExecutableSectionSize represents a section of the executable output file
110-
type ExecutableSectionSize struct {
111-
Name string `json:"name"`
112-
Size int `json:"size"`
113-
MaxSize int `json:"max_size"`
114-
}
115-
116-
// ExecutablesFileSections is an array of ExecutablesFileSection
117-
type ExecutablesFileSections []ExecutableSectionSize
118-
119-
// ToRPCExecutableSectionSizeArray transforms this array into a []*rpc.ExecutableSectionSize
120-
func (s ExecutablesFileSections) ToRPCExecutableSectionSizeArray() []*rpc.ExecutableSectionSize {
121-
res := []*rpc.ExecutableSectionSize{}
122-
for _, section := range s {
123-
res = append(res, &rpc.ExecutableSectionSize{
124-
Name: section.Name,
125-
Size: int64(section.Size),
126-
MaxSize: int64(section.MaxSize),
127-
})
128-
}
129-
return res
130-
}
131-
132109
func (ctx *Context) ExtractBuildOptions() *properties.Map {
133110
opts := properties.NewMap()
134111
opts.Set("hardwareFolders", strings.Join(ctx.HardwareDirs.AsStrings(), ","))

0 commit comments

Comments
 (0)