diff --git a/src/Console/Build/GenerateCodeBaselineCommand.php b/src/Console/Build/GenerateCodeBaselineCommand.php index a0ab9fcca347..c2f8d79b162c 100644 --- a/src/Console/Build/GenerateCodeBaselineCommand.php +++ b/src/Console/Build/GenerateCodeBaselineCommand.php @@ -65,23 +65,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $algorithm = $input->getOption('algorithm'); - $this->generateManifest($algorithm, $output); + try { + $this->generateManifest($algorithm, $output); + } catch (\Throwable $e) { + $output->writeln('' . sprintf('Failed to generate manifest. Error was: %s', PHP_EOL . $e->getMessage()) . ''); + return 1; + } return 0; } private function generateManifest(string $algorithm, OutputInterface $output): void { - $start = microtime(true); $manifest_output = GLPI_ROOT . '/version/' . VersionParser::getNormalizedVersion(GLPI_VERSION, false); $checker = new SourceCodeIntegrityChecker(); $manifest = $checker->generateManifest($algorithm); $manifest_json = json_encode($manifest, JSON_PRETTY_PRINT); $manifest_length = strlen($manifest_json); if (file_put_contents($manifest_output, $manifest_json) !== $manifest_length) { - $output->writeln('' . sprintf('Failed to write manifest to %s', $manifest_output) . ''); - return; + throw new \RuntimeException(sprintf('Failed to write manifest to %s', $manifest_output)); } - $duration = microtime(true) - $start; $output->writeln(sprintf('Manifest of %d files generated', count($manifest['files']))); } } diff --git a/src/System/Diagnostic/SourceCodeIntegrityChecker.php b/src/System/Diagnostic/SourceCodeIntegrityChecker.php index 0a3d7f858725..e7bd68b25474 100644 --- a/src/System/Diagnostic/SourceCodeIntegrityChecker.php +++ b/src/System/Diagnostic/SourceCodeIntegrityChecker.php @@ -83,7 +83,11 @@ private function getBaselineManifest(): ?array { $version = VersionParser::getNormalizedVersion(GLPI_VERSION, false); $manifest = file_get_contents($this->getCheckRootDir() . '/version/' . $version); - $content = json_decode($manifest, true, 512, JSON_THROW_ON_ERROR); + try { + $content = json_decode($manifest, true, 512, JSON_THROW_ON_ERROR); + } catch (\Throwable $e) { + throw new \RuntimeException('The source code file manifest is invalid', previous: $e); + } if (!isset($content['algorithm'], $content['files']) || !is_string($content['algorithm']) || !is_array($content['files'])) { throw new \RuntimeException('The source code file manifest is invalid'); } @@ -159,27 +163,22 @@ public function getSummary(): array private function getGLPIRelease(&$errors = []): string|null { - $gh_releases_endpoint = 'https://api.github.com/repos/glpi-project/glpi/releases'; $version_to_get = VersionParser::getNormalizedVersion(GLPI_VERSION); + $gh_releases_endpoint = 'https://api.github.com/repos/glpi-project/glpi/releases/tags/' . $version_to_get; $client = new Client(); $dest = null; try { $response = $client->request('GET', $gh_releases_endpoint); - $releases = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); - foreach ($releases as $release) { - if ($release['tag_name'] === $version_to_get) { - foreach ($release['assets'] as $asset) { - if (str_starts_with($asset['name'], 'glpi-' . $version_to_get)) { - $dest = GLPI_TMP_DIR . '/' . $asset['name']; - // Check if the file already exists in the tmp dir - if (file_exists($dest)) { - break; - } - $url = $asset['browser_download_url']; - $client->request('GET', $url, ['sink' => $dest]); - break; - } + $release = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); + foreach ($release['assets'] as $asset) { + if (str_starts_with($asset['name'], 'glpi-' . $version_to_get)) { + $dest = GLPI_TMP_DIR . '/' . $asset['name']; + // Check if the file already exists in the tmp dir + if (file_exists($dest)) { + break; } + $url = $asset['browser_download_url']; + $client->request('GET', $url, ['sink' => $dest]); break; } } @@ -195,18 +194,20 @@ public function getDiff(array &$errors = [], bool $allow_download = false): stri // ignore OK files in case they are present $summary = array_filter($summary, static fn ($status) => $status !== self::STATUS_OK); // Ensure the release is downloaded - if ($allow_download) { - $release_path = $this->getGLPIRelease($errors); - } else { - $release_path = GLPI_TMP_DIR . '/glpi-' . VersionParser::getNormalizedVersion(GLPI_VERSION) . '.tgz'; - if (!file_exists($release_path)) { + $release_path = GLPI_TMP_DIR . '/glpi-' . VersionParser::getNormalizedVersion(GLPI_VERSION) . '.tgz'; + if (!file_exists($release_path)) { + if ($allow_download) { + $release_path = $this->getGLPIRelease($errors); + if ($release_path === null) { + $errors[] = 'An error occurred while downloading the release'; + return ''; + } + } else { $errors[] = 'The release is not downloaded and downloading it was not allowed'; return ''; } } - if ($release_path === null) { - return 'An error occurred while downloading the release'; - } + $diff = ''; foreach ($summary as $file => $status) { @@ -216,14 +217,14 @@ public function getDiff(array &$errors = [], bool $allow_download = false): stri $current_file = 'b/' . $file; $original_content = ''; $current_content = ''; - // If status is missing, just add the info to the diff string - if ($status === self::STATUS_MISSING) { - $current_file = '/dev/null'; - } else if ($status === self::STATUS_ADDED || !file_exists('phar://' . $release_path . '/glpi/' . $file)) { + if ($status === self::STATUS_ADDED || !file_exists('phar://' . $release_path . '/glpi/' . $file)) { $original_file = '/dev/null'; - $current_content = file_get_contents($this->getCheckRootDir() . '/' . $file); } else { $original_content = file_get_contents('phar://' . $release_path . '/glpi/' . $file); + } + if ($status === self::STATUS_MISSING || !file_exists($this->getCheckRootDir() . '/' . $file)) { + $current_file = '/dev/null'; + } else { $current_content = file_get_contents($this->getCheckRootDir() . '/' . $file); } try { diff --git a/tests/functional/Glpi/System/Diagnostic/SourceCodeIntegrityChecker.php b/tests/functional/Glpi/System/Diagnostic/SourceCodeIntegrityChecker.php index 9fde88e7934a..d73f09198655 100644 --- a/tests/functional/Glpi/System/Diagnostic/SourceCodeIntegrityChecker.php +++ b/tests/functional/Glpi/System/Diagnostic/SourceCodeIntegrityChecker.php @@ -124,9 +124,9 @@ public function testGetSummary() unlink(vfsStream::url('check_root_dir/src/test2.php')); $this->array($checker->getSummary())->isEqualTo([ - 'src/test.php' => 1, - 'src/test2.php' => 2, - 'src/test3.php' => 3, + 'src/test.php' => 1, // 1 = STATUS_ALTERED + 'src/test2.php' => 2, // 2 = STATUS_MISSING + 'src/test3.php' => 3, // 3 = STATUS_ADDED ]); } @@ -154,17 +154,16 @@ public function testGetDiff() continue; } $path = preg_replace($path_pattern, '', $file->getPathname()); - $phar->addFromString($path, file_get_contents($file->getPathname())); + $phar->addFromString('glpi/' . $path, file_get_contents($file->getPathname())); } $phar->compress(\Phar::GZ); - // Rename from .tar.gz to .tgz because it changes the extension however it pleases $this->boolean(rename(GLPI_TMP_DIR . '/glpi-' . $version_full . '.tar.gz', GLPI_TMP_DIR . '/glpi-' . $version_full . '.tgz'))->isTrue(); unlink(vfsStream::url('check_root_dir/src/test.php')); file_put_contents(vfsStream::url('check_root_dir/src/test2.php'), <<array($errors)->isEqualTo([]); $this->string(trim($diff))->isEqualTo(<<