Skip to content

Commit

Permalink
refactor(Installers) support caching downloads
Browse files Browse the repository at this point in the history
  • Loading branch information
lucatume committed Nov 24, 2023
1 parent 5620d46 commit 2f536b4
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 50 deletions.
54 changes: 26 additions & 28 deletions src/Utils/ChromedriverInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ChromedriverInstaller
private string $platform;
private string $binary;
private string $milestone;
private bool $useEnvZipFile = true;

public function __construct(
string $version = null,
Expand Down Expand Up @@ -83,47 +84,39 @@ public function install(string $dir = null): string

$this->output->writeln("Fetching Chromedriver version URL ...");

$downloadUrl = $this->fetchChromedriverVersionUrl();

$zipFilePathname = $this->useEnvZipFile ?
Env::get('WPBROWSER_CHROMEDRIVER_ZIP_FILE', null)
: null;
$cacheDir = FS::cacheDir() . '/chromedriver';

if (!is_dir($cacheDir) && !(mkdir($cacheDir, 0777, true) && is_dir($cacheDir))) {
throw new RuntimeException("Could not create Chromedriver cache directory $cacheDir.");
}

$zipFilePathname = rtrim($cacheDir, '\\/') . '/' . basename($downloadUrl);
$executableFileName = $dir . '/' . $this->getExecutableFileName();

if (is_file($zipFilePathname) && !unlink($zipFilePathname)) {
throw new RuntimeException(
"Could not remove existing zip file $zipFilePathname",
self::ERR_REMOVE_EXISTING_ZIP_FILE
);
if (!(is_string($zipFilePathname) && is_file($zipFilePathname))) {
$downloadUrl = $this->fetchChromedriverVersionUrl();
if (!is_dir($cacheDir) && !(mkdir($cacheDir, 0777, true) && is_dir($cacheDir))) {
throw new RuntimeException("Could not create Chromedriver cache directory $cacheDir.");
}
$zipFilePathname = rtrim($cacheDir, '\\/') . '/chromedriver.zip';
if (is_file($zipFilePathname) && !unlink($zipFilePathname)) {
throw new RuntimeException(
"Could not remove existing zip file $zipFilePathname",
self::ERR_REMOVE_EXISTING_ZIP_FILE
);
}
$this->output->writeln('Downloading Chromedriver to ' . $zipFilePathname . ' ...');
$zipFilePathname = Download::fileFromUrl($downloadUrl, $zipFilePathname);
$this->output->writeln('Downloaded Chromedriver to ' . $zipFilePathname);
}

$zipFilePathname = Download::fileFromUrl($downloadUrl, $zipFilePathname);
$this->output->writeln('Downloaded Chromedriver to ' . $zipFilePathname);

if (is_file($executableFileName) && !unlink($executableFileName)) {
throw new RuntimeException(
"Could not remove existing executable file $executableFileName",
self::ERR_REMOVE_EXISTING_BINARY
);
}

Zip::extractTo($zipFilePathname, $cacheDir);
Zip::extractFile($zipFilePathname, $this->getExecutableFileName(), $executableFileName);

if (!rename(
"$cacheDir/chromedriver-$this->platform/" . $this->getExecutableFileName(),
$executableFileName
)) {
throw new RuntimeException(
"Could not copy Chromedriver to $executableFileName",
self::ERR_MOVE_BINARY
);
}

if (chmod($executableFileName, 0755) === false) {
if (!chmod($executableFileName, 0755)) {
throw new RuntimeException(
"Could not make Chromedriver executable",
self::ERR_BINARY_CHMOD
Expand Down Expand Up @@ -367,4 +360,9 @@ public function getPlatform(): string
{
return $this->platform;
}

public function useEnvZipFile(bool $useEnvZipFile): void
{
$this->useEnvZipFile = $useEnvZipFile;
}
}
24 changes: 24 additions & 0 deletions src/Utils/Zip.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace lucatume\WPBrowser\Utils;

use RuntimeException;
Expand All @@ -23,4 +24,27 @@ public static function extractTo(string $zipFile, string $destination): string

return $destination;
}

public static function extractFile(string $zipFile, string $filename, string $destinationFileName): string
{
$zip = new ZipArchive();

if ($zip->open($zipFile) !== true) {
throw new RuntimeException("Could not open {$zipFile}.");
}

if (($fileIndex = $zip->locateName($filename, ZipArchive::FL_NODIR)) === false) {
throw new RuntimeException("Could not locate {$filename} in {$zipFile}.");
}

if (($name = $zip->getNameIndex($fileIndex)) === false) {
throw new RuntimeException("Could not get name for {$fileIndex} in {$zipFile}.");
}

if (!copy("zip://{$zipFile}#{$name}", $destinationFileName)) {
throw new RuntimeException("Could not copy {$name} from {$zipFile} to {$destinationFileName}.");
}

return $destinationFileName;
}
}
7 changes: 7 additions & 0 deletions src/WordPress/Source.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@
use lucatume\WPBrowser\Utils\Download;
use lucatume\WPBrowser\Utils\Filesystem as FS;
use lucatume\WPBrowser\Utils\Zip;
use lucatume\WPBrowser\Utils\Env;

class Source
{
public static function getForVersion(string $version = 'latest'): string
{
$envSourceDir = Env::get('WPBROWSER_WORDPRESS_SOURCE_DIR', null);

if (is_string($envSourceDir) && is_dir($envSourceDir . DIRECTORY_SEPARATOR . $version)) {
return $envSourceDir . DIRECTORY_SEPARATOR . $version;
}

$cacheDir = FS::cacheDir();
$versionsCacheDir = $cacheDir . '/wordpress/';
$sourceDir = $versionsCacheDir . $version;
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/Codeception/Template/WpbrowserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ public function should_scaffold_for_plugin_with_plugin_php_file(): void
'wpbrowser',
'--path=' . $projectDir . '/plugin_89'
];
$process = new Process($command, null, ['COMPOSER_BIN_DIR' => $projectDir . '/plugin_89/vendor/bin']);
$process = new Process($command, null, [
'COMPOSER_BIN_DIR' => $projectDir . '/plugin_89/vendor/bin'
]);

$process->setInput(
"yes\n" // Yes, use recommended setup.
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/_bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php
// Here you can initialize variables that will be available to your tests

use lucatume\WPBrowser\Utils\Env;
use lucatume\WPBrowser\Utils\Filesystem as FS;

require_once dirname(__DIR__, 2) . '/vendor/php-stubs/wordpress-stubs/wordpress-stubs.php';

Env::loadEnvMap(
[
'WPBROWSER_WORDPRESS_SOURCE_DIR' => FS::realpath(FS::cacheDir() . '/wordpress'),
'WPBROWSER_CHROMEDRIVER_ZIP_FILE' => FS::realpath(FS::cacheDir() . '/chromedriver/chromedriver.zip')
]
);
26 changes: 5 additions & 21 deletions tests/unit/lucatume/WPBrowser/Utils/ChromedriverInstallerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public function should_throw_if_it_cannot_get_milestone_downloads(): void
}, true);

$ci = new ChromedriverInstaller(null, 'linux64', codecept_data_dir('bins/chrome-mock'));
$ci->useEnvZipFile(false);

$this->expectException(RuntimeException::class);
$this->expectExceptionCode(ChromedriverInstaller::ERR_FETCH_MILESTONE_DOWNLOADS);
Expand All @@ -179,6 +180,7 @@ public function should_throw_if_response_is_not_valid_json(): void
}, true);

