1
0
mirror of https://github.com/laravel/valet.git synced 2026-02-04 16:10:08 +01:00

Allow Valet to uninstall itself

`valet uninstall` only displays information about how to manually uninstall and clean up after Valet.

This PR adds a `--force` parameter, which will forcefully remove Valet and the Homebrew services it installs, as well as clean up the config files and log files.
But for a few post-uninstall composer dependencies, cleanup is very thorough.

This brings idempotency to both `valet install` and `valet uninstall --force`

(There may still be edge cases where other Homebrew or composer packages might create interference with install/uninstall, but this makes things much easier to self-troubleshoot.)
This commit is contained in:
Chris Brown
2019-12-05 19:50:33 -05:00
parent d301e4ac11
commit 6e01bfb5f4
7 changed files with 205 additions and 32 deletions

View File

@@ -62,7 +62,7 @@ function hasInstalledPhp()
}
/**
* Get a list of supported PHP versions
* Get a list of supported PHP versions.
*
* @return \Illuminate\Support\Collection
*/
@@ -83,7 +83,7 @@ function hasInstalledNginx()
}
/**
* Return name of the nginx service installed via Homebrewed.
* Return name of the nginx service installed via Homebrew.
*
* @return string
*/
@@ -185,7 +185,7 @@ function stopService($services)
}
/**
* Determine if php is currently linked
* Determine if php is currently linked.
*
* @return bool
*/
@@ -195,7 +195,7 @@ function hasLinkedPhp()
}
/**
* Get the linked php parsed
* Get the linked php parsed.
*
* @return mixed
*/
@@ -277,7 +277,17 @@ function createSudoersEntry()
}
/**
* Link passed formula
* Remove the "sudoers.d" entry for running Brew.
*
* @return void
*/
function removeSudoersEntry()
{
$this->cli->quietly('rm /etc/sudoers.d/brew');
}
/**
* Link passed formula.
*
* @param $formula
* @param bool $force
@@ -297,7 +307,7 @@ function ($exitCode, $errorOutput) use ($formula) {
}
/**
* Unlink passed formula
* Unlink passed formula.
* @param $formula
*
* @return string
@@ -315,7 +325,7 @@ function ($exitCode, $errorOutput) use ($formula) {
}
/**
* Get the currently running brew services
* Get the currently running brew services.
*
* @return \Illuminate\Support\Collection
*/
@@ -330,4 +340,45 @@ function ($exitCode, $errorOutput) {
}
))));
}
/**
* Tell Homebrew to forcefully remove all PHP versions that Valet supports.
*
* @return string
*/
function uninstallAllPhpVersions()
{
$this->supportedPhpVersions()->each(function ($formula) {
$this->uninstallFormula($formula);
});
return 'PHP versions removed.';
}
/**
* Uninstall a Homebrew app by formula name.
* @param string $formula
*
* @return void
*/
function uninstallFormula($formula)
{
$this->cli->runAsUser('brew uninstall --force '.$formula);
$this->cli->run('rm -rf /usr/local/Cellar/'.$formula);
}
/**
* Run Homebrew's cleanup commands.
*
* @return string
*/
function cleanupBrew()
{
return $this->cli->runAsUser(
'brew cleanup && brew services cleanup',
function ($exitCode, $errorOutput) {
output($errorOutput);
}
);
}
}

View File

@@ -34,6 +34,16 @@ function install()
$this->files->chown($this->path(), user());
}
/**
* Forcefully delete the Valet home configuration directory and contents.
*
* @return void
*/
function uninstall()
{
$this->files->unlink(VALET_HOME_PATH);
}
/**
* Create the Valet configuration directory.
*

View File

@@ -51,6 +51,23 @@ function install($tld = 'test')
info('Valet is configured to serve for TLD [.'.$tld.']');
}
/**
* Forcefully uninstall dnsmasq.
*
* @return void
*/
function uninstall()
{
$this->brew->stopService('dnsmasq');
$this->brew->uninstallFormula('dnsmasq');
$this->cli->run('rm -rf /usr/local/etc/dnsmasq.d/dnsmasq-valet.conf');
}
/**
* Tell Homebrew to restart dnsmasq
*
* @return void
*/
function restart()
{
$this->brew->restartService('dnsmasq');

View File

@@ -160,12 +160,14 @@ function stop()
}
/**
* Prepare Nginx for uninstallation.
* Forcefully uninstall Nginx.
*
* @return void
*/
function uninstall()
{
$this->stop();
$this->brew->stopService(['nginx', 'nginx-full']);
$this->brew->uninstallFormula('nginx nginx-full');
$this->cli->quietly('rm -rf /usr/local/etc/nginx /usr/local/var/log/nginx');
}
}

