diff --git a/config/optional/rest.resource.helfi_debug_package_version.yml b/config/optional/rest.resource.helfi_debug_package_version.yml deleted file mode 100644 index 7762b68..0000000 --- a/config/optional/rest.resource.helfi_debug_package_version.yml +++ /dev/null @@ -1,16 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - user -id: helfi_debug_package_version -plugin_id: 'helfi_debug_package_version' -granularity: resource -configuration: - methods: - - GET - formats: - - json - authentication: - - cookie - - basic_auth diff --git a/documentation/debug.md b/documentation/debug.md index 943a1a7..78503c8 100644 --- a/documentation/debug.md +++ b/documentation/debug.md @@ -13,14 +13,3 @@ See [src/Plugin/DebugDataItem/Composer.php](/src/Plugin/DebugDataItem/Composer.p At minimum, you need: - A plugin class that implements `\Drupal\helfi_debug\DebugDataItemInterface` - A plugin specific template (`debug-item--{plugin_id}.html.twig`). See [templates/debug-item.html.twig](/templates/debug-item.html.twig) for more information. - -## Package version checker - -The `/api/v1/version` endpoint can be used to fetch the latest version of a composer package. - -For example: - -Request `GET /api/v1/version?package=drupal/helfi_api_base&version=1.2.0` will respond with: - -- The latest version number -- Whether the given version is the latest version diff --git a/helfi_api_base.install b/helfi_api_base.install index 039871d..c4105a0 100644 --- a/helfi_api_base.install +++ b/helfi_api_base.install @@ -338,3 +338,13 @@ function _helfi_api_base_process_links(ContentEntityInterface $entity, string $f $entity->save(); } } + +/** + * UHF-10713 Remove VersionChecker. + */ +function helfi_api_base_update_9023(): void { + \Drupal::entityTypeManager() + ->getStorage('rest_resource_config') + ->load('helfi_debug_package_version') + ->delete(); +} diff --git a/helfi_api_base.permissions.yml b/helfi_api_base.permissions.yml index aea19c8..4076c7f 100644 --- a/helfi_api_base.permissions.yml +++ b/helfi_api_base.permissions.yml @@ -11,3 +11,5 @@ view remote entities: title: View remote entities edit remote entities: title: Edit remote entities +access debug page: + title: Access debug page diff --git a/helfi_api_base.routing.yml b/helfi_api_base.routing.yml index 3dc54f8..aef2245 100644 --- a/helfi_api_base.routing.yml +++ b/helfi_api_base.routing.yml @@ -20,4 +20,4 @@ helfi_api_base.debug_list: _title: 'Debug' _controller: '\Drupal\helfi_api_base\Controller\DebugController::build' requirements: - _permission: 'restful get helfi_debug_package_version' + _permission: 'access debug page' diff --git a/helfi_api_base.services.yml b/helfi_api_base.services.yml index 640c551..c62e535 100644 --- a/helfi_api_base.services.yml +++ b/helfi_api_base.services.yml @@ -70,21 +70,6 @@ services: class: Drupal\helfi_api_base\DebugDataItemPluginManager parent: default_plugin_manager - Drupal\helfi_api_base\Package\VersionChecker: '@helfi_api_base.package_version_checker' - helfi_api_base.package_version_checker: - class: Drupal\helfi_api_base\Package\VersionChecker - arguments: [] - tags: - - { name: service_collector, call: add, tag: helfi_api_base.version_checker } - - Drupal\helfi_api_base\Package\ComposerOutdatedProcess: ~ - - Drupal\helfi_api_base\Package\HelfiPackage: '@helfi_api_base.helfi_package_version_checker' - helfi_api_base.helfi_package_version_checker: - class: Drupal\helfi_api_base\Package\HelfiPackage - tags: - - { name: helfi_api_base.version_checker } - Drupal\helfi_api_base\EventSubscriber\EnvironmentResponseSubscriber: '@helfi_api_base.environment_response_subscriber' helfi_api_base.environment_response_subscriber: class: Drupal\helfi_api_base\EventSubscriber\EnvironmentResponseSubscriber diff --git a/src/Package/ComposerOutdatedProcess.php b/src/Package/ComposerOutdatedProcess.php deleted file mode 100644 index d9ef706..0000000 --- a/src/Package/ComposerOutdatedProcess.php +++ /dev/null @@ -1,30 +0,0 @@ -mustRun(); - return json_decode($process->getOutput(), TRUE); - } - -} diff --git a/src/Package/HelfiPackage.php b/src/Package/HelfiPackage.php deleted file mode 100644 index 4f8ff75..0000000 --- a/src/Package/HelfiPackage.php +++ /dev/null @@ -1,88 +0,0 @@ -client - ->request('GET', sprintf(self::BASE_URL, $packagePath)); - $content = json_decode($response->getBody()->getContents(), TRUE); - } - catch (GuzzleException $e) { - return []; - } - if (!isset($content['packages'][$packageName])) { - throw new InvalidPackageException('Package not found.'); - } - return $content['packages'][$packageName]; - } - - /** - * {@inheritdoc} - */ - public function get(string $packageName, string $version): ? Version { - // Attempt to get package data and fallback to dev version if - // no stable version is found. - if (!$packages = $this->getPackageData($packageName)) { - $packages = $this->getPackageData($packageName, TRUE); - } - usort($packages, function ($package1, $package2) { - return version_compare($package1['version'], $package2['version']); - }); - // Packages are sorted from oldest to newest. - $latest = end($packages); - - if (empty($latest['version']) || !is_string($latest['version'])) { - throw new InvalidPackageException('No version data found.'); - } - return new Version($packageName, $latest['version'], version_compare($version, $latest['version'], '>='), $version); - } - -} diff --git a/src/Package/Version.php b/src/Package/Version.php deleted file mode 100644 index d634727..0000000 --- a/src/Package/Version.php +++ /dev/null @@ -1,47 +0,0 @@ - $this->name, - 'latestVersion' => $this->latestVersion, - 'isLatest' => $this->isLatest, - 'version' => $this->version, - ]; - } - -} diff --git a/src/Package/VersionChecker.php b/src/Package/VersionChecker.php deleted file mode 100644 index 2cdffa3..0000000 --- a/src/Package/VersionChecker.php +++ /dev/null @@ -1,128 +0,0 @@ -collectors[] = $versionChecker; - return $this; - } - - /** - * Gets the package version. - * - * @param string $packageName - * The package name. - * @param string $version - * The version. - * - * @return \Drupal\helfi_api_base\Package\Version|null - * The version object or null. - * - * @throws \Drupal\helfi_api_base\Exception\InvalidPackageException - */ - public function get(string $packageName, string $version) : ? Version { - foreach ($this->collectors as $collector) { - if (!$collector->applies($packageName)) { - continue; - } - return $collector->get($packageName, $version); - } - return NULL; - } - - /** - * Gets outdated package versions. - * - * @param string|null $composerLockFile - * Path to composer lock file. Defaults to project lock file. - * - * @return Version[] - * Outdated packages. - * - * @throws \Drupal\helfi_api_base\Exception\VersionCheckException - */ - public function getOutdated(?string $composerLockFile = NULL) : array { - $packages = $this->getPackages($composerLockFile ?? $this->defaultComposerLockFile); - $versions = []; - - foreach ($packages as $packageName => $package) { - $versions[] = new Version($packageName, $package['latest'], FALSE, $package['version']); - } - - return $versions; - } - - /** - * Get outdated packages. - * - * Uses variable cache since running the composer process is expensive. - * - * @throws \Drupal\helfi_api_base\Exception\VersionCheckException - */ - private function getPackages(string $composerLockFile): array { - if (!$composerLockFile = realpath($composerLockFile)) { - throw new VersionCheckException('Composer lock file not found'); - } - - $workingDir = dirname($composerLockFile); - if (empty($this->packages[$workingDir])) { - try { - $packages = $this->process->run($workingDir); - $packages = $packages['installed'] ?? []; - } - catch (ProcessFailedException) { - throw new VersionCheckException("Composer process failed"); - } - - // Key with package name. - foreach ($packages as $package) { - $this->packages[$workingDir][$package['name']] = $package; - } - } - - return $this->packages[$workingDir] ?? []; - } - -} diff --git a/src/Package/VersionCheckerInterface.php b/src/Package/VersionCheckerInterface.php deleted file mode 100644 index 64a8d11..0000000 --- a/src/Package/VersionCheckerInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -packageVersion = $container->get('helfi_api_base.package_version_checker'); - return $instance; - } +final class PackageVersion extends ResourceBase { /** * Responds to GET requests. * - * @return \Drupal\rest\ResourceResponse - * The response containing the record. - * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ - public function get(Request $request) : ResourceResponse { - $args = []; - foreach (['name', 'version'] as $arg) { - if (!$value = $request->query->get($arg)) { - throw new BadRequestHttpException(sprintf('Missing required query argument: %s', $arg)); - } - if (is_array($value)) { - $value = reset($value); - } - $args[$arg] = (string) $value; - } - ['name' => $name, 'version' => $version] = $args; - - $data = $this->packageVersion->get($name, $version); - - if (!$data instanceof Version) { - throw new BadRequestHttpException(sprintf('Invalid package name: %s', $name)); - } - - $cacheableMetadata = new CacheableMetadata(); - $cacheableMetadata->addCacheContexts([ - 'url.query_args:name', - 'url.query_args:version', - ]) - ->setCacheMaxAge(180); - - return (new ResourceResponse($data->toArray())) - ->addCacheableDependency($cacheableMetadata); - } - - /** - * {@inheritdoc} - */ - public function calculateDependencies() : array { - return [ - 'module' => ['user'], - ]; + public function get() : ResourceResponse { + throw new BadRequestHttpException(sprintf('Deprecated')); } } diff --git a/tests/src/Unit/Package/HelfiPackageTest.php b/tests/src/Unit/Package/HelfiPackageTest.php deleted file mode 100644 index e6f712a..0000000 --- a/tests/src/Unit/Package/HelfiPackageTest.php +++ /dev/null @@ -1,238 +0,0 @@ -prophesize(ClientInterface::class)->reveal()); - $this->assertEquals($expected, $sut->applies($package)); - } - - /** - * Data provider for applies() test. - * - * @return array[] - * The data. - */ - public function appliesData() : array { - return [ - ['drupal/helfi_api_base', TRUE], - ['drupal/hdbt', TRUE], - ['drupal/hdbt_admin', TRUE], - ['city-of-helsinki/hauki', FALSE], - ]; - } - - /** - * Tests empty version. - * - * @covers ::get - * @covers ::__construct - * @covers ::getPackageData - * @dataProvider emptyVersionData - */ - public function testEmptyVersion($version) : void { - $client = $this->createMockHttpClient([ - new Response(body: json_encode([ - 'packages' => [ - 'drupal/helfi_api_base' => [ - [ - 'version' => $version, - ], - ], - ], - ])), - ]); - $sut = new HelfiPackage($client); - $this->expectException(InvalidPackageException::class); - $this->expectExceptionMessage('No version data found.'); - $sut->get('drupal/helfi_api_base', '1.2.0'); - } - - /** - * Data provider for empty version check. - * - * @return array - * The data. - */ - public function emptyVersionData() : array { - return [ - [NULL], - [1], - [''], - ]; - } - - /** - * Tests that client error returns null. - * - * @covers ::get - * @covers ::__construct - * @covers ::getPackageData - */ - public function testException() : void { - // First we try to fetch stable version, then fallback to dev. - $client = $this->createMockHttpClient([ - new RequestException('Stable package', new Request('GET', 'test')), - new RequestException('Dev package', new Request('GET', 'test')), - ]); - $sut = new HelfiPackage($client); - $this->expectException(InvalidPackageException::class); - $this->expectExceptionMessage('No version data found.'); - $sut->get('drupal/helfi_api_base', '1.2.0'); - } - - /** - * Tests empty packages. - * - * @covers ::get - * @covers ::__construct - * @covers ::getPackageData - */ - public function testEmptyPackage() : void { - $client = $this->createMockHttpClient([ - new Response(body: json_encode([ - 'packages' => [], - ])), - ]); - $sut = new HelfiPackage($client); - $this->expectException(InvalidPackageException::class); - $this->expectExceptionMessage('Package not found.'); - $sut->get('drupal/helfi_api_base', '1.2.0'); - } - - /** - * Tests get(). - * - * @covers ::__construct - * @covers ::get - * @covers \Drupal\helfi_api_base\Package\Version - * @covers ::getPackageData - * - * @dataProvider getData - */ - public function testGet( - string $packageName, - array $packageVersions, - string $packageVersion, - string $expectedLatestVersion, - bool $isLatest, - ) : void { - $client = $this->createMockHttpClient([ - new Response(body: json_encode([ - 'packages' => [ - $packageName => $packageVersions, - ], - ])), - ]); - $sut = new HelfiPackage($client); - $result = $sut->get($packageName, $packageVersion); - $this->assertInstanceOf(Version::class, $result); - $this->assertEquals($packageName, $result->name); - $this->assertEquals($expectedLatestVersion, $result->latestVersion); - $this->assertEquals($isLatest, $result->isLatest); - $this->assertNotEmpty($result->toArray()); - } - - /** - * Data provider for get(). - * - * @return array[] - * The data. - */ - public function getData() : array { - return [ - // Test with same version. - [ - 'drupal/helfi_api_base', - [ - [ - 'version' => '1.2.0', - ], - [ - 'version' => '1.3.0', - ], - ], - '1.3.0', - '1.3.0', - TRUE, - ], - // Test with dev-main. - [ - 'drupal/helfi_api_base', - [ - [ - 'version' => '1.2.0', - ], - [ - 'version' => '1.3.0', - ], - ], - 'dev-main', - '1.3.0', - FALSE, - ], - // Test with future release. - [ - 'drupal/helfi_api_base', - [ - [ - 'version' => '1.2.0', - ], - [ - 'version' => '1.3.0', - ], - ], - '1.4.0', - '1.3.0', - TRUE, - ], - // Test older release. - [ - 'drupal/hdbt', - [ - [ - 'version' => '1.2.0', - ], - [ - 'version' => '1.3.0', - ], - ], - '1.2.0', - '1.3.0', - FALSE, - ], - ]; - } - -} diff --git a/tests/src/Unit/Package/VersionCheckerTest.php b/tests/src/Unit/Package/VersionCheckerTest.php deleted file mode 100644 index 3f9ef4e..0000000 --- a/tests/src/Unit/Package/VersionCheckerTest.php +++ /dev/null @@ -1,85 +0,0 @@ -prophesize(ComposerOutdatedProcess::class); - $process->run(Argument::any())->willReturn([]); - $sut = new VersionChecker('nonexistent.lock', $process->reveal()); - - $this->expectException(VersionCheckException::class); - $sut->getOutdated(); - } - - /** - * Tests composer command failure. - */ - public function testProcessFailure(): void { - $process = $this->prophesize(ComposerOutdatedProcess::class); - $process - ->run(Argument::any()) - ->shouldBeCalled() - ->willThrow($this->prophesize(ProcessFailedException::class)->reveal()); - - $sut = new VersionChecker(__DIR__ . '/../../../fixtures/composer.lock', $process->reveal()); - - $this->expectException(VersionCheckException::class); - $sut->getOutdated(); - } - - /** - * Tests getOutdated(). - */ - public function testGetOutdated(): void { - $process = $this->prophesize(ComposerOutdatedProcess::class); - $process - ->run(Argument::any()) - ->shouldBeCalled() - ->willReturn([ - 'installed' => [ - [ - 'name' => 'drupal/helfi_api_base', - 'version' => '1.0.18', - 'latest' => '1.1.0', - ], - ], - ]); - - $sut = new VersionChecker(__DIR__ . '/../../../fixtures/composer.lock', $process->reveal()); - - $outdated = $sut->getOutdated(); - - $this->assertNotEmpty($outdated); - $outdated = reset($outdated); - $this->assertInstanceOf(Version::class, $outdated); - $this->assertEquals('drupal/helfi_api_base', $outdated->name); - $this->assertEquals('1.0.18', $outdated->version); - $this->assertEquals('1.1.0', $outdated->latestVersion); - $this->assertFalse($outdated->isLatest); - - } - -}