$ci = new ChromedriverInstaller(null, 'linux64', codecept_data_dir('bins/chrome-mock'));
$ci->useEnvZipFile(false);

$this->expectException(RuntimeException::class);
$this->expectExceptionCode(ChromedriverInstaller::ERR_DECODE_MILESTONE_DOWNLOADS);
Expand All @@ -200,6 +202,7 @@ public function should_throw_if_download_url_for_chrome_version_cannot_be_found_
}, true);

$ci = new ChromedriverInstaller(null, 'linux64', codecept_data_dir('bins/chrome-mock'));
$ci->useEnvZipFile(false);

$this->expectException(RuntimeException::class);
$this->expectExceptionCode(ChromedriverInstaller::ERR_DOWNLOAD_URL_NOT_FOUND);
Expand All @@ -215,12 +218,12 @@ public function should_throw_if_download_url_for_chrome_version_cannot_be_found_
public function should_throw_if_existing_zip_file_cannot_be_removed(): void
{
$this->uopzSetFunctionReturn('sys_get_temp_dir', codecept_output_dir());
touch(codecept_output_dir('chromedriver-linux64.zip'));
$this->uopzSetFunctionReturn('unlink', function (string $file): bool {
return preg_match('~chromedriver-linux64\\.zip$~' ,$file) ? false : unlink($file);
return preg_match('~chromedriver\\.zip$~' ,$file) ? false : unlink($file);
}, true);

$ci = new ChromedriverInstaller(null, 'linux64', codecept_data_dir('bins/chrome-mock'));
$ci->useEnvZipFile(false);

$this->expectException(RuntimeException::class);
$this->expectExceptionCode(ChromedriverInstaller::ERR_REMOVE_EXISTING_ZIP_FILE);
Expand Down Expand Up @@ -249,25 +252,6 @@ public function should_throw_if_existing_binary_cannot_be_removed(): void
$ci->install($dir);
}

/**
* It should throw if new binary cannot be moved in place
*
* @test
*/
public function should_throw_if_new_binary_cannot_be_moved_in_place(): void
{
$dir = Filesystem::tmpDir('chromedriver_installer_');
$this->uopzSetFunctionReturn('sys_get_temp_dir', codecept_output_dir());
$this->uopzSetFunctionReturn('rename', false);

$ci = new ChromedriverInstaller(null, 'linux64', codecept_data_dir('bins/chrome-mock'));

$this->expectException(RuntimeException::class);
$this->expectExceptionCode(ChromedriverInstaller::ERR_MOVE_BINARY);

$ci->install($dir);
}

/**
* It should throw if new binary cannot be made executable
*
Expand Down
Binary file added tests/unit/lucatume/WPBrowser/Utils/chromedriver
Binary file not shown.

0 comments on commit 2f536b4

Please sign in to comment.