Skip to content

Commit cf1a082

Browse files
authored
Merge pull request ActiveState#3396 from ActiveState/DX-2946
Fix `state exec` unable to run complex arguments
2 parents 95740fa + 9fa1007 commit cf1a082

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

internal/osutils/exeutils_windows.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"syscall"
99

1010
"github.com/thoas/go-funk"
11+
12+
"github.com/ActiveState/cli/internal/logging"
1113
)
1214

1315
const ExeExtension = ".exe"
@@ -28,6 +30,7 @@ func Command(name string, arg ...string) *exec.Cmd {
2830
// other characters that need escaping such as `<` and `>`.
2931
// This can be dropped once we update to a Go version that fixes this bug: https://github.com/golang/go/issues/68313
3032
cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: makeCmdLine(cmd.Args)}
33+
logging.Debug("Forcing command line: %s", cmd.SysProcAttr.CmdLine)
3134
}
3235

3336
return cmd

internal/runners/exec/exec.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) {
195195
lang := language.Bash
196196
scriptArgs := fmt.Sprintf(`%q "$@"`, exeTarget)
197197
if strings.Contains(s.subshell.Binary(), "cmd") {
198-
lang = language.PowerShell
199-
scriptArgs = fmt.Sprintf("& %q @args\nexit $LASTEXITCODE", exeTarget)
198+
lang = language.Batch
199+
scriptArgs = fmt.Sprintf("@ECHO OFF\n%q %%*", exeTarget)
200200
}
201201

202202
sf, err := scriptfile.New(lang, "state-exec", scriptArgs)

internal/subshell/sscommon/sscommon.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
func NewCommand(command string, args []string, env []string) *exec.Cmd {
18-
cmd := exec.Command(command, args...)
18+
cmd := osutils.Command(command, args...)
1919
if env != nil {
2020
cmd.Env = append(os.Environ(), env...)
2121
}
@@ -127,7 +127,7 @@ func runWithCmd(env []string, name string, args ...string) error {
127127
case ".bat":
128128
// No action required
129129
case ".ps1":
130-
args = append([]string{"-executionpolicy", "bypass", "-file", name}, args...)
130+
args = append([]string{"-file", name}, args...)
131131
name = "powershell"
132132
case ".sh":
133133
bashPath, err := osutils.BashifyPath(name)
@@ -166,7 +166,7 @@ func binaryPathCmd(env []string, name string) (string, error) {
166166
func runDirect(env []string, name string, args ...string) (rerr error) {
167167
logging.Debug("Running command: %s %s", name, strings.Join(args, " "))
168168

169-
runCmd := exec.Command(name, args...)
169+
runCmd := osutils.Command(name, args...)
170170
runCmd.Stdin, runCmd.Stdout, runCmd.Stderr = os.Stdin, os.Stdout, os.Stderr
171171
runCmd.Env = env
172172

test/integration/exec_int_test.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import (
66
"path/filepath"
77
"regexp"
88
"runtime"
9+
"strings"
910
"testing"
11+
"time"
1012

11-
"github.com/ActiveState/cli/internal/testhelpers/suite"
13+
"github.com/ActiveState/termtest"
1214

1315
"github.com/ActiveState/cli/internal/constants"
16+
"github.com/ActiveState/cli/internal/environment"
1417
"github.com/ActiveState/cli/internal/fileutils"
1518
"github.com/ActiveState/cli/internal/testhelpers/e2e"
19+
"github.com/ActiveState/cli/internal/testhelpers/suite"
1620
"github.com/ActiveState/cli/internal/testhelpers/tagsuite"
1721
)
1822

@@ -197,25 +201,26 @@ func (suite *ExecIntegrationTestSuite) TestExecWithPath() {
197201

198202
}
199203

200-
func (suite *ExecIntegrationTestSuite) TestExecPerlArgs() {
204+
func (suite *ExecIntegrationTestSuite) TestExeBatArguments() {
201205
suite.OnlyRunForTags(tagsuite.Exec)
202-
ts := e2e.New(suite.T(), false)
206+
207+
if runtime.GOOS != "windows" {
208+
suite.T().Skip("This test is only for windows")
209+
}
210+
211+
ts := e2e.New(suite.T(), true)
203212
defer ts.Close()
204213

205-
cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", ".")
206-
cp.Expect("Skipping runtime setup")
207-
cp.Expect("Checked out")
208-
cp.ExpectExitCode(0)
214+
ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b")
209215

210-
suite.NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "testargs.pl"), []byte(`
211-
printf "Argument: '%s'.\n", $ARGV[0];
212-
`)))
216+
root := environment.GetRootPathUnsafe()
217+
reportBat := filepath.Join(root, "test", "integration", "testdata", "batarguments", "report.bat")
218+
suite.Require().FileExists(reportBat)
213219

214-
cp = ts.SpawnWithOpts(
215-
e2e.OptArgs("exec", "perl", "testargs.pl", "<3"),
216-
e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
217-
)
218-
cp.Expect("Argument: '<3'", e2e.RuntimeSourcingTimeoutOpt)
220+
inputs := []string{"a<b", "b>a", "hello world", "&whoami", "imnot|apipe", "%NotAppData%", "^NotEscaped", "(NotAGroup)"}
221+
outputs := `"` + strings.Join(inputs, `" "`) + `"`
222+
cp := ts.SpawnWithOpts(e2e.OptArgs(append([]string{"exec", reportBat, "--"}, inputs...)...))
223+
cp.Expect(outputs, termtest.OptExpectTimeout(5*time.Second))
219224
cp.ExpectExitCode(0)
220225
}
221226

0 commit comments

Comments
 (0)