diff --git a/.gitignore b/.gitignore index 9a8905b..e548084 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -/bin/summary.json +/bin/k6* +/bin/*_summary.json +/bin/*_progress.json .idea/* .idea/codeStyleSettings.xml composer.lock diff --git a/bin/k6-linux-amd64 b/bin/k6-linux-amd64 deleted file mode 100755 index dadc924..0000000 Binary files a/bin/k6-linux-amd64 and /dev/null differ diff --git a/bin/k6-linux-arm64 b/bin/k6-linux-arm64 deleted file mode 100755 index cf1a426..0000000 Binary files a/bin/k6-linux-arm64 and /dev/null differ diff --git a/bin/k6-macos-amd64 b/bin/k6-macos-amd64 deleted file mode 100755 index 6e396ae..0000000 Binary files a/bin/k6-macos-amd64 and /dev/null differ diff --git a/bin/k6-macos-arm64 b/bin/k6-macos-arm64 deleted file mode 100755 index 099722e..0000000 Binary files a/bin/k6-macos-arm64 and /dev/null differ diff --git a/composer.json b/composer.json index 3d907b9..5716841 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "php": "^8.2", "pestphp/pest": "^2.24.2", "pestphp/pest-plugin": "^2.1.1", - "ext-curl": "*" + "ext-curl": "*", + "ext-zip": "*" }, "autoload": { "psr-4": { diff --git a/src/Binary.php b/src/Binary.php deleted file mode 100644 index 4daea4d..0000000 --- a/src/Binary.php +++ /dev/null @@ -1,52 +0,0 @@ - sprintf(self::K6, 'macos', $arch), - 'Linux' => sprintf(self::K6, 'linux', $arch), - 'Windows' => sprintf(self::K6, 'windows', $arch), - default => throw new RuntimeException('Unsupported OS.'), - }; - - return new self((string) realpath(__DIR__.'/../bin/'.$path)); - } - - /** - * The string representation of the binary. - */ - public function __toString(): string - { - return $this->path; - } -} diff --git a/src/Contracts/Block.php b/src/Contracts/Block.php deleted file mode 100644 index 577bdff..0000000 --- a/src/Contracts/Block.php +++ /dev/null @@ -1,21 +0,0 @@ - self::extractTarGz($fileName), + 'zip' => self::extractZip($fileName) + }; + + if (! self::ensureExecutable(self::path())) { + throw new RuntimeException('Unable to make k6 binary executable.'); + } + } + + /** + * Extracts the downloaded tar.gz archive + */ + private static function extractTarGz(string $fileName): void + { + $tarGz = new PharData(self::BIN_DIR.$fileName); + $tarGz->decompress(); + + $tar = new PharData(self::BIN_DIR.str_replace('.gz', '', $fileName)); + $tar->extractTo(self::BIN_DIR); + + unlink(self::BIN_DIR.str_replace('.gz', '', $fileName)); + unlink(self::BIN_DIR.$fileName); + } + + /** + * Extracts the downloaded zip archive + */ + private static function extractZip(string $fileName): void + { + $zip = new ZipArchive(); + + if ($zip->open(self::BIN_DIR.$fileName) !== true) { + throw new RuntimeException('Unable to open k6 zip archive.'); + } + + $zip->extractTo(self::BIN_DIR); + $zip->close(); + + unlink(self::BIN_DIR.$fileName); + } + + /** + * Returns the computer's architecture. + */ + private static function arch(): string + { + return str_contains(php_uname('m'), 'arm') ? 'arm64' : 'amd64'; + } + + /** + * Returns the operating system. + */ + private static function os(): string + { + return match (PHP_OS_FAMILY) { + 'Darwin' => 'macos', + 'Linux' => 'linux', + 'Windows' => 'windows', + default => throw new RuntimeException('Unsupported OS.'), + }; + } + + /** + * Make the binary executable. + */ + private static function ensureExecutable(string $binary): bool + { + return chmod($binary, 0755); + } + + /** + * The string representation of the binary. + */ + public function __toString(): string + { + return $this->path; + } +} diff --git a/src/Printers/Detail.php b/src/Printers/Detail.php index 5731c0c..d94f6ce 100644 --- a/src/Printers/Detail.php +++ b/src/Printers/Detail.php @@ -7,7 +7,6 @@ use Pest\Stressless\Result; use function Termwind\render; -use function Termwind\terminal; /** * @internal @@ -31,18 +30,20 @@ public function print(Result $result): void $color = $this->color($result->requests->dnsLookup->duration->avg, 20.0, 50.0, 100.0); $value = $this->ms($result->requests->dnsLookup->duration->avg); - // map all IPv4 and IPv6 addresses of the given domain $domain = $result->url(); $domain = (string) parse_url($domain, PHP_URL_HOST); $dnsRecords = dns_get_record($domain, DNS_AAAA + DNS_A); $dnsRecords = array_map(fn (array $record): string => $record['ipv6'] ?? $record['ip'], $dnsRecords ?: []); $dnsRecords = array_unique($dnsRecords); - $dnsRecords = implode(', ', $dnsRecords); - if (strlen($dnsRecords) > 0 && strlen($dnsRecords) > ($size = terminal()->width() - 30)) { - $dnsRecords = substr($dnsRecords, 0, $size).'(…)'; + if (count($dnsRecords) > 2) { + $lastDnsRecord = '(+ '.(count($dnsRecords) - 2).' more)'; + $dnsRecords = array_slice($dnsRecords, 0, 2); + $dnsRecords[] = $lastDnsRecord; } + $dnsRecords = implode(', ', $dnsRecords); + $this->twoColumnDetail('DNS Lookup Duration', <<$dnsRecords $value diff --git a/src/Run.php b/src/Run.php index 772a414..ba190c5 100644 --- a/src/Run.php +++ b/src/Run.php @@ -10,6 +10,8 @@ use RuntimeException; use Symfony\Component\Process\Process; +use function Termwind\render; + /** * @internal */ @@ -48,8 +50,19 @@ public function start(): Result $duration, ); + if (! K6::exists()) { + render(<<<'HTML' +