feat: added the namespace option to the publish command (#9278)

This commit is contained in:
Dimitri Sitchet Tomkeu 2024-12-01 20:31:46 +01:00 committed by GitHub
parent d6d30c0920
commit bcedf1ccfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 78 additions and 15 deletions

View File

@ -67,17 +67,24 @@ class Publish extends BaseCommand
* *
* @var array<string, string> * @var array<string, string>
*/ */
protected $options = []; protected $options = [
'--namespace' => 'The namespace from which to search for files to publish. By default, all namespaces are analysed.',
];
/** /**
* Displays the help for the spark cli script itself. * Displays the help for the spark cli script itself.
*/ */
public function run(array $params) public function run(array $params)
{ {
$directory = array_shift($params) ?? 'Publishers'; $directory = $params[0] ?? 'Publishers';
$namespace = $params['namespace'] ?? '';
if ([] === $publishers = Publisher::discover($directory)) { if ([] === $publishers = Publisher::discover($directory, $namespace)) {
CLI::write(lang('Publisher.publishMissing', [$directory])); if ($namespace === '') {
CLI::write(lang('Publisher.publishMissing', [$directory]));
} else {
CLI::write(lang('Publisher.publishMissingNamespace', [$directory, $namespace]));
}
return; return;
} }

View File

@ -18,7 +18,8 @@ return [
'fileNotAllowed' => '"{0}" fails the following restriction for "{1}": {2}', 'fileNotAllowed' => '"{0}" fails the following restriction for "{1}": {2}',
// Publish Command // Publish Command
'publishMissing' => 'No Publisher classes detected in {0} across all namespaces.', 'publishMissing' => 'No Publisher classes detected in {0} across all namespaces.',
'publishSuccess' => '"{0}" published {1} file(s) to "{2}".', 'publishMissingNamespace' => 'No Publisher classes detected in {0} in the {1} namespace.',
'publishFailure' => '"{0}" failed to publish to "{1}".', 'publishSuccess' => '"{0}" published {1} file(s) to "{2}".',
'publishFailure' => '"{0}" failed to publish to "{1}".',
]; ];

View File

@ -99,18 +99,24 @@ class Publisher extends FileCollection
* *
* @return list<self> * @return list<self>
*/ */
final public static function discover(string $directory = 'Publishers'): array final public static function discover(string $directory = 'Publishers', string $namespace = ''): array
{ {
if (isset(self::$discovered[$directory])) { $key = implode('.', [$namespace, $directory]);
return self::$discovered[$directory];
if (isset(self::$discovered[$key])) {
return self::$discovered[$key];
} }
self::$discovered[$directory] = []; self::$discovered[$key] = [];
/** @var FileLocatorInterface $locator */ /** @var FileLocatorInterface $locator */
$locator = service('locator'); $locator = service('locator');
if ([] === $files = $locator->listFiles($directory)) { $files = $namespace === ''
? $locator->listFiles($directory)
: $locator->listNamespaceFiles($namespace, $directory);
if ([] === $files) {
return []; return [];
} }
@ -119,13 +125,13 @@ class Publisher extends FileCollection
$className = $locator->findQualifiedNameFromPath($file); $className = $locator->findQualifiedNameFromPath($file);
if ($className !== false && class_exists($className) && is_a($className, self::class, true)) { if ($className !== false && class_exists($className) && is_a($className, self::class, true)) {
self::$discovered[$directory][] = new $className(); self::$discovered[$key][] = new $className();
} }
} }
sort(self::$discovered[$directory]); sort(self::$discovered[$key]);
return self::$discovered[$directory]; return self::$discovered[$key];
} }
/** /**

View File

@ -61,6 +61,20 @@ final class PublisherSupportTest extends CIUnitTestCase
$this->assertSame([], $result); $this->assertSame([], $result);
} }
public function testDiscoverInNamespace(): void
{
$result = Publisher::discover('Publishers', 'Tests\Support');
$this->assertCount(1, $result);
$this->assertInstanceOf(TestPublisher::class, $result[0]);
}
public function testDiscoverInUnknowNamespace(): void
{
$result = Publisher::discover('Publishers', 'Nothing\App');
$this->assertSame([], $result);
}
public function testDiscoverStores(): void public function testDiscoverStores(): void
{ {
$publisher = Publisher::discover()[0]; $publisher = Publisher::discover()[0];

View File

@ -160,6 +160,11 @@ Removed Deprecated Items
Enhancements Enhancements
************ ************
Publisher
=========
- ``Publisher::discover()`` now accepts a second parameter (``namespace``) specifying the namespace in which publishers should be searched. See :ref:`discovery-in-a-specific-namespace` for the details.
Exceptions Exceptions
========== ==========

View File

@ -75,6 +75,31 @@ Most of the time you will not need to handle your own discovery, just use the pr
By default on your class extension ``publish()`` will add all files from your ``$source`` and merge them By default on your class extension ``publish()`` will add all files from your ``$source`` and merge them
out to your destination, overwriting on collision. out to your destination, overwriting on collision.
.. _discovery-in-a-specific-namespace:
Discovery in a specific namespace
---------------------------------
.. versionadded:: 4.6.0
Since v4.6.0, you can also scan a specific namespace. This not only reduces the number of files to be scanned,
but also avoids the need to rerun a Publisher. All you need to do is specify the desired root namespace in the
second parameter of the ``discover()`` method.
.. literalinclude:: publisher/016.php
The specified namespace must be known to CodeIgniter. You can check the list of all namespaces using the "spark namespaces" command:
.. code-block:: console
php spark namespaces
The "publish" command also offers the ``--namespace`` option to define the namespace when searching for Publishers that might come from a library.
.. code-block:: console
php spark publish --namespace Namespace\Vendor\Package
Security Security
======== ========

View File

@ -0,0 +1,5 @@
<?php
use CodeIgniter\Publisher\Publisher;
$memePublishers = Publisher::discover('Publishers', 'Namespace\Vendor\Package');