Skip to content

Commit

Permalink
[MERGE]: Develop into main
Browse files Browse the repository at this point in the history
  • Loading branch information
asciito authored Oct 20, 2023
2 parents 15e6b57 + ccbc6c0 commit dfd5e60
Show file tree
Hide file tree
Showing 18 changed files with 820 additions and 40 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/run-pint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
paths:
- "**.php"

permissions:
contents: write
pull-requests: write

jobs:
pint-code-style:
runs-on: ubuntu-latest
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
/.vagrant
.phpunit.result.cache
.DS_Store
composer.lock
composer.lock
/storage/logs/*
!/storage/logs/.gitkeep
25 changes: 25 additions & 0 deletions app/Commands/InstallBrowserCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Commands;

use App\GoogleDownloadable;

class InstallBrowserCommand extends InstallCommand
{
protected int $component = GoogleDownloadable::BROWSER;

protected $name = 'install:browser';

/**
* The description of the command.
*
* @var string
*/
protected $description = 'Install Google Browser';

/**
* Execute the console command.
*
* @return mixed
*/
}
166 changes: 166 additions & 0 deletions app/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

namespace App\Commands;

use App\Facades\GoogleForTesting;
use App\GoogleDownloadable;
use App\OperatingSystem;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputOption;

use function Laravel\Prompts\error;
use function Laravel\Prompts\search;
use function Laravel\Prompts\spin;
use function Laravel\Prompts\warning;
use function Termwind\render;

abstract class InstallCommand extends Command
{
protected int $component;

protected array $platforms = [
'linux' => 'linux64',
'mac-arm' => 'mac-arm64',
'mac-intel' => 'mac-x64',
'win' => 'win64',
];

protected function configure(): void
{
$this->addOption(
'ver',
null,
InputOption::VALUE_OPTIONAL,
'Install a specific version',
'115.0.5763.0',
);

$this->addOption(
'latest',
null,
InputOption::VALUE_NONE,
'Install the latest version',
);

$this->addOption(
'path',
null,
InputOption::VALUE_OPTIONAL,
'Specify the path where to download it',
);
}

public function handle(): int
{
if (empty($downloadable = $this->version())) {
error("There' no versions available for [{$this->option('ver')}]");

return self::FAILURE;
}

$os = OperatingSystem::id();

$version = $downloadable->getVersion();

try {
spin(
callback: fn () => $downloadable->download(GoogleDownloadable::BROWSER, $this->getDownloadDirectory(), $this->platforms[$os], true),
message: "Downloading Google Chrome {$this->getComponentName()} [$version]"
);

$this->message("Google Chrome {$this->getComponentName()} unzip it on [{$this->getDownloadDirectory()}]", 'info');
} catch (\Throwable $e) {
Log::error($e->getMessage());

error("Unable to download/install Google Chrome {$this->getComponentName()} [$version]");

return self::FAILURE;
}

$this->message("Google Chrome {$this->getComponentName()} [$version] downloaded", 'success');

return self::SUCCESS;
}

protected function version(): ?GoogleDownloadable
{
if ($this->option('latest')) {
return GoogleForTesting::getLatestVersion();
}

$version = $this->option('ver');

$downloadable = spin(
callback: fn () => GoogleForTesting::getVersion($version),
message: "Searching for version [$version]"
);

if (filled($downloadable)) {
return $downloadable;
}

$versions = GoogleForTesting::getMilestone(Str::before($version, '.'));

if (empty($versions)) {
return null;
}

warning("There isn't an exact version [$version]");

$version = search(
label: 'We found similar versions, please choose one',
options: fn () => $versions->mapWithKeys(fn ($d) => [$d->getVersion() => $d->getVersion()])->all(),
placeholder: 'Choose your prefer version'
);

return GoogleForTesting::getVersion($version);
}

protected function getBasePath(string $path = null): string
{
$folder = join_paths(getenv('HOME'), '.google-for-testing');

File::ensureDirectoryExists($folder);

return join_paths($folder, $path ?? '');
}

public function message(string $text, string $type = 'line'): void
{
$color = match ($type) {
'success' => 'bg-green',
'warning' => 'bg-yellow',
'error' => 'bg-red',
'info' => 'bg-blue',
default => 'bg-gray-600',
};

$type = str($type)->upper();

render(<<<HTML
<p>
<span class="text-white $color px-2 mr-2">$type</span>
<span>$text</span>
</p>
HTML);
}

protected function getDownloadDirectory(): string
{
return $this->option('path') ?? $this->getBasePath();
}

protected function getComponent(): int
{
return $this->component;
}

protected function getComponentName(): string
{
return $this->getComponent() === GoogleDownloadable::BROWSER ? 'Browser' : 'Driver';
}
}
19 changes: 19 additions & 0 deletions app/Commands/InstallDriverCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Commands;

