Skip to content

Commit

Permalink
Implement valet fetch-share-url when working with Expose (#1349)
Browse files Browse the repository at this point in the history
* Flesh out Expose currentTunnelUrl method

* Apply fixes from StyleCI

* Prep for requiring a certain version of Expose

* Don't call installed() before installedVersion() in Composer

Co-authored-by: StyleCI Bot <[email protected]>
  • Loading branch information
mattstauffer and StyleCIBot authored Jan 25, 2023
1 parent f23e145 commit dd8e15e
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 10 deletions.
27 changes: 22 additions & 5 deletions cli/Valet/Composer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ 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;
}

if (starts_with($result, 'Changed current')) {
$result = strstr($result, '{');
}

$details = json_decode($result, true);

return ! empty($details);
Expand All @@ -38,4 +37,22 @@ public function installOrFail(string $namespacedPackage): void
throw new DomainException('Composer was unable to install ['.$namespacedPackage.'].');
});
}

public function installedVersion(string $namespacedPackage): ?string
{
$result = $this->cli->runAsUser("composer global show --format json -- $namespacedPackage");

if (str_contains($result, 'InvalidArgumentException') && str_contains($result, 'not found')) {
return null;
}

if (starts_with($result, 'Changed current')) {
$result = strstr($result, '{');
}

$details = json_decode($result, true);
$versions = $details['versions'];

return reset($versions);
}
}
51 changes: 48 additions & 3 deletions cli/Valet/Expose.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,52 @@

namespace Valet;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;

class Expose
{
public function __construct(public Composer $composer)
public function __construct(public Composer $composer, public CommandLine $cli)
{
}

public function currentTunnelUrl(?string $domain = null): string
public function currentTunnelUrl(?string $domain = null): ?string
{
$endpoint = 'http://127.0.0.1:4040/api/tunnels';

try {
$response = retry(20, function () use ($endpoint, $domain) {
$body = json_decode((new Client())->get($endpoint)->getBody());

if (isset($body->tunnels) && count($body->tunnels) > 0) {
if ($tunnelUrl = $this->findHttpTunnelUrl($body->tunnels, $domain)) {
return $tunnelUrl;
}
}
}, 250);

if (! empty($response)) {
return $response;
}

return warning('The project '.$domain.' cannot be found as an Expose share.');
} catch (ConnectException $e) {
return warning('There is no Expose instance running.');
}
}

/**
* Find the HTTP tunnel URL from the list of tunnels.
*/
public function findHttpTunnelUrl(array $tunnels, string $domain): ?string
{
return '@todo';
foreach ($tunnels as $tunnel) {
if (strpos($tunnel, strtolower($domain))) {
return $tunnel;
}
}

return null;
}

/**
Expand All @@ -21,6 +58,14 @@ public function installed(): bool
return $this->composer->installed('beyondcode/expose');
}

/**
* Return which version of Expose is installed.
*/
public function installedVersion(): ?string
{
return $this->composer->installedVersion('beyondcode/expose');
}

/**
* Make sure Expose is installed.
*/
Expand Down
6 changes: 5 additions & 1 deletion cli/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ function (ConsoleCommandEvent $event) {

switch ($tool) {
case 'expose':
output(Expose::currentTunnelUrl(Site::domain($domain)));
output(Expose::currentTunnelUrl($domain ?: Site::host(getcwd())));
break;
case 'ngrok':
try {
Expand Down Expand Up @@ -380,6 +380,10 @@ function (ConsoleCommandEvent $event) {

if ($tool === 'expose') {
if (Expose::installed()) {
// @todo: Check it's the right version (has /api/tunnels/)
// E.g. if (Expose::installedVersion)
// if (version_compare(Expose::installedVersion(), $minimumExposeVersion) < 0) {
// prompt them to upgrade
return;
}

Expand Down
2 changes: 1 addition & 1 deletion cli/includes/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function testing(): bool
/**
* Output the given text to the console.
*/
function output(string $output = ''): void
function output(?string $output = ''): void
{
writer()->writeln($output);
}
Expand Down
20 changes: 20 additions & 0 deletions tests/ComposerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,24 @@ public function test_install_or_fail_will_install_composer_package()

resolve(Composer::class)->installOrFail('beyondcode/expose');
}

public function test_installed_version_returns_null_when_given_package_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->assertNull(resolve(Composer::class)->installedVersion('beyondcode/expose'));
}

public function test_installed_version_returns_version_when_package_is_installed()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('composer global show --format json -- beyondcode/expose')
->andReturn('{"versions":["1.4.2"]}');
swap(CommandLine::class, $cli);

$this->assertEquals('1.4.2', resolve(Composer::class)->installedVersion('beyondcode/expose'));
}
}

0 comments on commit dd8e15e

Please sign in to comment.