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

Add Expose support, drop ngrok binary and move it to be managed by Brew, drop copying ngrok share URL to clipbaord

* Extract basic driver with public/ from basic driver, and simplify both

* Apply fixes from StyleCI

* Set HTTP_HOST in BaseDriverTest

* Move server helpers to their own file; add type hints

* Update drivers location and loading

- Extract much of server.php into a `Server` class
- Move all but the Laravel and Basic drivers into a subfolder
- Load all but the Laravel and Basic drivers via glob
- Add `beforeLoading` hook to simplify the `frontControllerPath` method for some drivers

* Apply fixes from StyleCI

* Add additional notes to upgrade.md

* Apply fixes from StyleCI

* Require PHP 8.0

* Add type hints and return type hints to Brew

* Apply fixes from StyleCI

* Add type hints and return type hints to CommandLine

* Add type hints and return type hints to Configuration

* Add type hints and return type hints to Diagnose

* Apply fixes from StyleCI

* Add type hints and return type hints to DnsMasq

* Add type hints and return hints to Filesystem

* Add type hints and return types to Nginx

* Add type hints and return types to ngrok

* Add type hints and return types to PhpFpm

* Apply fixes from StyleCI

* Add type hints and return types to Site and Valet

* Apply fixes from StyleCI

* Require passing a version number to isolate command

* Apply fixes from StyleCI

* Bump compat to php 8; add type hints and return types to helpers

* Apply fixes from StyleCI

* Use constructor promotion

* Apply fixes from StyleCI

* Write tests for Server.php

* Apply fixes from StyleCI

* Move upgrade calls into Upgrader class, and add upgrade to check for old custom drivers

* Apply fixes from StyleCI

* Replace some \n with PHP_EOL; move custom drivers into Custom namespace

* Apply fixes from StyleCI

* Add doc blocks

* Clean up NullWriter; drop legacy config check

* Allow null response from frontControllerPath

* Apply fixes from StyleCI

* Drop exits, fix 404 path

* Better handle new installations

* Apply fixes from StyleCI

* Drop extensions

* Clean up DX for fetch-share-url

* Apply fixes from StyleCI

* Fix site::unlink method signature and docblock

* Tweak the wording for the which command

* Support isolated sites running PHP 7.4