use App\GoogleDownloadable;

class InstallDriverCommand extends InstallCommand
{
protected int $component = GoogleDownloadable::DRIVER;

protected $name = 'install:driver';

/**
* The description of the command.
*
* @var string
*/
protected $description = 'Install Google Driver';
}
20 changes: 20 additions & 0 deletions app/Facades/GoogleForTesting.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Facades;

use App\GoogleDownloadable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;

/**
* @method static null|GoogleDownloadable getLatestVersion() Get the latest version of Google Chrome Browser and Google Chrome Driver
* @method static null|GoogleDownloadable getVersion(string $version) Get a specific version
* @method static null|Collection<GoogleDownloadable> getMilestone(string $version) Get a collection with all the versions available for a Milestone
*/
class GoogleForTesting extends Facade
{
public static function getFacadeAccessor(): string
{
return 'gft';
}
}
97 changes: 97 additions & 0 deletions app/GoogleDownloadable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace App;

use Illuminate\Support\Str;

class GoogleDownloadable
{
const BROWSER = 1;

const DRIVER = 2;

protected function __construct(
protected string $version,
protected string $revision,
protected array $browserDownloads,
protected array $driverDownloads
) {
//
}

public function getVersion(): string
{
return $this->version;
}

public function getMilestone(): string
{
return Str::of($this->version)->before('.');
}

/**
* @throws \RuntimeException if the required platform doesn't exist
*/
public function getChromeBrowserURL(string $platform): string
{
$item = collect($this->browserDownloads)->first(fn (array $item) => $item['platform'] === $platform);

if (empty($item)) {
throw new \RuntimeException("The URL for Google Chrome Browser for platform [$platform], it's not available");
}

return $item['url'];
}

/**
* @throws \RuntimeException if the required platform doesn't exist
*/
public function getChromeDriverURL(string $platform): string
{
$item = collect($this->driverDownloads)->first(fn (array $item) => $item['platform'] === $platform);

if (empty($item)) {
throw new \RuntimeException("The URL for Google Chrome Driver for platform [$platform], it's not available");
}

return $item['url'];
}

public function download(int $component, string $to, string $platform, bool $unzip = false): void
{
if ($component & static::BROWSER) {
$url = $this->getChromeBrowserURL($platform);
$filename = join_paths($to, Str::afterLast($url, '/'));

download($url, $filename);

$unzip && unzip($filename);
}

if ($component & static::DRIVER) {
$url = $this->getChromeDriverURL($platform);
$filename = join_paths($to, Str::afterLast($url, '/'));

download($url, $filename);

$unzip && unzip($filename);
}
}

public static function make(string $version, string $revision, array $browserDownloads, array $driverDownloads): static
{
return new static($version, $revision, $browserDownloads, $driverDownloads);
}

public static function makeFromArray(array $data): static
{
$downloads = $data['downloads'];

$version = $data['version'];
$revision = $data['revision'];
$browserDownloads = $downloads['chrome'];
$driverDownloads = $downloads['chromedriver'] ?? [];

return static::make($version, $revision, $browserDownloads, $driverDownloads);
}
}
Loading

0 comments on commit dfd5e60

Please sign in to comment.