From f1d100dde0ebeae54216383fe3f9f9e6297f4968 Mon Sep 17 00:00:00 2001 From: Patrick Dawkins Date: Wed, 15 Jan 2025 16:10:28 +0000 Subject: [PATCH] Add phpManager type to enforce OS-specific interface --- internal/legacy/legacy.go | 14 +++++----- internal/legacy/php_manager.go | 20 +++++++++++++ internal/legacy/php_manager_test.go | 16 +++++++++++ internal/legacy/php_manager_unix.go | 21 ++++++++++++++ ...{php_windows.go => php_manager_windows.go} | 28 +++++++++---------- internal/legacy/php_unix.go | 24 ---------------- 6 files changed, 77 insertions(+), 46 deletions(-) create mode 100644 internal/legacy/php_manager.go create mode 100644 internal/legacy/php_manager_test.go create mode 100644 internal/legacy/php_manager_unix.go rename internal/legacy/{php_windows.go => php_manager_windows.go} (75%) delete mode 100644 internal/legacy/php_unix.go diff --git a/internal/legacy/legacy.go b/internal/legacy/legacy.go index 29a75ec..d5edddb 100644 --- a/internal/legacy/legacy.go +++ b/internal/legacy/legacy.go @@ -108,9 +108,8 @@ func (c *CLIWrapper) init() error { } return nil }) - g.Go(func() error { - return c.copyPHP(cacheDir) - }) + + g.Go(newPHPManager(cacheDir).copy) if err := g.Wait(); err != nil { return err @@ -176,14 +175,15 @@ func (c *CLIWrapper) Exec(ctx context.Context, args ...string) error { // makeCmd makes a legacy CLI command with the given context and arguments. func (c *CLIWrapper) makeCmd(ctx context.Context, args []string, cacheDir string) *exec.Cmd { - iniSettings := c.phpSettings(cacheDir) - var cmdArgs = make([]string, 0, len(args)+2+len(iniSettings)*2) - for _, s := range iniSettings { + phpMgr := newPHPManager(cacheDir) + settings := phpMgr.iniSettings() + var cmdArgs = make([]string, 0, len(args)+2+len(settings)*2) + for _, s := range settings { cmdArgs = append(cmdArgs, "-d", s) } cmdArgs = append(cmdArgs, c.pharPath(cacheDir)) cmdArgs = append(cmdArgs, args...) - return exec.CommandContext(ctx, c.phpPath(cacheDir), cmdArgs...) //nolint:gosec + return exec.CommandContext(ctx, phpMgr.binPath(), cmdArgs...) //nolint:gosec } // PharPath returns the path to the legacy CLI's Phar file. diff --git a/internal/legacy/php_manager.go b/internal/legacy/php_manager.go new file mode 100644 index 0000000..96f7c58 --- /dev/null +++ b/internal/legacy/php_manager.go @@ -0,0 +1,20 @@ +package legacy + +type phpManager interface { + // copy writes embedded PHP files to temporary files. + copy() error + + // binPath returns the path to the temporary PHP binary. + binPath() string + + // iniSettings returns PHP INI entries (key=value format). + iniSettings() []string +} + +type phpManagerPerOS struct { + cacheDir string +} + +func newPHPManager(cacheDir string) phpManager { + return &phpManagerPerOS{cacheDir} +} diff --git a/internal/legacy/php_manager_test.go b/internal/legacy/php_manager_test.go new file mode 100644 index 0000000..4f9c683 --- /dev/null +++ b/internal/legacy/php_manager_test.go @@ -0,0 +1,16 @@ +package legacy + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPHPManager(t *testing.T) { + tempDir := t.TempDir() + + pm := newPHPManager(tempDir) + assert.NoError(t, pm.copy()) + + assert.FileExists(t, pm.binPath()) +} diff --git a/internal/legacy/php_manager_unix.go b/internal/legacy/php_manager_unix.go new file mode 100644 index 0000000..819e095 --- /dev/null +++ b/internal/legacy/php_manager_unix.go @@ -0,0 +1,21 @@ +//go:build darwin || linux + +package legacy + +import ( + "path/filepath" + + "github.com/platformsh/cli/internal/file" +) + +func (m *phpManagerPerOS) copy() error { + return file.WriteIfNeeded(m.binPath(), phpCLI, 0o755) +} + +func (m *phpManagerPerOS) binPath() string { + return filepath.Join(m.cacheDir, "php") +} + +func (m *phpManagerPerOS) iniSettings() []string { + return nil +} diff --git a/internal/legacy/php_windows.go b/internal/legacy/php_manager_windows.go similarity index 75% rename from internal/legacy/php_windows.go rename to internal/legacy/php_manager_windows.go index 8ca08f0..8d6fe62 100644 --- a/internal/legacy/php_windows.go +++ b/internal/legacy/php_manager_windows.go @@ -22,9 +22,8 @@ var phpCLI []byte //go:embed archives/cacert.pem var caCert []byte -// copyPHP to destination, if it does not exist -func (c *CLIWrapper) copyPHP(cacheDir string) error { - destDir := filepath.Join(cacheDir, "php") +func (m *phpManagerPerOS) copy() error { + destDir := filepath.Join(m.cacheDir, "php") r, err := zip.NewReader(bytes.NewReader(phpCLI), int64(len(phpCLI))) if err != nil { @@ -49,9 +48,16 @@ func (c *CLIWrapper) copyPHP(cacheDir string) error { return nil } -// phpPath returns the path to the temporary PHP-CLI binary -func (c *CLIWrapper) phpPath(cacheDir string) string { - return filepath.Join(cacheDir, "php", "php.exe") +func (m *phpManagerPerOS) binPath() string { + return filepath.Join(m.cacheDir, "php", "php.exe") +} + +func (m *phpManagerPerOS) iniSettings() []string { + return []string{ + "extension=" + filepath.Join(m.cacheDir, "php", "ext", "php_curl.dll"), + "extension=" + filepath.Join(m.cacheDir, "php", "ext", "php_openssl.dll"), + "openssl.cafile=" + filepath.Join(m.cacheDir, "php", "extras", "cacert.pem"), + } } // copyZipFile extracts a file from the Zip to the destination directory. @@ -89,16 +95,8 @@ func copyZipFile(f *zip.File, destDir string) error { } if err := file.Write(destPath, b, f.Mode()); err != nil { - return fmt.Errorf("could not write extracted file %s: %w", destPath, err) + return fmt.Errorf("could not copy extracted file %s: %w", destPath, err) } return nil } - -func (c *CLIWrapper) phpSettings(cacheDir string) []string { - return []string{ - "extension=" + filepath.Join(cacheDir, "php", "ext", "php_curl.dll"), - "extension=" + filepath.Join(cacheDir, "php", "ext", "php_openssl.dll"), - "openssl.cafile=" + filepath.Join(cacheDir, "php", "extras", "cacert.pem"), - } -} diff --git a/internal/legacy/php_unix.go b/internal/legacy/php_unix.go deleted file mode 100644 index af34774..0000000 --- a/internal/legacy/php_unix.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build darwin || linux -// +build darwin linux - -package legacy - -import ( - "path/filepath" - - "github.com/platformsh/cli/internal/file" -) - -// copyPHP to destination, if it does not exist -func (c *CLIWrapper) copyPHP(cacheDir string) error { - return file.WriteIfNeeded(c.phpPath(cacheDir), phpCLI, 0o755) -} - -// PHPPath returns the path that the PHP CLI will reside -func (c *CLIWrapper) phpPath(cacheDir string) string { - return filepath.Join(cacheDir, "php") -} - -func (c *CLIWrapper) phpSettings(_ string) []string { - return nil -}