* Add a bunch more CLI command tests (#1332)

* Wip some cli tests

* Apply fixes from StyleCI

* Test parked command

* Test forget command

* Update Filesystem::rmDirAndContents to respect symlinks

* Wip cli commands

* Apply fixes from StyleCI

* Test link command, unlink command, and secure command

* Apply fixes from StyleCI

* Add tests for unsecure, unsecure --all, secured commands

Add placeholders for the remaining CLI commands
Add nginx::restart to unsecure --all command

Co-authored-by: StyleCI Bot <bot@styleci.io>

* Drop old config migrations

* Add status command (#1329)

* Build the foundation of a status command

* Apply fixes from StyleCI

* Wip testing status command

* Apply fixes from StyleCI

* Fix status test

* Apply fixes from StyleCI

* Fix race condition in creating test config file

* Apply fixes from StyleCI

* Reset container for each test

* Differentiate response code based on success or failure of status command

* Apply fixes from StyleCI

* Add the ability to test if a Brew service is running

* Apply fixes from StyleCI

* Check for more services running in status command

* Apply fixes from StyleCI

* Test Status

* Apply fixes from StyleCI

* Drop Yoast from base application test case

Co-authored-by: StyleCI Bot <bot@styleci.io>

* Test most of the remaining CLI commands

* Test set tld command

* Test set loopback command

* Test proxy, unproxy, and proxies commands

* Apply fixes from StyleCI

* Test which command

* Test diagnose command

* Test directory-listing and which-php commands

* Text isolate and unisolate and isolated commands

* Apply fixes from StyleCI

* Test trust command

* Apply fixes from StyleCI

* Test on-latest-version command

* Move uninstall text to a class, and tweak text and presentation

* Apply fixes from StyleCI

* Test use command

* Test stop command

* Test start command

* Test restart command

Co-authored-by: StyleCI Bot <bot@styleci.io>

* Drop unnecessary doc blocks (#1339)

* Drop unnecessary doc blocks

* Apply fixes from StyleCI

Co-authored-by: StyleCI Bot <bot@styleci.io>

* Tweak status output and install output

* Add debug instructions to valet status, expand "valet installed" status check

* Drop extensions directory

* Apply fixes from StyleCI

* Remove more docblocks

* Upgrade ngrok to 3.1.0

* Test force uninstall command

* Test log command

* Drop copying Ngrok share to clipboard; add first steps of Expose code

* Add logic paths for Expose vs. ngrok and the share-tool config

* Apply fixes from StyleCI

* Take the first steps of manually installing ngrok and expose when needed

* Apply fixes from StyleCI

* Next steps Brew-installed ngrok

* Apply fixes from StyleCI

* Add class to represent Composer; continue ngrok + expose updates

* Apply fixes from StyleCI

* Add ensureInstalled() method to Expose and installOrFail() to Composer

* Apply fixes from StyleCI

* Require global PHP 8+ to install

* Exit if invalid domain is passed to valet share

* Update Composer dependencies to use Illuminate/Container

* Drop the idea of passing a custom domain to valet share

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Matt Stauffer
2023-01-13 21:34:37 -05:00
committed by GitHub
parent 401a2e96fa
commit 303462ffd1
16 changed files with 462 additions and 79 deletions

View File

@@ -34,27 +34,36 @@ public function test_brew_can_be_resolved_from_container()
public function test_installed_returns_true_when_given_formula_is_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json')
->andReturn('[{"name":"php@8.2","full_name":"php@8.2","aliases":[],"versioned_formulae":[],"versions":{"stable":"8.2.5"},"installed":[{"version":"8.2.5"}]}]');
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json=v2')
->andReturn('{"formulae":[{"name":"php@8.2","full_name":"php@8.2","aliases":[],"versioned_formulae":[],"versions":{"stable":"8.2.5"},"installed":[{"version":"8.2.5"}]}]}');
swap(CommandLine::class, $cli);
$this->assertTrue(resolve(Brew::class)->installed('php@8.2'));
$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"}]}]');
$cli->shouldReceive('runAsUser')->once()->with('brew info php --json=v2')
->andReturn('{"formulae":[{"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'));
}
public function test_installed_returns_true_when_given_cask_formula_is_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info ngrok --json=v2')
->andReturn('{"casks":[{"name":"ngrok","full_name":"ngrok","aliases":[],"versioned_formulae":[],"versions":{"stable":"8.2.5"},"installed":[{"version":"8.2.5"}]}]}');
swap(CommandLine::class, $cli);
$this->assertTrue(resolve(Brew::class)->installed('ngrok'));
}
public function test_installed_returns_false_when_given_formula_is_not_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json')->andReturn('');
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json=v2')->andReturn('');
swap(CommandLine::class, $cli);
$this->assertFalse(resolve(Brew::class)->installed('php@8.2'));
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json')->andReturn('Error: No formula found');
$cli->shouldReceive('runAsUser')->once()->with('brew info php@8.2 --json=v2')->andReturn('Error: No formula found');
swap(CommandLine::class, $cli);
$this->assertFalse(resolve(Brew::class)->installed('php@8.2'));
}
@@ -112,7 +121,7 @@ public function test_tap_taps_the_given_homebrew_repository()
public function test_restart_restarts_the_service_using_homebrew_services()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info dnsmasq --json')->andReturn('[{"name":"dnsmasq","full_name":"dnsmasq","aliases":[],"versioned_formulae":[],"versions":{"stable":"1"},"installed":[{"version":"1"}]}]');
$cli->shouldReceive('runAsUser')->once()->with('brew info dnsmasq --json=v2')->andReturn('{"formulae":[{"name":"dnsmasq","full_name":"dnsmasq","aliases":[],"versioned_formulae":[],"versions":{"stable":"1"},"installed":[{"version":"1"}]}]}');
$cli->shouldReceive('quietly')->once()->with('brew services stop dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services stop dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services start dnsmasq');
@@ -123,7 +132,7 @@ public function test_restart_restarts_the_service_using_homebrew_services()
public function test_stop_stops_the_service_using_homebrew_services()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew info dnsmasq --json')->andReturn('[{"name":"dnsmasq","full_name":"dnsmasq","aliases":[],"versioned_formulae":[],"versions":{"stable":"1"},"installed":[{"version":"1"}]}]');
$cli->shouldReceive('runAsUser')->once()->with('brew info dnsmasq --json=v2')->andReturn('{"formulae":[{"name":"dnsmasq","full_name":"dnsmasq","aliases":[],"versioned_formulae":[],"versions":{"stable":"1"},"installed":[{"version":"1"}]}]}');
$cli->shouldReceive('quietly')->once()->with('brew services stop dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services stop dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo chown -R '.user().":admin '".BREW_PREFIX."/Cellar/dnsmasq'");