View File

@@ -45,6 +45,18 @@ function install()
$this->restart();
}
/**
* Forcefully uninstall all of Valet's supported PHP versions and configurations
*
* @return void
*/
function uninstall()
{
$this->brew->uninstallAllPhpVersions();
rename('/usr/local/etc/php', '/usr/local/etc/php-valet-bak'.time());
$this->cli->run('rm -rf /usr/local/var/log/php-fpm.log');
}
/**
* Update the PHP FPM configuration.
*

View File

@@ -34,6 +34,16 @@ function symlinkToUsersBin()
$this->cli->runAsUser('ln -s "'.realpath(__DIR__.'/../../valet').'" '.$this->valetBin);
}
/**
* Remove the symlink from the user's local bin.
*
* @return void
*/
function unlinkFromUsersBin()
{
$this->cli->quietlyAsUser('rm '.$this->valetBin);
}
/**
* Get the paths to all of the Valet extensions.
*
@@ -81,4 +91,30 @@ function createSudoersEntry()
$this->files->put('/etc/sudoers.d/valet', 'Cmnd_Alias VALET = /usr/local/bin/valet *
%admin ALL=(root) NOPASSWD:SETENV: VALET'.PHP_EOL);
}
/**
* Remove the "sudoers.d" entry for running Valet.
*
* @return void
*/
function removeSudoersEntry()
{
$this->cli->quietly('rm /etc/sudoers.d/valet');
}
/**
* Run composer global diagnose
*/
function composerGlobalDiagnose()
{
$this->cli->runAsUser('composer global diagnose');
}
/**
* Run composer global update
*/
function composerGlobalUpdate()
{
$this->cli->runAsUser('composer global update');
}
}

View File

