Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5a2a707

Browse files
authored
Added 'source override' feature to compile command. (#1099)
This feature allows to selectively "override" the content of a sketch. Overridden files will not be read from disk as usual but fetched directly from gRPC paramaters (if the cli is running as daemon) or from a .json file containing the new source code (if running from command line).
1 parent cbb9d19 commit 5a2a707

File tree

8 files changed

+153
-85
lines changed

8 files changed

+153
-85
lines changed

‎arduino/builder/sketch.go‎

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,23 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) {
216216
}
217217

218218
// SketchMergeSources merges all the source files included in a sketch
219-
func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) {
219+
func SketchMergeSources(sk *sketch.Sketch, overridesmap[string]string) (int, string, error) {
220220
lineOffset := 0
221221
mergedSource := ""
222222

223+
getSource := func(i *sketch.Item) (string, error) {
224+
path, err := filepath.Rel(sk.LocationPath, i.Path)
225+
if err != nil {
226+
return "", errors.Wrap(err, "unable to compute relative path to the sketch for the item")
227+
}
228+
if override, ok := overrides[path]; ok {
229+
return override, nil
230+
}
231+
return i.GetSourceStr()
232+
}
233+
223234
// add Arduino.h inclusion directive if missing
224-
mainSrc, err := sketch.MainFile.GetSourceStr()
235+
mainSrc, err := getSource(sk.MainFile)
225236
if err != nil {
226237
return 0, "", err
227238
}
@@ -230,12 +241,12 @@ func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) {
230241
lineOffset++
231242
}
232243

233-
mergedSource += "#line 1 " + QuoteCppString(sketch.MainFile.Path) + "\n"
244+
mergedSource += "#line 1 " + QuoteCppString(sk.MainFile.Path) + "\n"
234245
mergedSource += mainSrc + "\n"
235246
lineOffset++
236247

237-
for _, item := range sketch.OtherSketchFiles {
238-
src, err := item.GetSourceStr()
248+
for _, item := range sk.OtherSketchFiles {
249+
src, err := getSource(item)
239250
if err != nil {
240251
return 0, "", err
241252
}
@@ -248,7 +259,7 @@ func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) {
248259

249260
// SketchCopyAdditionalFiles copies the additional files for a sketch to the
250261
// specified destination directory.
251-
func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error {
262+
func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string, overridesmap[string]string) error {
252263
if err := os.MkdirAll(destPath, os.FileMode(0755)); err != nil {
253264
return errors.Wrap(err, "unable to create a folder to save the sketch files")
254265
}
@@ -265,7 +276,20 @@ func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error {
265276
return errors.Wrap(err, "unable to create the folder containing the item")
266277
}
267278

268-
err = writeIfDifferent(item.Path, targetPath)
279+
var sourceBytes []byte
280+
if override, ok := overrides[relpath]; ok {
281+
// use override source
282+
sourceBytes = []byte(override)
283+
} else {
284+
// read the source file
285+
s, err := item.GetSourceBytes()
286+
if err != nil {
287+
return errors.Wrap(err, "unable to read contents of the source item")
288+
}
289+
sourceBytes = s
290+
}
291+
292+
err = writeIfDifferent(sourceBytes, targetPath)
269293
if err != nil {
270294
return errors.Wrap(err, "unable to write to destination file")
271295
}
@@ -274,18 +298,12 @@ func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error {
274298
return nil
275299
}
276300

277-
func writeIfDifferent(sourcePath, destPath string) error {
278-
// read the source file
279-
newbytes, err := ioutil.ReadFile(sourcePath)
280-
if err != nil {
281-
return errors.Wrap(err, "unable to read contents of the source item")
282-
}
283-
301+
func writeIfDifferent(source []byte, destPath string) error {
284302
// check whether the destination file exists
285-
_, err = os.Stat(destPath)
303+
_, err := os.Stat(destPath)
286304
if os.IsNotExist(err) {
287305
// write directly
288-
return ioutil.WriteFile(destPath, newbytes, os.FileMode(0644))
306+
return ioutil.WriteFile(destPath, source, os.FileMode(0644))
289307
}
290308

291309
// read the destination file if it ex
@@ -295,8 +313,8 @@ func writeIfDifferent(sourcePath, destPath string) error {
295313
}
296314

297315
// overwrite if contents are different
298-
if bytes.Compare(existingBytes, newbytes) != 0 {
299-
return ioutil.WriteFile(destPath, newbytes, os.FileMode(0644))
316+
if bytes.Compare(existingBytes, source) != 0 {
317+
return ioutil.WriteFile(destPath, source, os.FileMode(0644))
300318
}
301319

302320
// source and destination are the same, don't write anything

‎arduino/builder/sketch_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func TestMergeSketchSources(t *testing.T) {
180180
t.Fatalf("unable to read golden file %s: %v", mergedPath, err)
181181
}
182182

183-
offset, source, err := builder.SketchMergeSources(s)
183+
offset, source, err := builder.SketchMergeSources(s, nil)
184184
require.Nil(t, err)
185185
require.Equal(t, 2, offset)
186186
require.Equal(t, string(mergedBytes), source)
@@ -192,7 +192,7 @@ func TestMergeSketchSourcesArduinoIncluded(t *testing.T) {
192192
require.NotNil(t, s)
193193

194194
// ensure not to include Arduino.h when it's already there
195-
_, source, err := builder.SketchMergeSources(s)
195+
_, source, err := builder.SketchMergeSources(s, nil)
196196
require.Nil(t, err)
197197
require.Equal(t, 1, strings.Count(source, "<Arduino.h>"))
198198
}
@@ -208,7 +208,7 @@ func TestCopyAdditionalFiles(t *testing.T) {
208208

209209
// copy the sketch over, create a fake main file we don't care about it
210210
// but we need it for `SketchLoad` to succeed later
211-
err = builder.SketchCopyAdditionalFiles(s1, tmp)
211+
err = builder.SketchCopyAdditionalFiles(s1, tmp, nil)
212212
require.Nil(t, err)
213213
fakeIno := filepath.Join(tmp, fmt.Sprintf("%s.ino", filepath.Base(tmp)))
214214
require.Nil(t, ioutil.WriteFile(fakeIno, []byte{}, os.FileMode(0644)))
@@ -223,7 +223,7 @@ func TestCopyAdditionalFiles(t *testing.T) {
223223
require.Nil(t, err)
224224

225225
// copy again
226-
err = builder.SketchCopyAdditionalFiles(s1, tmp)
226+
err = builder.SketchCopyAdditionalFiles(s1, tmp, nil)
227227
require.Nil(t, err)
228228

229229
// verify file hasn't changed

‎cli/compile/compile.go‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package compile
1818
import (
1919
"bytes"
2020
"context"
21+
"encoding/json"
2122
"os"
2223

2324
"github.com/arduino/arduino-cli/cli/feedback"
@@ -55,6 +56,7 @@ var (
5556
clean bool // Cleanup the build folder and do not use any cached build
5657
exportBinaries bool // Copies compiled binaries to sketch folder when true
5758
compilationDatabaseOnly bool // Only create compilation database without actually compiling
59+
sourceOverrides string // Path to a .json file that contains a set of replacements of the sketch source code.
5860
)
5961

6062
// NewCommand created a new `compile` command
@@ -102,6 +104,8 @@ func NewCommand() *cobra.Command {
102104
// This must be done because the value is set when the binding is accessed from viper. Accessing from cobra would only
103105
// read the value if the flag is set explicitly by the user.
104106
command.Flags().BoolP("export-binaries", "e", false, "If set built binaries will be exported to the sketch folder.")
107+
command.Flags().StringVar(&sourceOverrides, "source-override", "", "Optional. Path to a .json file that contains a set of replacements of the sketch source code.")
108+
command.Flag("source-override").Hidden = true
105109

106110
configuration.Settings.BindPFlag("sketch.always_export_binaries", command.Flags().Lookup("export-binaries"))
107111

@@ -128,6 +132,23 @@ func run(cmd *cobra.Command, args []string) {
128132
// the config file and the env vars.
129133
exportBinaries = configuration.Settings.GetBool("sketch.always_export_binaries")
130134

135+
var overrides map[string]string
136+
if sourceOverrides != "" {
137+
data, err := paths.New(sourceOverrides).ReadFile()
138+
if err != nil {
139+
feedback.Errorf("Error opening source code overrides data file: %v", err)
140+
os.Exit(errorcodes.ErrGeneric)
141+
}
142+
var o struct {
143+
Overrides map[string]string `json:"overrides"`
144+
}
145+
if err := json.Unmarshal(data, &o); err != nil {
146+
feedback.Errorf("Error: invalid source code overrides data file: %v", err)
147+
os.Exit(errorcodes.ErrGeneric)
148+
}
149+
overrides = o.Overrides
150+
}
151+
131152
compileReq := &rpc.CompileReq{
132153
Instance: inst,
133154
Fqbn: fqbn,
@@ -147,6 +168,7 @@ func run(cmd *cobra.Command, args []string) {
147168
Clean: clean,
148169
ExportBinaries: exportBinaries,
149170
CreateCompilationDatabaseOnly: compilationDatabaseOnly,
171+
SourceOverride: overrides,
150172
}
151173
compileOut := new(bytes.Buffer)
152174
compileErr := new(bytes.Buffer)

‎commands/compile/compile.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
192192
builderCtx.Clean = req.GetClean()
193193
builderCtx.OnlyUpdateCompilationDatabase = req.GetCreateCompilationDatabaseOnly()
194194

195+
builderCtx.SourceOverride = req.GetSourceOverride()
196+
195197
// Use defer() to create an rpc.CompileResp with all the information available at the
196198
// moment of return.
197199
defer func() {

‎legacy/builder/container_merge_copy_sketch_files.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func (s *ContainerMergeCopySketchFiles) Run(ctx *types.Context) error {
2828
if sk == nil {
2929
return errors.New("unable to convert legacy sketch to the new type")
3030
}
31-
offset, source, err := bldr.SketchMergeSources(sk)
31+
offset, source, err := bldr.SketchMergeSources(sk, ctx.SourceOverride)
3232
if err != nil {
3333
return err
3434
}
@@ -39,7 +39,7 @@ func (s *ContainerMergeCopySketchFiles) Run(ctx *types.Context) error {
3939
return errors.WithStack(err)
4040
}
4141

42-
if err := bldr.SketchCopyAdditionalFiles(sk, ctx.SketchBuildPath.String()); err != nil {
42+
if err := bldr.SketchCopyAdditionalFiles(sk, ctx.SketchBuildPath.String(), ctx.SourceOverride); err != nil {
4343
return errors.WithStack(err)
4444
}
4545

‎legacy/builder/types/context.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ type Context struct {
169169
CompilationDatabase *builder.CompilationDatabase
170170
// Set to true to skip build and produce only Compilation Database
171171
OnlyUpdateCompilationDatabase bool
172+
173+
// Source code overrides (filename -> content map).
174+
// The provided source data is used instead of reading it from disk.
175+
// The keys of the map are paths relative to sketch folder.
176+
SourceOverride map[string]string
172177
}
173178

174179
// ExecutableSectionSize represents a section of the executable output file

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /