]> git.mxchange.org Git - friendica.git/commitdiff
Implement parsing of addon files to AddonInfo
authorArt4 <art4@wlabs.de>
Tue, 29 Apr 2025 13:59:58 +0000 (13:59 +0000)
committerArt4 <art4@wlabs.de>
Tue, 29 Apr 2025 13:59:58 +0000 (13:59 +0000)
src/Core/Addon/AddonInfo.php
tests/Unit/Core/Addon/AddonInfoTest.php

index ce5f07fc0f50d278247ee1f0efbaf2541990fdce..8b44b6f8410e4f9fc8198d56a5072a886411365a 100644 (file)
@@ -14,6 +14,76 @@ namespace Friendica\Core\Addon;
  */
 final class AddonInfo
 {
+       /**
+        * Parse addon comment in search of addon infos.
+        *
+        * like
+        * \code
+        *   * Name: addon
+        *   * Description: An addon which plugs in
+        * . * Version: 1.2.3
+        *   * Author: John <profile url>
+        *   * Author: Jane <email>
+        *   * Maintainer: Jess without link
+        *   * Maintainer: Robin <email>
+        *   * Status: in development
+        * \endcode
+        *
+        * @internal Never create this object by yourself, use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead.
+        * @see Friendica\Core\Addon\AddonHelper::getAddonInfo()
+        *
+        * @param string $addonId the name of the addon
+        * @param string $raw The raw file content
+        */
+       public static function fromString(string $addonId, string $raw): self
+       {
+               $data = [
+                       'id' => $addonId,
+               ];
+
+               $result = preg_match("|/\*.*\*/|msU", $raw, $m);
+
+               if ($result === false || $result === 0) {
+                       return self::fromArray($data);
+               }
+
+               $ll = explode("\n", $m[0]);
+
+               foreach ($ll as $l) {
+                       $l = trim($l, "\t\n\r */");
+                       if ($l !== '') {
+                               $addon_info = array_map('trim', explode(":", $l, 2));
+                               if (count($addon_info) < 2) {
+                                       continue;
+                               }
+
+                               list($type, $v) = $addon_info;
+                               $type           = strtolower($type);
+
+                               if ($type === 'author' || $type === 'maintainer') {
+                                       $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);
+                                       if ($r === false || $r === 0) {
+                                               $data[$type][] = ['name' => trim($v)];
+                                       } else {
+                                               $data[$type][] = ['name' => trim($m[1]), 'link' => $m[2]];
+                                       }
+                               } else {
+                                       $data[$type] = $v;
+                               }
+                       }
+               }
+
+               // rename author to authors
+               $data['authors'] = $data['author'];
+               unset($data['author']);
+
+               // rename maintainer to maintainers
+               $data['maintainers'] = $data['maintainer'];
+               unset($data['maintainer']);
+
+               return self::fromArray($data);
+       }
+
        /**
         * @internal Never create this object by yourself, use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead.
         *
@@ -21,25 +91,21 @@ final class AddonInfo
         */
        public static function fromArray(array $info): self
        {
-               $id          = array_key_exists('id', $info) ? (string) $info['id'] : '';
-               $name        = array_key_exists('name', $info) ? (string) $info['name'] : '';
-               $description = array_key_exists('description', $info) ? (string) $info['description'] : '';
-               $authors     = array_key_exists('authors', $info) ? self::parseContributors($info['authors']) : [];
-               $maintainers = array_key_exists('maintainers', $info) ? self::parseContributors($info['maintainers']) : [];
-               $version     = array_key_exists('version', $info) ? (string) $info['version'] : '';
-               $status      = array_key_exists('status', $info) ? (string) $info['status'] : '';
-
-               return new self(
-                       $id,
-                       $name,
-                       $description,
-                       $authors,
-                       $maintainers,
-                       $version,
-                       $status
-               );
+               $addonInfo              = new self();
+               $addonInfo->id          = array_key_exists('id', $info) ? (string) $info['id'] : '';
+               $addonInfo->name        = array_key_exists('name', $info) ? (string) $info['name'] : '';
+               $addonInfo->description = array_key_exists('description', $info) ? (string) $info['description'] : '';
+               $addonInfo->authors     = array_key_exists('authors', $info) ? self::parseContributors($info['authors']) : [];
+               $addonInfo->maintainers = array_key_exists('maintainers', $info) ? self::parseContributors($info['maintainers']) : [];
+               $addonInfo->version     = array_key_exists('version', $info) ? (string) $info['version'] : '';
+               $addonInfo->status      = array_key_exists('status', $info) ? (string) $info['status'] : '';
+
+               return $addonInfo;
        }
 