@@ -14,6 +14,7 @@
use Silly\Application;
use Illuminate\Container\Container;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use function Valet\info;
use function Valet\output;
use function Valet\table;
@@ -268,50 +269,94 @@
})->descriptions('Stop the Valet services');
/**
* Uninstall Valet entirely.
* Uninstall Valet entirely. Requires --force to actually remove; otherwise manual instructions are displayed.
*/
$app->command('uninstall', function () {
$app->command('uninstall [--force]', function ($input, $output, $force) {
if ($force) {
warning('YOU ARE ABOUT TO UNINSTALL Nginx, PHP, Dnsmasq and all Valet configs and logs.');
$helper = $this->getHelperSet()->get('question');
$question = new ConfirmationQuestion('Are you sure you want to proceed? ', false);
if (false === $helper->ask($input, $output, $question)) {
return warning('Uninstall aborted.');
}
info('Removing certificates for all Secured sites...');
Site::unsecureAll();
info('Removing Nginx and configs...');
Nginx::uninstall();
info('Removing Dnsmasq and configs...');
DnsMasq::uninstall();
info('Removing Valet configs and customizations...');
Configuration::uninstall();
info('Removing PHP versions and configs...');
PhpFpm::uninstall();
info('Attempting to unlink Valet from bin path...');
Valet::unlinkFromUsersBin();
info('Removing sudoers entries...');
Brew::removeSudoersEntry();
Valet::removeSudoersEntry();
return output("<fg=red>NOTE:</>
<comment>Valet has attempted to uninstall itself, but there are some steps you need to do manually:</comment>
Run <info>php -v</info> to see what PHP version you are now really using.
Run <info>composer global update</info> to update your globally-installed Composer packages to work with your default PHP.
NOTE: Composer may have other dependencies for other global apps you have installed, and those may not be compatible with your default PHP.
Thus, you may need to delete things from your <info>~/.composer/composer.json</info> file before running <info>composer global update</info> successfully.
Then to finish removing any Composer fragments of Valet:
Run <info>composer global remove laravel/valet</info>
and then <info>rm /usr/local/bin/valet</info> to remove the Valet bin link if it still exists.
Optional:
- <info>brew list</info> will show any other Homebrew services installed, in case you want to make changes to those as well.
- <info>brew doctor</info> can indicate if there might be any broken things left behind.
- <info>brew cleanup</info> can purge old cached Homebrew downloads.
<fg=red>If you had customized your Mac DNS settings in System Preferences->Network, you will need to remove 127.0.0.1 from that list.</>
Additionally you might also want to open Keychain Access and search for <comment>valet</comment> to remove any leftover trust certificates.
");
}
output("WAIT! Before you uninstall things, consider cleaning things up in the following order. (Or skip to the bottom for troubleshooting suggestions.):
<info>The uninstall of Valet is not automated</info>, since a forced removal may delete your custom configuration information.
<info>You did not pass the <fg=red>--force</> parameter so we are NOT ACTUALLY uninstalling anything.</info>
A --force removal WILL delete your custom configuration information, so you will want to make backups first.
IF YOU WANT TO UNINSTALL VALET MANUALLY, DO THE FOLLOWING...
<info>1. Valet Keychain Certificates</info>
Before removing Valet configuration files, we recommend that you run <comment>valet unsecure --all</comment> to clean up the certificates that Valet inserted into your Keychain.
Alternatively you can do a search for <comment>@laravel.valet</comment> in KeychainAccess and delete those certificates there manually.
Alternatively you can do a search for <comment>@laravel.valet</comment> in Keychain Access and delete those certificates there manually.
You may also run <comment>valet parked</comment> to see a list of all sites Valet could serve.
<info>2. Homebrew Services</info>
<fg=red>You may remove the core services (php, nginx, dnsmasq) by running:</> <comment>brew uninstall --force php nginx dnsmasq</comment>
<fg=red>You can then remove selected leftover configurations for these services manually</> in your <comment>/usr/local/etc/</comment> subdirectory.
<error>BEWARE:</error> Uninstalling PHP via Homebrew will leave your Mac with its original PHP version, which may not be compatible with other composer dependencies you have installed. Thus you may get unexpected errors.
<info>3. Valet Configuration Files</info>
<info>2. Valet Configuration Files</info>
<fg=red>You may remove your user-specific Valet config files by running:</> <comment>rm -rf ~/.config/valet</comment>
<info>4. Other Housekeeping</info>
<info>3. Remove Valet package</info>
You can run <comment>composer global remove laravel/valet</comment> to uninstall the Valet package.
<info>4. Homebrew Services</info>
<fg=red>You may remove the core services (php, nginx, dnsmasq) by running:</> <comment>brew uninstall --force php nginx dnsmasq</comment>
<fg=red>You can then remove selected leftover configurations for these services manually</> in both <comment>/usr/local/etc/</comment> and <comment>/usr/local/logs/</comment>.
(If you have other PHP versions installed, run <info>brew list | grep php</info> to see which versions you should also uninstall manually.)
<error>BEWARE:</error> Uninstalling PHP via Homebrew will leave your Mac with its original PHP version, which may not be compatible with other Composer dependencies you have installed. Thus you may get unexpected errors.
Some additional services which you may have installed (but which Valet does not directly configure or manage) include: <comment>mariadb mysql mailhog</comment>.
If you wish to also remove them, you may manually run <comment>brew uninstall SERVICENAME</comment> and clean up their configurations in /usr/local/etc if necessary.
You can discover more homebrew services by running: <comment>brew services list</comment>
You can discover more Homebrew services by running: <comment>brew services list</comment> and <comment>brew list</comment>
<info>5. Remove Valet package</info>
You can run <comment>composer global remove laravel/valet</comment> to uninstall the Valet package.
<fg=red>If you have customized your Mac DNS settings in System Preferences->Network, you may need to add or remove 127.0.0.1 from the top of that list.</>
<info>6. GENERAL TROUBLESHOOTING</info>
<info>5. GENERAL TROUBLESHOOTING</info>
If your reasons for considering an uninstall are more for troubleshooting purposes, consider running <comment>brew doctor</comment> and/or <comment>brew cleanup</comment> to see if any problems exist there.
Also consider running <comment>sudo nginx -t</comment> to test your nginx configs in case there are failures/errors there preventing nginx from running.
Most of the nginx configs used by Valet are in your ~/.config/valet/Nginx directory.
You might also want to investigate your global composer configs. Helpful commands there include:
<comment>composer global diagnose</comment> and <comment>composer global outdated</comment>
as well as <comment>composer global update</comment>
You might also want to investigate your global Composer configs. Helpful commands include:
<comment>composer global update</comment> to apply updates to packages
<comment>composer global outdated</comment> to indentify outdated packages
<comment>composer global diagnose</comment> to run diagnostics
");
// Stopping PHP so the ~/.config/valet/valet.sock file is released so the directory can be deleted if desired
PhpFpm::stopRunning();
Nginx::uninstall(); // this currently only calls stop()
})->descriptions('Uninstall the Valet services');
Nginx::stop();
})->descriptions('Uninstall the Valet services', ['--force' => 'Do a forceful uninstall of Valet and related Homebrew pkgs']);
/**
* Determine if this is the latest release of Valet.