@@ -3,6 +3,7 @@ package build
33import (
44 "fmt"
55 "path/filepath"
6+ "runtime"
67 "testing"
78
89 "github.com/jfrog/build-info-go/utils"
@@ -103,31 +104,113 @@ func TestParseGradleVersion(t *testing.T) {
103104 }
104105}
105106
106- func TestFormatCommandProperties (t * testing.T ) {
107+ func TestQuoteArgsForLog (t * testing.T ) {
107108 tests := []struct {
108109 input []string
109110 expected []string
110111 }{
111112 {
112113 input : []string {"clean" , "-Dparam=value" , "build" , "-Pkey=value" },
113- expected : []string {"clean" , "-Dparam=value" , "build" , "-Pkey=value" },
114+ expected : []string {"clean" , "-Dparam=' value' " , "build" , "-Pkey=' value' " },
114115 },
115116 {
116117 input : []string {"-Dprop1=value1" , "test" , "-Pprop2=value2" },
117- expected : []string {"-Dprop1=value1" , "test" , "-Pprop2=value2" },
118+ expected : []string {"-Dprop1=' value1' " , "test" , "-Pprop2=' value2' " },
118119 },
119120 {
120121 input : []string {"-Dparam1=value1 value2" , "-Pkey1=value1" , "-Dparam2=value2" , "-Pkey2=value1 value2" },
121- expected : []string {"-Dparam1='value1 value2'" , "-Pkey1=value1" , "-Dparam2=value2" , "-Pkey2='value1 value2'" },
122+ expected : []string {"-Dparam1='value1 value2'" , "-Pkey1=' value1' " , "-Dparam2=' value2' " , "-Pkey2='value1 value2'" },
122123 },
123124 {
124125 input : []string {"-Dparam1=value1" , "run" , "-Psign" },
125- expected : []string {"-Dparam1=value1" , "run" , "-Psign" },
126+ expected : []string {"-Dparam1=' value1' " , "run" , "-Psign" },
126127 },
127128 }
128129
129130 for _ , test := range tests {
130- result := formatCommandProperties (test .input )
131+ result := quoteArgsForLog (test .input )
131132 assert .ElementsMatch (t , test .expected , result )
132133 }
133134}
135+
136+ func TestUnquoteProperty (t * testing.T ) {
137+ tests := []struct {
138+ input string
139+ expected string
140+ }{
141+ {input : "-Dparam=value" , expected : "-Dparam=value" },
142+ {input : "-Ddeploy.test.property=test test" , expected : "-Ddeploy.test.property=test test" },
143+ {input : "-Ddeploy.test.property='test test'" , expected : "-Ddeploy.test.property=test test" },
144+ {input : `-Pkey="value with spaces"` , expected : "-Pkey=value with spaces" },
145+ // Mismatched quote pair: left as-is.
146+ {input : `-Dparam='value"` , expected : `-Dparam='value"` },
147+ // No '=' at all: returned unchanged rather than panicking on the missing value part.
148+ {input : "-Dparam" , expected : "-Dparam" },
149+ }
150+
151+ for _ , test := range tests {
152+ assert .Equal (t , test .expected , unquoteProperty (test .input ))
153+ }
154+ }
155+
156+ func TestStripPropertyQuotes (t * testing.T ) {
157+ tests := []struct {
158+ input []string
159+ expected []string
160+ }{
161+ {
162+ input : []string {"clean" , "-Dparam=value" , "build" , "-Pkey=value" },
163+ expected : []string {"clean" , "-Dparam=value" , "build" , "-Pkey=value" },
164+ },
165+ {
166+ // Quotes already stripped by the shell, value has no surrounding quotes: left as-is.
167+ input : []string {"-Ddeploy.test.property=test test" },
168+ expected : []string {"-Ddeploy.test.property=test test" },
169+ },
170+ {
171+ // Quotes still present in the raw arg (e.g. on Windows, where cmd.exe/PowerShell don't strip
172+ // single quotes the way bash/zsh do): stripped only on Windows.
173+ input : []string {"-Ddeploy.test.property='test test'" },
174+ expected : []string {"-Ddeploy.test.property=test test" },
175+ },
176+ {
177+ input : []string {`-Pkey="value with spaces"` },
178+ expected : []string {"-Pkey=value with spaces" },
179+ },
180+ {
181+ // Mismatched quote pair: left as-is.
182+ input : []string {`-Dparam='value"` },
183+ expected : []string {`-Dparam='value"` },
184+ },
185+ }
186+
187+ for _ , test := range tests {
188+ result := stripPropertyQuotes (test .input )
189+ if runtime .GOOS == "windows" {
190+ assert .Equal (t , test .expected , result )
191+ } else {
192+ // On non-Windows platforms the shell already stripped shell-level quoting, so any quotes
193+ // still present in the argument were typed deliberately and must be left untouched.
194+ assert .Equal (t , test .input , result )
195+ }
196+ }
197+ }
198+
199+ func TestGetCmdDoesNotQuotePropertyValues (t * testing.T ) {
200+ config := & gradleRunConfig {
201+ gradle : "gradle" ,
202+ tasks : []string {"artifactoryPublish" , "-Ddeploy.test.property='test test'" },
203+ logger : utils .NewDefaultLogger (utils .INFO ),
204+ }
205+
206+ cmd := config .GetCmd ()
207+
208+ expectedValue := "'test test'"
209+ if runtime .GOOS == "windows" {
210+ // Pre-existing quotes are only stripped on Windows, where the shell doesn't strip them itself.
211+ expectedValue = "test test"
212+ }
213+ // exec.Command runs the process directly, without a shell, so quotes around the value would be passed to
214+ // Gradle literally, instead of being stripped, if we didn't strip them ourselves.
215+ assert .Equal (t , []string {"gradle" , "artifactoryPublish" , "-Ddeploy.test.property=" + expectedValue }, cmd .Args )
216+ }
0 commit comments