From ee6a17ea57564746ca6b687d371260d1caab4a1e Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Mon, 21 Mar 2022 19:50:43 +0600 Subject: [PATCH 01/29] wip --- cli/valet.php | 13 ++++++++++--- valet | 20 ++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/cli/valet.php b/cli/valet.php index 426c76139..340202df3 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -555,10 +555,17 @@ /** * List isolated sites. */ - $app->command('isolated', function () { - $sites = PhpFpm::isolatedDirectories(); + $app->command('isolated [--site=]', function ($site) { + if ($site) { + if ($phpVersion = Site::customPhpVersion($site.'.'.data_get(Configuration::read(), 'tld'))) { + $phpVersion = PhpFpm::normalizePhpVersion($phpVersion); + return output($phpVersion); + } + } else { + $sites = PhpFpm::isolatedDirectories(); - table(['Path', 'PHP Version'], $sites->all()); + table(['Path', 'PHP Version'], $sites->all()); + } })->descriptions('List all sites using isolated versions of PHP.'); /** diff --git a/valet b/valet index 03eadeed2..e204988ab 100755 --- a/valet +++ b/valet @@ -20,12 +20,6 @@ then DIR=$(php -r "echo realpath('$DIR/../laravel/valet');") fi -if [[ "$EUID" -ne 0 ]] -then - sudo USER="$USER" --preserve-env "$SOURCE" "$@" - exit -fi - # If the command is the "share" command we will need to resolve out any # symbolic links for the site. Before starting Ngrok, we will fire a # process to retrieve the live Ngrok tunnel URL in the background. @@ -88,9 +82,23 @@ then exit +elif [[ "$1" = "php" ]] +then + php "${@:2}" + +elif [[ "$1" = "composer" ]] +then + php /usr/local/bin/composer "${@:2}" + # Finally, for every other command we will just proxy into the PHP tool # and let it handle the request. These are commands which can be run # without sudo and don't require taking over terminals like Ngrok. else + if [[ "$EUID" -ne 0 ]] + then + sudo USER="$USER" --preserve-env "$SOURCE" "$@" + exit + fi + php "$DIR/cli/valet.php" "$@" fi From 794fbc0c577931494ca9b16fe6ec5df24098c580 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 01:10:06 +0600 Subject: [PATCH 02/29] wip --- cli/Valet/Brew.php | 26 ++++++++++++++++++++++++++ cli/valet.php | 8 +++++++- valet | 4 ++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index d9f02731f..f54fed8f7 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -298,6 +298,32 @@ function ($version) use ($resolvedPhpVersion) { }); } + + /** + * Get PHP binary path for a given version + * + * @param string $phpVersion + * + * @return string|bool + */ + public function getPhpBinaryPath($phpVersion) + { + if (file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { + return BREW_PREFIX . "/opt/$phpVersion/bin/php"; + } + + $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); + $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion")); + + $path = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; + + if (file_exists(trim($cellar).'/'.$path.'/bin/php')) { + return trim($cellar).'/'.$path.'/bin/php'; + } + + return "php"; + } + /** * Restart the linked PHP-FPM Homebrew service. * diff --git a/cli/valet.php b/cli/valet.php index 340202df3..54451af17 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -555,10 +555,16 @@ /** * List isolated sites. */ - $app->command('isolated [--site=]', function ($site) { + $app->command('isolated [--site=] [--binary]', function ($site, $binary) { if ($site) { if ($phpVersion = Site::customPhpVersion($site.'.'.data_get(Configuration::read(), 'tld'))) { + $phpVersion = PhpFpm::normalizePhpVersion($phpVersion); + + if($binary){ + return output(Brew::getPhpBinaryPath($phpVersion)); + } + return output($phpVersion); } } else { diff --git a/valet b/valet index e204988ab..b1c1671dc 100755 --- a/valet +++ b/valet @@ -84,11 +84,11 @@ then elif [[ "$1" = "php" ]] then - php "${@:2}" + $(php "$DIR/cli/valet.php" isolated --site=$(basename "$PWD") --binary) "${@:2}" elif [[ "$1" = "composer" ]] then - php /usr/local/bin/composer "${@:2}" + $(php "$DIR/cli/valet.php" isolated --site=$(basename "$PWD") --binary) $(which composer) "${@:2}" # Finally, for every other command we will just proxy into the PHP tool # and let it handle the request. These are commands which can be run From 3d85b44e6a9e2898bf91ee86973f66f42e6aa10c Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 01:47:37 +0600 Subject: [PATCH 03/29] wip --- cli/Valet/Brew.php | 26 +++++++++++++++++++++++--- cli/Valet/PhpFpm.php | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index f54fed8f7..1f27d7282 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -304,12 +304,14 @@ function ($version) use ($resolvedPhpVersion) { * * @param string $phpVersion * - * @return string|bool + * @return string */ public function getPhpBinaryPath($phpVersion) { - if (file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { - return BREW_PREFIX . "/opt/$phpVersion/bin/php"; + $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); + + if (file_exists(BREW_PREFIX . "/bin/valetphp{$versionInteger}")) { + return BREW_PREFIX . "/bin/valetphp{$versionInteger}"; } $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); @@ -321,9 +323,27 @@ public function getPhpBinaryPath($phpVersion) return trim($cellar).'/'.$path.'/bin/php'; } + if (file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { + return BREW_PREFIX . "/opt/$phpVersion/bin/php"; + } + return "php"; } + /** + * Create a PHP binary symlink for a PHP version + * + * @param string $phpVersion + * + * @return void + */ + public function symlinkPhpBinary($phpVersion) + { + $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); + + $this->files->symlinkAsUser($this->getPhpBinaryPath($phpVersion), BREW_PREFIX . "/bin/valetphp{$versionInteger}"); + } + /** * Restart the linked PHP-FPM Homebrew service. * diff --git a/cli/Valet/PhpFpm.php b/cli/Valet/PhpFpm.php index 990a37355..951c29f7c 100644 --- a/cli/Valet/PhpFpm.php +++ b/cli/Valet/PhpFpm.php @@ -221,6 +221,7 @@ public function isolateDirectory($directory, $version) $this->createConfigurationFiles($version); $this->site->isolate($site, $version); + $this->brew->symlinkPhpBinary($version); $this->stopIfUnused($oldCustomPhpVersion); $this->restart($version); From b7880793a9b10b214a5901c8d62e91b77845b34a Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 01:52:51 +0600 Subject: [PATCH 04/29] wip --- cli/Valet/Brew.php | 26 +++++++++----------------- cli/Valet/PhpFpm.php | 1 - 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 1f27d7282..519067475 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -309,6 +309,7 @@ function ($version) use ($resolvedPhpVersion) { public function getPhpBinaryPath($phpVersion) { $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); + $binPath = null; if (file_exists(BREW_PREFIX . "/bin/valetphp{$versionInteger}")) { return BREW_PREFIX . "/bin/valetphp{$versionInteger}"; @@ -320,30 +321,21 @@ public function getPhpBinaryPath($phpVersion) $path = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; if (file_exists(trim($cellar).'/'.$path.'/bin/php')) { - return trim($cellar).'/'.$path.'/bin/php'; + $binPath = trim($cellar).'/'.$path.'/bin/php'; } - if (file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { - return BREW_PREFIX . "/opt/$phpVersion/bin/php"; + // if (!$binPath && file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { + // return BREW_PREFIX . "/opt/$phpVersion/bin/php"; + // } + + if($binPath){ + $this->files->symlinkAsUser($binPath, BREW_PREFIX . "/bin/valetphp{$versionInteger}"); + return $binPath; } return "php"; } - /** - * Create a PHP binary symlink for a PHP version - * - * @param string $phpVersion - * - * @return void - */ - public function symlinkPhpBinary($phpVersion) - { - $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); - - $this->files->symlinkAsUser($this->getPhpBinaryPath($phpVersion), BREW_PREFIX . "/bin/valetphp{$versionInteger}"); - } - /** * Restart the linked PHP-FPM Homebrew service. * diff --git a/cli/Valet/PhpFpm.php b/cli/Valet/PhpFpm.php index 951c29f7c..990a37355 100644 --- a/cli/Valet/PhpFpm.php +++ b/cli/Valet/PhpFpm.php @@ -221,7 +221,6 @@ public function isolateDirectory($directory, $version) $this->createConfigurationFiles($version); $this->site->isolate($site, $version); - $this->brew->symlinkPhpBinary($version); $this->stopIfUnused($oldCustomPhpVersion); $this->restart($version); From 09f3d3e39277cec06ac9804c37fb790e51a187ba Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 02:02:12 +0600 Subject: [PATCH 05/29] wip --- cli/Valet/Brew.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 519067475..eddcaaedc 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -311,8 +311,11 @@ public function getPhpBinaryPath($phpVersion) $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); $binPath = null; - if (file_exists(BREW_PREFIX . "/bin/valetphp{$versionInteger}")) { - return BREW_PREFIX . "/bin/valetphp{$versionInteger}"; + if ($this->files->isLink(BREW_PREFIX . "/bin/valetphp{$versionInteger}")) { + $binPath = $this->files->readLink(BREW_PREFIX . "/bin/valetphp{$versionInteger}"); + if($this->files->exists($binPath)){ + return $binPath; + } } $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); @@ -320,11 +323,11 @@ public function getPhpBinaryPath($phpVersion) $path = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; - if (file_exists(trim($cellar).'/'.$path.'/bin/php')) { + if ($this->files->exists(trim($cellar).'/'.$path.'/bin/php')) { $binPath = trim($cellar).'/'.$path.'/bin/php'; } - // if (!$binPath && file_exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { + // if (!$binPath && $this->>files->exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { // return BREW_PREFIX . "/opt/$phpVersion/bin/php"; // } From 4f098a8028f7fcfc7a6bf80a3772b853c9b7a917 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 15:26:53 +0600 Subject: [PATCH 06/29] refactor with which-php command --- cli/Valet/Brew.php | 41 ++++++++++++++++++++++------------------ cli/valet.php | 47 +++++++++++++++++++++++++++++++++------------- valet | 8 ++++++-- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index eddcaaedc..ffe030923 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -300,43 +300,48 @@ function ($version) use ($resolvedPhpVersion) { /** - * Get PHP binary path for a given version + * Get PHP binary path for a given PHP Version * - * @param string $phpVersion + * @param string|null $phpVersion * * @return string */ - public function getPhpBinaryPath($phpVersion) + public function getPhpBinaryPath($phpVersion = null) { + if(! $phpVersion){ + return BREW_PREFIX.'/bin/php'; + } + $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); - $binPath = null; + $phpBinaryPath = null; + $symlinkedPath = BREW_PREFIX. "/bin/valetphp{$versionInteger}"; - if ($this->files->isLink(BREW_PREFIX . "/bin/valetphp{$versionInteger}")) { - $binPath = $this->files->readLink(BREW_PREFIX . "/bin/valetphp{$versionInteger}"); - if($this->files->exists($binPath)){ - return $binPath; + if ($this->files->isLink($symlinkedPath)) { + $phpBinaryPath = $this->files->readLink($symlinkedPath); + if ($this->files->exists($phpBinaryPath)) { + return $symlinkedPath; } } $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion")); - $path = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; + $phpDirectory = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; - if ($this->files->exists(trim($cellar).'/'.$path.'/bin/php')) { - $binPath = trim($cellar).'/'.$path.'/bin/php'; + if ($this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { + $phpBinaryPath = trim($cellar).'/'.$phpDirectory.'/bin/php'; } - // if (!$binPath && $this->>files->exists(BREW_PREFIX . "/opt/$phpVersion/bin/php")) { - // return BREW_PREFIX . "/opt/$phpVersion/bin/php"; - // } + if (is_null($phpBinaryPath) && $this->files->exists(BREW_PREFIX . "/opt/{$phpVersion}/bin/php")) { + $phpBinaryPath = BREW_PREFIX . "/opt/{$phpVersion}/bin/php"; + } - if($binPath){ - $this->files->symlinkAsUser($binPath, BREW_PREFIX . "/bin/valetphp{$versionInteger}"); - return $binPath; + if($phpBinaryPath){ + $this->files->symlinkAsUser($phpBinaryPath, $symlinkedPath); + return $phpBinaryPath; } - return "php"; + return BREW_PREFIX.'/bin/php'; } /** diff --git a/cli/valet.php b/cli/valet.php index 54451af17..3c2b57f6e 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -555,24 +555,45 @@ /** * List isolated sites. */ - $app->command('isolated [--site=] [--binary]', function ($site, $binary) { - if ($site) { - if ($phpVersion = Site::customPhpVersion($site.'.'.data_get(Configuration::read(), 'tld'))) { + $app->command('isolated', function () { + $sites = PhpFpm::isolatedDirectories(); - $phpVersion = PhpFpm::normalizePhpVersion($phpVersion); + table(['Path', 'PHP Version'], $sites->all()); + })->descriptions('List all sites using isolated versions of PHP.'); - if($binary){ - return output(Brew::getPhpBinaryPath($phpVersion)); - } + /** + * Get PHP Birnary + */ + $app->command('which-php [site]', function ($site = null) { + $host = Site::host($site ? $site : getcwd()).'.'.Configuration::read()['tld']; + $phpVersion = Site::customPhpVersion($host); - return output($phpVersion); + if(! $phpVersion){ + $path = getcwd().'/.valetphprc'; + if (file_exists($path)) { + $phpVersion = trim(file_get_contents($path)); } - } else { - $sites = PhpFpm::isolatedDirectories(); - - table(['Path', 'PHP Version'], $sites->all()); } - })->descriptions('List all sites using isolated versions of PHP.'); + + $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; + return output(Brew::getPhpBinaryPath($phpVersion)); + })->descriptions('Get the PHP binary path for a given site', [ + 'site' => 'The site to get the PHP binary path for', + ]); + + /** + * Proxy PHP Commands with correct version + */ + $app->command('php', function () { + warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); + })->descriptions('Proxy PHP Commands with isolated PHP version'); + + /** + * Proxy composer commands with the "php" binary on the isolated site + */ + $app->command('composer', function () { + warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); + })->descriptions('Proxy composer Commands with isolated PHP version'); /** * Tail log file. diff --git a/valet b/valet index b1c1671dc..d7964a9f5 100755 --- a/valet +++ b/valet @@ -82,13 +82,17 @@ then exit +# Proxy PHP commands to the "php" binary on the isolated site elif [[ "$1" = "php" ]] then - $(php "$DIR/cli/valet.php" isolated --site=$(basename "$PWD") --binary) "${@:2}" + $(php "$DIR/cli/valet.php" which-php) "${@:2}" + exit +# Proxy composer commands with the "php" binary on the isolated site elif [[ "$1" = "composer" ]] then - $(php "$DIR/cli/valet.php" isolated --site=$(basename "$PWD") --binary) $(which composer) "${@:2}" + $(php "$DIR/cli/valet.php" which-php) $(which composer) "${@:2}" + exit # Finally, for every other command we will just proxy into the PHP tool # and let it handle the request. These are commands which can be run From 1824ae4989ff6452a947977bc48f900130c9f2e0 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 16:25:26 +0600 Subject: [PATCH 07/29] wip --- cli/Valet/Brew.php | 35 ++++++++++++++++++++++------------- cli/valet.php | 3 ++- tests/BrewTest.php | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index ffe030923..d42e63b80 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -312,36 +312,45 @@ public function getPhpBinaryPath($phpVersion = null) return BREW_PREFIX.'/bin/php'; } - $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); $phpBinaryPath = null; - $symlinkedPath = BREW_PREFIX. "/bin/valetphp{$versionInteger}"; + $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); + $symlinkedValetPhpPath = BREW_PREFIX. "/bin/valetphp{$versionInteger}"; - if ($this->files->isLink($symlinkedPath)) { - $phpBinaryPath = $this->files->readLink($symlinkedPath); + // If the symlinked valet php path exists, then we can use that + if ($this->files->isLink($symlinkedValetPhpPath)) { + $phpBinaryPath = $this->files->readLink($symlinkedValetPhpPath); + + // Still make sure that the version of the binrary exists if ($this->files->exists($phpBinaryPath)) { - return $symlinkedPath; + return $symlinkedValetPhpPath; } } - $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); + // If the symlinked valet php path doesn't exist, then we need to look for the correct binary path + $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); // Example output: `/opt/homebrew/Cellar/php@8.0` $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion")); - $phpDirectory = !empty($details[0]->linked_keg) ? $details[0]->linked_keg : $details[0]->installed[0]->version; + if (!empty($details[0]->linked_keg)) { + $phpDirectory = $details[0]->linked_keg; + } elseif (!empty($details[0]->installed[0]->version)) { + $phpDirectory = $details[0]->installed[0]->version; + } - if ($this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { + if (isset($phpDirectory) && $this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { $phpBinaryPath = trim($cellar).'/'.$phpDirectory.'/bin/php'; } - if (is_null($phpBinaryPath) && $this->files->exists(BREW_PREFIX . "/opt/{$phpVersion}/bin/php")) { - $phpBinaryPath = BREW_PREFIX . "/opt/{$phpVersion}/bin/php"; + // When PHP Version is installed directly though shivammathur/homebrew-php, it usually stores the binaries in this directory + if (is_null($phpBinaryPath) && $this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { + $phpBinaryPath = BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } + // Create a symlink to the valet php version, so next time valet won't have to look for the binary path if($phpBinaryPath){ - $this->files->symlinkAsUser($phpBinaryPath, $symlinkedPath); - return $phpBinaryPath; + $this->files->symlinkAsUser($phpBinaryPath, $symlinkedValetPhpPath); } - return BREW_PREFIX.'/bin/php'; + return $phpBinaryPath ?: BREW_PREFIX.'/bin/php'; } /** diff --git a/cli/valet.php b/cli/valet.php index 3c2b57f6e..e91fd81b1 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -565,7 +565,7 @@ * Get PHP Birnary */ $app->command('which-php [site]', function ($site = null) { - $host = Site::host($site ? $site : getcwd()).'.'.Configuration::read()['tld']; + $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; $phpVersion = Site::customPhpVersion($host); if(! $phpVersion){ @@ -576,6 +576,7 @@ } $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; + return output(Brew::getPhpBinaryPath($phpVersion)); })->descriptions('Get the PHP binary path for a given site', [ 'site' => 'The site to get the PHP binary path for', diff --git a/tests/BrewTest.php b/tests/BrewTest.php index f2886277f..370e70d42 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -395,6 +395,23 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ $brewMock->restartLinkedPhp(); } + public function test_it_can_get_php_binary_path_from_php_version() + { + $cli = Mockery::mock(CommandLine::class); + $cli->shouldReceive('runAsUser')->once()->with('brew info php@7.4 --json') + ->andReturn('[{"name":"php@7.4","full_name":"php@7.4","aliases":[],"versioned_formulae":[],"versions":{"stable":"7.4.5"},"installed":[{"version":"7.4.5"}]}]'); + swap(CommandLine::class, $cli); + + dd(resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + + // $cli = Mockery::mock(CommandLine::class); + // $cli->shouldReceive('runAsUser')->once()->with('brew info php --json') + // ->andReturn('[{"name":"php","full_name":"php","aliases":["php@8.0"],"versioned_formulae":[],"versions":{"stable":"8.0.0"},"installed":[{"version":"8.0.0"}]}]'); + // swap(CommandLine::class, $cli); + // $this->assertTrue(resolve(Brew::class)->installed('php')); + } + + /** * Provider of php links and their expected split matches. * From d9ebb471b7354e0014607dcdc86ec774d4575a9a Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 17:00:24 +0600 Subject: [PATCH 08/29] tests added --- tests/BrewTest.php | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 370e70d42..adc950cae 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -397,20 +397,48 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ public function test_it_can_get_php_binary_path_from_php_version() { + // Scenario when there is no linked valet php exists + $files = Mockery::mock(Filesystem::class); $cli = Mockery::mock(CommandLine::class); - $cli->shouldReceive('runAsUser')->once()->with('brew info php@7.4 --json') - ->andReturn('[{"name":"php@7.4","full_name":"php@7.4","aliases":[],"versioned_formulae":[],"versions":{"stable":"7.4.5"},"installed":[{"version":"7.4.5"}]}]'); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(false); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn("/opt/homebrew/Cellar/php@7.4"); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); + $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); + $files->shouldReceive('symlinkAsUser')->once()->withArgs(["/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); swap(CommandLine::class, $cli); + swap(Filesystem::class, $files); + $this->assertEquals("/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); - dd(resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + // Scenario when user has installed directly though shivammathur/homebrew-php + $files = Mockery::mock(Filesystem::class); + $cli = Mockery::mock(CommandLine::class); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(false); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn("/opt/homebrew/Cellar/php@7.4"); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"installed":[{"version":"7.4.5"}]}]'); + $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php")->andReturn(false); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); + $files->shouldReceive('symlinkAsUser')->once()->withArgs(["/opt/homebrew/opt/php@7.4/bin/php", BREW_PREFIX."/bin/valetphp74"]); + swap(CommandLine::class, $cli); + swap(Filesystem::class, $files); + $this->assertEquals("/opt/homebrew/opt/php@7.4/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); - // $cli = Mockery::mock(CommandLine::class); - // $cli->shouldReceive('runAsUser')->once()->with('brew info php --json') - // ->andReturn('[{"name":"php","full_name":"php","aliases":["php@8.0"],"versioned_formulae":[],"versions":{"stable":"8.0.0"},"installed":[{"version":"8.0.0"}]}]'); - // swap(CommandLine::class, $cli); - // $this->assertTrue(resolve(Brew::class)->installed('php')); - } + // Scenario when there is a linked valet php exists + $files = Mockery::mock(Filesystem::class); + $cli = Mockery::mock(CommandLine::class); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(true); + $files->shouldReceive('readLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php"); + $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php")->andReturn(true); + swap(CommandLine::class, $cli); + swap(Filesystem::class, $files); + $this->assertEquals(BREW_PREFIX. "/bin/valetphp74", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + // Scenario when non php version is proivided + $files = Mockery::mock(Filesystem::class); + $cli = Mockery::mock(CommandLine::class); + swap(CommandLine::class, $cli); + swap(Filesystem::class, $files); + $this->assertEquals(BREW_PREFIX.'/bin/php', resolve(Brew::class)->getPhpBinaryPath(null)); + } /** * Provider of php links and their expected split matches. From 245c68e70806b02620668231bdccb15736ac8cea Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 17:05:10 +0600 Subject: [PATCH 09/29] wip --- tests/BrewTest.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/BrewTest.php b/tests/BrewTest.php index adc950cae..056b9098b 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -400,37 +400,37 @@ public function test_it_can_get_php_binary_path_from_php_version() // Scenario when there is no linked valet php exists $files = Mockery::mock(Filesystem::class); $cli = Mockery::mock(CommandLine::class); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(false); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn("/opt/homebrew/Cellar/php@7.4"); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); - $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); - $files->shouldReceive('symlinkAsUser')->once()->withArgs(["/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); swap(CommandLine::class, $cli); swap(Filesystem::class, $files); - $this->assertEquals("/opt/homebrew/Cellar/php@7.4/7.4.6/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); // Scenario when user has installed directly though shivammathur/homebrew-php $files = Mockery::mock(Filesystem::class); $cli = Mockery::mock(CommandLine::class); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(false); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn("/opt/homebrew/Cellar/php@7.4"); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"installed":[{"version":"7.4.5"}]}]'); - $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php")->andReturn(false); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php")->andReturn(false); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); - $files->shouldReceive('symlinkAsUser')->once()->withArgs(["/opt/homebrew/opt/php@7.4/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX ."/opt/php@7.4/bin/php", BREW_PREFIX."/bin/valetphp74"]); swap(CommandLine::class, $cli); swap(Filesystem::class, $files); - $this->assertEquals("/opt/homebrew/opt/php@7.4/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX ."/opt/php@7.4/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); // Scenario when there is a linked valet php exists $files = Mockery::mock(Filesystem::class); $cli = Mockery::mock(CommandLine::class); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn(true); - $files->shouldReceive('readLink')->once()->with(BREW_PREFIX. "/bin/valetphp74")->andReturn("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php"); - $files->shouldReceive('exists')->once()->with("/opt/homebrew/Cellar/php@7.4/7.4.5/bin/php")->andReturn(true); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(true); + $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php"); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php")->andReturn(true); swap(CommandLine::class, $cli); swap(Filesystem::class, $files); - $this->assertEquals(BREW_PREFIX. "/bin/valetphp74", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/bin/valetphp74", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); // Scenario when non php version is proivided $files = Mockery::mock(Filesystem::class); From 720fed1a431bd7b3c29da9065432c4289b12f659 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 19:07:45 +0600 Subject: [PATCH 10/29] refactor code & tests --- cli/Valet/Brew.php | 53 +++++++++++++++++--------- cli/valet.php | 5 ++- tests/BrewTest.php | 92 +++++++++++++++++++++++++++++----------------- 3 files changed, 96 insertions(+), 54 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index d42e63b80..8caf5a43b 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -303,37 +303,59 @@ function ($version) use ($resolvedPhpVersion) { * Get PHP binary path for a given PHP Version * * @param string|null $phpVersion + * @param boolean $skipCache * * @return string */ - public function getPhpBinaryPath($phpVersion = null) + public function whichPhp($phpVersion = null, $skipCache = false) { if(! $phpVersion){ return BREW_PREFIX.'/bin/php'; } - $phpBinaryPath = null; $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); $symlinkedValetPhpPath = BREW_PREFIX. "/bin/valetphp{$versionInteger}"; - // If the symlinked valet php path exists, then we can use that - if ($this->files->isLink($symlinkedValetPhpPath)) { + // If the symlinked Valet PHP path exists, then we can use that + if (!$skipCache && $this->files->isLink($symlinkedValetPhpPath)) { $phpBinaryPath = $this->files->readLink($symlinkedValetPhpPath); - // Still make sure that the version of the binrary exists + // Still make sure that the version of the binary exists if ($this->files->exists($phpBinaryPath)) { - return $symlinkedValetPhpPath; + return $phpBinaryPath; } } - // If the symlinked valet php path doesn't exist, then we need to look for the correct binary path + // Create a symlink to the Valet PHP version, so next time valet won't have to look for the binary path + if ($phpBinaryPath = $this->getPhpBinaryPath($phpVersion)) { + $this->files->symlinkAsUser($phpBinaryPath, $symlinkedValetPhpPath); + } + + return $phpBinaryPath ?: BREW_PREFIX.'/bin/php'; + } + + + /** + * Get PHP binary path from PHP Version + * + * @param string $phpVersion + * @return string + */ + public function getPhpBinaryPath($phpVersion) + { + $phpBinaryPath = null; + + // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct binary path $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); // Example output: `/opt/homebrew/Cellar/php@8.0` - $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion")); + $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion"), true); + $phpDirectory = data_get($details, '0.linked_keg'); + + if (is_null($phpDirectory) && $installed = data_get($details, '0.installed')) { + $phpDirectory = data_get(collect($installed)->where('installed_as_dependency', false)->last(), 'version'); - if (!empty($details[0]->linked_keg)) { - $phpDirectory = $details[0]->linked_keg; - } elseif (!empty($details[0]->installed[0]->version)) { - $phpDirectory = $details[0]->installed[0]->version; + if (is_null($phpDirectory)) { + $phpDirectory = data_get(collect($installed)->last(), 'version'); + } } if (isset($phpDirectory) && $this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { @@ -345,12 +367,7 @@ public function getPhpBinaryPath($phpVersion = null) $phpBinaryPath = BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } - // Create a symlink to the valet php version, so next time valet won't have to look for the binary path - if($phpBinaryPath){ - $this->files->symlinkAsUser($phpBinaryPath, $symlinkedValetPhpPath); - } - - return $phpBinaryPath ?: BREW_PREFIX.'/bin/php'; + return $phpBinaryPath; } /** diff --git a/cli/valet.php b/cli/valet.php index e91fd81b1..dcc7ce9f6 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -564,7 +564,7 @@ /** * Get PHP Birnary */ - $app->command('which-php [site]', function ($site = null) { + $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; $phpVersion = Site::customPhpVersion($host); @@ -577,9 +577,10 @@ $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; - return output(Brew::getPhpBinaryPath($phpVersion)); + return output(Brew::whichPhp($phpVersion, $skipCache)); })->descriptions('Get the PHP binary path for a given site', [ 'site' => 'The site to get the PHP binary path for', + '--skip-cache' => 'Force a re-check of the PHP binary path', ]); /** diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 056b9098b..15cf21828 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -395,49 +395,73 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ $brewMock->restartLinkedPhp(); } - public function test_it_can_get_php_binary_path_from_php_version() + public function test_it_can_get_php_binary_path_from_php_version_and_create_symblink() { - // Scenario when there is no linked valet php exists - $files = Mockery::mock(Filesystem::class); - $cli = Mockery::mock(CommandLine::class); + // Scenario when there is no linked Valet PHP exists + $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4')); + + // Scenario when there is a linked Valet PHP exists + $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $brewMock->shouldNotHaveReceived('getPhpBinaryPath'); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(true); + $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php"); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php")->andReturn(true); + $files->shouldNotHaveReceived('symlinkAsUser'); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php", $brewMock->whichPhp('php@8.1')); + + // Check with $skipCache enabled + $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4', true)); + + // Scenario when non PHP Version is proivided + $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), Mockery::mock(Filesystem::class)])->makePartial(); + $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->whichPhp(null)); + } + + public function test_it_can_get_php_binary_path_from_php_version() + { + // linked_keg + $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); - swap(CommandLine::class, $cli); - swap(Filesystem::class, $files); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); + + // no linked_keg + $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.0")->andReturn(BREW_PREFIX."/Cellar/php@8.0"); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.0")->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpBinaryPath('php@8.0')); + + // installed_as_dependency + $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.1")->andReturn(BREW_PREFIX."/Cellar/php@8.1"); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.1") + ->andReturn('[{"installed":[{"version":"8.1.1", "installed_as_dependency":true}, {"version":"8.1.2", "installed_as_dependency":false}]}]'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpBinaryPath('php@8.1')); + + // installed_as_dependency 2 + $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4") + ->andReturn('[{"installed":[{"version":"7.4.1", "installed_as_dependency":false}, {"version":"7.4.3", "installed_as_dependency":false}]}]'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); // Scenario when user has installed directly though shivammathur/homebrew-php - $files = Mockery::mock(Filesystem::class); - $cli = Mockery::mock(CommandLine::class); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); + $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"installed":[{"version":"7.4.5"}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php")->andReturn(false); + $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn(false); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX ."/opt/php@7.4/bin/php", BREW_PREFIX."/bin/valetphp74"]); - swap(CommandLine::class, $cli); - swap(Filesystem::class, $files); - $this->assertEquals(BREW_PREFIX ."/opt/php@7.4/bin/php", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); - - // Scenario when there is a linked valet php exists - $files = Mockery::mock(Filesystem::class); - $cli = Mockery::mock(CommandLine::class); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(true); - $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php"); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.5/bin/php")->andReturn(true); - swap(CommandLine::class, $cli); - swap(Filesystem::class, $files); - $this->assertEquals(BREW_PREFIX."/bin/valetphp74", resolve(Brew::class)->getPhpBinaryPath('php@7.4')); - - // Scenario when non php version is proivided - $files = Mockery::mock(Filesystem::class); - $cli = Mockery::mock(CommandLine::class); - swap(CommandLine::class, $cli); - swap(Filesystem::class, $files); - $this->assertEquals(BREW_PREFIX.'/bin/php', resolve(Brew::class)->getPhpBinaryPath(null)); + $this->assertEquals(BREW_PREFIX."/opt/php@7.4/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); } /** From 84f59b48904f8f08864e18265c56f4dafd02f5f0 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 22 Mar 2022 19:44:10 +0600 Subject: [PATCH 11/29] test readability --- tests/BrewTest.php | 76 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 15cf21828..93266e2b1 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -397,70 +397,114 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ public function test_it_can_get_php_binary_path_from_php_version_and_create_symblink() { - // Scenario when there is no linked Valet PHP exists - $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when there is no symlinked Valet PHP exists + $brewMock = Mockery::mock(Brew::class, [ + Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4')); - // Scenario when there is a linked Valet PHP exists - $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when there is a symlinked Valet PHP exists + $brewMock = Mockery::mock(Brew::class, [ + Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $brewMock->shouldNotHaveReceived('getPhpBinaryPath'); $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(true); $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php"); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php")->andReturn(true); $files->shouldNotHaveReceived('symlinkAsUser'); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php", $brewMock->whichPhp('php@8.1')); // Check with $skipCache enabled - $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $brewMock = Mockery::mock(Brew::class, [ + Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4', true)); - // Scenario when non PHP Version is proivided - $brewMock = Mockery::mock(Brew::class, [Mockery::mock(CommandLine::class), Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when no PHP Version is proivided + $brewMock = Mockery::mock(Brew::class, [ + Mockery::mock(CommandLine::class), + Mockery::mock(Filesystem::class) + ])->makePartial(); + $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->whichPhp(null)); } public function test_it_can_get_php_binary_path_from_php_version() { - // linked_keg - $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when brew info has `linked_keg` + $brewMock = Mockery::mock(Brew::class, [ + $cli = Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); - // no linked_keg - $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when brew info doesn't have `linked_keg` + $brewMock = Mockery::mock(Brew::class, [ + $cli = Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.0")->andReturn(BREW_PREFIX."/Cellar/php@8.0"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.0")->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpBinaryPath('php@8.0')); - // installed_as_dependency - $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when brew info has a version with that was not installed_as_dependency + $brewMock = Mockery::mock(Brew::class, [ + $cli = Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.1")->andReturn(BREW_PREFIX."/Cellar/php@8.1"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.1") ->andReturn('[{"installed":[{"version":"8.1.1", "installed_as_dependency":true}, {"version":"8.1.2", "installed_as_dependency":false}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpBinaryPath('php@8.1')); - // installed_as_dependency 2 - $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + // Scenario when brew info has no version that was installed manually, it should pick the last PHP version + $brewMock = Mockery::mock(Brew::class, [ + $cli = Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4") ->andReturn('[{"installed":[{"version":"7.4.1", "installed_as_dependency":false}, {"version":"7.4.3", "installed_as_dependency":false}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); // Scenario when user has installed directly though shivammathur/homebrew-php - $brewMock = Mockery::mock(Brew::class, [$cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class)])->makePartial(); + $brewMock = Mockery::mock(Brew::class, [ + $cli = Mockery::mock(CommandLine::class), + $files = Mockery::mock(Filesystem::class) + ])->makePartial(); + $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn(false); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); + $this->assertEquals(BREW_PREFIX."/opt/php@7.4/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); } From ca2924daca0874213403181f0603445bc9c66b49 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Wed, 23 Mar 2022 01:35:30 +0600 Subject: [PATCH 12/29] Self code review --- cli/Valet/Brew.php | 35 ++++++++++++++++++----------------- cli/valet.php | 24 ++++++++++++++---------- tests/BrewTest.php | 18 +++++++++--------- valet | 10 ++++++---- 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 8caf5a43b..b721b0bf3 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -300,7 +300,7 @@ function ($version) use ($resolvedPhpVersion) { /** - * Get PHP binary path for a given PHP Version + * Get PHP executable path for a given PHP Version * * @param string|null $phpVersion * @param boolean $skipCache @@ -318,34 +318,35 @@ public function whichPhp($phpVersion = null, $skipCache = false) // If the symlinked Valet PHP path exists, then we can use that if (!$skipCache && $this->files->isLink($symlinkedValetPhpPath)) { - $phpBinaryPath = $this->files->readLink($symlinkedValetPhpPath); + $phpExecutablePath = $this->files->readLink($symlinkedValetPhpPath); - // Still make sure that the version of the binary exists - if ($this->files->exists($phpBinaryPath)) { - return $phpBinaryPath; + // Still make sure that the version of the executable exists + if ($this->files->exists($phpExecutablePath)) { + return $phpExecutablePath; } } - // Create a symlink to the Valet PHP version, so next time valet won't have to look for the binary path - if ($phpBinaryPath = $this->getPhpBinaryPath($phpVersion)) { - $this->files->symlinkAsUser($phpBinaryPath, $symlinkedValetPhpPath); + // Create a symlink to the Valet PHP version, so next time valet won't have to look for the executable path + if ($phpExecutablePath = $this->getPhpExecutablePath($phpVersion)) { + $this->files->symlinkAsUser($phpExecutablePath, $symlinkedValetPhpPath); } - return $phpBinaryPath ?: BREW_PREFIX.'/bin/php'; + return $phpExecutablePath ?: BREW_PREFIX.'/bin/php'; } /** - * Get PHP binary path from PHP Version + * Extract PHP executable path from PHP Version * * @param string $phpVersion + * * @return string */ - public function getPhpBinaryPath($phpVersion) + public function getPhpExecutablePath($phpVersion) { - $phpBinaryPath = null; + $phpExecutablePath = null; - // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct binary path + // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct executable path $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); // Example output: `/opt/homebrew/Cellar/php@8.0` $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion"), true); $phpDirectory = data_get($details, '0.linked_keg'); @@ -359,15 +360,15 @@ public function getPhpBinaryPath($phpVersion) } if (isset($phpDirectory) && $this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { - $phpBinaryPath = trim($cellar).'/'.$phpDirectory.'/bin/php'; + $phpExecutablePath = trim($cellar).'/'.$phpDirectory.'/bin/php'; } // When PHP Version is installed directly though shivammathur/homebrew-php, it usually stores the binaries in this directory - if (is_null($phpBinaryPath) && $this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { - $phpBinaryPath = BREW_PREFIX."/opt/{$phpVersion}/bin/php"; + if (is_null($phpExecutablePath) && $this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { + $phpExecutablePath = BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } - return $phpBinaryPath; + return $phpExecutablePath; } /** diff --git a/cli/valet.php b/cli/valet.php index 220ff1d1c..c1c438d6a 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -562,7 +562,7 @@ })->descriptions('List all sites using isolated versions of PHP.'); /** - * Get PHP Birnary + * Get PHP Executable */ $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; @@ -578,24 +578,28 @@ $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; return output(Brew::whichPhp($phpVersion, $skipCache)); - })->descriptions('Get the PHP binary path for a given site', [ - 'site' => 'The site to get the PHP binary path for', - '--skip-cache' => 'Force a re-check of the PHP binary path', + })->descriptions('Get the PHP executable path for a given site', [ + 'site' => 'The site to get the PHP executable path for', + '--skip-cache' => 'Force re-check of the PHP executable path', ]); /** - * Proxy PHP Commands with correct version + * Proxy PHP commands with isolated site's PHP executable */ - $app->command('php', function () { + $app->command('php [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); - })->descriptions('Proxy PHP Commands with isolated PHP version'); + })->descriptions("Proxy PHP commands with isolated site's PHP executable", [ + 'command' => "Command to run with isolated site's PHP executable", + ]); /** - * Proxy composer commands with the "php" binary on the isolated site + * Proxy Composer commands with isolated site's PHP executable */ - $app->command('composer', function () { + $app->command('composer [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); - })->descriptions('Proxy composer Commands with isolated PHP version'); + })->descriptions("Proxy Composer commands with isolated site's PHP executable", [ + 'command' => "Composer command to run with isolated site's PHP executable", + ]); /** * Tail log file. diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 93266e2b1..9d9e26ac4 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -395,7 +395,7 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ $brewMock->restartLinkedPhp(); } - public function test_it_can_get_php_binary_path_from_php_version_and_create_symblink() + public function test_it_can_get_php_binary_path_from_php_version_and_create_symlink() { // Scenario when there is no symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ @@ -405,7 +405,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_symb $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); - $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4')); @@ -415,7 +415,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_symb $files = Mockery::mock(Filesystem::class) ])->makePartial(); - $brewMock->shouldNotHaveReceived('getPhpBinaryPath'); + $brewMock->shouldNotHaveReceived('getPhpExecutablePath'); $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(true); $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php"); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php")->andReturn(true); @@ -429,7 +429,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_symb $files = Mockery::mock(Filesystem::class) ])->makePartial(); - $brewMock->shouldReceive('getPhpBinaryPath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4', true)); @@ -455,7 +455,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); // Scenario when brew info doesn't have `linked_keg` $brewMock = Mockery::mock(Brew::class, [ @@ -467,7 +467,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.0")->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php")->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpBinaryPath('php@8.0')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpExecutablePath('php@8.0')); // Scenario when brew info has a version with that was not installed_as_dependency $brewMock = Mockery::mock(Brew::class, [ @@ -480,7 +480,7 @@ public function test_it_can_get_php_binary_path_from_php_version() ->andReturn('[{"installed":[{"version":"8.1.1", "installed_as_dependency":true}, {"version":"8.1.2", "installed_as_dependency":false}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php")->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpBinaryPath('php@8.1')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpExecutablePath('php@8.1')); // Scenario when brew info has no version that was installed manually, it should pick the last PHP version $brewMock = Mockery::mock(Brew::class, [ @@ -493,7 +493,7 @@ public function test_it_can_get_php_binary_path_from_php_version() ->andReturn('[{"installed":[{"version":"7.4.1", "installed_as_dependency":false}, {"version":"7.4.3", "installed_as_dependency":false}]}]'); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php")->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); // Scenario when user has installed directly though shivammathur/homebrew-php $brewMock = Mockery::mock(Brew::class, [ @@ -505,7 +505,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn(false); $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); - $this->assertEquals(BREW_PREFIX."/opt/php@7.4/bin/php", $brewMock->getPhpBinaryPath('php@7.4')); + $this->assertEquals(BREW_PREFIX."/opt/php@7.4/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); } /** diff --git a/valet b/valet index d7964a9f5..cd01a1132 100755 --- a/valet +++ b/valet @@ -75,23 +75,25 @@ then ARCH=$(uname -m) if [[ $ARCH == 'arm64' ]]; then - sudo -u "$USER" "$DIR/bin/ngrok-arm" http "$HOST.$TLD:$PORT" -host-header=rewrite $PARAMS + "$DIR/bin/ngrok-arm" http "$HOST.$TLD:$PORT" -host-header=rewrite $PARAMS else - sudo -u "$USER" "$DIR/bin/ngrok" http "$HOST.$TLD:$PORT" -host-header=rewrite $PARAMS + "$DIR/bin/ngrok" http "$HOST.$TLD:$PORT" -host-header=rewrite $PARAMS fi exit -# Proxy PHP commands to the "php" binary on the isolated site +# Proxy PHP commands to the "php" executable on the isolated site elif [[ "$1" = "php" ]] then $(php "$DIR/cli/valet.php" which-php) "${@:2}" + exit -# Proxy composer commands with the "php" binary on the isolated site +# Proxy Composer commands with the "php" executable on the isolated site elif [[ "$1" = "composer" ]] then $(php "$DIR/cli/valet.php" which-php) $(which composer) "${@:2}" + exit # Finally, for every other command we will just proxy into the PHP tool From faeee5eb9a88aa4470ad2c5270216278ec80a913 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 23 Mar 2022 02:02:49 +0600 Subject: [PATCH 13/29] Apply suggestions from code review --- cli/Valet/Brew.php | 4 ++-- cli/valet.php | 2 +- tests/BrewTest.php | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index b721b0bf3..f4bc0a862 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -326,7 +326,8 @@ public function whichPhp($phpVersion = null, $skipCache = false) } } - // Create a symlink to the Valet PHP version, so next time valet won't have to look for the executable path + // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct executable path + // Create a symlink to the Valet PHP version, so next time Valet won't have to look for the executable path if ($phpExecutablePath = $this->getPhpExecutablePath($phpVersion)) { $this->files->symlinkAsUser($phpExecutablePath, $symlinkedValetPhpPath); } @@ -346,7 +347,6 @@ public function getPhpExecutablePath($phpVersion) { $phpExecutablePath = null; - // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct executable path $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); // Example output: `/opt/homebrew/Cellar/php@8.0` $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion"), true); $phpDirectory = data_get($details, '0.linked_keg'); diff --git a/cli/valet.php b/cli/valet.php index c1c438d6a..2728a74b3 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -562,7 +562,7 @@ })->descriptions('List all sites using isolated versions of PHP.'); /** - * Get PHP Executable + * Get the PHP executable path for a site */ $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 9d9e26ac4..52dc39ac5 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -397,7 +397,7 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ public function test_it_can_get_php_binary_path_from_php_version_and_create_symlink() { - // Scenario when there is no symlinked Valet PHP exists + // When there is no symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -409,7 +409,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4')); - // Scenario when there is a symlinked Valet PHP exists + // When there is a symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -434,7 +434,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4', true)); - // Scenario when no PHP Version is proivided + // When no PHP Version is provided $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), Mockery::mock(Filesystem::class) @@ -445,7 +445,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml public function test_it_can_get_php_binary_path_from_php_version() { - // Scenario when brew info has `linked_keg` + // When brew info has `linked_keg` paramert $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -457,7 +457,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); - // Scenario when brew info doesn't have `linked_keg` + // When brew info doesn't have `linked_keg` $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -469,7 +469,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpExecutablePath('php@8.0')); - // Scenario when brew info has a version with that was not installed_as_dependency + // When brew info has a version that was manually installed $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -482,7 +482,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpExecutablePath('php@8.1')); - // Scenario when brew info has no version that was installed manually, it should pick the last PHP version + // When brew info has no version that was installed manually, it should pick the last PHP version $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) @@ -495,7 +495,7 @@ public function test_it_can_get_php_binary_path_from_php_version() $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); - // Scenario when user has installed directly though shivammathur/homebrew-php + // When user has installed directly though `shivammathur/homebrew-php` $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) From 67ba790e370ec1e5e23d3a451373507afc107244 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 23 Mar 2022 03:25:41 +0600 Subject: [PATCH 14/29] Update cli/valet.php --- cli/valet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/valet.php b/cli/valet.php index 2728a74b3..88086c516 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -562,7 +562,7 @@ })->descriptions('List all sites using isolated versions of PHP.'); /** - * Get the PHP executable path for a site + * Get the PHP executable path for a site */ $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; From 605118d3e4357a61f84c84f861f07952c1ad20a0 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 23 Mar 2022 03:46:11 +0600 Subject: [PATCH 15/29] Update tests/BrewTest.php --- tests/BrewTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 52dc39ac5..982f9ab78 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -445,7 +445,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml public function test_it_can_get_php_binary_path_from_php_version() { - // When brew info has `linked_keg` paramert + // When brew info has `linked_keg` paramerter $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class) From 6f085bc70e04b65e6a365f8e9be37250f1157118 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Wed, 23 Mar 2022 04:11:58 +0600 Subject: [PATCH 16/29] StyleCI Patch --- cli/Valet/Brew.php | 18 ++++------ cli/valet.php | 10 +++--- tests/BrewTest.php | 82 +++++++++++++++++++++++----------------------- 3 files changed, 53 insertions(+), 57 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index f4bc0a862..8cc2b78e8 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -298,26 +298,24 @@ function ($version) use ($resolvedPhpVersion) { }); } - /** - * Get PHP executable path for a given PHP Version - * - * @param string|null $phpVersion - * @param boolean $skipCache + * Get PHP executable path for a given PHP Version. * + * @param string|null $phpVersion + * @param bool $skipCache * @return string */ public function whichPhp($phpVersion = null, $skipCache = false) { - if(! $phpVersion){ + if (! $phpVersion) { return BREW_PREFIX.'/bin/php'; } $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); - $symlinkedValetPhpPath = BREW_PREFIX. "/bin/valetphp{$versionInteger}"; + $symlinkedValetPhpPath = BREW_PREFIX."/bin/valetphp{$versionInteger}"; // If the symlinked Valet PHP path exists, then we can use that - if (!$skipCache && $this->files->isLink($symlinkedValetPhpPath)) { + if (! $skipCache && $this->files->isLink($symlinkedValetPhpPath)) { $phpExecutablePath = $this->files->readLink($symlinkedValetPhpPath); // Still make sure that the version of the executable exists @@ -335,12 +333,10 @@ public function whichPhp($phpVersion = null, $skipCache = false) return $phpExecutablePath ?: BREW_PREFIX.'/bin/php'; } - /** - * Extract PHP executable path from PHP Version + * Extract PHP executable path from PHP Version. * * @param string $phpVersion - * * @return string */ public function getPhpExecutablePath($phpVersion) diff --git a/cli/valet.php b/cli/valet.php index 88086c516..ee7f730e2 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -562,13 +562,13 @@ })->descriptions('List all sites using isolated versions of PHP.'); /** - * Get the PHP executable path for a site + * Get the PHP executable path for a site. */ $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; $phpVersion = Site::customPhpVersion($host); - if(! $phpVersion){ + if (! $phpVersion) { $path = getcwd().'/.valetphprc'; if (file_exists($path)) { $phpVersion = trim(file_get_contents($path)); @@ -584,16 +584,16 @@ ]); /** - * Proxy PHP commands with isolated site's PHP executable + * Proxy PHP commands with isolated site's PHP executable. */ $app->command('php [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); - })->descriptions("Proxy PHP commands with isolated site's PHP executable", [ + })->descriptions("Proxy PHP commands with isolated site's PHP executable", [ 'command' => "Command to run with isolated site's PHP executable", ]); /** - * Proxy Composer commands with isolated site's PHP executable + * Proxy Composer commands with isolated site's PHP executable. */ $app->command('composer [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 982f9ab78..c5df0e746 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -400,44 +400,44 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml // When there is no symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp74")->andReturn(false); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); - $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX.'/bin/valetphp74')->andReturn(false); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', BREW_PREFIX.'/bin/valetphp74']); + $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php'); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->whichPhp('php@7.4')); // When there is a symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); $brewMock->shouldNotHaveReceived('getPhpExecutablePath'); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(true); - $files->shouldReceive('readLink')->once()->with(BREW_PREFIX."/bin/valetphp81")->andReturn(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php"); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php")->andReturn(true); + $files->shouldReceive('isLink')->once()->with(BREW_PREFIX.'/bin/valetphp81')->andReturn(true); + $files->shouldReceive('readLink')->once()->with(BREW_PREFIX.'/bin/valetphp81')->andReturn(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php')->andReturn(true); $files->shouldNotHaveReceived('symlinkAsUser'); - $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.5/bin/php", $brewMock->whichPhp('php@8.1')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php', $brewMock->whichPhp('php@8.1')); // Check with $skipCache enabled $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php"); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", BREW_PREFIX."/bin/valetphp74"]); + $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php'); + $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', BREW_PREFIX.'/bin/valetphp74']); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->whichPhp('php@7.4', true)); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->whichPhp('php@7.4', true)); // When no PHP Version is provided $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), - Mockery::mock(Filesystem::class) + Mockery::mock(Filesystem::class), ])->makePartial(); $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->whichPhp(null)); @@ -445,67 +445,67 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml public function test_it_can_get_php_binary_path_from_php_version() { - // When brew info has `linked_keg` paramerter + // When brew info has `linked_keg` parameter $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php")->andReturn(true); + $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); + $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4')->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php')->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.6/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); // When brew info doesn't have `linked_keg` $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.0")->andReturn(BREW_PREFIX."/Cellar/php@8.0"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.0")->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php")->andReturn(true); + $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@8.0')->andReturn(BREW_PREFIX.'/Cellar/php@8.0'); + $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@8.0')->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.0/8.0.5/bin/php')->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@8.0/8.0.5/bin/php", $brewMock->getPhpExecutablePath('php@8.0')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.0/8.0.5/bin/php', $brewMock->getPhpExecutablePath('php@8.0')); // When brew info has a version that was manually installed $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@8.1")->andReturn(BREW_PREFIX."/Cellar/php@8.1"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@8.1") + $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@8.1')->andReturn(BREW_PREFIX.'/Cellar/php@8.1'); + $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@8.1') ->andReturn('[{"installed":[{"version":"8.1.1", "installed_as_dependency":true}, {"version":"8.1.2", "installed_as_dependency":false}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php")->andReturn(true); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.1/8.1.2/bin/php')->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@8.1/8.1.2/bin/php", $brewMock->getPhpExecutablePath('php@8.1')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.1/8.1.2/bin/php', $brewMock->getPhpExecutablePath('php@8.1')); // When brew info has no version that was installed manually, it should pick the last PHP version $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4") + $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); + $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4') ->andReturn('[{"installed":[{"version":"7.4.1", "installed_as_dependency":false}, {"version":"7.4.3", "installed_as_dependency":false}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php")->andReturn(true); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@7.4/7.4.3/bin/php')->andReturn(true); - $this->assertEquals(BREW_PREFIX."/Cellar/php@7.4/7.4.3/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); + $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.3/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); // When user has installed directly though `shivammathur/homebrew-php` $brewMock = Mockery::mock(Brew::class, [ $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class) + $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with("brew --cellar php@7.4")->andReturn(BREW_PREFIX."/Cellar/php@7.4"); - $cli->shouldReceive('runAsUser')->once()->with("brew info --json php@7.4")->andReturn(false); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX."/opt/php@7.4/bin/php")->andReturn(true); + $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); + $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4')->andReturn(false); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(true); - $this->assertEquals(BREW_PREFIX."/opt/php@7.4/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); + $this->assertEquals(BREW_PREFIX.'/opt/php@7.4/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); } /** From fbf96b9abcf1f15e5cfb90f270da2f225a4f250f Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 23 Mar 2022 14:16:57 +0600 Subject: [PATCH 17/29] Apply suggestions from code review Co-authored-by: Shifat Hossain <52673893+shifat160@users.noreply.github.com> --- cli/valet.php | 2 +- tests/BrewTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/valet.php b/cli/valet.php index ee7f730e2..32605f657 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -584,7 +584,7 @@ ]); /** - * Proxy PHP commands with isolated site's PHP executable. + * Proxy PHP commands with isolated site's PHP executable file. */ $app->command('php [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); diff --git a/tests/BrewTest.php b/tests/BrewTest.php index c5df0e746..f67dfbe02 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -409,7 +409,7 @@ public function test_it_can_get_php_binary_path_from_php_version_and_create_syml $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->whichPhp('php@7.4')); - // When there is a symlinked Valet PHP exists + // When a symlinked Valet PHP exists $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class), From 6d3d191f44f3edf3df5f8bf24f9d15725cef3f41 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Thu, 24 Mar 2022 05:15:45 +0600 Subject: [PATCH 18/29] [wip] Valet run/refactor with brew opt (#9) --- cli/Valet/Brew.php | 122 +++++++++++++++++++++------------------------ cli/valet.php | 5 +- tests/BrewTest.php | 114 ++++++++++++------------------------------ 3 files changed, 92 insertions(+), 149 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 8cc2b78e8..93599365f 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -251,16 +251,7 @@ public function getParsedLinkedPhp() $resolvedPath = $this->files->readLink(BREW_PREFIX.'/bin/php'); - /** - * Typical homebrew path resolutions are like: - * "../Cellar/php@7.4/7.4.13/bin/php" - * or older styles: - * "../Cellar/php/7.4.9_2/bin/php - * "../Cellar/php55/bin/php. - */ - preg_match('~\w{3,}/(php)(@?\d\.?\d)?/(\d\.\d)?([_\d\.]*)?/?\w{3,}~', $resolvedPath, $matches); - - return $matches; + return $this->parsePhpPath($resolvedPath); } /** @@ -289,82 +280,46 @@ public function linkedPhp() return $this->supportedPhpVersions()->first( function ($version) use ($resolvedPhpVersion) { - $resolvedVersionNormalized = preg_replace('/[^\d]/', '', $resolvedPhpVersion); - $versionNormalized = preg_replace('/[^\d]/', '', $version); - - return $resolvedVersionNormalized === $versionNormalized; + return $this->isPhpVersionsEqual($resolvedPhpVersion, $version); }, function () use ($resolvedPhpVersion) { throw new DomainException("Unable to determine linked PHP when parsing '$resolvedPhpVersion'"); }); } /** - * Get PHP executable path for a given PHP Version. + * Extract PHP executable path from PHP Version. * - * @param string|null $phpVersion - * @param bool $skipCache + * @param string $phpVersion * @return string */ - public function whichPhp($phpVersion = null, $skipCache = false) + public function getPhpExecutablePath($phpVersion = null) { if (! $phpVersion) { return BREW_PREFIX.'/bin/php'; } - $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); - $symlinkedValetPhpPath = BREW_PREFIX."/bin/valetphp{$versionInteger}"; - - // If the symlinked Valet PHP path exists, then we can use that - if (! $skipCache && $this->files->isLink($symlinkedValetPhpPath)) { - $phpExecutablePath = $this->files->readLink($symlinkedValetPhpPath); - - // Still make sure that the version of the executable exists - if ($this->files->exists($phpExecutablePath)) { - return $phpExecutablePath; - } + // Check the default `/opt/homebrew/opt/php@8.1/bin/php` location first + if ($this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { + return BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } - // If the symlinked Valet PHP path doesn't exist, then we need to look for the correct executable path - // Create a symlink to the Valet PHP version, so next time Valet won't have to look for the executable path - if ($phpExecutablePath = $this->getPhpExecutablePath($phpVersion)) { - $this->files->symlinkAsUser($phpExecutablePath, $symlinkedValetPhpPath); + // Check the `/opt/homebrew/opt/php71/bin/php` location for older installations + $phpVersion = str_replace(['@', '.'], '' , $phpVersion); // php@8.1 to php81 + if ($this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { + return BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } - return $phpExecutablePath ?: BREW_PREFIX.'/bin/php'; - } - - /** - * Extract PHP executable path from PHP Version. - * - * @param string $phpVersion - * @return string - */ - public function getPhpExecutablePath($phpVersion) - { - $phpExecutablePath = null; - - $cellar = $this->cli->runAsUser("brew --cellar $phpVersion"); // Example output: `/opt/homebrew/Cellar/php@8.0` - $details = json_decode($this->cli->runAsUser("brew info --json $phpVersion"), true); - $phpDirectory = data_get($details, '0.linked_keg'); - - if (is_null($phpDirectory) && $installed = data_get($details, '0.installed')) { - $phpDirectory = data_get(collect($installed)->where('installed_as_dependency', false)->last(), 'version'); - - if (is_null($phpDirectory)) { - $phpDirectory = data_get(collect($installed)->last(), 'version'); + // Check if the default PHP is the version we are looking for + if ($this->files->isLink(BREW_PREFIX."/opt/php")) { + $resolvedPath = $this->files->readLink(BREW_PREFIX."/opt/php"); + $matches = $this->parsePhpPath($resolvedPath); + $resolvedPhpVersion = $matches[3] ?: $matches[2]; + if ($this->isPhpVersionsEqual($resolvedPhpVersion, $phpVersion)) { + return BREW_PREFIX."/opt/php/bin/php"; } } - if (isset($phpDirectory) && $this->files->exists(trim($cellar).'/'.$phpDirectory.'/bin/php')) { - $phpExecutablePath = trim($cellar).'/'.$phpDirectory.'/bin/php'; - } - - // When PHP Version is installed directly though shivammathur/homebrew-php, it usually stores the binaries in this directory - if (is_null($phpExecutablePath) && $this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { - $phpExecutablePath = BREW_PREFIX."/opt/{$phpVersion}/bin/php"; - } - - return $phpExecutablePath; + return BREW_PREFIX.'/bin/php'; } /** @@ -532,4 +487,41 @@ function ($exitCode, $errorOutput) { } ); } + + /** + * Parse homebrew PHP Path + * + * @param string $resolvedPath + * + * @return mixed + */ + public function parsePhpPath($resolvedPath) + { + /** + * Typical homebrew path resolutions are like: + * "../Cellar/php@7.4/7.4.13/bin/php" + * or older styles: + * "../Cellar/php/7.4.9_2/bin/php + * "../Cellar/php55/bin/php. + */ + preg_match('~\w{3,}/(php)(@?\d\.?\d)?/(\d\.\d)?([_\d\.]*)?/?\w{3,}~', $resolvedPath, $matches); + + return $matches; + } + + /** + * Check if two PHP versions are equal + * + * @param string $resolvedPhpVersion + * @param string $version + * + * @return bool + */ + public function isPhpVersionsEqual($resolvedPhpVersion, $version) + { + $resolvedVersionNormalized = preg_replace('/[^\d]/', '', $resolvedPhpVersion); + $versionNormalized = preg_replace('/[^\d]/', '', $version); + + return $resolvedVersionNormalized === $versionNormalized; + } } diff --git a/cli/valet.php b/cli/valet.php index 32605f657..972da2e6a 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -564,7 +564,7 @@ /** * Get the PHP executable path for a site. */ - $app->command('which-php [site] [--skip-cache]', function ($site, $skipCache) { + $app->command('which-php [site]', function ($site) { $host = Site::host($site ?: getcwd()).'.'.Configuration::read()['tld']; $phpVersion = Site::customPhpVersion($host); @@ -577,10 +577,9 @@ $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; - return output(Brew::whichPhp($phpVersion, $skipCache)); + return output(Brew::getPhpExecutablePath($phpVersion)); })->descriptions('Get the PHP executable path for a given site', [ 'site' => 'The site to get the PHP executable path for', - '--skip-cache' => 'Force re-check of the PHP executable path', ]); /** diff --git a/tests/BrewTest.php b/tests/BrewTest.php index f67dfbe02..0551b18a8 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -395,117 +395,69 @@ public function test_restart_linked_php_will_pass_through_linked_php_formula_to_ $brewMock->restartLinkedPhp(); } - public function test_it_can_get_php_binary_path_from_php_version_and_create_symlink() + public function test_it_can_get_php_binary_path_from_php_version() { - // When there is no symlinked Valet PHP exists + // Check the default `/opt/homebrew/opt/php@8.1/bin/php` location first $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX.'/bin/valetphp74')->andReturn(false); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', BREW_PREFIX.'/bin/valetphp74']); - $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php'); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->whichPhp('php@7.4')); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(true); + $files->shouldNotReceive('exists')->with(BREW_PREFIX.'/opt/php@74/bin/php'); + $this->assertEquals(BREW_PREFIX.'/opt/php@7.4/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); - // When a symlinked Valet PHP exists + // Check the `/opt/homebrew/opt/php71/bin/php` location for older installations $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $brewMock->shouldNotHaveReceived('getPhpExecutablePath'); - $files->shouldReceive('isLink')->once()->with(BREW_PREFIX.'/bin/valetphp81')->andReturn(true); - $files->shouldReceive('readLink')->once()->with(BREW_PREFIX.'/bin/valetphp81')->andReturn(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php')->andReturn(true); - $files->shouldNotHaveReceived('symlinkAsUser'); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.1/8.1.5/bin/php', $brewMock->whichPhp('php@8.1')); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(false); + $files->shouldReceive('exists')->with(BREW_PREFIX.'/opt/php74/bin/php')->andReturn(true); + $this->assertEquals(BREW_PREFIX.'/opt/php74/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); - // Check with $skipCache enabled + // When the default PHP is the version we are looking for $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $brewMock->shouldReceive('getPhpExecutablePath')->once()->with('php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php'); - $files->shouldReceive('symlinkAsUser')->once()->withArgs([BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', BREW_PREFIX.'/bin/valetphp74']); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->whichPhp('php@7.4', true)); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(false); + $files->shouldReceive('exists')->with(BREW_PREFIX.'/opt/php74/bin/php')->andReturn(false); + $files->shouldReceive('isLink')->with(BREW_PREFIX."/opt/php")->andReturn(true); + $files->shouldReceive('readLink')->with(BREW_PREFIX."/opt/php")->andReturn('../Cellar/php@7.4/7.4.13/bin/php'); + $this->assertEquals(BREW_PREFIX."/opt/php/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); - // When no PHP Version is provided + // When the default PHP is not the version we are looking for $brewMock = Mockery::mock(Brew::class, [ Mockery::mock(CommandLine::class), - Mockery::mock(Filesystem::class), - ])->makePartial(); - - $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->whichPhp(null)); - } - - public function test_it_can_get_php_binary_path_from_php_version() - { - // When brew info has `linked_keg` parameter - $brewMock = Mockery::mock(Brew::class, [ - $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class), - ])->makePartial(); - - $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); - $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4')->andReturn('[{"linked_keg":"7.4.6","installed":[{"version":"7.4.5"}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php')->andReturn(true); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.6/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); - - // When brew info doesn't have `linked_keg` - $brewMock = Mockery::mock(Brew::class, [ - $cli = Mockery::mock(CommandLine::class), $files = Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@8.0')->andReturn(BREW_PREFIX.'/Cellar/php@8.0'); - $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@8.0')->andReturn('[{"installed":[{"version":"8.0.5"}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.0/8.0.5/bin/php')->andReturn(true); + $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(false); + $files->shouldReceive('exists')->with(BREW_PREFIX.'/opt/php74/bin/php')->andReturn(false); + $files->shouldReceive('isLink')->with(BREW_PREFIX."/opt/php")->andReturn(true); + $files->shouldReceive('readLink')->with(BREW_PREFIX."/opt/php")->andReturn('../Cellar/php@8.1/8.1.13/bin/php'); + $this->assertEquals(BREW_PREFIX."/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); // Could not find a version, so retuned the default binary - $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.0/8.0.5/bin/php', $brewMock->getPhpExecutablePath('php@8.0')); - - // When brew info has a version that was manually installed - $brewMock = Mockery::mock(Brew::class, [ - $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class), - ])->makePartial(); - - $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@8.1')->andReturn(BREW_PREFIX.'/Cellar/php@8.1'); - $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@8.1') - ->andReturn('[{"installed":[{"version":"8.1.1", "installed_as_dependency":true}, {"version":"8.1.2", "installed_as_dependency":false}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@8.1/8.1.2/bin/php')->andReturn(true); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@8.1/8.1.2/bin/php', $brewMock->getPhpExecutablePath('php@8.1')); - - // When brew info has no version that was installed manually, it should pick the last PHP version + // When no PHP Version is provided $brewMock = Mockery::mock(Brew::class, [ - $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class), + Mockery::mock(CommandLine::class), + Mockery::mock(Filesystem::class), ])->makePartial(); - $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); - $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4') - ->andReturn('[{"installed":[{"version":"7.4.1", "installed_as_dependency":false}, {"version":"7.4.3", "installed_as_dependency":false}]}]'); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/Cellar/php@7.4/7.4.3/bin/php')->andReturn(true); - - $this->assertEquals(BREW_PREFIX.'/Cellar/php@7.4/7.4.3/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); - - // When user has installed directly though `shivammathur/homebrew-php` - $brewMock = Mockery::mock(Brew::class, [ - $cli = Mockery::mock(CommandLine::class), - $files = Mockery::mock(Filesystem::class), - ])->makePartial(); + $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->getPhpExecutablePath(null)); + } - $cli->shouldReceive('runAsUser')->once()->with('brew --cellar php@7.4')->andReturn(BREW_PREFIX.'/Cellar/php@7.4'); - $cli->shouldReceive('runAsUser')->once()->with('brew info --json php@7.4')->andReturn(false); - $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(true); + public function test_it_can_compare_two_php_versions() + { + $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@7.1')); + $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@71')); + $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', '71')); - $this->assertEquals(BREW_PREFIX.'/opt/php@7.4/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); + $this->assertFalse(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@70')); + $this->assertFalse(resolve(Brew::class)->isPhpVersionsEqual('php71', '72')); } /** From 23aebbe1d96d2f04d2c1759226a76a8c9e162451 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Thu, 24 Mar 2022 05:17:13 +0600 Subject: [PATCH 19/29] StyleCI Patch --- cli/Valet/Brew.php | 18 ++++++++---------- tests/BrewTest.php | 12 ++++++------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 93599365f..ad7ef1ca8 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -304,18 +304,18 @@ public function getPhpExecutablePath($phpVersion = null) } // Check the `/opt/homebrew/opt/php71/bin/php` location for older installations - $phpVersion = str_replace(['@', '.'], '' , $phpVersion); // php@8.1 to php81 + $phpVersion = str_replace(['@', '.'], '', $phpVersion); // php@8.1 to php81 if ($this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { return BREW_PREFIX."/opt/{$phpVersion}/bin/php"; } // Check if the default PHP is the version we are looking for - if ($this->files->isLink(BREW_PREFIX."/opt/php")) { - $resolvedPath = $this->files->readLink(BREW_PREFIX."/opt/php"); + if ($this->files->isLink(BREW_PREFIX.'/opt/php')) { + $resolvedPath = $this->files->readLink(BREW_PREFIX.'/opt/php'); $matches = $this->parsePhpPath($resolvedPath); $resolvedPhpVersion = $matches[3] ?: $matches[2]; if ($this->isPhpVersionsEqual($resolvedPhpVersion, $phpVersion)) { - return BREW_PREFIX."/opt/php/bin/php"; + return BREW_PREFIX.'/opt/php/bin/php'; } } @@ -489,10 +489,9 @@ function ($exitCode, $errorOutput) { } /** - * Parse homebrew PHP Path + * Parse homebrew PHP Path. * * @param string $resolvedPath - * * @return mixed */ public function parsePhpPath($resolvedPath) @@ -510,11 +509,10 @@ public function parsePhpPath($resolvedPath) } /** - * Check if two PHP versions are equal - * - * @param string $resolvedPhpVersion - * @param string $version + * Check if two PHP versions are equal. * + * @param string $resolvedPhpVersion + * @param string $version * @return bool */ public function isPhpVersionsEqual($resolvedPhpVersion, $version) diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 0551b18a8..56d4e942e 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -425,9 +425,9 @@ public function test_it_can_get_php_binary_path_from_php_version() $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(false); $files->shouldReceive('exists')->with(BREW_PREFIX.'/opt/php74/bin/php')->andReturn(false); - $files->shouldReceive('isLink')->with(BREW_PREFIX."/opt/php")->andReturn(true); - $files->shouldReceive('readLink')->with(BREW_PREFIX."/opt/php")->andReturn('../Cellar/php@7.4/7.4.13/bin/php'); - $this->assertEquals(BREW_PREFIX."/opt/php/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); + $files->shouldReceive('isLink')->with(BREW_PREFIX.'/opt/php')->andReturn(true); + $files->shouldReceive('readLink')->with(BREW_PREFIX.'/opt/php')->andReturn('../Cellar/php@7.4/7.4.13/bin/php'); + $this->assertEquals(BREW_PREFIX.'/opt/php/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); // When the default PHP is not the version we are looking for $brewMock = Mockery::mock(Brew::class, [ @@ -437,9 +437,9 @@ public function test_it_can_get_php_binary_path_from_php_version() $files->shouldReceive('exists')->once()->with(BREW_PREFIX.'/opt/php@7.4/bin/php')->andReturn(false); $files->shouldReceive('exists')->with(BREW_PREFIX.'/opt/php74/bin/php')->andReturn(false); - $files->shouldReceive('isLink')->with(BREW_PREFIX."/opt/php")->andReturn(true); - $files->shouldReceive('readLink')->with(BREW_PREFIX."/opt/php")->andReturn('../Cellar/php@8.1/8.1.13/bin/php'); - $this->assertEquals(BREW_PREFIX."/bin/php", $brewMock->getPhpExecutablePath('php@7.4')); // Could not find a version, so retuned the default binary + $files->shouldReceive('isLink')->with(BREW_PREFIX.'/opt/php')->andReturn(true); + $files->shouldReceive('readLink')->with(BREW_PREFIX.'/opt/php')->andReturn('../Cellar/php@8.1/8.1.13/bin/php'); + $this->assertEquals(BREW_PREFIX.'/bin/php', $brewMock->getPhpExecutablePath('php@7.4')); // Could not find a version, so retuned the default binary // When no PHP Version is provided $brewMock = Mockery::mock(Brew::class, [ From 9a9f73faf98ce9c136d7df719ed7015610cb01f9 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Thu, 24 Mar 2022 18:21:50 +0600 Subject: [PATCH 20/29] Update cli/Valet/Brew.php --- cli/Valet/Brew.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index ad7ef1ca8..3078af74f 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -492,7 +492,7 @@ function ($exitCode, $errorOutput) { * Parse homebrew PHP Path. * * @param string $resolvedPath - * @return mixed + * @return array */ public function parsePhpPath($resolvedPath) { From 40cb21ec915d6b90afcc0060d87a66e59e21c646 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Tue, 29 Mar 2022 08:56:01 +0600 Subject: [PATCH 21/29] Apply suggestions from code review Co-authored-by: Matt Stauffer --- cli/Valet/Brew.php | 19 ++++++++++--------- cli/valet.php | 4 ++-- tests/BrewTest.php | 10 +++++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 3078af74f..ad2246daf 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -280,7 +280,7 @@ public function linkedPhp() return $this->supportedPhpVersions()->first( function ($version) use ($resolvedPhpVersion) { - return $this->isPhpVersionsEqual($resolvedPhpVersion, $version); + return $this->arePhpVersionsEqual($resolvedPhpVersion, $version); }, function () use ($resolvedPhpVersion) { throw new DomainException("Unable to determine linked PHP when parsing '$resolvedPhpVersion'"); }); @@ -289,7 +289,7 @@ function ($version) use ($resolvedPhpVersion) { /** * Extract PHP executable path from PHP Version. * - * @param string $phpVersion + * @param string $phpVersion For example, "php@8.1" * @return string */ public function getPhpExecutablePath($phpVersion = null) @@ -314,7 +314,8 @@ public function getPhpExecutablePath($phpVersion = null) $resolvedPath = $this->files->readLink(BREW_PREFIX.'/opt/php'); $matches = $this->parsePhpPath($resolvedPath); $resolvedPhpVersion = $matches[3] ?: $matches[2]; - if ($this->isPhpVersionsEqual($resolvedPhpVersion, $phpVersion)) { + + if ($this->arePhpVersionsEqual($resolvedPhpVersion, $phpVersion)) { return BREW_PREFIX.'/opt/php/bin/php'; } } @@ -511,15 +512,15 @@ public function parsePhpPath($resolvedPath) /** * Check if two PHP versions are equal. * - * @param string $resolvedPhpVersion - * @param string $version + * @param string $versionA + * @param string $versionB * @return bool */ - public function isPhpVersionsEqual($resolvedPhpVersion, $version) + public function arePhpVersionsEqual($versionA, $version) { - $resolvedVersionNormalized = preg_replace('/[^\d]/', '', $resolvedPhpVersion); - $versionNormalized = preg_replace('/[^\d]/', '', $version); + $versionANormalized = preg_replace('/[^\d]/', '', $versionA); + $versionBNormalized = preg_replace('/[^\d]/', '', $versionB); - return $resolvedVersionNormalized === $versionNormalized; + return $versionANormalized === $versionBNormalized; } } diff --git a/cli/valet.php b/cli/valet.php index 972da2e6a..0edad92be 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -583,7 +583,7 @@ ]); /** - * Proxy PHP commands with isolated site's PHP executable file. + * Proxy commands through to an isolated site's version of PHP. */ $app->command('php [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); @@ -592,7 +592,7 @@ ]); /** - * Proxy Composer commands with isolated site's PHP executable. + * Proxy commands through to an isolated site's version of Composer. */ $app->command('composer [command]', function ($command) { warning('It looks like you are running `cli/valet.php` directly; please use the `valet` script in the project root instead.'); diff --git a/tests/BrewTest.php b/tests/BrewTest.php index 56d4e942e..c96f35415 100644 --- a/tests/BrewTest.php +++ b/tests/BrewTest.php @@ -452,12 +452,12 @@ public function test_it_can_get_php_binary_path_from_php_version() public function test_it_can_compare_two_php_versions() { - $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@7.1')); - $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@71')); - $this->assertTrue(resolve(Brew::class)->isPhpVersionsEqual('php71', '71')); + $this->assertTrue(resolve(Brew::class)->arePhpVersionsEqual('php71', 'php@7.1')); + $this->assertTrue(resolve(Brew::class)->arePhpVersionsEqual('php71', 'php@71')); + $this->assertTrue(resolve(Brew::class)->arePhpVersionsEqual('php71', '71')); - $this->assertFalse(resolve(Brew::class)->isPhpVersionsEqual('php71', 'php@70')); - $this->assertFalse(resolve(Brew::class)->isPhpVersionsEqual('php71', '72')); + $this->assertFalse(resolve(Brew::class)->arePhpVersionsEqual('php71', 'php@70')); + $this->assertFalse(resolve(Brew::class)->arePhpVersionsEqual('php71', '72')); } /** From 1838945f57d9e059b4680a7c131b8709c47cae9a Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 29 Mar 2022 09:01:22 +0600 Subject: [PATCH 22/29] Fix typo on arePhpVersionsEqual --- cli/Valet/Brew.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index ad2246daf..28e9478be 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -516,7 +516,7 @@ public function parsePhpPath($resolvedPath) * @param string $versionB * @return bool */ - public function arePhpVersionsEqual($versionA, $version) + public function arePhpVersionsEqual($versionA, $versionB) { $versionANormalized = preg_replace('/[^\d]/', '', $versionA); $versionBNormalized = preg_replace('/[^\d]/', '', $versionB); From dd8c8fc66306053b409f631d4b5c1aac0df4d48e Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 29 Mar 2022 09:10:07 +0600 Subject: [PATCH 23/29] add normalizePhpVersion inside getPhpExecutablePath --- cli/Valet/Brew.php | 2 ++ cli/Valet/PhpFpm.php | 2 +- cli/valet.php | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 28e9478be..b5a8bd94f 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -298,6 +298,8 @@ public function getPhpExecutablePath($phpVersion = null) return BREW_PREFIX.'/bin/php'; } + $phpVersion = PhpFpm::normalizePhpVersion($phpVersion); + // Check the default `/opt/homebrew/opt/php@8.1/bin/php` location first if ($this->files->exists(BREW_PREFIX."/opt/{$phpVersion}/bin/php")) { return BREW_PREFIX."/opt/{$phpVersion}/bin/php"; diff --git a/cli/Valet/PhpFpm.php b/cli/Valet/PhpFpm.php index 990a37355..bd124f329 100644 --- a/cli/Valet/PhpFpm.php +++ b/cli/Valet/PhpFpm.php @@ -322,7 +322,7 @@ public function symlinkPrimaryValetSock($phpVersion) /** * If passed php7.4, or php74, 7.4, or 74 formats, normalize to php@7.4 format. */ - public function normalizePhpVersion($version) + public static function normalizePhpVersion($version) { return preg_replace('/(?:php@?)?([0-9+])(?:.)?([0-9+])/i', 'php@$1.$2', $version); } diff --git a/cli/valet.php b/cli/valet.php index 0edad92be..70002eed2 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -575,8 +575,6 @@ } } - $phpVersion = $phpVersion ? PhpFpm::normalizePhpVersion($phpVersion) : null; - return output(Brew::getPhpExecutablePath($phpVersion)); })->descriptions('Get the PHP executable path for a given site', [ 'site' => 'The site to get the PHP executable path for', From 0202f7773a67d1e76bd3e315448a8874d7b875e5 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Tue, 29 Mar 2022 23:17:32 +0600 Subject: [PATCH 24/29] remove static from normalizePhpVersion --- cli/Valet/Brew.php | 1 + cli/Valet/PhpFpm.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index b5a8bd94f..53e9d3288 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -2,6 +2,7 @@ namespace Valet; +use PhpFpm; use DomainException; class Brew diff --git a/cli/Valet/PhpFpm.php b/cli/Valet/PhpFpm.php index bd124f329..990a37355 100644 --- a/cli/Valet/PhpFpm.php +++ b/cli/Valet/PhpFpm.php @@ -322,7 +322,7 @@ public function symlinkPrimaryValetSock($phpVersion) /** * If passed php7.4, or php74, 7.4, or 74 formats, normalize to php@7.4 format. */ - public static function normalizePhpVersion($version) + public function normalizePhpVersion($version) { return preg_replace('/(?:php@?)?([0-9+])(?:.)?([0-9+])/i', 'php@$1.$2', $version); } From d198d7739c7deee560ed7c455c9be9016de6de3b Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 30 Mar 2022 03:48:03 +0600 Subject: [PATCH 25/29] wip - refactor with valetphprc version (#10) --- cli/Valet/Brew.php | 2 +- cli/Valet/Site.php | 18 +++++++++++++++++ cli/valet.php | 23 ++++++++++++---------- tests/SiteTest.php | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 53e9d3288..828eabe46 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -2,8 +2,8 @@ namespace Valet; -use PhpFpm; use DomainException; +use PhpFpm; class Brew { diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index c1a315281..7922c8593 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -3,6 +3,7 @@ namespace Valet; use DomainException; +use PhpFpm; class Site { @@ -1108,4 +1109,21 @@ public function replaceSockFile($siteConf, $phpVersion) return '# '.ISOLATED_PHP_VERSION.'='.$phpVersion.PHP_EOL.$siteConf; } + + /** + * Get PHP version from .valetphprc for a site. + * + * @param string $site + * @return string|null + */ + public function phpRcVersion($site) + { + if ($site = $this->parked()->merge($this->links())->where('site', $site)->first()) { + $path = data_get($site, 'path').'/.valetphprc'; + + if ($this->files->exists($path)) { + return PhpFpm::normalizePhpVersion(trim($this->files->get($path))); + } + } + } } diff --git a/cli/valet.php b/cli/valet.php index 70002eed2..ecb5fd922 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -506,18 +506,19 @@ */ $app->command('use [phpVersion] [--force]', function ($phpVersion, $force) { if (! $phpVersion) { - $path = getcwd().'/.valetphprc'; + $site = basename(getcwd()); $linkedVersion = Brew::linkedPhp(); - if (! file_exists($path)) { + $phpVersion = Site::phpRcVersion($site); + + if (! $phpVersion) { return info("Valet is using {$linkedVersion}."); } - $phpVersion = trim(file_get_contents($path)); - info("Found '{$path}' specifying version: {$phpVersion}"); - - if ($linkedVersion == $phpVersion) { + if ($linkedVersion == $phpVersion && ! $force) { return info("Valet is already using {$linkedVersion}."); } + + info("Found '{$site}' specifying version: {$phpVersion}"); } PhpFpm::useVersion($phpVersion, $force); @@ -533,6 +534,11 @@ $site = basename(getcwd()); } + if (! $phpVersion) { + $phpVersion = Site::phpRcVersion($site); + info("Found '{$site}' specifying version: {$phpVersion}"); + } + PhpFpm::isolateDirectory($site, $phpVersion); })->descriptions('Change the version of PHP used by Valet to serve the current working directory', [ 'phpVersion' => 'The PHP version you want to use; e.g php@8.1', @@ -569,10 +575,7 @@ $phpVersion = Site::customPhpVersion($host); if (! $phpVersion) { - $path = getcwd().'/.valetphprc'; - if (file_exists($path)) { - $phpVersion = trim(file_get_contents($path)); - } + $phpVersion = Site::phpRcVersion($site ?: basename(getcwd())); } return output(Brew::getPhpExecutablePath($phpVersion)); diff --git a/tests/SiteTest.php b/tests/SiteTest.php index abe836047..9b5d6064b 100644 --- a/tests/SiteTest.php +++ b/tests/SiteTest.php @@ -819,6 +819,55 @@ public function test_it_returns_secured_sites() $this->assertSame(['helloworld.tld'], $sites); } + + public function test_it_can_read_php_rc_version() + { + $config = Mockery::mock(Configuration::class); + $files = Mockery::mock(Filesystem::class); + + swap(Configuration::class, $config); + swap(Filesystem::class, $files); + + $siteMock = Mockery::mock(Site::class, [ + resolve(Configuration::class), + resolve(CommandLine::class), + resolve(Filesystem::class) + ])->makePartial(); + + swap(Site::class, $siteMock); + + $config->shouldReceive('read') + ->andReturn(['tld' => 'test', 'loopback' => VALET_LOOPBACK, 'paths' => []]); + + $siteMock->shouldReceive('parked') + ->andReturn(collect([ + 'site1' => [ + 'site' => 'site1', + 'secured' => '', + 'url' => 'http://site1.test', + 'path' => '/Users/name/code/site1', + ], + ])); + + $siteMock->shouldReceive('links')->andReturn(collect([ + 'site2' => [ + 'site' => 'site2', + 'secured' => 'X', + 'url' => 'http://site2.test', + 'path' => '/Users/name/some-other-directory/site2', + ], + ])); + + $files->shouldReceive('exists')->with('/Users/name/code/site1/.valetphprc')->andReturn(true); + $files->shouldReceive('get')->with('/Users/name/code/site1/.valetphprc')->andReturn('php@8.1'); + + $files->shouldReceive('exists')->with('/Users/name/some-other-directory/site2/.valetphprc')->andReturn(true); + $files->shouldReceive('get')->with('/Users/name/some-other-directory/site2/.valetphprc')->andReturn('php@8.0'); + + $this->assertEquals('php@8.1', $siteMock->phpRcVersion('site1')); + $this->assertEquals('php@8.0', $siteMock->phpRcVersion('site2')); + $this->assertEquals(null, $siteMock->phpRcVersion('site3')); // Site doesn't exists + } } class CommandLineFake extends CommandLine From 2acd133f9f31746006d188f5f25c7dbe8e830117 Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Wed, 30 Mar 2022 03:49:06 +0600 Subject: [PATCH 26/29] StyleCI Patch --- cli/valet.php | 2 +- tests/SiteTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/valet.php b/cli/valet.php index ecb5fd922..f8fc69c4d 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -514,7 +514,7 @@ return info("Valet is using {$linkedVersion}."); } - if ($linkedVersion == $phpVersion && ! $force) { + if ($linkedVersion == $phpVersion && ! $force) { return info("Valet is already using {$linkedVersion}."); } diff --git a/tests/SiteTest.php b/tests/SiteTest.php index 9b5d6064b..7899b0707 100644 --- a/tests/SiteTest.php +++ b/tests/SiteTest.php @@ -831,7 +831,7 @@ public function test_it_can_read_php_rc_version() $siteMock = Mockery::mock(Site::class, [ resolve(Configuration::class), resolve(CommandLine::class), - resolve(Filesystem::class) + resolve(Filesystem::class), ])->makePartial(); swap(Site::class, $siteMock); From 390f87eaa82d065beba5d8d3e3391f95c77fb62c Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 30 Mar 2022 11:10:11 +0600 Subject: [PATCH 27/29] Update cli/valet.php Co-authored-by: Matt Stauffer --- cli/valet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/valet.php b/cli/valet.php index f8fc69c4d..ea1329d93 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -518,7 +518,7 @@ return info("Valet is already using {$linkedVersion}."); } - info("Found '{$site}' specifying version: {$phpVersion}"); + info("Found '{$site}/.valetphprc' specifying version: {$phpVersion}"); } PhpFpm::useVersion($phpVersion, $force); From 6bc502446db04d6c0ba3d62a863f2a62c774bd07 Mon Sep 17 00:00:00 2001 From: Nasir Uddin Nobin Date: Wed, 30 Mar 2022 11:11:43 +0600 Subject: [PATCH 28/29] Update cli/valet.php --- cli/valet.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cli/valet.php b/cli/valet.php index ea1329d93..246ef3ac7 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -534,10 +534,6 @@ $site = basename(getcwd()); } - if (! $phpVersion) { - $phpVersion = Site::phpRcVersion($site); - info("Found '{$site}' specifying version: {$phpVersion}"); - } PhpFpm::isolateDirectory($site, $phpVersion); })->descriptions('Change the version of PHP used by Valet to serve the current working directory', [ From 804a924c539875ba7f1e939d027bd5e412fb1fbb Mon Sep 17 00:00:00 2001 From: NasirNobin Date: Wed, 30 Mar 2022 11:13:21 +0600 Subject: [PATCH 29/29] StyleCI Patch --- cli/valet.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/valet.php b/cli/valet.php index 246ef3ac7..ffc0e78ae 100755 --- a/cli/valet.php +++ b/cli/valet.php @@ -534,7 +534,6 @@ $site = basename(getcwd()); } - PhpFpm::isolateDirectory($site, $phpVersion); })->descriptions('Change the version of PHP used by Valet to serve the current working directory', [ 'phpVersion' => 'The PHP version you want to use; e.g php@8.1',