From d2cdf175c924ca0e3196835c9f1e61ace8e3f26f Mon Sep 17 00:00:00 2001 From: Stanislav Zhuk Date: Wed, 30 Oct 2024 02:43:26 +0200 Subject: [PATCH] fix: composer revert Cmd back to RawCmd and add PATH env, for #6604, fixes #6628 (#6627) Co-authored-by: Randy Fay --- cmd/ddev/cmd/composer_test.go | 24 ++++++++++++++++++++++-- pkg/ddevapp/composer.go | 22 +++++++++++++++------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/cmd/ddev/cmd/composer_test.go b/cmd/ddev/cmd/composer_test.go index 3516736b856..4afb2e10ddf 100644 --- a/cmd/ddev/cmd/composer_test.go +++ b/cmd/ddev/cmd/composer_test.go @@ -89,7 +89,7 @@ func TestComposerCmdCreateConfigInstall(t *testing.T) { } } -func TestComposerCmdCreateRequireRemove(t *testing.T) { +func TestComposerCmdCreateRequireRemoveConfigVersion(t *testing.T) { // 2022-05-24: I've spent lots of time debugging intermittent `composer create` failures when NFS // is enabled, both on macOS and Windows. As far as I can tell, it only happens in this test, I've // never recreated manually. I do see https://github.com/composer/composer/issues/9627 which seemed @@ -148,10 +148,11 @@ func TestComposerCmdCreateRequireRemove(t *testing.T) { out, err = exec.RunHostCommand(DdevBin, args...) assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) assert.Contains(out, "Created project in ") + assert.FileExists(filepath.Join(tmpDir, composerRoot, "composer.json")) assert.FileExists(filepath.Join(tmpDir, composerRoot, "Psr/Log/LogLevel.php")) // Test a composer require, with passthrough args - args = []string{"composer", "require", "sebastian/version", "--no-plugins", "--ansi"} + args = []string{"composer", "require", "sebastian/version:5.0.1 as 5.0.0", "--no-plugins", "--ansi"} out, err = exec.RunHostCommand(DdevBin, args...) assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) assert.Contains(out, "Generating autoload files") @@ -162,6 +163,25 @@ func TestComposerCmdCreateRequireRemove(t *testing.T) { assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) assert.Contains(out, "Generating autoload files") assert.False(fileutil.FileExists(filepath.Join(tmpDir, composerRoot, "vendor/sebastian"))) + // Test a composer config, with passthrough args + args = []string{"composer", "config", "repositories.packagist", `{"type": "composer", "url": "https://packagist.org"}`} + out, err = exec.RunHostCommand(DdevBin, args...) + assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) + composerJSON, err := fileutil.ReadFileIntoString(filepath.Join(tmpDir, composerRoot, "composer.json")) + assert.NoError(err, "failed to read %v: err=%v", filepath.Join(tmpDir, composerRoot, "composer.json"), err) + assert.Contains(composerJSON, "https://packagist.org") + // Test a composer binary override using /var/www/html/vendor/bin from $PATH + args = []string{"composer", "--version"} + out, err = exec.RunHostCommand(DdevBin, args...) + assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) + assert.NotContains(out, "2.8.0") + args = []string{"composer", "require", "composer/composer:v2.8.0"} + out, err = exec.RunHostCommand(DdevBin, args...) + assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) + args = []string{"composer", "--version"} + out, err = exec.RunHostCommand(DdevBin, args...) + assert.NoError(err, "failed to run %v: err=%v, output=\n=====\n%s\n=====\n", args, err, out) + assert.Contains(out, "2.8.0") } } diff --git a/pkg/ddevapp/composer.go b/pkg/ddevapp/composer.go index 02386784241..28c4fc416af 100644 --- a/pkg/ddevapp/composer.go +++ b/pkg/ddevapp/composer.go @@ -2,12 +2,11 @@ package ddevapp import ( "fmt" + "github.com/ddev/ddev/pkg/fileutil" + "github.com/mattn/go-isatty" "os" "runtime" "strings" - - "github.com/ddev/ddev/pkg/fileutil" - "github.com/mattn/go-isatty" ) // Composer runs Composer commands in the web container, managing pre- and post- hooks @@ -18,14 +17,23 @@ func (app *DdevApp) Composer(args []string) (string, string, error) { return "", "", fmt.Errorf("failed to process pre-composer hooks: %v", err) } - argString := strings.Join(args, " ") + // Prevent Composer from debugging when Xdebug is enabled + env := []string{"XDEBUG_MODE=off"} + // Let Composer know which binary to run from the PATH + path, _, err := app.Exec(&ExecOpts{ + Cmd: "echo $PATH", + }) + path = strings.Trim(path, "\n") + if err == nil && path != "" { + env = append(env, "PATH="+path) + } + stdout, stderr, err := app.Exec(&ExecOpts{ Service: "web", Dir: app.GetComposerRoot(true, true), - Cmd: "composer " + argString, + RawCmd: append([]string{"composer"}, args...), Tty: isatty.IsTerminal(os.Stdin.Fd()), - // Prevent Composer from debugging when Xdebug is enabled - Env: []string{"XDEBUG_MODE=off"}, + Env: env, }) if err != nil { return stdout, stderr, fmt.Errorf("composer command failed: %v", err)