diff --git a/README.MD b/README.MD index 7cd3e9c5..1c08ff33 100644 --- a/README.MD +++ b/README.MD @@ -13,7 +13,7 @@ Valet+ is a development environment for macOS. No Vagrant, no Docker, no `/etc/h > :warning: Valet+ requires [Composer](https://getcomposer.org/) to be installed. -To get started, you first need to ensure that Homebrew is up to date using the update command: +To get started, you first need to ensure that Homebrew is up-to-date using the update command: ```shell brew update ``` diff --git a/cli/includes/find-usable-php.php b/cli/includes/find-usable-php.php new file mode 100644 index 00000000..f01c4c53 --- /dev/null +++ b/cli/includes/find-usable-php.php @@ -0,0 +1,101 @@ += 0) { + // Current linked php is the correct version. + echo exec('which php'); + + return; +} + +// If not, let's find it whether we have the required version of PHP installed; +// all users that run through this code path will see Valet run more slowly +$phps = explode(PHP_EOL, trim(shell_exec('brew list --formula | grep php'))); + +// Normalize version numbers +$phps = array_reduce($phps, function ($carry, $php) { + $carry[$php] = presumePhpVersionFromBrewFormulaName($php); + + return $carry; +}, []); + +// If we don't have the required run version of PHP, throw an error +if (array_search($runPhpVersion, $phps) === false) { + throw new Exception("Sorry, but you don't have the required version of PHP ($runPhpVersion) installed to run Valet+."); +} + +echo getPhpExecutablePath(array_search($runPhpVersion, $phps)); +return; + + +// Filter out older versions of PHP +$modernPhps = array_filter($phps, function ($php) use ($runPhpVersion) { + return version_compare($php, $runPhpVersion) >= 0; +}); + +// If we don't have any modern versions of PHP, throw an error +if (empty($modernPhps)) { + throw new Exception('Sorry, but you do not have a version of PHP installed that is compatible with Valet (8+).'); +} + +// Sort newest version to oldest +sort($modernPhps); +$modernPhps = array_reverse($modernPhps); + +// Grab the highest, set as $foundVersion, and output its path +$foundVersion = reset($modernPhps); +echo getPhpExecutablePath(array_search($foundVersion, $phps)); + +/** + * Function definitions. + */ + +/** + * Extract PHP executable path from PHP Version. + * Copied from Brew.php and modified. + * + * @param string|null $phpFormulaName For example, "php@8.1" + * @return string + */ +function getPhpExecutablePath(?string $phpFormulaName = null) +{ + $brewPrefix = exec('printf $(brew --prefix)'); + + // Check the default `/opt/homebrew/opt/php@8.1/bin/php` location first + if (file_exists($brewPrefix."/opt/{$phpFormulaName}/bin/php")) { + return $brewPrefix."/opt/{$phpFormulaName}/bin/php"; + } + + // Check the `/opt/homebrew/opt/php71/bin/php` location for older installations + $oldPhpFormulaName = str_replace(['@', '.'], '', $phpFormulaName); // php@7.1 to php71 + if (file_exists($brewPrefix."/opt/{$oldPhpFormulaName}/bin/php")) { + return $brewPrefix."/opt/{$oldPhpFormulaName}/bin/php"; + } + + throw new Exception('Cannot find an executable path for provided PHP version: '.$phpFormulaName); +} + +function presumePhpVersionFromBrewFormulaName(string $formulaName) +{ + if ($formulaName === 'php') { + // Figure out its link + $details = json_decode(shell_exec("brew info $formulaName --json")); + + if (! empty($details[0]->aliases[0])) { + $formulaName = $details[0]->aliases[0]; + } else { + return null; + } + } + + if (strpos($formulaName, 'php@') === false) { + return null; + } + + return substr($formulaName, strpos($formulaName, '@') + 1); +} diff --git a/valet-plus b/valet-plus index 6fdb1ca4..042a99a7 100755 --- a/valet-plus +++ b/valet-plus @@ -29,12 +29,12 @@ if [ ! -d "$LARAVEL_DIR" ]; then LARAVEL_DIR=$(php -r "echo realpath('$DIR/../../laravel/valet');") fi -# Get a command-line executable we can use for php that's 8+; if this +# Get a command-line executable we can use for the required php version; if this # is the inside loop (Valet runs itself 2x in some settings), skip # checking and pulling again by reading the exported env var if [[ $PHP_EXECUTABLE = "" ]] then - PHP=$(php $LARAVEL_DIR/find-usable-php.php) + PHP=$(php $DIR/cli/includes/find-usable-php.php) # Validate output before running it on the CLI if [[ ! -f $PHP ]]; then @@ -49,6 +49,7 @@ else PHP=$PHP_EXECUTABLE 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.