View File

@@ -5,6 +5,7 @@
use Valet\Configuration as RealConfiguration;
use Valet\Diagnose;
use Valet\DnsMasq;
use Valet\Expose;
use Valet\Filesystem;
use Valet\Nginx;
use Valet\Ngrok;
@@ -434,6 +435,85 @@ public function test_open_command()
$tester->assertCommandIsSuccessful();
}
public function test_get_share_tool_command()
{
[$app, $tester] = $this->appAndTester();
$tester->run(['command' => 'share-tool']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('(not set)', $tester->getDisplay());
Configuration::updateKey('share-tool', 'expose');
$tester->run(['command' => 'share-tool']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('expose', $tester->getDisplay());
}
public function test_set_share_tool_command()
{
[$app, $tester] = $this->appAndTester();
$expose = Mockery::mock(Expose::class);
$expose->shouldReceive('installed')->andReturn(true);
swap(Expose::class, $expose);
$tester->run(['command' => 'share-tool', 'tool' => 'expose']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('expose', Configuration::read()['share-tool']);
$ngrok = Mockery::mock(Ngrok::class);
$ngrok->shouldReceive('installed')->andReturn(true);
swap(Ngrok::class, $ngrok);
$tester->run(['command' => 'share-tool', 'tool' => 'ngrok']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('ngrok', Configuration::read()['share-tool']);
$tester->run(['command' => 'share-tool', 'tool' => 'asdfoijasdofijqoiwejrqwer']);
$this->assertEquals(1, $tester->getStatusCode()); // Assert comand failure
$this->assertStringContainsString('ngrok', Configuration::read()['share-tool']);
}
public function test_share_tool_prompts_expose_install()
{
[$app, $tester] = $this->appAndTester();
$tester->setInputs(['Y']);
$expose = Mockery::mock(Expose::class);
$expose->shouldReceive('installed')->once()->andReturn(false);
$expose->shouldReceive('ensureInstalled')->once();
swap(Expose::class, $expose);
$tester->run(['command' => 'share-tool', 'tool' => 'expose']);
$tester->assertCommandIsSuccessful();
}
public function test_share_tool_prompts_ngrok_install()
{
[$app, $tester] = $this->appAndTester();
$tester->setInputs(['Y']);
$ngrok = Mockery::mock(Ngrok::class);
$ngrok->shouldReceive('installed')->once()->andReturn(false);
$ngrok->shouldReceive('ensureInstalled')->once();
swap(Ngrok::class, $ngrok);
$tester->run(['command' => 'share-tool', 'tool' => 'ngrok']);
$tester->assertCommandIsSuccessful();
}
public function test_set_ngrok_token_command()
{
[$app, $tester] = $this->appAndTester();
@@ -446,6 +526,48 @@ public function test_set_ngrok_token_command()
$tester->assertCommandIsSuccessful();
}
public function test_fetch_share_url_command_with_expose()
{
[$app, $tester] = $this->appAndTester();
Configuration::updateKey('share-tool', 'expose');
$expose = Mockery::mock(Expose::class);
$expose->shouldReceive('currentTunnelUrl')->once()->andReturn('command-output');
swap(Expose::class, $expose);
$tester->run(['command' => 'fetch-share-url']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('command-output', $tester->getDisplay());
}
public function test_fetch_share_url_command_with_ngrok()
{
[$app, $tester] = $this->appAndTester();
Configuration::updateKey('share-tool', 'ngrok');
$ngrok = Mockery::mock(Ngrok::class);
$ngrok->shouldReceive('currentTunnelUrl')->once()->andReturn('command-output');
swap(Ngrok::class, $ngrok);
$tester->run(['command' => 'fetch-share-url']);
$tester->assertCommandIsSuccessful();
$this->assertStringContainsString('command-output', $tester->getDisplay());
}
public function test_fetch_share_url_command_with_unset_share_tool()
{
[$app, $tester] = $this->appAndTester();
$tester->run(['command' => 'fetch-share-url']);
$this->assertEquals(1, $tester->getStatusCode());
$this->assertStringContainsString('Please set your share tool', $tester->getDisplay());
}
public function test_restart_command()
{
[$app, $tester] = $this->appAndTester();

60
tests/ComposerTest.php Normal file
View File

@@ -0,0 +1,60 @@
<?php
use Illuminate\Container\Container;
use Valet\CommandLine;
use Valet\Composer;
use function Valet\resolve;
use function Valet\swap;
use function Valet\user;
class ComposerTest extends Yoast\PHPUnitPolyfills\TestCases\TestCase
{
use UsesNullWriter;
public function set_up()
{
$_SERVER['SUDO_USER'] = user();
Container::setInstance(new Container);
$this->setNullWriter();
}
public function tear_down()
{
Mockery::close();
}
public function test_composer_can_be_resolved_from_container()
{
$this->assertInstanceOf(Composer::class, resolve(Composer::class));
}
public function test_installed_returns_true_when_given_package_is_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('composer global show --format json -- beyondcode/expose')
->andReturn('{"name":"beyondcode/expose"}');
swap(CommandLine::class, $cli);
$this->assertTrue(resolve(Composer::class)->installed('beyondcode/expose'));
}
public function test_installed_returns_false_when_given_formula_is_not_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('composer global show --format json -- beyondcode/expose')
->andReturn("Changed current directory to /Users/mattstauffer/.composer\n\n[InvalidArgumentException]\nPackage beyondcode/expose not found");
swap(CommandLine::class, $cli);
$this->assertFalse(resolve(Composer::class)->installed('beyondcode/expose'));
}
public function test_install_or_fail_will_install_composer_package()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('composer global require beyondcode/expose', Mockery::type('Closure'));
swap(CommandLine::class, $cli);
resolve(Composer::class)->installOrFail('beyondcode/expose');
}
}

View File

@@ -1,8 +1,8 @@
<?php
use Illuminate\Container\Container;
use Valet\CommandLine;
use Valet\Ngrok;
use function Valet\resolve;
use function Valet\user;
class NgrokTest extends Yoast\PHPUnitPolyfills\TestCases\TestCase
@@ -48,7 +48,7 @@ public function test_it_matches_correct_share_tunnel()
],
];
$ngrok = new Ngrok(new CommandLine);
$ngrok = resolve(Ngrok::class);
$this->assertEquals('http://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysite'));
}
@@ -64,7 +64,7 @@ public function test_it_checks_against_lowercased_domain()
],
];
$ngrok = new Ngrok(new CommandLine);
$ngrok = resolve(Ngrok::class);
$this->assertEquals('http://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'MySite'));
}
}