From e8f804f857c3754049412ac7359c7b7754aba638 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 3 Dec 2020 17:30:05 +0100 Subject: [PATCH] Added 'source override' feature to compile command. 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). --- arduino/builder/sketch.go | 54 ++++--- arduino/builder/sketch_test.go | 8 +- cli/compile/compile.go | 22 +++ commands/compile/compile.go | 2 + .../container_merge_copy_sketch_files.go | 4 +- legacy/builder/types/context.go | 5 + rpc/commands/compile.pb.go | 142 ++++++++++-------- rpc/commands/compile.proto | 1 + 8 files changed, 153 insertions(+), 85 deletions(-) diff --git a/arduino/builder/sketch.go b/arduino/builder/sketch.go index b540d9d943a..3c20f003609 100644 --- a/arduino/builder/sketch.go +++ b/arduino/builder/sketch.go @@ -216,12 +216,23 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) { } // SketchMergeSources merges all the source files included in a sketch -func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) { +func SketchMergeSources(sk *sketch.Sketch, overrides map[string]string) (int, string, error) { lineOffset := 0 mergedSource := "" + getSource := func(i *sketch.Item) (string, error) { + path, err := filepath.Rel(sk.LocationPath, i.Path) + if err != nil { + return "", errors.Wrap(err, "unable to compute relative path to the sketch for the item") + } + if override, ok := overrides[path]; ok { + return override, nil + } + return i.GetSourceStr() + } + // add Arduino.h inclusion directive if missing - mainSrc, err := sketch.MainFile.GetSourceStr() + mainSrc, err := getSource(sk.MainFile) if err != nil { return 0, "", err } @@ -230,12 +241,12 @@ func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) { lineOffset++ } - mergedSource += "#line 1 " + QuoteCppString(sketch.MainFile.Path) + "\n" + mergedSource += "#line 1 " + QuoteCppString(sk.MainFile.Path) + "\n" mergedSource += mainSrc + "\n" lineOffset++ - for _, item := range sketch.OtherSketchFiles { - src, err := item.GetSourceStr() + for _, item := range sk.OtherSketchFiles { + src, err := getSource(item) if err != nil { return 0, "", err } @@ -248,7 +259,7 @@ func SketchMergeSources(sketch *sketch.Sketch) (int, string, error) { // SketchCopyAdditionalFiles copies the additional files for a sketch to the // specified destination directory. -func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error { +func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string, overrides map[string]string) error { if err := os.MkdirAll(destPath, os.FileMode(0755)); err != nil { return errors.Wrap(err, "unable to create a folder to save the sketch files") } @@ -265,7 +276,20 @@ func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error { return errors.Wrap(err, "unable to create the folder containing the item") } - err = writeIfDifferent(item.Path, targetPath) + var sourceBytes []byte + if override, ok := overrides[relpath]; ok { + // use override source + sourceBytes = []byte(override) + } else { + // read the source file + s, err := item.GetSourceBytes() + if err != nil { + return errors.Wrap(err, "unable to read contents of the source item") + } + sourceBytes = s + } + + err = writeIfDifferent(sourceBytes, targetPath) if err != nil { return errors.Wrap(err, "unable to write to destination file") } @@ -274,18 +298,12 @@ func SketchCopyAdditionalFiles(sketch *sketch.Sketch, destPath string) error { return nil } -func writeIfDifferent(sourcePath, destPath string) error { - // read the source file - newbytes, err := ioutil.ReadFile(sourcePath) - if err != nil { - return errors.Wrap(err, "unable to read contents of the source item") - } - +func writeIfDifferent(source []byte, destPath string) error { // check whether the destination file exists - _, err = os.Stat(destPath) + _, err := os.Stat(destPath) if os.IsNotExist(err) { // write directly - return ioutil.WriteFile(destPath, newbytes, os.FileMode(0644)) + return ioutil.WriteFile(destPath, source, os.FileMode(0644)) } // read the destination file if it ex @@ -295,8 +313,8 @@ func writeIfDifferent(sourcePath, destPath string) error { } // overwrite if contents are different - if bytes.Compare(existingBytes, newbytes) != 0 { - return ioutil.WriteFile(destPath, newbytes, os.FileMode(0644)) + if bytes.Compare(existingBytes, source) != 0 { + return ioutil.WriteFile(destPath, source, os.FileMode(0644)) } // source and destination are the same, don't write anything diff --git a/arduino/builder/sketch_test.go b/arduino/builder/sketch_test.go index dbe040edae4..33a2f034cb0 100644 --- a/arduino/builder/sketch_test.go +++ b/arduino/builder/sketch_test.go @@ -180,7 +180,7 @@ func TestMergeSketchSources(t *testing.T) { t.Fatalf("unable to read golden file %s: %v", mergedPath, err) } - offset, source, err := builder.SketchMergeSources(s) + offset, source, err := builder.SketchMergeSources(s, nil) require.Nil(t, err) require.Equal(t, 2, offset) require.Equal(t, string(mergedBytes), source) @@ -192,7 +192,7 @@ func TestMergeSketchSourcesArduinoIncluded(t *testing.T) { require.NotNil(t, s) // ensure not to include Arduino.h when it's already there - _, source, err := builder.SketchMergeSources(s) + _, source, err := builder.SketchMergeSources(s, nil) require.Nil(t, err) require.Equal(t, 1, strings.Count(source, "")) } @@ -208,7 +208,7 @@ func TestCopyAdditionalFiles(t *testing.T) { // copy the sketch over, create a fake main file we don't care about it // but we need it for `SketchLoad` to succeed later - err = builder.SketchCopyAdditionalFiles(s1, tmp) + err = builder.SketchCopyAdditionalFiles(s1, tmp, nil) require.Nil(t, err) fakeIno := filepath.Join(tmp, fmt.Sprintf("%s.ino", filepath.Base(tmp))) require.Nil(t, ioutil.WriteFile(fakeIno, []byte{}, os.FileMode(0644))) @@ -223,7 +223,7 @@ func TestCopyAdditionalFiles(t *testing.T) { require.Nil(t, err) // copy again - err = builder.SketchCopyAdditionalFiles(s1, tmp) + err = builder.SketchCopyAdditionalFiles(s1, tmp, nil) require.Nil(t, err) // verify file hasn't changed diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 6216cc99035..e77b3fb5740 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -18,6 +18,7 @@ package compile import ( "bytes" "context" + "encoding/json" "os" "github.com/arduino/arduino-cli/cli/feedback" @@ -55,6 +56,7 @@ var ( clean bool // Cleanup the build folder and do not use any cached build exportBinaries bool // Copies compiled binaries to sketch folder when true compilationDatabaseOnly bool // Only create compilation database without actually compiling + sourceOverrides string // Path to a .json file that contains a set of replacements of the sketch source code. ) // NewCommand created a new `compile` command @@ -102,6 +104,8 @@ func NewCommand() *cobra.Command { // This must be done because the value is set when the binding is accessed from viper. Accessing from cobra would only // read the value if the flag is set explicitly by the user. command.Flags().BoolP("export-binaries", "e", false, "If set built binaries will be exported to the sketch folder.") + command.Flags().StringVar(&sourceOverrides, "source-override", "", "Optional. Path to a .json file that contains a set of replacements of the sketch source code.") + command.Flag("source-override").Hidden = true configuration.Settings.BindPFlag("sketch.always_export_binaries", command.Flags().Lookup("export-binaries")) @@ -128,6 +132,23 @@ func run(cmd *cobra.Command, args []string) { // the config file and the env vars. exportBinaries = configuration.Settings.GetBool("sketch.always_export_binaries") + var overrides map[string]string + if sourceOverrides != "" { + data, err := paths.New(sourceOverrides).ReadFile() + if err != nil { + feedback.Errorf("Error opening source code overrides data file: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + var o struct { + Overrides map[string]string `json:"overrides"` + } + if err := json.Unmarshal(data, &o); err != nil { + feedback.Errorf("Error: invalid source code overrides data file: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + overrides = o.Overrides + } + compileReq := &rpc.CompileReq{ Instance: inst, Fqbn: fqbn, @@ -147,6 +168,7 @@ func run(cmd *cobra.Command, args []string) { Clean: clean, ExportBinaries: exportBinaries, CreateCompilationDatabaseOnly: compilationDatabaseOnly, + SourceOverride: overrides, } compileOut := new(bytes.Buffer) compileErr := new(bytes.Buffer) diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 7eb8eefd9b3..3607c6dc6aa 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -192,6 +192,8 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W builderCtx.Clean = req.GetClean() builderCtx.OnlyUpdateCompilationDatabase = req.GetCreateCompilationDatabaseOnly() + builderCtx.SourceOverride = req.GetSourceOverride() + // Use defer() to create an rpc.CompileResp with all the information available at the // moment of return. defer func() { diff --git a/legacy/builder/container_merge_copy_sketch_files.go b/legacy/builder/container_merge_copy_sketch_files.go index bd7302e70a7..d62f603f316 100644 --- a/legacy/builder/container_merge_copy_sketch_files.go +++ b/legacy/builder/container_merge_copy_sketch_files.go @@ -28,7 +28,7 @@ func (s *ContainerMergeCopySketchFiles) Run(ctx *types.Context) error { if sk == nil { return errors.New("unable to convert legacy sketch to the new type") } - offset, source, err := bldr.SketchMergeSources(sk) + offset, source, err := bldr.SketchMergeSources(sk, ctx.SourceOverride) if err != nil { return err } @@ -39,7 +39,7 @@ func (s *ContainerMergeCopySketchFiles) Run(ctx *types.Context) error { return errors.WithStack(err) } - if err := bldr.SketchCopyAdditionalFiles(sk, ctx.SketchBuildPath.String()); err != nil { + if err := bldr.SketchCopyAdditionalFiles(sk, ctx.SketchBuildPath.String(), ctx.SourceOverride); err != nil { return errors.WithStack(err) } diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index 906a0c1c365..4a8e7ad9ff4 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -169,6 +169,11 @@ type Context struct { CompilationDatabase *builder.CompilationDatabase // Set to true to skip build and produce only Compilation Database OnlyUpdateCompilationDatabase bool + + // Source code overrides (filename -> content map). + // The provided source data is used instead of reading it from disk. + // The keys of the map are paths relative to sketch folder. + SourceOverride map[string]string } // ExecutableSectionSize represents a section of the executable output file diff --git a/rpc/commands/compile.pb.go b/rpc/commands/compile.pb.go index f5a6ce2bbee..ad9ad31192a 100644 --- a/rpc/commands/compile.pb.go +++ b/rpc/commands/compile.pb.go @@ -45,25 +45,26 @@ type CompileReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Instance *Instance `protobuf:"bytes,1,opt,name=instance,proto3" json:"instance,omitempty"` // Arduino Core Service instance from the `Init` response. - Fqbn string `protobuf:"bytes,2,opt,name=fqbn,proto3" json:"fqbn,omitempty"` // Fully Qualified Board Name, e.g.: `arduino:avr:uno`. If this field is not defined, the FQBN of the board attached to the sketch via the `BoardAttach` method is used. - SketchPath string `protobuf:"bytes,3,opt,name=sketchPath,proto3" json:"sketchPath,omitempty"` // The path where the sketch is stored. - ShowProperties bool `protobuf:"varint,4,opt,name=showProperties,proto3" json:"showProperties,omitempty"` // Show all build preferences used instead of compiling. - Preprocess bool `protobuf:"varint,5,opt,name=preprocess,proto3" json:"preprocess,omitempty"` // Print preprocessed code to stdout instead of compiling. - BuildCachePath string `protobuf:"bytes,6,opt,name=buildCachePath,proto3" json:"buildCachePath,omitempty"` // Builds of 'core.a' are saved into this path to be cached and reused. - BuildPath string `protobuf:"bytes,7,opt,name=buildPath,proto3" json:"buildPath,omitempty"` // Path to use to store the files used for the compilation. If omitted, a directory will be created in the operating system's default temporary path. - BuildProperties []string `protobuf:"bytes,8,rep,name=buildProperties,proto3" json:"buildProperties,omitempty"` // List of custom build properties separated by commas. - Warnings string `protobuf:"bytes,9,opt,name=warnings,proto3" json:"warnings,omitempty"` // Used to tell gcc which warning level to use. The level names are: "none", "default", "more" and "all". - Verbose bool `protobuf:"varint,10,opt,name=verbose,proto3" json:"verbose,omitempty"` // Turns on verbose mode. - Quiet bool `protobuf:"varint,11,opt,name=quiet,proto3" json:"quiet,omitempty"` // Suppresses almost every output. - VidPid string `protobuf:"bytes,12,opt,name=vidPid,proto3" json:"vidPid,omitempty"` // VID/PID specific build properties. - Jobs int32 `protobuf:"varint,14,opt,name=jobs,proto3" json:"jobs,omitempty"` // The max number of concurrent compiler instances to run (as `make -jx`). If jobs is set to 0, it will use the number of available CPUs as the maximum. - Libraries []string `protobuf:"bytes,15,rep,name=libraries,proto3" json:"libraries,omitempty"` // List of custom libraries paths separated by commas. - OptimizeForDebug bool `protobuf:"varint,16,opt,name=optimizeForDebug,proto3" json:"optimizeForDebug,omitempty"` // Optimize compile output for debug, not for release. - ExportDir string `protobuf:"bytes,18,opt,name=export_dir,json=exportDir,proto3" json:"export_dir,omitempty"` // Optional: save the build artifacts in this directory, the directory must exist. - Clean bool `protobuf:"varint,19,opt,name=clean,proto3" json:"clean,omitempty"` // Optional: cleanup the build folder and do not use any previously cached build - ExportBinaries bool `protobuf:"varint,20,opt,name=export_binaries,json=exportBinaries,proto3" json:"export_binaries,omitempty"` // When set to `true` the compiled binary will be copied to the export directory. - CreateCompilationDatabaseOnly bool `protobuf:"varint,21,opt,name=create_compilation_database_only,json=createCompilationDatabaseOnly,proto3" json:"create_compilation_database_only,omitempty"` // When set to `true` only the compilation database will be produced and no actual build will be performed. + Instance *Instance `protobuf:"bytes,1,opt,name=instance,proto3" json:"instance,omitempty"` // Arduino Core Service instance from the `Init` response. + Fqbn string `protobuf:"bytes,2,opt,name=fqbn,proto3" json:"fqbn,omitempty"` // Fully Qualified Board Name, e.g.: `arduino:avr:uno`. If this field is not defined, the FQBN of the board attached to the sketch via the `BoardAttach` method is used. + SketchPath string `protobuf:"bytes,3,opt,name=sketchPath,proto3" json:"sketchPath,omitempty"` // The path where the sketch is stored. + ShowProperties bool `protobuf:"varint,4,opt,name=showProperties,proto3" json:"showProperties,omitempty"` // Show all build preferences used instead of compiling. + Preprocess bool `protobuf:"varint,5,opt,name=preprocess,proto3" json:"preprocess,omitempty"` // Print preprocessed code to stdout instead of compiling. + BuildCachePath string `protobuf:"bytes,6,opt,name=buildCachePath,proto3" json:"buildCachePath,omitempty"` // Builds of 'core.a' are saved into this path to be cached and reused. + BuildPath string `protobuf:"bytes,7,opt,name=buildPath,proto3" json:"buildPath,omitempty"` // Path to use to store the files used for the compilation. If omitted, a directory will be created in the operating system's default temporary path. + BuildProperties []string `protobuf:"bytes,8,rep,name=buildProperties,proto3" json:"buildProperties,omitempty"` // List of custom build properties separated by commas. + Warnings string `protobuf:"bytes,9,opt,name=warnings,proto3" json:"warnings,omitempty"` // Used to tell gcc which warning level to use. The level names are: "none", "default", "more" and "all". + Verbose bool `protobuf:"varint,10,opt,name=verbose,proto3" json:"verbose,omitempty"` // Turns on verbose mode. + Quiet bool `protobuf:"varint,11,opt,name=quiet,proto3" json:"quiet,omitempty"` // Suppresses almost every output. + VidPid string `protobuf:"bytes,12,opt,name=vidPid,proto3" json:"vidPid,omitempty"` // VID/PID specific build properties. + Jobs int32 `protobuf:"varint,14,opt,name=jobs,proto3" json:"jobs,omitempty"` // The max number of concurrent compiler instances to run (as `make -jx`). If jobs is set to 0, it will use the number of available CPUs as the maximum. + Libraries []string `protobuf:"bytes,15,rep,name=libraries,proto3" json:"libraries,omitempty"` // List of custom libraries paths separated by commas. + OptimizeForDebug bool `protobuf:"varint,16,opt,name=optimizeForDebug,proto3" json:"optimizeForDebug,omitempty"` // Optimize compile output for debug, not for release. + ExportDir string `protobuf:"bytes,18,opt,name=export_dir,json=exportDir,proto3" json:"export_dir,omitempty"` // Optional: save the build artifacts in this directory, the directory must exist. + Clean bool `protobuf:"varint,19,opt,name=clean,proto3" json:"clean,omitempty"` // Optional: cleanup the build folder and do not use any previously cached build + ExportBinaries bool `protobuf:"varint,20,opt,name=export_binaries,json=exportBinaries,proto3" json:"export_binaries,omitempty"` // When set to `true` the compiled binary will be copied to the export directory. + CreateCompilationDatabaseOnly bool `protobuf:"varint,21,opt,name=create_compilation_database_only,json=createCompilationDatabaseOnly,proto3" json:"create_compilation_database_only,omitempty"` // When set to `true` only the compilation database will be produced and no actual build will be performed. + SourceOverride map[string]string `protobuf:"bytes,22,rep,name=source_override,json=sourceOverride,proto3" json:"source_override,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // This map (source file -> new content) let the builder use the provided content instead of reading the corresponding file on disk. This is useful for IDE that have unsaved changes in memory. The path must be relative to the sketch directory. Only files from the sketch are allowed. } func (x *CompileReq) Reset() { @@ -231,6 +232,13 @@ func (x *CompileReq) GetCreateCompilationDatabaseOnly() bool { return false } +func (x *CompileReq) GetSourceOverride() map[string]string { + if x != nil { + return x.SourceOverride + } + return nil +} + type CompileResp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -381,7 +389,7 @@ var file_commands_compile_proto_rawDesc = []byte{ 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2f, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa0, 0x05, 0x0a, + 0x64, 0x73, 0x2f, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc5, 0x06, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, @@ -423,35 +431,45 @@ var file_commands_compile_proto_rawDesc = []byte{ 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x22, - 0x9d, 0x02, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, - 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x0e, - 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, - 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x64, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x68, 0x0a, 0x18, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x16, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x22, - 0x59, 0x0a, 0x15, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, - 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, - 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, + 0x60, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, + 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x2e, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x1a, 0x41, 0x0a, 0x13, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, 0x02, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x47, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, + 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x0d, 0x75, 0x73, 0x65, + 0x64, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x68, 0x0a, 0x18, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, + 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x16, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x53, 0x69, 0x7a, 0x65, 0x22, 0x59, 0x0a, 0x15, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x42, + 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, + 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, + 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -466,23 +484,25 @@ func file_commands_compile_proto_rawDescGZIP() []byte { return file_commands_compile_proto_rawDescData } -var file_commands_compile_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_commands_compile_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_commands_compile_proto_goTypes = []interface{}{ (*CompileReq)(nil), // 0: cc.arduino.cli.commands.CompileReq (*CompileResp)(nil), // 1: cc.arduino.cli.commands.CompileResp (*ExecutableSectionSize)(nil), // 2: cc.arduino.cli.commands.ExecutableSectionSize - (*Instance)(nil), // 3: cc.arduino.cli.commands.Instance - (*Library)(nil), // 4: cc.arduino.cli.commands.Library + nil, // 3: cc.arduino.cli.commands.CompileReq.SourceOverrideEntry + (*Instance)(nil), // 4: cc.arduino.cli.commands.Instance + (*Library)(nil), // 5: cc.arduino.cli.commands.Library } var file_commands_compile_proto_depIdxs = []int32{ - 3, // 0: cc.arduino.cli.commands.CompileReq.instance:type_name -> cc.arduino.cli.commands.Instance - 4, // 1: cc.arduino.cli.commands.CompileResp.used_libraries:type_name -> cc.arduino.cli.commands.Library - 2, // 2: cc.arduino.cli.commands.CompileResp.executable_sections_size:type_name -> cc.arduino.cli.commands.ExecutableSectionSize - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 4, // 0: cc.arduino.cli.commands.CompileReq.instance:type_name -> cc.arduino.cli.commands.Instance + 3, // 1: cc.arduino.cli.commands.CompileReq.source_override:type_name -> cc.arduino.cli.commands.CompileReq.SourceOverrideEntry + 5, // 2: cc.arduino.cli.commands.CompileResp.used_libraries:type_name -> cc.arduino.cli.commands.Library + 2, // 3: cc.arduino.cli.commands.CompileResp.executable_sections_size:type_name -> cc.arduino.cli.commands.ExecutableSectionSize + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_commands_compile_proto_init() } @@ -536,7 +556,7 @@ func file_commands_compile_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commands_compile_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/commands/compile.proto b/rpc/commands/compile.proto index 60d18c81a8d..9ef7a7eaecd 100644 --- a/rpc/commands/compile.proto +++ b/rpc/commands/compile.proto @@ -42,6 +42,7 @@ message CompileReq { bool clean = 19; // Optional: cleanup the build folder and do not use any previously cached build bool export_binaries = 20; // When set to `true` the compiled binary will be copied to the export directory. bool create_compilation_database_only = 21; // When set to `true` only the compilation database will be produced and no actual build will be performed. + map source_override = 22; // This map (source file -> new content) let the builder use the provided content instead of reading the corresponding file on disk. This is useful for IDE that have unsaved changes in memory. The path must be relative to the sketch directory. Only files from the sketch are allowed. } message CompileResp {