mirror of
https://github.com/laravel/valet.git
synced 2026-02-04 08:10:07 +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:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -17,5 +17,3 @@ phpunit.xml export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
phpunit.xml.dist export-ignore
|
||||
UPGRADE.md export-ignore
|
||||
|
||||
/bin/ngrok -diff
|
||||
|
||||
@@ -27,16 +27,24 @@ public function __construct(public CommandLine $cli, public Filesystem $files)
|
||||
*/
|
||||
public function installed(string $formula): bool
|
||||
{
|
||||
$result = $this->cli->runAsUser("brew info $formula --json");
|
||||
$result = $this->cli->runAsUser("brew info $formula --json=v2");
|
||||
|
||||
// should be a json response, but if not installed then "Error: No available formula ..."
|
||||
if (starts_with($result, 'Error: No')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$details = json_decode($result);
|
||||
$details = json_decode($result, true);
|
||||
|
||||
return ! empty($details[0]->installed);
|
||||
if (! empty($details['formulae'])) {
|
||||
return ! empty($details['formulae'][0]['installed']);
|
||||
}
|
||||
|
||||
if (! empty($details['casks'])) {
|
||||
return ! is_null($details['casks'][0]['installed']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
41
cli/Valet/Composer.php
Normal file
41
cli/Valet/Composer.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Valet;
|
||||
|
||||
use DomainException;
|
||||
|
||||
class Composer
|
||||
{
|
||||
public function __construct(public CommandLine $cli)
|
||||
{
|
||||
}
|
||||
|
||||
public function installed(string $namespacedPackage): bool
|
||||
{
|
||||
$result = $this->cli->runAsUser("composer global show --format json -- $namespacedPackage");
|
||||
|
||||
if (starts_with($result, 'Changed current')) {
|
||||
$result = strstr($result, '{');
|
||||
}
|
||||
|
||||
// should be a json response, but if not installed then "not found"
|
||||
if (str_contains($result, 'InvalidArgumentException') && str_contains($result, 'not found')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$details = json_decode($result, true);
|
||||
|
||||
return ! empty($details);
|
||||
}
|
||||
|
||||
public function installOrFail(string $namespacedPackage): void
|
||||
{
|
||||
info('['.$namespacedPackage.'] is not installed, installing it now via Composer...</info> 🎼');
|
||||
|
||||
$this->cli->runAsUser(('composer global require '.$namespacedPackage), function ($exitCode, $errorOutput) use ($namespacedPackage) {
|
||||
output($errorOutput);
|
||||
|
||||
throw new DomainException('Composer was unable to install ['.$namespacedPackage.'].');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class Diagnose
|
||||
'nginx -v',
|
||||
'curl --version',
|
||||
'php --ri curl',
|
||||
'~/.composer/vendor/laravel/valet/bin/ngrok version',
|
||||
BREW_PREFIX.'/bin/ngrok version',
|
||||
'ls -al ~/.ngrok2',
|
||||
'brew info nginx',
|
||||
'brew info php',
|
||||
|
||||
33
cli/Valet/Expose.php
Normal file
33
cli/Valet/Expose.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Valet;
|
||||
|
||||
class Expose
|
||||
{
|
||||
public function __construct(public Composer $composer)
|
||||
{
|
||||
}
|
||||
|
||||
public function currentTunnelUrl(?string $domain = null): string
|
||||
{
|
||||
return '@todo';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether Expose is installed.
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->composer->installed('beyondcode/expose');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure Expose is installed.
|
||||
*/
|
||||
public function ensureInstalled(): void
|
||||
{
|
||||
if (! $this->installed()) {
|
||||
$this->composer->installOrFail('beyondcode/expose');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
class Ngrok
|
||||
{
|
||||
public $cli;
|
||||
public $tunnelsEndpoints = [
|
||||
'http://127.0.0.1:4040/api/tunnels',
|
||||
'http://127.0.0.1:4041/api/tunnels',
|
||||
];
|
||||
|
||||
public function __construct(CommandLine $cli)
|
||||
public function __construct(public CommandLine $cli, public Brew $brew)
|
||||
{
|
||||
$this->cli = $cli;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,8 +70,24 @@ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string
|
||||
/**
|
||||
* Set the Ngrok auth token.
|
||||
*/
|
||||
public function setToken($token)
|
||||
public function setToken($token): string
|
||||
{
|
||||
return $this->cli->runAsUser('./bin/ngrok authtoken '.$token);
|
||||
return $this->cli->runAsUser(BREW_PREFIX.'/bin/ngrok authtoken '.$token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether ngrok is installed.
|
||||
*/
|
||||
public function installed(): bool
|
||||
{
|
||||
return $this->brew->installed('ngrok');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure ngrok is installed.
|
||||
*/
|
||||
public function ensureInstalled(): void
|
||||
{
|
||||
$this->brew->ensureInstalled('ngrok');
|
||||
}
|
||||
}
|
||||
|
||||
74
cli/app.php
74
cli/app.php
@@ -338,16 +338,72 @@ function (ConsoleCommandEvent $event) {
|
||||
/**
|
||||
* Echo the currently tunneled URL.
|
||||
*/
|
||||
$app->command('fetch-share-url [domain]', function (OutputInterface $output, $domain = null) {
|
||||
try {
|
||||
output(Ngrok::currentTunnelUrl(Site::domain($domain)));
|
||||
} catch (\Throwable $e) {
|
||||
warning($e->getMessage());
|
||||
if ($domain) {
|
||||
warning('Make sure to leave out the TLD; `valet fetch-share-url project-name`');
|
||||
}
|
||||
$app->command('fetch-share-url [domain]', function ($domain = null) {
|
||||
$tool = Configuration::read()['share-tool'] ?? null;
|
||||
|
||||
switch ($tool) {
|
||||
case 'expose':
|
||||
output(Expose::currentTunnelUrl(Site::domain($domain)));
|
||||
break;
|
||||
case 'ngrok':
|
||||
try {
|
||||
output(Ngrok::currentTunnelUrl(Site::domain($domain)));
|
||||
} catch (\Throwable $e) {
|
||||
warning($e->getMessage());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
info('Please set your share tool with `valet share-tool expose` or `valet share-tool ngrok`.');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
})->descriptions('Get the URL to the current Ngrok tunnel');
|
||||
})->descriptions('Get the URL to the current share tunnel (for Expose or ngrok)');
|
||||
|
||||
/**
|
||||
* Echo or set the name of the currently-selected share tool (either "ngrok" or "expose").
|
||||
*/
|
||||
$app->command('share-tool [tool]', function (InputInterface $input, OutputInterface $output, $tool = null) {
|
||||
if ($tool === null) {
|
||||
return output(Configuration::read()['share-tool'] ?? '(not set)');
|
||||
}
|
||||
|
||||
if ($tool !== 'expose' && $tool !== 'ngrok') {
|
||||
warning($tool.' is not a valid share tool. Please use `ngrok` or `expose`.');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
Configuration::updateKey('share-tool', $tool);
|
||||
info('Share tool set to '.$tool.'.');
|
||||
|
||||
if ($tool === 'expose') {
|
||||
if (Expose::installed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$helper = $this->getHelperSet()->get('question');
|
||||
$question = new ConfirmationQuestion('Would you like to install Expose now? ', false);
|
||||
|
||||
if (false === $helper->ask($input, $output, $question)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Expose::ensureInstalled();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! Ngrok::installed()) {
|
||||
$helper = $this->getHelperSet()->get('question');
|
||||
$question = new ConfirmationQuestion('Would you like to install ngrok now? ', false);
|
||||
|
||||
if (false === $helper->ask($input, $output, $question)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ngrok::ensureInstalled();
|
||||
}
|
||||
})->descriptions('Get the name of the current share tool (Expose or ngrok).');
|
||||
|
||||
/**
|
||||
* Set the ngrok auth token.
|
||||
|
||||
@@ -34,6 +34,9 @@ class Nginx extends Facade
|
||||
class CommandLine extends Facade
|
||||
{
|
||||
}
|
||||
class Composer extends Facade
|
||||
{
|
||||
}
|
||||
class Configuration extends Facade
|
||||
{
|
||||
}
|
||||
@@ -43,6 +46,9 @@ class Diagnose extends Facade
|
||||
class DnsMasq extends Facade
|
||||
{
|
||||
}
|
||||
class Expose extends Facade
|
||||
{
|
||||
}
|
||||
class Filesystem extends Facade
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
php $DIR/../valet.php fetch-share-url $1 | pbcopy
|
||||
@@ -35,12 +35,12 @@
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0|^8.0",
|
||||
"illuminate/container": "~5.1|^6.0|^7.0|^8.0|^9.0",
|
||||
"php": "^8.0",
|
||||
"illuminate/collections": "^8.0|^9.0|^10.0",
|
||||
"illuminate/container": "~5.1|^6.0|^7.0|^8.0|^9.0|^10.0",
|
||||
"mnapoli/silly": "^1.0",
|
||||
"symfony/console": "^3.0|^4.0|^5.0|^6.0",
|
||||
"symfony/process": "^3.0|^4.0|^5.0|^6.0",
|
||||
"tightenco/collect": "^5.3|^6.0|^7.0|^8.0",
|
||||
"guzzlehttp/guzzle": "^6.0|^7.4",
|
||||
"symfony/event-dispatcher": "^3.0|^4.0|^5.0|^6.0"
|
||||
},
|
||||
|
||||
@@ -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'");
|
||||
|
||||
@@ -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
60
tests/ComposerTest.php
Normal 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');
|
||||
}
|
||||
}
|
||||
@@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
121
valet
121
valet
@@ -25,30 +25,24 @@ fi
|
||||
# process to retrieve the live Ngrok tunnel URL in the background.
|
||||
if [[ "$1" = "share" ]]
|
||||
then
|
||||
# Check for parameters to pass through to ngrok (these will start with '-' or '--')
|
||||
PARAMS=(${@:2})
|
||||
for PARAM in ${PARAMS[@]}
|
||||
do
|
||||
if [[ ${PARAM:0:1} != '-' ]]; then
|
||||
PARAMS=("${PARAMS[@]/$PARAM}") #Quotes when working with strings
|
||||
fi
|
||||
done
|
||||
SHARETOOL="$(php "$DIR/cli/valet.php" share-tool)"
|
||||
|
||||
PARAMS=${PARAMS[@]}
|
||||
if [[ $SHARETOOL = "ngrok" ]]
|
||||
then
|
||||
# ngrok
|
||||
# Check for parameters to pass through to ngrok (these will start with '-' or '--')
|
||||
PARAMS=(${@:2})
|
||||
for PARAM in ${PARAMS[@]}
|
||||
do
|
||||
if [[ ${PARAM:0:1} != '-' ]]; then
|
||||
PARAMS=("${PARAMS[@]/$PARAM}") #Quotes when working with strings
|
||||
fi
|
||||
done
|
||||
|
||||
HOST="${PWD##*/}"
|
||||
PARAMS=${PARAMS[@]}
|
||||
|
||||
# Check for custom domain passed through to the share command ($2 w/o '-' prefix)
|
||||
if [[ ${2:0:1} != '-' ]]; then
|
||||
# If not blank and is a link, or is the cwd, use it
|
||||
if [[ ! -z $2 && (-L ~/.config/valet/Sites/$2 || $2 == $HOST) ]]; then
|
||||
HOST=$2
|
||||
CLIHOST=$2
|
||||
fi
|
||||
fi
|
||||
HOST="${PWD##*/}"
|
||||
|
||||
# If no custom domain passed, then check if there's a linked site for cwd
|
||||
if [[ -z $CLIHOST ]]; then
|
||||
# Find the first linked site for the current dir, if one exists
|
||||
for linkname in ~/.config/valet/Sites/*; do
|
||||
if [[ "$(readlink $linkname)" = "$PWD" ]]
|
||||
@@ -57,28 +51,75 @@ then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
TLD=$(php "$DIR/cli/valet.php" tld)
|
||||
|
||||
# Decide the correct PORT: uses 60 for secure, else 80
|
||||
if grep --quiet --no-messages 443 ~/.config/valet/Nginx/$HOST*
|
||||
then
|
||||
PORT=60
|
||||
else
|
||||
PORT=80
|
||||
fi
|
||||
|
||||
# Lowercase the host to match how the rest of our domains are looked up
|
||||
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
BREW_PREFIX=$(brew --prefix)
|
||||
sudo -u "$USER" "$BREW_PREFIX/bin/ngrok" http "$HOST.$TLD:$PORT" --host-header=rewrite $PARAMS
|
||||
|
||||
exit
|
||||
|
||||
elif [[ $SHARETOOL = "expose" ]]
|
||||
then
|
||||
|
||||
# expose
|
||||
# Check for parameters to pass through to Expose (these will start with '-' or '--')
|
||||
PARAMS=(${@:2})
|
||||
for PARAM in ${PARAMS[@]}
|
||||
do
|
||||
if [[ ${PARAM:0:1} != '-' ]]; then
|
||||
PARAMS=("${PARAMS[@]/$PARAM}") #Quotes when working with strings
|
||||
fi
|
||||
done
|
||||
|
||||
PARAMS=${PARAMS[@]}
|
||||
|
||||
HOST="${PWD##*/}"
|
||||
|
||||
# Find the first linked site for the current dir, if one exists
|
||||
for linkname in ~/.config/valet/Sites/*; do
|
||||
if [[ "$(readlink $linkname)" = "$PWD" ]]
|
||||
then
|
||||
HOST="${linkname##*/}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
TLD=$(php "$DIR/cli/valet.php" tld)
|
||||
|
||||
# Decide the correct PORT: uses 443 for secure, else 80
|
||||
if grep --quiet --no-messages 443 ~/.config/valet/Nginx/$HOST*
|
||||
then
|
||||
PORT=443
|
||||
else
|
||||
PORT=80
|
||||
fi
|
||||
|
||||
# Lowercase the host to match how the rest of our domains are looked up
|
||||
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
sudo -u "$USER" expose share "$HOST.$TLD:$PORT" $PARAMS
|
||||
|
||||
exit
|
||||
|
||||
else
|
||||
echo ''
|
||||
echo "Please use 'valet share-tool ngrok' or 'valet share-tool expose'"
|
||||
echo "to set your preferred share tool."
|
||||
exit
|
||||
fi
|
||||
|
||||
TLD=$(php "$DIR/cli/valet.php" tld)
|
||||
|
||||
# Decide the correct PORT: uses 60 for secure, else 80
|
||||
if grep --quiet --no-messages 443 ~/.config/valet/Nginx/$HOST*
|
||||
then
|
||||
PORT=60
|
||||
else
|
||||
PORT=80
|
||||
fi
|
||||
|
||||
# Lowercase the host to match how the rest of our domains are looked up
|
||||
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Fetch Ngrok URL In Background...
|
||||
bash "$DIR/cli/scripts/fetch-share-url.sh" "$HOST" &
|
||||
|
||||
sudo -u "$USER" "$DIR/bin/ngrok" http "$HOST.$TLD:$PORT" --host-header=rewrite $PARAMS
|
||||
|
||||
exit
|
||||
|
||||
# Proxy PHP commands to the "php" executable on the isolated site
|
||||
elif [[ "$1" = "php" ]]
|
||||
then
|
||||
|
||||
Reference in New Issue
Block a user