+       /**
+        * @param mixed $entries
+        */
        private static function parseContributors($entries): array
        {
                if (!is_array($entries)) {
@@ -85,22 +151,7 @@ final class AddonInfo
 
        private string $status = '';
 
-       private function __construct(
-               string $id,
-               string $name,
-               string $description,
-               array $authors,
-               array $maintainers,
-               string $version,
-               string $status
-       ) {
-               $this->id          = $id;
-               $this->name        = $name;
-               $this->description = $description;
-               $this->authors     = $authors;
-               $this->maintainers = $maintainers;
-               $this->version     = $version;
-               $this->status      = $status;
+       private function __construct() {
        }
 
        public function getId(): string
index a8e007b50aa4058828379e7da761fb624cdd60cc..a1887d5dfd145648f3d0bd34fdf2db94545fc742 100644 (file)
@@ -14,19 +14,65 @@ use PHPUnit\Framework\TestCase;
 
 class AddonInfoTest extends TestCase
 {
-       public function testFromArrayCreatesObject(): void
+       public function testFromStringCreatesObject(): void
        {
-               $data = [
-                       'id'          => '',
-                       'name'        => '',
-                       'description' => '',
-                       'authors'     => [],
-                       'maintainers' => [],
-                       'version'     => '',
-                       'status'      => '',
+               $this->assertInstanceOf(AddonInfo::class, AddonInfo::fromString('addonId', ''));
+       }
+
+       public static function getStringData(): array
+       {
+               return [
+                       'minimal' => [
+                               'test',
+                               '',
+                               ['id' => 'test'],
+                       ],
+                       'complete' => [
+                               'test',
+                               <<<TEXT
+                               <?php
+                               /*
+                                * Name: Test Addon
+                                * Description: adds awesome features to friendica
+                                * Version: 100.4.50-beta.5
+                                * Author: Sam
+                                * Author: Sam With Mail <mail@example.org>
+                                * Maintainer: Robin
+                                * Maintainer: Robin With Profile <https://example.org/profile/robin>
+                                * Status: beta
+                                * Ignore: The "ignore" key is unsupported and will be ignored
+                                */
+                               TEXT,
+                               [
+                                       'id' => 'test',
+                                       'name' => 'Test Addon',
+                                       'description' => 'adds awesome features to friendica',
+                                       'authors' => [
+                                               ['name' => 'Sam'],
+                                               ['name' => 'Sam With Mail', 'link' => 'mail@example.org'],
+                                       ],
+                                       'maintainers' => [
+                                               ['name' => 'Robin'],
+                                               ['name' => 'Robin With Profile', 'link' => 'https://example.org/profile/robin'],
+                                       ],
+                                       'version' => '100.4.50-beta.5',
+                                       'status' => 'beta',
+                               ],
+                       ],
                ];
+       }
 
-               $this->assertInstanceOf(AddonInfo::class, AddonInfo::fromArray($data));
+       /**
+        * @dataProvider getStringData
+        */
+       public function testFromStringReturnsCorrectValues(string $addonId, string $raw, array $expected): void
+       {
+               $this->assertAddonInfoData($expected, AddonInfo::fromString($addonId, $raw));
+       }
+
+       public function testFromArrayCreatesObject(): void
+       {
+               $this->assertInstanceOf(AddonInfo::class, AddonInfo::fromArray([]));
        }
 
        public function testGetterReturningCorrectValues(): void
@@ -41,15 +87,34 @@ class AddonInfoTest extends TestCase
                        'status'      => 'In Development',
                ];
 
-               $info = AddonInfo::fromArray($data);
+               $this->assertAddonInfoData($data, AddonInfo::fromArray($data));
+       }
+
+       private function assertAddonInfoData(array $expected, AddonInfo $info): void
+       {
+               $expected = array_merge(
+                       [
+                               'id'          => '',
+                               'name'        => '',
+                               'description' => '',
+                               'authors'     => [],
+                               'maintainers' => [],
+                               'version'     => '',
+                               'status'      => '',
+                       ],
+                       $expected
+               );
+
+               $data = [
+                       'id' => $info->getId(),
+                       'name' => $info->getName(),
+                       'description' => $info->getDescription(),
+                       'authors' => $info->getAuthors(),
+                       'maintainers' => $info->getMaintainers(),
+                       'version' => $info->getVersion(),
+                       'status' => $info->getStatus(),
+               ];
 
-               $this->assertSame($data['id'], $info->getId());
-               $this->assertSame($data['name'], $info->getName());
-               $this->assertSame($data['description'], $info->getDescription());
-               $this->assertSame($data['description'], $info->getDescription());
-               $this->assertSame($data['authors'], $info->getAuthors());
-               $this->assertSame($data['maintainers'], $info->getMaintainers());
-               $this->assertSame($data['version'], $info->getVersion());
-               $this->assertSame($data['status'], $info->getStatus());
+               $this->assertSame($expected, $data);
        }
 }