Skip to content

Commit 647d629

Browse files
author
Luca Bianconi
committed
feat: expand properties option
1 parent 53a6f25 commit 647d629

File tree

2 files changed

+120
-12
lines changed

2 files changed

+120
-12
lines changed

Diff for: internal/cli/compile/compile.go

+55-8
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,40 @@ 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+
showPropertiesModePattern
52+
showPropertiesModeValue
53+
)
54+
55+
func getShowPropertiesMode(showProperties string) showPropertiesMode {
56+
if showProperties == "" {
57+
// default with no flag
58+
return showPropertiesModeDisabled
59+
}
60+
val, ok := map[string]showPropertiesMode{
61+
"disabled": showPropertiesModeDisabled,
62+
"pattern": showPropertiesModePattern,
63+
"value": showPropertiesModeValue,
64+
}[showProperties]
65+
if !ok {
66+
return showPropertiesModePattern
67+
}
68+
return val
69+
}
70+
4671
var (
4772
fqbnArg arguments.Fqbn // Fully Qualified Board Name, e.g.: arduino:avr:uno.
4873
profileArg arguments.Profile // Profile to use
49-
showProperties bool // Show all build preferences used instead of compiling.
74+
showProperties string // Show all build preferences used instead of compiling.
5075
preprocess bool // Print preprocessed code to stdout.
5176
buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused.
5277
buildPath string // Path where to save compiled files.
@@ -95,7 +120,13 @@ func NewCommand() *cobra.Command {
95120
fqbnArg.AddToCommand(compileCommand)
96121
profileArg.AddToCommand(compileCommand)
97122
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."))
123+
compileCommand.Flags().StringVar(
124+
&showProperties,
125+
"show-properties",
126+
"disabled",
127+
tr(`Show build properties instead of compiling. With "pattern" properties are returned as they are defined. If "value" the placeholders are replaced with compilation context values.`),
128+
)
129+
compileCommand.Flags().Lookup("show-properties").NoOptDefVal = "pattern" // default if the flag is present with no value
99130
compileCommand.Flags().BoolVar(&preprocess, "preprocess", false, tr("Print preprocessed code to stdout instead of compiling."))
100131
compileCommand.Flags().StringVar(&buildCachePath, "build-cache-path", "", tr("Builds of 'core.a' are saved into this path to be cached and reused."))
101132
compileCommand.Flags().StringVarP(&exportDir, "output-dir", "", "", tr("Save build artifacts in this directory."))
@@ -188,9 +219,10 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
188219
overrides = o.Overrides
189220
}
190221

222+
showPropertiesM := getShowPropertiesMode(showProperties)
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 == showPropertiesModeValue {
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)

Diff for: internal/integrationtest/compile_3/compile_show_properties_test.go

+65-4
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=pattern output is clean
78+
// properties are not expanded
79+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=pattern", 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=pattern output is clean
88+
// properties are not expanded
89+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=pattern", "--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=value output is clean
99+
// properties are expanded
100+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=value", 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=value --format JSON output is clean
109+
// properties are expanded
110+
stdout, stderr, err = cli.Run("compile", "--fqbn", "arduino:avr:uno", "-v", "--show-properties=value", "--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)