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

Appearance settings

Commit a1e69dc

Browse filesBrowse files
authored
feat: option to expand properties with flag --show-properties (#2074)
1 parent 425aaf0 commit a1e69dc
Copy full SHA for a1e69dc

File tree

Expand file treeCollapse file tree

2 files changed

+120
-12
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+120
-12
lines changed

‎internal/cli/compile/compile.go

Copy file name to clipboardExpand all lines: internal/cli/compile/compile.go
+55-8Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,36 @@ import (
3838
"github.com/arduino/arduino-cli/table"
3939
"github.com/arduino/arduino-cli/version"
4040
"github.com/arduino/go-paths-helper"
41+
"github.com/arduino/go-properties-orderedmap"
4142
"github.com/fatih/color"
4243
"github.com/sirupsen/logrus"
4344
"github.com/spf13/cobra"
4445
)
4546

47+
type showPropertiesMode int
48+
49+
const (
50+
showPropertiesModeDisabled showPropertiesMode = iota
51+
showPropertiesModeUnexpanded
52+
showPropertiesModeExpanded
53+
)
54+
55+
func parseShowPropertiesMode(showProperties string) (showPropertiesMode, error) {
56+
val, ok := map[string]showPropertiesMode{
57+
"disabled": showPropertiesModeDisabled,
58+
"unexpanded": showPropertiesModeUnexpanded,
59+
"expanded": showPropertiesModeExpanded,
60+
}[showProperties]
61+
if !ok {
62+
return showPropertiesModeDisabled, fmt.Errorf(tr("invalid option '%s'.", showProperties))
63+
}
64+
return val, nil
65+
}
66+
4667
var (
4768
fqbnArg arguments.Fqbn // Fully Qualified Board Name, e.g.: arduino:avr:uno.
4869
profileArg arguments.Profile // Profile to use
49-
showProperties bool // Show all build preferences used instead of compiling.
70+
showProperties string // Show all build preferences used instead of compiling.
5071
preprocess bool // Print preprocessed code to stdout.
5172
buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused.
5273
buildPath string // Path where to save compiled files.
@@ -95,7 +116,13 @@ func NewCommand() *cobra.Command {
95116
fqbnArg.AddToCommand(compileCommand)
96117
profileArg.AddToCommand(compileCommand)
97118
compileCommand.Flags().BoolVar(&dumpProfile, "dump-profile", false, tr("Create and print a profile configuration from the build."))
98-
compileCommand.Flags().BoolVar(&showProperties, "show-properties", false, tr("Show all build properties used instead of compiling."))
119+
compileCommand.Flags().StringVar(
120+
&showProperties,
121+
"show-properties",
122+
"disabled",
123+
tr(`Show build properties instead of compiling. The properties are returned exactly as they are defined. Use "--show-properties=expanded" to replace placeholders with compilation context values.`),
124+
)
125+
compileCommand.Flags().Lookup("show-properties").NoOptDefVal = "unexpanded" // default if the flag is present with no value
99126
compileCommand.Flags().BoolVar(&preprocess, "preprocess", false, tr("Print preprocessed code to stdout instead of compiling."))
100127
compileCommand.Flags().StringVar(&buildCachePath, "build-cache-path", "", tr("Builds of 'core.a' are saved into this path to be cached and reused."))
101128
compileCommand.Flags().StringVarP(&exportDir, "output-dir", "", "", tr("Save build artifacts in this directory."))
@@ -188,9 +215,14 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
188215
overrides = o.Overrides
189216
}
190217

218+
showPropertiesM, err := parseShowPropertiesMode(showProperties)
219+
if err != nil {
220+
feedback.Fatal(tr("Error parsing --show-properties flag: %v", err), feedback.ErrGeneric)
221+
}
222+
191223
var stdOut, stdErr io.Writer
192224
var stdIORes func() *feedback.OutputStreamsResult
193-
if showProperties {
225+
if showPropertiesM != showPropertiesModeDisabled {
194226
stdOut, stdErr, stdIORes = feedback.NewBufferedStreams()
195227
} else {
196228
stdOut, stdErr, stdIORes = feedback.OutputStreams()
@@ -200,7 +232,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
200232
Instance: inst,
201233
Fqbn: fqbn,
202234
SketchPath: sketchPath.String(),
203-
ShowProperties: showProperties,
235+
ShowProperties: showPropertiesM != showPropertiesModeDisabled,
204236
Preprocess: preprocess,
205237
BuildCachePath: buildCachePath,
206238
BuildPath: buildPath,
@@ -318,7 +350,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
318350
BuilderResult: compileRes,
319351
ProfileOut: profileOut,
320352
Success: compileError == nil,
321-
showOnlyProperties: showProperties,
353+
showPropertiesMode: showPropertiesM,
322354
}
323355

324356
if compileError != nil {
@@ -353,9 +385,24 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
353385
}
354386
feedback.FatalResult(res, feedback.ErrGeneric)
355387
}
388+
if showPropertiesM == showPropertiesModeExpanded {
389+
expandPropertiesInResult(res)
390+
}
356391
feedback.PrintResult(res)
357392
}
358393

394+
func expandPropertiesInResult(res *compileResult) {
395+
expanded, err := properties.LoadFromSlice(res.BuilderResult.GetBuildProperties())
396+
if err != nil {
397+
res.Error = tr(err.Error())
398+
}
399+
expandedSlice := make([]string, expanded.Size())
400+
for i, k := range expanded.Keys() {
401+
expandedSlice[i] = strings.Join([]string{k, expanded.ExpandPropsInString(expanded.Get(k))}, "=")
402+
}
403+
res.BuilderResult.BuildProperties = expandedSlice
404+
}
405+
359406
type compileResult struct {
360407
CompilerOut string `json:"compiler_out"`
361408
CompilerErr string `json:"compiler_err"`
@@ -364,16 +411,16 @@ type compileResult struct {
364411
ProfileOut string `json:"profile_out,omitempty"`
365412
Error string `json:"error,omitempty"`
366413

367-
showOnlyProperties bool
414+
showPropertiesMode showPropertiesMode
368415
}
369416

370417
func (r *compileResult) Data() interface{} {
371418
return r
372419
}
373420

374421
func (r *compileResult) String() string {
375-
if r.showOnlyProperties {
376-
return strings.Join(r.BuilderResult.BuildProperties, fmt.Sprintln())
422+
if r.showPropertiesMode != showPropertiesModeDisabled {
423+
return strings.Join(r.BuilderResult.GetBuildProperties(), fmt.Sprintln())
377424
}
378425

379426
titleColor := color.New(color.FgHiGreen)

‎internal/integrationtest/compile_3/compile_show_properties_test.go

Copy file name to clipboardExpand all lines: internal/integrationtest/compile_3/compile_show_properties_test.go
+65-4Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@
1616
package compile_test
1717

1818
import (
19+
"encoding/json"
1920
"testing"
2021

2122
"github.com/arduino/arduino-cli/internal/integrationtest"
23+
"github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2224
"github.com/arduino/go-properties-orderedmap"
2325
"github.com/stretchr/testify/require"
24-
"go.bug.st/testifyjson/requirejson"
2526
)
2627

28+
type cliCompileResponse struct {
29+
BuilderResult *commands.CompileResponse `json:"builder_result"`
30+
}
31+
2732
func TestCompileShowProperties(t *testing.T) {
2833
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
2934
defer env.CleanUp()
@@ -36,17 +41,25 @@ func TestCompileShowProperties(t *testing.T) {
3641
bareMinimum := cli.CopySketch("bare_minimum")
3742

3843
// Test --show-properties output is clean
44+
// properties are not expanded
3945
stdout, stderr, err := cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties", bareMinimum.String())
4046
require.NoError(t, err)
41-
_, err = properties.LoadFromBytes(stdout)
47+
props, err := properties.LoadFromBytes(stdout)
4248
require.NoError(t, err, "Output must be a clean property list")
4349
require.Empty(t, stderr)
50+
require.True(t, props.ContainsKey("archive_file_path"))
51+
require.Contains(t, props.Get("archive_file_path"), "{build.path}")
4452

4553
// Test --show-properties --format JSON output is clean
54+
// properties are not expanded
4655
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties", "--format", "json", bareMinimum.String())
4756
require.NoError(t, err)
48-
requirejson.Parse(t, stdout, "Output must be a valid JSON")
4957
require.Empty(t, stderr)
58+
props, err = properties.LoadFromSlice(
59+
requireCompileResponseJson(t, stdout).BuilderResult.GetBuildProperties())
60+
require.NoError(t, err)
61+
require.True(t, props.ContainsKey("archive_file_path"))
62+
require.Contains(t, props.Get("archive_file_path"), "{build.path}")
5063

5164
// Test --show-properties output is clean, with a wrong FQBN
5265
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:unoa", "-v", "--show-properties", bareMinimum.String())
@@ -58,6 +71,54 @@ func TestCompileShowProperties(t *testing.T) {
5871
// Test --show-properties --format JSON output is clean, with a wrong FQBN
5972
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:unoa", "-v", "--show-properties", "--format", "json", bareMinimum.String())
6073
require.Error(t, err)
61-
requirejson.Parse(t, stdout, "Output must be a valid JSON")
6274
require.Empty(t, stderr)
75+
requireCompileResponseJson(t, stdout)
76+
77+
// Test --show-properties=unexpanded output is clean
78+
// properties are not expanded
79+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=unexpanded", bareMinimum.String())
80+
require.NoError(t, err)
81+
props, err = properties.LoadFromBytes(stdout)
82+
require.NoError(t, err, "Output must be a clean property list")
83+
require.Empty(t, stderr)
84+
require.True(t, props.ContainsKey("archive_file_path"))
85+
require.Contains(t, props.Get("archive_file_path"), "{build.path}")
86+
87+
// Test --show-properties=unexpanded output is clean
88+
// properties are not expanded
89+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=unexpanded", "--format", "json", bareMinimum.String())
90+
require.NoError(t, err)
91+
require.Empty(t, stderr)
92+
props, err = properties.LoadFromSlice(
93+
requireCompileResponseJson(t, stdout).BuilderResult.GetBuildProperties())
94+
require.NoError(t, err)
95+
require.True(t, props.ContainsKey("archive_file_path"))
96+
require.Contains(t, props.Get("archive_file_path"), "{build.path}")
97+
98+
// Test --show-properties=expanded output is clean
99+
// properties are expanded
100+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=expanded", bareMinimum.String())
101+
require.NoError(t, err)
102+
props, err = properties.LoadFromBytes(stdout)
103+
require.NoError(t, err, "Output must be a clean property list")
104+
require.Empty(t, stderr)
105+
require.True(t, props.ContainsKey("archive_file_path"))
106+
require.NotContains(t, props.Get("archive_file_path"), "{build.path}")
107+
108+
// Test --show-properties=expanded --format JSON output is clean
109+
// properties are expanded
110+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=expanded", "--format", "json", bareMinimum.String())
111+
require.NoError(t, err)
112+
require.Empty(t, stderr)
113+
props, err = properties.LoadFromSlice(
114+
requireCompileResponseJson(t, stdout).BuilderResult.GetBuildProperties())
115+
require.NoError(t, err)
116+
require.True(t, props.ContainsKey("archive_file_path"))
117+
require.NotContains(t, props.Get("archive_file_path"), "{build.path}")
118+
}
119+
120+
func requireCompileResponseJson(t *testing.T, stdout []byte) *cliCompileResponse {
121+
var compileResponse cliCompileResponse
122+
require.NoError(t, json.Unmarshal(stdout, &compileResponse))
123+
return &compileResponse
63124
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.