/home/mip/mip/public/img/credit/datatables/phar-io.tar
manifest/composer.lock000064400000004777151235471010011071 0ustar00{
    "_readme": [
        "This file locks the dependencies of your project to a known state",
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "279b3c4fe44357abd924fdcc0cfa5664",
    "packages": [
        {
            "name": "phar-io/version",
            "version": "3.2.1",
            "source": {
                "type": "git",
                "url": "https://github.com/phar-io/version.git",
                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
                "shasum": ""
            },
            "require": {
                "php": "^7.2 || ^8.0"
            },
            "type": "library",
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Arne Blankerts",
                    "email": "arne@blankerts.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Heuer",
                    "email": "sebastian@phpeople.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "Developer"
                }
            ],
            "description": "Library for handling version information and constraints",
            "support": {
                "issues": "https://github.com/phar-io/version/issues",
                "source": "https://github.com/phar-io/version/tree/3.2.1"
            },
            "time": "2022-02-21T01:04:05+00:00"
        }
    ],
    "packages-dev": [],
    "aliases": [],
    "minimum-stability": "stable",
    "stability-flags": [],
    "prefer-stable": false,
    "prefer-lowest": false,
    "platform": {
        "php": "^7.2 || ^8.0",
        "ext-dom": "*",
        "ext-phar": "*",
        "ext-libxml": "*",
        "ext-xmlwriter": "*"
    },
    "platform-dev": [],
    "plugin-api-version": "2.3.0"
}
manifest/LICENSE000064400000003140151235471010007354 0ustar00Phar.io - Manifest

Copyright (c) 2016-2019 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>, and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of Arne Blankerts nor the names of contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  * NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

manifest/src/exceptions/ManifestDocumentLoadingException.php000064400000002373151235471010020461 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use LibXMLError;
use function sprintf;

class ManifestDocumentLoadingException extends \Exception implements Exception {
    /** @var LibXMLError[] */
    private $libxmlErrors;

    /**
     * ManifestDocumentLoadingException constructor.
     *
     * @param LibXMLError[] $libxmlErrors
     */
    public function __construct(array $libxmlErrors) {
        $this->libxmlErrors = $libxmlErrors;
        $first              = $this->libxmlErrors[0];

        parent::__construct(
            sprintf(
                '%s (Line: %d / Column: %d / File: %s)',
                $first->message,
                $first->line,
                $first->column,
                $first->file
            ),
            $first->code
        );
    }

    /**
     * @return LibXMLError[]
     */
    public function getLibxmlErrors(): array {
        return $this->libxmlErrors;
    }
}
manifest/src/exceptions/ManifestElementException.php000064400000000766151235471010017002 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use RuntimeException;

class ManifestElementException extends RuntimeException implements Exception {
}
manifest/src/exceptions/InvalidUrlException.php000064400000001001151235471010015752 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use InvalidArgumentException;

class InvalidUrlException extends InvalidArgumentException implements Exception {
}
manifest/src/exceptions/InvalidEmailException.php000064400000001003151235471010016241 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use InvalidArgumentException;

class InvalidEmailException extends InvalidArgumentException implements Exception {
}
manifest/src/exceptions/ManifestDocumentMapperException.php000064400000000775151235471010020334 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use RuntimeException;

class ManifestDocumentMapperException extends RuntimeException implements Exception {
}
manifest/src/exceptions/NoEmailAddressException.php000064400000001005151235471010016537 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use InvalidArgumentException;

class NoEmailAddressException extends InvalidArgumentException implements Exception {
}
manifest/src/exceptions/InvalidApplicationNameException.php000064400000001061151235471010020262 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use InvalidArgumentException;

class InvalidApplicationNameException extends InvalidArgumentException implements Exception {
    public const InvalidFormat = 2;
}
manifest/src/exceptions/ElementCollectionException.php000064400000001010151235471010017306 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use InvalidArgumentException;

class ElementCollectionException extends InvalidArgumentException implements Exception {
}
manifest/src/exceptions/ManifestDocumentException.php000064400000000767151235471010017170 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use RuntimeException;

class ManifestDocumentException extends RuntimeException implements Exception {
}
manifest/src/exceptions/ManifestLoaderException.php000064400000000730151235471010016606 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ManifestLoaderException extends \Exception implements Exception {
}
manifest/src/exceptions/Exception.php000064400000000710151235471010013766 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Throwable;

interface Exception extends Throwable {
}
manifest/src/xml/ElementCollection.php000064400000003313151235471010014056 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use DOMElement;
use DOMNodeList;
use Iterator;
use ReturnTypeWillChange;
use function count;
use function get_class;
use function sprintf;

/** @template-implements Iterator<int,DOMElement> */
abstract class ElementCollection implements Iterator {
    /** @var DOMElement[] */
    private $nodes = [];

    /** @var int */
    private $position;

    public function __construct(DOMNodeList $nodeList) {
        $this->position = 0;
        $this->importNodes($nodeList);
    }

    #[ReturnTypeWillChange]
    abstract public function current();

    public function next(): void {
        $this->position++;
    }

    public function key(): int {
        return $this->position;
    }

    public function valid(): bool {
        return $this->position < count($this->nodes);
    }

    public function rewind(): void {
        $this->position = 0;
    }

    protected function getCurrentElement(): DOMElement {
        return $this->nodes[$this->position];
    }

    private function importNodes(DOMNodeList $nodeList): void {
        foreach ($nodeList as $node) {
            if (!$node instanceof DOMElement) {
                throw new ElementCollectionException(
                    sprintf('\DOMElement expected, got \%s', get_class($node))
                );
            }

            $this->nodes[] = $node;
        }
    }
}
manifest/src/xml/RequiresElement.php000064400000001113151235471010013556 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class RequiresElement extends ManifestElement {
    public function getPHPElement(): PhpElement {
        return new PhpElement(
            $this->getChildByName('php')
        );
    }
}
manifest/src/xml/AuthorElementCollection.php000064400000001123151235471010015236 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class AuthorElementCollection extends ElementCollection {
    public function current(): AuthorElement {
        return new AuthorElement(
            $this->getCurrentElement()
        );
    }
}
manifest/src/xml/CopyrightElement.php000064400000001414151235471010013733 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class CopyrightElement extends ManifestElement {
    public function getAuthorElements(): AuthorElementCollection {
        return new AuthorElementCollection(
            $this->getChildrenByName('author')
        );
    }

    public function getLicenseElement(): LicenseElement {
        return new LicenseElement(
            $this->getChildByName('license')
        );
    }
}
manifest/src/xml/ContainsElement.php000064400000001611151235471010013540 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ContainsElement extends ManifestElement {
    public function getName(): string {
        return $this->getAttributeValue('name');
    }

    public function getVersion(): string {
        return $this->getAttributeValue('version');
    }

    public function getType(): string {
        return $this->getAttributeValue('type');
    }

    public function getExtensionElement(): ExtensionElement {
        return new ExtensionElement(
            $this->getChildByName('extension')
        );
    }
}
manifest/src/xml/PhpElement.php000064400000001437151235471010012517 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class PhpElement extends ManifestElement {
    public function getVersion(): string {
        return $this->getAttributeValue('version');
    }

    public function hasExtElements(): bool {
        return $this->hasChild('ext');
    }

    public function getExtElements(): ExtElementCollection {
        return new ExtElementCollection(
            $this->getChildrenByName('ext')
        );
    }
}
manifest/src/xml/ComponentElement.php000064400000001206151235471010013724 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ComponentElement extends ManifestElement {
    public function getName(): string {
        return $this->getAttributeValue('name');
    }

    public function getVersion(): string {
        return $this->getAttributeValue('version');
    }
}
manifest/src/xml/ManifestElement.php000064400000004156151235471010013537 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use DOMElement;
use DOMNodeList;
use function sprintf;

class ManifestElement {
    public const XMLNS = 'https://phar.io/xml/manifest/1.0';

    /** @var DOMElement */
    private $element;

    public function __construct(DOMElement $element) {
        $this->element = $element;
    }

    protected function getAttributeValue(string $name): string {
        if (!$this->element->hasAttribute($name)) {
            throw new ManifestElementException(
                sprintf(
                    'Attribute %s not set on element %s',
                    $name,
                    $this->element->localName
                )
            );
        }

        return $this->element->getAttribute($name);
    }

    protected function hasAttribute(string $name): bool {
        return $this->element->hasAttribute($name);
    }

    protected function getChildByName(string $elementName): DOMElement {
        $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);

        if (!$element instanceof DOMElement) {
            throw new ManifestElementException(
                sprintf('Element %s missing', $elementName)
            );
        }

        return $element;
    }

    protected function getChildrenByName(string $elementName): DOMNodeList {
        $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName);

        if ($elementList->length === 0) {
            throw new ManifestElementException(
                sprintf('Element(s) %s missing', $elementName)
            );
        }

        return $elementList;
    }

    protected function hasChild(string $elementName): bool {
        return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0;
    }
}
manifest/src/xml/ExtensionElement.php000064400000001212151235471010013733 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ExtensionElement extends ManifestElement {
    public function getFor(): string {
        return $this->getAttributeValue('for');
    }

    public function getCompatible(): string {
        return $this->getAttributeValue('compatible');
    }
}
manifest/src/xml/ManifestDocument.php000064400000006414151235471010013723 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use DOMDocument;
use DOMElement;
use Throwable;
use function count;
use function file_get_contents;
use function is_file;
use function libxml_clear_errors;
use function libxml_get_errors;
use function libxml_use_internal_errors;
use function sprintf;

class ManifestDocument {
    public const XMLNS = 'https://phar.io/xml/manifest/1.0';

    /** @var DOMDocument */
    private $dom;

    public static function fromFile(string $filename): ManifestDocument {
        if (!is_file($filename)) {
            throw new ManifestDocumentException(
                sprintf('File "%s" not found', $filename)
            );
        }

        return self::fromString(
            file_get_contents($filename)
        );
    }

    public static function fromString(string $xmlString): ManifestDocument {
        $prev = libxml_use_internal_errors(true);
        libxml_clear_errors();

        try {
            $dom = new DOMDocument();
            $dom->loadXML($xmlString);
            $errors = libxml_get_errors();
            libxml_use_internal_errors($prev);
        } catch (Throwable $t) {
            throw new ManifestDocumentException($t->getMessage(), 0, $t);
        }

        if (count($errors) !== 0) {
            throw new ManifestDocumentLoadingException($errors);
        }

        return new self($dom);
    }

    private function __construct(DOMDocument $dom) {
        $this->ensureCorrectDocumentType($dom);

        $this->dom = $dom;
    }

    public function getContainsElement(): ContainsElement {
        return new ContainsElement(
            $this->fetchElementByName('contains')
        );
    }

    public function getCopyrightElement(): CopyrightElement {
        return new CopyrightElement(
            $this->fetchElementByName('copyright')
        );
    }

    public function getRequiresElement(): RequiresElement {
        return new RequiresElement(
            $this->fetchElementByName('requires')
        );
    }

    public function hasBundlesElement(): bool {
        return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;
    }

    public function getBundlesElement(): BundlesElement {
        return new BundlesElement(
            $this->fetchElementByName('bundles')
        );
    }

    private function ensureCorrectDocumentType(DOMDocument $dom): void {
        $root = $dom->documentElement;

        if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {
            throw new ManifestDocumentException('Not a phar.io manifest document');
        }
    }

    private function fetchElementByName(string $elementName): DOMElement {
        $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);

        if (!$element instanceof DOMElement) {
            throw new ManifestDocumentException(
                sprintf('Element %s missing', $elementName)
            );
        }

        return $element;
    }
}
manifest/src/xml/AuthorElement.php000064400000001332151235471010013224 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class AuthorElement extends ManifestElement {
    public function getName(): string {
        return $this->getAttributeValue('name');
    }

    public function getEmail(): string {
        return $this->getAttributeValue('email');
    }

    public function hasEMail(): bool {
        return $this->hasAttribute('email');
    }
}
manifest/src/xml/ExtElement.php000064400000001032151235471010012517 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ExtElement extends ManifestElement {
    public function getName(): string {
        return $this->getAttributeValue('name');
    }
}
manifest/src/xml/LicenseElement.php000064400000001174151235471010013350 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class LicenseElement extends ManifestElement {
    public function getType(): string {
        return $this->getAttributeValue('type');
    }

    public function getUrl(): string {
        return $this->getAttributeValue('url');
    }
}
manifest/src/xml/BundlesElement.php000064400000001172151235471010013360 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class BundlesElement extends ManifestElement {
    public function getComponentElements(): ComponentElementCollection {
        return new ComponentElementCollection(
            $this->getChildrenByName('component')
        );
    }
}
manifest/src/xml/ComponentElementCollection.php000064400000001134151235471010015740 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ComponentElementCollection extends ElementCollection {
    public function current(): ComponentElement {
        return new ComponentElement(
            $this->getCurrentElement()
        );
    }
}
manifest/src/xml/ExtElementCollection.php000064400000001112151235471010014532 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class ExtElementCollection extends ElementCollection {
    public function current(): ExtElement {
        return new ExtElement(
            $this->getCurrentElement()
        );
    }
}
manifest/src/values/Author.php000064400000002430151235471010012411 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use function sprintf;

class Author {
    /** @var string */
    private $name;

    /** @var null|Email */
    private $email;

    public function __construct(string $name, ?Email $email = null) {
        $this->name  = $name;
        $this->email = $email;
    }

    public function asString(): string {
        if (!$this->hasEmail()) {
            return $this->name;
        }

        return sprintf(
            '%s <%s>',
            $this->name,
            $this->email->asString()
        );
    }

    public function getName(): string {
        return $this->name;
    }

    /**
     * @psalm-assert-if-true Email $this->email
     */
    public function hasEmail(): bool {
        return $this->email !== null;
    }

    public function getEmail(): Email {
        if (!$this->hasEmail()) {
            throw new NoEmailAddressException();
        }

        return $this->email;
    }
}
manifest/src/values/PhpExtensionRequirement.php000064400000001252151235471010016015 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class PhpExtensionRequirement implements Requirement {
    /** @var string */
    private $extension;

    public function __construct(string $extension) {
        $this->extension = $extension;
    }

    public function asString(): string {
        return $this->extension;
    }
}
manifest/src/values/Manifest.php000064400000005055151235471010012723 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\Version;

class Manifest {
    /** @var ApplicationName */
    private $name;

    /** @var Version */
    private $version;

    /** @var Type */
    private $type;

    /** @var CopyrightInformation */
    private $copyrightInformation;

    /** @var RequirementCollection */
    private $requirements;

    /** @var BundledComponentCollection */
    private $bundledComponents;

    public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents) {
        $this->name                 = $name;
        $this->version              = $version;
        $this->type                 = $type;
        $this->copyrightInformation = $copyrightInformation;
        $this->requirements         = $requirements;
        $this->bundledComponents    = $bundledComponents;
    }

    public function getName(): ApplicationName {
        return $this->name;
    }

    public function getVersion(): Version {
        return $this->version;
    }

    public function getType(): Type {
        return $this->type;
    }

    public function getCopyrightInformation(): CopyrightInformation {
        return $this->copyrightInformation;
    }

    public function getRequirements(): RequirementCollection {
        return $this->requirements;
    }

    public function getBundledComponents(): BundledComponentCollection {
        return $this->bundledComponents;
    }

    public function isApplication(): bool {
        return $this->type->isApplication();
    }

    public function isLibrary(): bool {
        return $this->type->isLibrary();
    }

    public function isExtension(): bool {
        return $this->type->isExtension();
    }

    public function isExtensionFor(ApplicationName $application, ?Version $version = null): bool {
        if (!$this->isExtension()) {
            return false;
        }

        /** @var Extension $type */
        $type = $this->type;

        if ($version !== null) {
            return $type->isCompatibleWith($application, $version);
        }

        return $type->isExtensionFor($application);
    }
}
manifest/src/values/Library.php000064400000000760151235471010012557 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class Library extends Type {
    public function isLibrary(): bool {
        return true;
    }
}
manifest/src/values/ApplicationName.php000064400000002234151235471010014215 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use function preg_match;
use function sprintf;

class ApplicationName {
    /** @var string */
    private $name;

    public function __construct(string $name) {
        $this->ensureValidFormat($name);
        $this->name = $name;
    }

    public function asString(): string {
        return $this->name;
    }

    public function isEqual(ApplicationName $name): bool {
        return $this->name === $name->name;
    }

    private function ensureValidFormat(string $name): void {
        if (!preg_match('#\w/\w#', $name)) {
            throw new InvalidApplicationNameException(
                sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name),
                InvalidApplicationNameException::InvalidFormat
            );
        }
    }
}
manifest/src/values/BundledComponent.php000064400000001510151235471010014405 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\Version;

class BundledComponent {
    /** @var string */
    private $name;

    /** @var Version */
    private $version;

    public function __construct(string $name, Version $version) {
        $this->name    = $name;
        $this->version = $version;
    }

    public function getName(): string {
        return $this->name;
    }

    public function getVersion(): Version {
        return $this->version;
    }
}
manifest/src/values/Type.php000064400000002243151235471010012072 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\VersionConstraint;

abstract class Type {
    public static function application(): Application {
        return new Application;
    }

    public static function library(): Library {
        return new Library;
    }

    public static function extension(ApplicationName $application, VersionConstraint $versionConstraint): Extension {
        return new Extension($application, $versionConstraint);
    }

    /** @psalm-assert-if-true Application $this */
    public function isApplication(): bool {
        return false;
    }

    /** @psalm-assert-if-true Library $this */
    public function isLibrary(): bool {
        return false;
    }

    /** @psalm-assert-if-true Extension $this */
    public function isExtension(): bool {
        return false;
    }
}
manifest/src/values/CopyrightInformation.php000064400000001534151235471010015331 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class CopyrightInformation {
    /** @var AuthorCollection */
    private $authors;

    /** @var License */
    private $license;

    public function __construct(AuthorCollection $authors, License $license) {
        $this->authors = $authors;
        $this->license = $license;
    }

    public function getAuthors(): AuthorCollection {
        return $this->authors;
    }

    public function getLicense(): License {
        return $this->license;
    }
}
manifest/src/values/BundledComponentCollection.php000064400000002242151235471010016424 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Countable;
use IteratorAggregate;
use function count;

/** @template-implements IteratorAggregate<int,BundledComponent> */
class BundledComponentCollection implements Countable, IteratorAggregate {
    /** @var BundledComponent[] */
    private $bundledComponents = [];

    public function add(BundledComponent $bundledComponent): void {
        $this->bundledComponents[] = $bundledComponent;
    }

    /**
     * @return BundledComponent[]
     */
    public function getBundledComponents(): array {
        return $this->bundledComponents;
    }

    public function count(): int {
        return count($this->bundledComponents);
    }

    public function getIterator(): BundledComponentCollectionIterator {
        return new BundledComponentCollectionIterator($this);
    }
}
manifest/src/values/License.php000064400000001374151235471010012537 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class License {
    /** @var string */
    private $name;

    /** @var Url */
    private $url;

    public function __construct(string $name, Url $url) {
        $this->name = $name;
        $this->url  = $url;
    }

    public function getName(): string {
        return $this->name;
    }

    public function getUrl(): Url {
        return $this->url;
    }
}
manifest/src/values/AuthorCollectionIterator.php000064400000002205151235471010016137 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Iterator;
use function count;

/** @template-implements Iterator<int,Author> */
class AuthorCollectionIterator implements Iterator {
    /** @var Author[] */
    private $authors;

    /** @var int */
    private $position = 0;

    public function __construct(AuthorCollection $authors) {
        $this->authors = $authors->getAuthors();
    }

    public function rewind(): void {
        $this->position = 0;
    }

    public function valid(): bool {
        return $this->position < count($this->authors);
    }

    public function key(): int {
        return $this->position;
    }

    public function current(): Author {
        return $this->authors[$this->position];
    }

    public function next(): void {
        $this->position++;
    }
}
manifest/src/values/Email.php000064400000001620151235471010012176 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use const FILTER_VALIDATE_EMAIL;
use function filter_var;

class Email {
    /** @var string */
    private $email;

    public function __construct(string $email) {
        $this->ensureEmailIsValid($email);

        $this->email = $email;
    }

    public function asString(): string {
        return $this->email;
    }

    private function ensureEmailIsValid(string $url): void {
        if (filter_var($url, FILTER_VALIDATE_EMAIL) === false) {
            throw new InvalidEmailException;
        }
    }
}
manifest/src/values/Url.php000064400000001653151235471010011717 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use const FILTER_VALIDATE_URL;
use function filter_var;

class Url {
    /** @var string */
    private $url;

    public function __construct(string $url) {
        $this->ensureUrlIsValid($url);

        $this->url = $url;
    }

    public function asString(): string {
        return $this->url;
    }

    /**
     * @throws InvalidUrlException
     */
    private function ensureUrlIsValid(string $url): void {
        if (filter_var($url, FILTER_VALIDATE_URL) === false) {
            throw new InvalidUrlException;
        }
    }
}
manifest/src/values/Application.php000064400000000770151235471010013417 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

class Application extends Type {
    public function isApplication(): bool {
        return true;
    }
}
manifest/src/values/RequirementCollection.php000064400000002134151235471010015464 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Countable;
use IteratorAggregate;
use function count;

/** @template-implements IteratorAggregate<int,Requirement> */
class RequirementCollection implements Countable, IteratorAggregate {
    /** @var Requirement[] */
    private $requirements = [];

    public function add(Requirement $requirement): void {
        $this->requirements[] = $requirement;
    }

    /**
     * @return Requirement[]
     */
    public function getRequirements(): array {
        return $this->requirements;
    }

    public function count(): int {
        return count($this->requirements);
    }

    public function getIterator(): RequirementCollectionIterator {
        return new RequirementCollectionIterator($this);
    }
}
manifest/src/values/RequirementCollectionIterator.php000064400000002301151235471010017172 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Iterator;
use function count;

/** @template-implements Iterator<int,Requirement> */
class RequirementCollectionIterator implements Iterator {
    /** @var Requirement[] */
    private $requirements;

    /** @var int */
    private $position = 0;

    public function __construct(RequirementCollection $requirements) {
        $this->requirements = $requirements->getRequirements();
    }

    public function rewind(): void {
        $this->position = 0;
    }

    public function valid(): bool {
        return $this->position < count($this->requirements);
    }

    public function key(): int {
        return $this->position;
    }

    public function current(): Requirement {
        return $this->requirements[$this->position];
    }

    public function next(): void {
        $this->position++;
    }
}
manifest/src/values/Requirement.php000064400000000650151235471010013451 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

interface Requirement {
}
manifest/src/values/AuthorCollection.php000064400000002026151235471010014426 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Countable;
use IteratorAggregate;
use function count;

/** @template-implements IteratorAggregate<int,Author> */
class AuthorCollection implements Countable, IteratorAggregate {
    /** @var Author[] */
    private $authors = [];

    public function add(Author $author): void {
        $this->authors[] = $author;
    }

    /**
     * @return Author[]
     */
    public function getAuthors(): array {
        return $this->authors;
    }

    public function count(): int {
        return count($this->authors);
    }

    public function getIterator(): AuthorCollectionIterator {
        return new AuthorCollectionIterator($this);
    }
}
manifest/src/values/Extension.php000064400000002626151235471010013132 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\Version;
use PharIo\Version\VersionConstraint;

class Extension extends Type {
    /** @var ApplicationName */
    private $application;

    /** @var VersionConstraint */
    private $versionConstraint;

    public function __construct(ApplicationName $application, VersionConstraint $versionConstraint) {
        $this->application       = $application;
        $this->versionConstraint = $versionConstraint;
    }

    public function getApplicationName(): ApplicationName {
        return $this->application;
    }

    public function getVersionConstraint(): VersionConstraint {
        return $this->versionConstraint;
    }

    public function isExtension(): bool {
        return true;
    }

    public function isExtensionFor(ApplicationName $name): bool {
        return $this->application->isEqual($name);
    }

    public function isCompatibleWith(ApplicationName $name, Version $version): bool {
        return $this->isExtensionFor($name) && $this->versionConstraint->complies($version);
    }
}
manifest/src/values/BundledComponentCollectionIterator.php000064400000002375151235471010020145 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use Iterator;
use function count;

/** @template-implements Iterator<int,BundledComponent> */
class BundledComponentCollectionIterator implements Iterator {
    /** @var BundledComponent[] */
    private $bundledComponents;

    /** @var int */
    private $position = 0;

    public function __construct(BundledComponentCollection $bundledComponents) {
        $this->bundledComponents = $bundledComponents->getBundledComponents();
    }

    public function rewind(): void {
        $this->position = 0;
    }

    public function valid(): bool {
        return $this->position < count($this->bundledComponents);
    }

    public function key(): int {
        return $this->position;
    }

    public function current(): BundledComponent {
        return $this->bundledComponents[$this->position];
    }

    public function next(): void {
        $this->position++;
    }
}
manifest/src/values/PhpVersionRequirement.php000064400000001444151235471010015471 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\VersionConstraint;

class PhpVersionRequirement implements Requirement {
    /** @var VersionConstraint */
    private $versionConstraint;

    public function __construct(VersionConstraint $versionConstraint) {
        $this->versionConstraint = $versionConstraint;
    }

    public function getVersionConstraint(): VersionConstraint {
        return $this->versionConstraint;
    }
}
manifest/src/ManifestDocumentMapper.php000064400000011600151235471010014261 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\Exception as VersionException;
use PharIo\Version\Version;
use PharIo\Version\VersionConstraintParser;
use Throwable;
use function sprintf;

class ManifestDocumentMapper {
    public function map(ManifestDocument $document): Manifest {
        try {
            $contains          = $document->getContainsElement();
            $type              = $this->mapType($contains);
            $copyright         = $this->mapCopyright($document->getCopyrightElement());
            $requirements      = $this->mapRequirements($document->getRequiresElement());
            $bundledComponents = $this->mapBundledComponents($document);

            return new Manifest(
                new ApplicationName($contains->getName()),
                new Version($contains->getVersion()),
                $type,
                $copyright,
                $requirements,
                $bundledComponents
            );
        } catch (Throwable $e) {
            throw new ManifestDocumentMapperException($e->getMessage(), (int)$e->getCode(), $e);
        }
    }

    private function mapType(ContainsElement $contains): Type {
        switch ($contains->getType()) {
            case 'application':
                return Type::application();
            case 'library':
                return Type::library();
            case 'extension':
                return $this->mapExtension($contains->getExtensionElement());
        }

        throw new ManifestDocumentMapperException(
            sprintf('Unsupported type %s', $contains->getType())
        );
    }

    private function mapCopyright(CopyrightElement $copyright): CopyrightInformation {
        $authors = new AuthorCollection();

        foreach ($copyright->getAuthorElements() as $authorElement) {
            $authors->add(
                new Author(
                    $authorElement->getName(),
                    $authorElement->hasEMail() ? new Email($authorElement->getEmail()) : null
                )
            );
        }

        $licenseElement = $copyright->getLicenseElement();
        $license        = new License(
            $licenseElement->getType(),
            new Url($licenseElement->getUrl())
        );

        return new CopyrightInformation(
            $authors,
            $license
        );
    }

    private function mapRequirements(RequiresElement $requires): RequirementCollection {
        $collection = new RequirementCollection();
        $phpElement = $requires->getPHPElement();
        $parser     = new VersionConstraintParser;

        try {
            $versionConstraint = $parser->parse($phpElement->getVersion());
        } catch (VersionException $e) {
            throw new ManifestDocumentMapperException(
                sprintf('Unsupported version constraint - %s', $e->getMessage()),
                (int)$e->getCode(),
                $e
            );
        }

        $collection->add(
            new PhpVersionRequirement(
                $versionConstraint
            )
        );

        if (!$phpElement->hasExtElements()) {
            return $collection;
        }

        foreach ($phpElement->getExtElements() as $extElement) {
            $collection->add(
                new PhpExtensionRequirement($extElement->getName())
            );
        }

        return $collection;
    }

    private function mapBundledComponents(ManifestDocument $document): BundledComponentCollection {
        $collection = new BundledComponentCollection();

        if (!$document->hasBundlesElement()) {
            return $collection;
        }

        foreach ($document->getBundlesElement()->getComponentElements() as $componentElement) {
            $collection->add(
                new BundledComponent(
                    $componentElement->getName(),
                    new Version(
                        $componentElement->getVersion()
                    )
                )
            );
        }

        return $collection;
    }

    private function mapExtension(ExtensionElement $extension): Extension {
        try {
            $versionConstraint = (new VersionConstraintParser)->parse($extension->getCompatible());

            return Type::extension(
                new ApplicationName($extension->getFor()),
                $versionConstraint
            );
        } catch (VersionException $e) {
            throw new ManifestDocumentMapperException(
                sprintf('Unsupported version constraint - %s', $e->getMessage()),
                (int)$e->getCode(),
                $e
            );
        }
    }
}
manifest/src/ManifestSerializer.php000064400000013607151235471010013460 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use PharIo\Version\AnyVersionConstraint;
use PharIo\Version\Version;
use PharIo\Version\VersionConstraint;
use XMLWriter;
use function count;
use function file_put_contents;
use function str_repeat;

/** @psalm-suppress MissingConstructor */
class ManifestSerializer {
    /** @var XMLWriter */
    private $xmlWriter;

    public function serializeToFile(Manifest $manifest, string $filename): void {
        file_put_contents(
            $filename,
            $this->serializeToString($manifest)
        );
    }

    public function serializeToString(Manifest $manifest): string {
        $this->startDocument();

        $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
        $this->addCopyright($manifest->getCopyrightInformation());
        $this->addRequirements($manifest->getRequirements());
        $this->addBundles($manifest->getBundledComponents());

        return $this->finishDocument();
    }

    private function startDocument(): void {
        $xmlWriter = new XMLWriter();
        $xmlWriter->openMemory();
        $xmlWriter->setIndent(true);
        $xmlWriter->setIndentString(str_repeat(' ', 4));
        $xmlWriter->startDocument('1.0', 'UTF-8');
        $xmlWriter->startElement('phar');
        $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');

        $this->xmlWriter = $xmlWriter;
    }

    private function finishDocument(): string {
        $this->xmlWriter->endElement();
        $this->xmlWriter->endDocument();

        return $this->xmlWriter->outputMemory();
    }

    private function addContains(ApplicationName $name, Version $version, Type $type): void {
        $this->xmlWriter->startElement('contains');
        $this->xmlWriter->writeAttribute('name', $name->asString());
        $this->xmlWriter->writeAttribute('version', $version->getVersionString());

        switch (true) {
            case $type->isApplication(): {
                $this->xmlWriter->writeAttribute('type', 'application');

                break;
            }

            case $type->isLibrary(): {
                $this->xmlWriter->writeAttribute('type', 'library');

                break;
            }

            case $type->isExtension(): {
                $this->xmlWriter->writeAttribute('type', 'extension');
                /* @var $type Extension */
                $this->addExtension(
                    $type->getApplicationName(),
                    $type->getVersionConstraint()
                );

                break;
            }

            default: {
                $this->xmlWriter->writeAttribute('type', 'custom');
            }
        }

        $this->xmlWriter->endElement();
    }

    private function addCopyright(CopyrightInformation $copyrightInformation): void {
        $this->xmlWriter->startElement('copyright');

        foreach ($copyrightInformation->getAuthors() as $author) {
            $this->xmlWriter->startElement('author');
            $this->xmlWriter->writeAttribute('name', $author->getName());
            $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString());
            $this->xmlWriter->endElement();
        }

        $license = $copyrightInformation->getLicense();

        $this->xmlWriter->startElement('license');
        $this->xmlWriter->writeAttribute('type', $license->getName());
        $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString());
        $this->xmlWriter->endElement();

        $this->xmlWriter->endElement();
    }

    private function addRequirements(RequirementCollection $requirementCollection): void {
        $phpRequirement = new AnyVersionConstraint();
        $extensions     = [];

        foreach ($requirementCollection as $requirement) {
            if ($requirement instanceof PhpVersionRequirement) {
                $phpRequirement = $requirement->getVersionConstraint();

                continue;
            }

            if ($requirement instanceof PhpExtensionRequirement) {
                $extensions[] = $requirement->asString();
            }
        }

        $this->xmlWriter->startElement('requires');
        $this->xmlWriter->startElement('php');
        $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());

        foreach ($extensions as $extension) {
            $this->xmlWriter->startElement('ext');
            $this->xmlWriter->writeAttribute('name', $extension);
            $this->xmlWriter->endElement();
        }

        $this->xmlWriter->endElement();
        $this->xmlWriter->endElement();
    }

    private function addBundles(BundledComponentCollection $bundledComponentCollection): void {
        if (count($bundledComponentCollection) === 0) {
            return;
        }
        $this->xmlWriter->startElement('bundles');

        foreach ($bundledComponentCollection as $bundledComponent) {
            $this->xmlWriter->startElement('component');
            $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
            $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
            $this->xmlWriter->endElement();
        }

        $this->xmlWriter->endElement();
    }

    private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void {
        $this->xmlWriter->startElement('extension');
        $this->xmlWriter->writeAttribute('for', $applicationName->asString());
        $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
        $this->xmlWriter->endElement();
    }
}
manifest/src/ManifestLoader.php000064400000002640151235471010012550 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Manifest.
 *
 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */
namespace PharIo\Manifest;

use function sprintf;

class ManifestLoader {
    public static function fromFile(string $filename): Manifest {
        try {
            return (new ManifestDocumentMapper())->map(
                ManifestDocument::fromFile($filename)
            );
        } catch (Exception $e) {
            throw new ManifestLoaderException(
                sprintf('Loading %s failed.', $filename),
                (int)$e->getCode(),
                $e
            );
        }
    }

    public static function fromPhar(string $filename): Manifest {
        return self::fromFile('phar://' . $filename . '/manifest.xml');
    }

    public static function fromString(string $manifest): Manifest {
        try {
            return (new ManifestDocumentMapper())->map(
                ManifestDocument::fromString($manifest)
            );
        } catch (Exception $e) {
            throw new ManifestLoaderException(
                'Processing string failed',
                (int)$e->getCode(),
                $e
            );
        }
    }
}
manifest/CHANGELOG.md000064400000002751151235471010010167 0ustar00# Changelog

All notable changes to phar-io/manifest are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

## [2.0.4] - 03-03-2024

### Changed

- Make `EMail` an optional attribute for author
- Stick with PHP 7.2 compatibilty 
- Do not use implict nullable type (thanks @sebastianbergmann), this should make things work on PHP 8.4

## [2.0.3] - 20.07.2021

- Fixed PHP 7.2 / PHP 7.3 incompatibility introduced in previous release

## [2.0.2] - 20.07.2021

- Fixed PHP 8.1 deprecation notice

## [2.0.1] - 27.06.2020

This release now supports the use of PHP 7.2+ and ^8.0

## [2.0.0] - 10.05.2020

This release now requires PHP 7.2+

### Changed

- Upgraded to phar-io/version 3.0
    - Version strings `v1.2.3` will now be converted to valid semantic version strings `1.2.3`
    - Abreviated strings like `1.0` will get expaneded to `1.0.0`  

### Unreleased

[Unreleased]: https://github.com/phar-io/manifest/compare/2.1.0...HEAD
[2.1.0]: https://github.com/phar-io/manifest/compare/2.0.3...2.1.0
[2.0.3]: https://github.com/phar-io/manifest/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/phar-io/manifest/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/phar-io/manifest/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/phar-io/manifest/compare/1.0.1...2.0.0
[1.0.3]: https://github.com/phar-io/manifest/compare/1.0.2...1.0.3
[1.0.2]: https://github.com/phar-io/manifest/compare/1.0.1...1.0.2
[1.0.1]: https://github.com/phar-io/manifest/compare/1.0.0...1.0.1
manifest/.php-cs-fixer.dist.php000064400000027561151235471010012422 0ustar00<?php

require __DIR__ . '/tools/php-cs-fixer.d/PhpdocSingleLineVarFixer.php';

$header = file_get_contents(__DIR__ . '/tools/php-cs-fixer.d/header.txt');

return (new PhpCsFixer\Config())
    ->registerCustomFixers([
        new \PharIo\CSFixer\PhpdocSingleLineVarFixer()
    ])
    ->setRiskyAllowed(true)
    ->setRules(
        [
            'PharIo/phpdoc_single_line_var_fixer'           => true,

            'align_multiline_comment'                       => true,
            'array_indentation'                             => true,
            'array_syntax'                                  => ['syntax' => 'short'],
            'binary_operator_spaces'                        => [
                'operators' => [
                    '='  => 'align',
                    '=>' => 'align',
                ],
            ],
            'blank_line_after_namespace'                    => true,
            'blank_line_after_opening_tag'                  => false,
            'blank_line_before_statement'                   => [
                'statements' => [
                    'break',
                    'continue',
                    'declare',
                    'do',
                    'for',
                    'foreach',
                    'if',
                    'include',
                    'include_once',
                    'require',
                    'require_once',
                    'return',
                    'switch',
                    'throw',
                    'try',
                    'while',
                    'yield',
                ],
            ],
            'braces'                                        => [
                'allow_single_line_closure'                   => false,
                'position_after_anonymous_constructs'         => 'same',
                'position_after_control_structures'           => 'same',
                'position_after_functions_and_oop_constructs' => 'same'
            ],
            'cast_spaces'                                   => ['space' => 'none'],

            // This fixer removes the blank line at class start, no way to disable that, so we disable the fixer :(
            //'class_attributes_separation'                   => ['elements' => ['const', 'method', 'property']],

            'combine_consecutive_issets'                    => true,
            'combine_consecutive_unsets'                    => true,
            'compact_nullable_typehint'                     => true,
            'concat_space'                                  => ['spacing' => 'one'],
            'date_time_immutable'                           => true,
            'declare_equal_normalize'                       => ['space' => 'single'],
            'declare_strict_types'                          => true,
            'dir_constant'                                  => true,
            'elseif'                                        => true,
            'encoding'                                      => true,
            'full_opening_tag'                              => true,
            'fully_qualified_strict_types'                  => true,
            'function_declaration'                          => [
                'closure_function_spacing' => 'one'
            ],
            'global_namespace_import'                       => [
                'import_classes'   => true,
                'import_constants' => true,
                'import_functions' => true,
            ],
            'header_comment'                                => ['header' => $header, 'separate' => 'none'],
            'indentation_type'                              => true,
            'is_null'                                       => true,
            'line_ending'                                   => true,
            'list_syntax'                                   => ['syntax' => 'short'],
            'logical_operators'                             => true,
            'lowercase_cast'                                => true,
            'constant_case'                                 => ['case' => 'lower'],
            'lowercase_keywords'                            => true,
            'lowercase_static_reference'                    => true,
            'magic_constant_casing'                         => true,
            'method_argument_space'                         => ['on_multiline' => 'ensure_fully_multiline'],
            'modernize_types_casting'                       => true,
            'multiline_comment_opening_closing'             => true,
            'multiline_whitespace_before_semicolons'        => true,
            'new_with_braces'                               => false,
            'no_alias_functions'                            => true,
            'no_alternative_syntax'                         => true,
            'no_blank_lines_after_class_opening'            => false,
            'no_blank_lines_after_phpdoc'                   => true,
            'no_blank_lines_before_namespace'               => true,
            'no_closing_tag'                                => true,
            'no_empty_comment'                              => true,
            'no_empty_phpdoc'                               => true,
            'no_empty_statement'                            => true,
            'no_extra_blank_lines'                          => true,
            'no_homoglyph_names'                            => true,
            'no_leading_import_slash'                       => true,
            'no_leading_namespace_whitespace'               => true,
            'no_mixed_echo_print'                           => ['use' => 'print'],
            'no_multiline_whitespace_around_double_arrow'   => true,
            'no_null_property_initialization'               => true,
            'no_php4_constructor'                           => true,
            'no_short_bool_cast'                            => true,
            'echo_tag_syntax'                               => ['format' => 'long'],
            'no_singleline_whitespace_before_semicolons'    => true,
            'no_spaces_after_function_name'                 => true,
            'no_spaces_inside_parenthesis'                  => true,
            'no_superfluous_elseif'                         => true,
            'no_superfluous_phpdoc_tags'                    => true,
            'no_trailing_comma_in_list_call'                => true,
            'no_trailing_comma_in_singleline_array'         => true,
            'no_trailing_whitespace'                        => true,
            'no_trailing_whitespace_in_comment'             => true,
            'no_unneeded_control_parentheses'               => false,
            'no_unneeded_curly_braces'                      => false,
            'no_unneeded_final_method'                      => true,
            'no_unreachable_default_argument_value'         => true,
            'no_unset_on_property'                          => true,
            'no_unused_imports'                             => true,
            'no_useless_else'                               => true,
            'no_useless_return'                             => true,
            'no_whitespace_before_comma_in_array'           => true,
            'no_whitespace_in_blank_line'                   => true,
            'non_printable_character'                       => true,
            'normalize_index_brace'                         => true,
            'object_operator_without_whitespace'            => true,
            'ordered_class_elements'                        => [
                'order' => [
                    'use_trait',
                    'constant_public',
                    'constant_protected',
                    'constant_private',
                    'property_public_static',
                    'property_protected_static',
                    'property_private_static',
                    'property_public',
                    'property_protected',
                    'property_private',
                    'method_public_static',
                    'construct',
                    'destruct',
                    'magic',
                    'phpunit',
                    'method_public',
                    'method_protected',
                    'method_private',
                    'method_protected_static',
                    'method_private_static',
                ],
            ],
            'ordered_imports' => [
                'imports_order' => [
                    PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CLASS,
                    PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CONST,
                    PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_FUNCTION,
                ]
            ],
            'phpdoc_add_missing_param_annotation'           => true,
            'phpdoc_align'                                  => true,
            'phpdoc_annotation_without_dot'                 => true,
            'phpdoc_indent'                                 => true,
            'phpdoc_no_access'                              => true,
            'phpdoc_no_empty_return'                        => true,
            'phpdoc_no_package'                             => true,
            'phpdoc_order'                                  => true,
            'phpdoc_return_self_reference'                  => true,
            'phpdoc_scalar'                                 => true,
            'phpdoc_separation'                             => true,
            'phpdoc_single_line_var_spacing'                => true,
            'phpdoc_to_comment'                             => true,
            'phpdoc_trim'                                   => true,
            'phpdoc_trim_consecutive_blank_line_separation' => true,
            'phpdoc_types'                                  => ['groups' => ['simple', 'meta']],
            'phpdoc_types_order'                            => true,
            'phpdoc_to_return_type'                         => true,
            'phpdoc_var_without_name'                       => true,
            'pow_to_exponentiation'                         => true,
            'protected_to_private'                          => true,
            'return_assignment'                             => true,
            'return_type_declaration'                       => ['space_before' => 'none'],
            'self_accessor'                                 => false,
            'semicolon_after_instruction'                   => true,
            'set_type_to_cast'                              => true,
            'short_scalar_cast'                             => true,
            'simplified_null_return'                        => true,
            'single_blank_line_at_eof'                      => true,
            'single_import_per_statement'                   => true,
            'single_line_after_imports'                     => true,
            'single_quote'                                  => true,
            'standardize_not_equals'                        => true,
            'ternary_to_null_coalescing'                    => true,
            'trailing_comma_in_multiline'                   => false,
            'trim_array_spaces'                             => true,
            'unary_operator_spaces'                         => true,
            'visibility_required'                           => [
                'elements' => [
                    'const',
                    'method',
                    'property',
                ],
            ],
            'void_return'                                   => true,
            'whitespace_after_comma_in_array'               => true,
            'yoda_style'                                    => false
        ]
    )
    ->setFinder(
        PhpCsFixer\Finder::create()
            ->files()
            ->in(__DIR__ . '/build')
            ->in(__DIR__ . '/src')
            ->in(__DIR__ . '/tests')
            ->notName('autoload.php')
    );
manifest/.github/FUNDING.yml000064400000000101151235471010011516 0ustar00# These are supported funding model platforms

github: [theseer]
manifest/.github/workflows/ci.yml000064400000003764151235471010013076 0ustar00name: "CI"

on:
  push:
    branches:
      - "master"
  pull_request: null

jobs:
  qa:
    name: "QA"

    runs-on: "ubuntu-latest"

    steps:
      - name: "Checkout"
        uses: "actions/checkout@v3.5.2"

      - name: "Set up PHP"
        uses: "shivammathur/setup-php@2.25.1"
        with:
          coverage: "none"
          php-version: "8.0"
          tools: "phive"

      - name: "Install dependencies with composer"
        run: "composer install --no-interaction --optimize-autoloader --prefer-dist"

      - name: "Install dependencies with phive"
        env:
          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: "ant install-tools"

      - name: "Run php-cs-fixer"
        run: "ant php-cs-fixer"

      - name: "Run psalm"
        run: "ant psalm"

  tests:
    name: "Tests"

    runs-on: "ubuntu-latest"

    strategy:
      fail-fast: false

      matrix:
        php-versions:
          - "7.2"
          - "7.3"
          - "7.4"
          - "8.0"
          - "8.1"
          - "8.2"

    steps:
      - name: "Checkout"
        uses: "actions/checkout@v3.5.2"

      - name: "Set up PHP"
        uses: "shivammathur/setup-php@2.25.1"
        env:
          COMPOSER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
        with:
          coverage: "pcov"
          extensions: "${{ env.extensions }}"
          ini-values: "display_errors=On, error_reporting=-1, memory_limit=2G"
          php-version: "${{ matrix.php-versions }}"
          tools: "phive"

      - name: "Install dependencies with composer"
        run: "composer install --no-interaction --optimize-autoloader --prefer-dist"

      - name: "Install dependencies with phive"
        env:
          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: "ant install-tools"

      - name: "Run PHPUnit"
        run: "tools/phpunit --coverage-clover build/logs/clover.xml"

      - name: "Send code coverage report to codecov.io"
        uses: "codecov/codecov-action@v3.1.4"
        with:
          files: "build/logs/clover.xml"
manifest/tools/php-cs-fixer.d/PhpdocSingleLineVarFixer.php000064400000004016151235471010017610 0ustar00<?php
namespace PharIo\CSFixer;

use PhpCsFixer\Fixer\FixerInterface;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixer\Tokenizer\Token;

/**
 * Main implementation taken from kubawerlos/php-cs-fixer-customere-fixers
 * Copyright (c) 2018 Kuba Werłos
 *
 * Slightly modified to work without the gazillion of composer dependencies
 *
 * Original:
 * https://github.com/kubawerlos/php-cs-fixer-custom-fixers/blob/master/src/Fixer/PhpdocSingleLineVarFixer.php
 *
 */
class PhpdocSingleLineVarFixer implements FixerInterface {

    public function getDefinition(): FixerDefinition {
        return new FixerDefinition(
            '`@var` annotation must be in single line when is the only content.',
            [new CodeSample('<?php
                    /**
                     * @var string
                     */
                ')]
        );
    }

    public function isCandidate(Tokens $tokens): bool {
        return $tokens->isTokenKindFound(T_DOC_COMMENT);
    }

    public function isRisky(): bool {
        return false;
    }

    public function fix(\SplFileInfo $file, Tokens $tokens): void {
        foreach($tokens as $index => $token) {
            if (!$token->isGivenKind(T_DOC_COMMENT)) {
                continue;
            }
            if (\stripos($token->getContent(), '@var') === false) {
                continue;
            }

            if (preg_match('#^/\*\*[\s\*]+(@var[^\r\n]+)[\s\*]*\*\/$#u', $token->getContent(), $matches) !== 1) {
                continue;
            }
            $newContent = '/** ' . \rtrim($matches[1]) . ' */';
            if ($newContent === $token->getContent()) {
                continue;
            }
            $tokens[$index] = new Token([T_DOC_COMMENT, $newContent]);
        }
    }

    public function getPriority(): int {
        return 0;
    }

    public function getName(): string {
        return 'PharIo/phpdoc_single_line_var_fixer';
    }

    public function supports(\SplFileInfo $file): bool {
        return true;
    }

}
manifest/tools/php-cs-fixer.d/header.txt000064400000000467151235471010014240 0ustar00This file is part of PharIo\Manifest.

Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
manifest/composer.json000064400000001601151235471010011071 0ustar00{
  "name": "phar-io/manifest",
  "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
  "license": "BSD-3-Clause",
  "authors": [
    {
      "name": "Arne Blankerts",
      "email": "arne@blankerts.de",
      "role": "Developer"
    },
    {
      "name": "Sebastian Heuer",
      "email": "sebastian@phpeople.de",
      "role": "Developer"
    },
    {
      "name": "Sebastian Bergmann",
      "email": "sebastian@phpunit.de",
      "role": "Developer"
    }
  ],
  "support": {
    "issues": "https://github.com/phar-io/manifest/issues"
  },
  "require": {
    "php": "^7.2 || ^8.0",
    "ext-dom": "*",
    "ext-phar": "*",
    "ext-libxml": "*",
    "ext-xmlwriter": "*",
    "phar-io/version": "^3.0.1"
  },
  "autoload": {
    "classmap": [
      "src/"
    ]
  },
  "extra": {
    "branch-alias": {
        "dev-master": "2.0.x-dev"
    }
  }
}
manifest/README.md000064400000013177151235471010007641 0ustar00# Manifest

Component for reading [phar.io](https://phar.io/) manifest information from a [PHP Archive (PHAR)](http://php.net/phar).

## Installation

You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):

    composer require phar-io/manifest

If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:

    composer require --dev phar-io/manifest

## Usage Examples

### Read from `manifest.xml`
```php
use PharIo\Manifest\ManifestLoader;
use PharIo\Manifest\ManifestSerializer;

$manifest = ManifestLoader::fromFile('manifest.xml');

var_dump($manifest);

echo (new ManifestSerializer)->serializeToString($manifest);
```

<details>
  <summary>Output</summary>
    
```shell
object(PharIo\Manifest\Manifest)#14 (6) {
  ["name":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Manifest\ApplicationName)#10 (1) {
    ["name":"PharIo\Manifest\ApplicationName":private]=>
    string(12) "some/library"
  }
  ["version":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Version\Version)#12 (5) {
    ["originalVersionString":"PharIo\Version\Version":private]=>
    string(5) "1.0.0"
    ["major":"PharIo\Version\Version":private]=>
    object(PharIo\Version\VersionNumber)#13 (1) {
      ["value":"PharIo\Version\VersionNumber":private]=>
      int(1)
    }
    ["minor":"PharIo\Version\Version":private]=>
    object(PharIo\Version\VersionNumber)#23 (1) {
      ["value":"PharIo\Version\VersionNumber":private]=>
      int(0)
    }
    ["patch":"PharIo\Version\Version":private]=>
    object(PharIo\Version\VersionNumber)#22 (1) {
      ["value":"PharIo\Version\VersionNumber":private]=>
      int(0)
    }
    ["preReleaseSuffix":"PharIo\Version\Version":private]=>
    NULL
  }
  ["type":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Manifest\Library)#6 (0) {
  }
  ["copyrightInformation":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Manifest\CopyrightInformation)#19 (2) {
    ["authors":"PharIo\Manifest\CopyrightInformation":private]=>
    object(PharIo\Manifest\AuthorCollection)#9 (1) {
      ["authors":"PharIo\Manifest\AuthorCollection":private]=>
      array(1) {
        [0]=>
        object(PharIo\Manifest\Author)#15 (2) {
          ["name":"PharIo\Manifest\Author":private]=>
          string(13) "Reiner Zufall"
          ["email":"PharIo\Manifest\Author":private]=>
          object(PharIo\Manifest\Email)#16 (1) {
            ["email":"PharIo\Manifest\Email":private]=>
            string(16) "reiner@zufall.de"
          }
        }
      }
    }
    ["license":"PharIo\Manifest\CopyrightInformation":private]=>
    object(PharIo\Manifest\License)#11 (2) {
      ["name":"PharIo\Manifest\License":private]=>
      string(12) "BSD-3-Clause"
      ["url":"PharIo\Manifest\License":private]=>
      object(PharIo\Manifest\Url)#18 (1) {
        ["url":"PharIo\Manifest\Url":private]=>
        string(26) "https://domain.tld/LICENSE"
      }
    }
  }
  ["requirements":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Manifest\RequirementCollection)#17 (1) {
    ["requirements":"PharIo\Manifest\RequirementCollection":private]=>
    array(1) {
      [0]=>
      object(PharIo\Manifest\PhpVersionRequirement)#20 (1) {
        ["versionConstraint":"PharIo\Manifest\PhpVersionRequirement":private]=>
        object(PharIo\Version\SpecificMajorAndMinorVersionConstraint)#24 (3) {
          ["originalValue":"PharIo\Version\AbstractVersionConstraint":private]=>
          string(3) "7.0"
          ["major":"PharIo\Version\SpecificMajorAndMinorVersionConstraint":private]=>
          int(7)
          ["minor":"PharIo\Version\SpecificMajorAndMinorVersionConstraint":private]=>
          int(0)
        }
      }
    }
  }
  ["bundledComponents":"PharIo\Manifest\Manifest":private]=>
  object(PharIo\Manifest\BundledComponentCollection)#8 (1) {
    ["bundledComponents":"PharIo\Manifest\BundledComponentCollection":private]=>
    array(0) {
    }
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<phar xmlns="https://phar.io/xml/manifest/1.0">
    <contains name="some/library" version="1.0.0" type="library"/>
    <copyright>
        <author name="Reiner Zufall" email="reiner@zufall.de"/>
        <license type="BSD-3-Clause" url="https://domain.tld/LICENSE"/>
    </copyright>
    <requires>
        <php version="7.0"/>
    </requires>
</phar>
```
</details>

### Create via API
```php
$bundled = new \PharIo\Manifest\BundledComponentCollection();
$bundled->add(
    new \PharIo\Manifest\BundledComponent('vendor/packageA', new \PharIo\Version\Version('1.2.3-dev')
    )
);

$manifest = new PharIo\Manifest\Manifest(
    new \PharIo\Manifest\ApplicationName('vendor/package'),
    new \PharIo\Version\Version('1.0.0'),
    new \PharIo\Manifest\Library(),
    new \PharIo\Manifest\CopyrightInformation(
        new \PharIo\Manifest\AuthorCollection(),
        new \PharIo\Manifest\License(
            'BSD-3-Clause',
            new \PharIo\Manifest\Url('https://spdx.org/licenses/BSD-3-Clause.html')
        )
    ),
    new \PharIo\Manifest\RequirementCollection(),
    $bundled
);

echo (new ManifestSerializer)->serializeToString($manifest);
```

<details>
  <summary>Output</summary>
    
```xml
<?xml version="1.0" encoding="UTF-8"?>
<phar xmlns="https://phar.io/xml/manifest/1.0">
    <contains name="vendor/package" version="1.0.0" type="library"/>
    <copyright>
        <license type="BSD-3-Clause" url="https://spdx.org/licenses/BSD-3-Clause.html"/>
    </copyright>
    <requires>
        <php version="*"/>
    </requires>
    <bundles>
        <component name="vendor/packageA" version="1.2.3-dev"/>
    </bundles>
</phar>
```
    
</details>

manifest/manifest.xsd000064400000007174151235471010010710 0ustar00<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="https://phar.io/xml/manifest/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns="https://phar.io/xml/manifest/1.0">

  <xs:element name="phar">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns:contains" maxOccurs="1" />
        <xs:element ref="ns:copyright" maxOccurs="1" />
        <xs:element ref="ns:requires" maxOccurs="1" />
        <xs:element ref="ns:bundles" minOccurs="0" maxOccurs="1" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="contains">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute type="xs:string" use="required" name="name"/>
          <xs:attribute type="xs:string" use="required" name="version"/>
          <xs:attribute use="required" name="type">
            <xs:simpleType>
              <xs:restriction base="xs:string">
                <xs:enumeration value="application"/>
                <xs:enumeration value="extension"/>
                <xs:enumeration value="library"/>
                <xs:enumeration value="stub"/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name="copyright">
    <xs:complexType>
      <xs:sequence>
        <xs:choice maxOccurs="unbounded">
          <xs:element ref="ns:author" minOccurs="1" maxOccurs="unbounded" />
        </xs:choice>
        <xs:element ref="ns:license" minOccurs="1" maxOccurs="1" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="author">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute type="xs:string" use="required" name="name"/>
          <xs:attribute type="xs:string" use="optional" name="email"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name="license">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute type="xs:string" use="required" name="type"/>
          <xs:attribute type="xs:string" use="required" name="url"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name="requires">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns:php" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="php">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns:ext" maxOccurs="unbounded" minOccurs="0"  />
      </xs:sequence>
      <xs:attribute type="xs:string" use="required" name="version"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="ext">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute type="xs:string" name="name" use="required" />
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name="bundles">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ns:component" maxOccurs="unbounded" minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="component">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute type="xs:string" name="name" use="required"/>
          <xs:attribute type="xs:string" name="version" use="required"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

</xs:schema>
version/LICENSE000064400000003046151235471010007240 0ustar00Copyright (c) 2016-2017 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de> and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  * NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

version/src/constraints/OrVersionConstraintGroup.php000064400000001777151235471010017123 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class OrVersionConstraintGroup extends AbstractVersionConstraint {
    /** @var VersionConstraint[] */
    private $constraints = [];

    /**
     * @param string              $originalValue
     * @param VersionConstraint[] $constraints
     */
    public function __construct($originalValue, array $constraints) {
        parent::__construct($originalValue);

        $this->constraints = $constraints;
    }

    public function complies(Version $version): bool {
        foreach ($this->constraints as $constraint) {
            if ($constraint->complies($version)) {
                return true;
            }
        }

        return false;
    }
}
version/src/constraints/AndVersionConstraintGroup.php000064400000001727151235471010017240 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class AndVersionConstraintGroup extends AbstractVersionConstraint {
    /** @var VersionConstraint[] */
    private $constraints = [];

    /**
     * @param VersionConstraint[] $constraints
     */
    public function __construct(string $originalValue, array $constraints) {
        parent::__construct($originalValue);

        $this->constraints = $constraints;
    }

    public function complies(Version $version): bool {
        foreach ($this->constraints as $constraint) {
            if (!$constraint->complies($version)) {
                return false;
            }
        }

        return true;
    }
}
version/src/constraints/AnyVersionConstraint.php000064400000001100151235471010016231 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class AnyVersionConstraint implements VersionConstraint {
    public function complies(Version $version): bool {
        return true;
    }

    public function asString(): string {
        return '*';
    }
}
version/src/constraints/SpecificMajorVersionConstraint.php000064400000001372151235471010020233 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class SpecificMajorVersionConstraint extends AbstractVersionConstraint {
    /** @var int */
    private $major;

    public function __construct(string $originalValue, int $major) {
        parent::__construct($originalValue);

        $this->major = $major;
    }

    public function complies(Version $version): bool {
        return $version->getMajor()->getValue() === $this->major;
    }
}
version/src/constraints/VersionConstraint.php000064400000000755151235471010015600 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

interface VersionConstraint {
    public function complies(Version $version): bool;

    public function asString(): string;
}
version/src/constraints/AbstractVersionConstraint.php000064400000001257151235471010017262 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

abstract class AbstractVersionConstraint implements VersionConstraint {
    /** @var string */
    private $originalValue;

    public function __construct(string $originalValue) {
        $this->originalValue = $originalValue;
    }

    public function asString(): string {
        return $this->originalValue;
    }
}
version/src/constraints/ExactVersionConstraint.php000064400000001310151235471010016551 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class ExactVersionConstraint extends AbstractVersionConstraint {
    public function complies(Version $version): bool {
        $other = $version->getVersionString();

        if ($version->hasBuildMetaData()) {
            $other .= '+' . $version->getBuildMetaData()->asString();
        }

        return $this->asString() === $other;
    }
}
version/src/constraints/SpecificMajorAndMinorVersionConstraint.php000064400000001674151235471010021670 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class SpecificMajorAndMinorVersionConstraint extends AbstractVersionConstraint {
    /** @var int */
    private $major;

    /** @var int */
    private $minor;

    public function __construct(string $originalValue, int $major, int $minor) {
        parent::__construct($originalValue);

        $this->major = $major;
        $this->minor = $minor;
    }

    public function complies(Version $version): bool {
        if ($version->getMajor()->getValue() !== $this->major) {
            return false;
        }

        return $version->getMinor()->getValue() === $this->minor;
    }
}
version/src/constraints/GreaterThanOrEqualToVersionConstraint.php000064400000001604151235471010021513 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class GreaterThanOrEqualToVersionConstraint extends AbstractVersionConstraint {
    /** @var Version */
    private $minimalVersion;

    public function __construct(string $originalValue, Version $minimalVersion) {
        parent::__construct($originalValue);

        $this->minimalVersion = $minimalVersion;
    }

    public function complies(Version $version): bool {
        return $version->getVersionString() === $this->minimalVersion->getVersionString()
            || $version->isGreaterThan($this->minimalVersion);
    }
}
version/src/exceptions/NoPreReleaseSuffixException.php000064400000000212151235471010017274 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class NoPreReleaseSuffixException extends \Exception implements Exception {
}
version/src/exceptions/NoBuildMetaDataException.php000064400000000207151235471010016524 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class NoBuildMetaDataException extends \Exception implements Exception {
}
version/src/exceptions/InvalidPreReleaseSuffixException.php000064400000000217151235471010020313 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class InvalidPreReleaseSuffixException extends \Exception implements Exception {
}
version/src/exceptions/UnsupportedVersionConstraintException.php000064400000000723151235471010021535 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

final class UnsupportedVersionConstraintException extends \RuntimeException implements Exception {
}
version/src/exceptions/Exception.php000064400000000650151235471010013650 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

use Throwable;

interface Exception extends Throwable {
}
version/src/exceptions/InvalidVersionException.php000064400000000225151235471010016523 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class InvalidVersionException extends \InvalidArgumentException implements Exception {
}
version/src/VersionNumber.php000064400000001241151235471010012324 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class VersionNumber {

    /** @var ?int */
    private $value;

    public function __construct(?int $value) {
        $this->value = $value;
    }

    public function isAny(): bool {
        return $this->value === null;
    }

    public function getValue(): ?int {
        return $this->value;
    }
}
version/src/Version.php000064400000013453151235471010011163 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class Version {
    /** @var string */
    private $originalVersionString;

    /** @var VersionNumber */
    private $major;

    /** @var VersionNumber */
    private $minor;

    /** @var VersionNumber */
    private $patch;

    /** @var null|PreReleaseSuffix */
    private $preReleaseSuffix;

    /** @var null|BuildMetaData */
    private $buildMetadata;

    public function __construct(string $versionString) {
        $this->ensureVersionStringIsValid($versionString);
        $this->originalVersionString = $versionString;
    }

    /**
     * @throws NoPreReleaseSuffixException
     */
    public function getPreReleaseSuffix(): PreReleaseSuffix {
        if ($this->preReleaseSuffix === null) {
            throw new NoPreReleaseSuffixException('No pre-release suffix set');
        }

        return $this->preReleaseSuffix;
    }

    public function getOriginalString(): string {
        return $this->originalVersionString;
    }

    public function getVersionString(): string {
        $str = \sprintf(
            '%d.%d.%d',
            $this->getMajor()->getValue() ?? 0,
            $this->getMinor()->getValue() ?? 0,
            $this->getPatch()->getValue() ?? 0
        );

        if (!$this->hasPreReleaseSuffix()) {
            return $str;
        }

        return $str . '-' . $this->getPreReleaseSuffix()->asString();
    }

    public function hasPreReleaseSuffix(): bool {
        return $this->preReleaseSuffix !== null;
    }

    public function equals(Version $other): bool {
        if ($this->getVersionString() !== $other->getVersionString()) {
            return false;
        }

        if ($this->hasBuildMetaData() !== $other->hasBuildMetaData()) {
            return false;
        }

        if ($this->hasBuildMetaData() && $other->hasBuildMetaData() &&
            !$this->getBuildMetaData()->equals($other->getBuildMetaData())) {
            return false;
        }

        return true;
    }

    public function isGreaterThan(Version $version): bool {
        if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) {
            return false;
        }

        if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) {
            return true;
        }

        if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) {
            return false;
        }

        if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) {
            return true;
        }

        if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) {
            return false;
        }

        if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) {
            return true;
        }

        if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
            return false;
        }

        if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
            return true;
        }

        if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) {
            return false;
        }

        return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix());
    }

    public function getMajor(): VersionNumber {
        return $this->major;
    }

    public function getMinor(): VersionNumber {
        return $this->minor;
    }

    public function getPatch(): VersionNumber {
        return $this->patch;
    }

    /**
     * @psalm-assert-if-true BuildMetaData $this->buildMetadata
     * @psalm-assert-if-true BuildMetaData $this->getBuildMetaData()
     */
    public function hasBuildMetaData(): bool {
        return $this->buildMetadata !== null;
    }

    /**
     * @throws NoBuildMetaDataException
     */
    public function getBuildMetaData(): BuildMetaData {
        if (!$this->hasBuildMetaData()) {
            throw new NoBuildMetaDataException('No build metadata set');
        }

        return $this->buildMetadata;
    }

    /**
     * @param string[] $matches
     *
     * @throws InvalidPreReleaseSuffixException
     */
    private function parseVersion(array $matches): void {
        $this->major = new VersionNumber((int)$matches['Major']);
        $this->minor = new VersionNumber((int)$matches['Minor']);
        $this->patch = isset($matches['Patch']) ? new VersionNumber((int)$matches['Patch']) : new VersionNumber(0);

        if (isset($matches['PreReleaseSuffix']) && $matches['PreReleaseSuffix'] !== '') {
            $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']);
        }

        if (isset($matches['BuildMetadata'])) {
            $this->buildMetadata = new BuildMetaData($matches['BuildMetadata']);
        }
    }

    /**
     * @param string $version
     *
     * @throws InvalidVersionException
     */
    private function ensureVersionStringIsValid($version): void {
        $regex = '/^v?
            (?P<Major>0|[1-9]\d*)
            \\.
            (?P<Minor>0|[1-9]\d*)
            (\\.
                (?P<Patch>0|[1-9]\d*)
            )?
            (?:
                -
                (?<PreReleaseSuffix>(?:(dev|beta|b|rc|alpha|a|patch|p|pl)\.?\d*))
            )?
            (?:
                \\+
                (?P<BuildMetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-@]+)*)
            )?
        $/xi';

        if (\preg_match($regex, $version, $matches) !== 1) {
            throw new InvalidVersionException(
                \sprintf("Version string '%s' does not follow SemVer semantics", $version)
            );
        }

        $this->parseVersion($matches);
    }
}
version/src/BuildMetaData.php000064400000001317151235471010012172 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class BuildMetaData {

    /** @var string */
    private $value;

    public function __construct(string $value) {
        $this->value = $value;
    }

    public function asString(): string {
        return $this->value;
    }

    public function equals(BuildMetaData $other): bool {
        return $this->asString() === $other->asString();
    }
}
version/src/PreReleaseSuffix.php000064400000003536151235471010012753 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class PreReleaseSuffix {
    private const valueScoreMap = [
        'dev'   => 0,
        'a'     => 1,
        'alpha' => 1,
        'b'     => 2,
        'beta'  => 2,
        'rc'    => 3,
        'p'     => 4,
        'pl'    => 4,
        'patch' => 4,
    ];

    /** @var string */
    private $value;

    /** @var int */
    private $valueScore;

    /** @var int */
    private $number = 0;

    /** @var string */
    private $full;

    /**
     * @throws InvalidPreReleaseSuffixException
     */
    public function __construct(string $value) {
        $this->parseValue($value);
    }

    public function asString(): string {
        return $this->full;
    }

    public function getValue(): string {
        return $this->value;
    }

    public function getNumber(): ?int {
        return $this->number;
    }

    public function isGreaterThan(PreReleaseSuffix $suffix): bool {
        if ($this->valueScore > $suffix->valueScore) {
            return true;
        }

        if ($this->valueScore < $suffix->valueScore) {
            return false;
        }

        return $this->getNumber() > $suffix->getNumber();
    }

    private function mapValueToScore(string $value): int {
        $value = \strtolower($value);

        return self::valueScoreMap[$value];
    }

    private function parseValue(string $value): void {
        $regex = '/-?((dev|beta|b|rc|alpha|a|patch|p|pl)\.?(\d*)).*$/i';

        if (\preg_match($regex, $value, $matches) !== 1) {
            throw new InvalidPreReleaseSuffixException(\sprintf('Invalid label %s', $value));
        }

        $this->full  = $matches[1];
        $this->value = $matches[2];

        if ($matches[3] !== '') {
            $this->number = (int)$matches[3];
        }

        $this->valueScore = $this->mapValueToScore($matches[2]);
    }
}
version/src/VersionConstraintParser.php000064400000007377151235471010014415 0ustar00<?php declare(strict_types = 1);
/*
 * This file is part of PharIo\Version.
 *
 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PharIo\Version;

class VersionConstraintParser {
    /**
     * @throws UnsupportedVersionConstraintException
     */
    public function parse(string $value): VersionConstraint {
        if (\strpos($value, '|') !== false) {
            return $this->handleOrGroup($value);
        }

        if (!\preg_match('/^[\^~*]?v?[\d.*]+(?:-.*)?$/i', $value)) {
            throw new UnsupportedVersionConstraintException(
                \sprintf('Version constraint %s is not supported.', $value)
            );
        }

        switch ($value[0]) {
            case '~':
                return $this->handleTildeOperator($value);
            case '^':
                return $this->handleCaretOperator($value);
        }

        $constraint = new VersionConstraintValue($value);

        if ($constraint->getMajor()->isAny()) {
            return new AnyVersionConstraint();
        }

        if ($constraint->getMinor()->isAny()) {
            return new SpecificMajorVersionConstraint(
                $constraint->getVersionString(),
                $constraint->getMajor()->getValue() ?? 0
            );
        }

        if ($constraint->getPatch()->isAny()) {
            return new SpecificMajorAndMinorVersionConstraint(
                $constraint->getVersionString(),
                $constraint->getMajor()->getValue() ?? 0,
                $constraint->getMinor()->getValue() ?? 0
            );
        }

        return new ExactVersionConstraint($constraint->getVersionString());
    }

    private function handleOrGroup(string $value): OrVersionConstraintGroup {
        $constraints = [];

        foreach (\preg_split('{\s*\|\|?\s*}', \trim($value)) as $groupSegment) {
            $constraints[] = $this->parse(\trim($groupSegment));
        }

        return new OrVersionConstraintGroup($value, $constraints);
    }

    private function handleTildeOperator(string $value): AndVersionConstraintGroup {
        $constraintValue = new VersionConstraintValue(\substr($value, 1));

        if ($constraintValue->getPatch()->isAny()) {
            return $this->handleCaretOperator($value);
        }

        $constraints = [
            new GreaterThanOrEqualToVersionConstraint(
                $value,
                new Version(\substr($value, 1))
            ),
            new SpecificMajorAndMinorVersionConstraint(
                $value,
                $constraintValue->getMajor()->getValue() ?? 0,
                $constraintValue->getMinor()->getValue() ?? 0
            )
        ];

        return new AndVersionConstraintGroup($value, $constraints);
    }

    private function handleCaretOperator(string $value): AndVersionConstraintGroup {
        $constraintValue = new VersionConstraintValue(\substr($value, 1));

        $constraints = [
            new GreaterThanOrEqualToVersionConstraint($value, new Version(\substr($value, 1)))
        ];

        if ($constraintValue->getMajor()->getValue() === 0) {
            $constraints[] = new SpecificMajorAndMinorVersionConstraint(
                $value,
                $constraintValue->getMajor()->getValue() ?? 0,
                $constraintValue->getMinor()->getValue() ?? 0
            );
        } else {
            $constraints[] = new SpecificMajorVersionConstraint(
                $value,
                $constraintValue->getMajor()->getValue() ?? 0
            );
        }

        return new AndVersionConstraintGroup(
            $value,
            $constraints
        );
    }
}
version/src/VersionConstraintValue.php000064400000005046151235471010014224 0ustar00<?php declare(strict_types = 1);
namespace PharIo\Version;

class VersionConstraintValue {
    /** @var VersionNumber */
    private $major;

    /** @var VersionNumber */
    private $minor;

    /** @var VersionNumber */
    private $patch;

    /** @var string */
    private $label = '';

    /** @var string */
    private $buildMetaData = '';

    /** @var string */
    private $versionString = '';

    public function __construct(string $versionString) {
        $this->versionString = $versionString;

        $this->parseVersion($versionString);
    }

    public function getLabel(): string {
        return $this->label;
    }

    public function getBuildMetaData(): string {
        return $this->buildMetaData;
    }

    public function getVersionString(): string {
        return $this->versionString;
    }

    public function getMajor(): VersionNumber {
        return $this->major;
    }

    public function getMinor(): VersionNumber {
        return $this->minor;
    }

    public function getPatch(): VersionNumber {
        return $this->patch;
    }

    private function parseVersion(string $versionString): void {
        $this->extractBuildMetaData($versionString);
        $this->extractLabel($versionString);
        $this->stripPotentialVPrefix($versionString);

        $versionSegments = \explode('.', $versionString);
        $this->major     = new VersionNumber(\is_numeric($versionSegments[0]) ? (int)$versionSegments[0] : null);

        $minorValue = isset($versionSegments[1]) && \is_numeric($versionSegments[1]) ? (int)$versionSegments[1] : null;
        $patchValue = isset($versionSegments[2]) && \is_numeric($versionSegments[2]) ? (int)$versionSegments[2] : null;

        $this->minor = new VersionNumber($minorValue);
        $this->patch = new VersionNumber($patchValue);
    }

    private function extractBuildMetaData(string &$versionString): void {
        if (\preg_match('/\+(.*)/', $versionString, $matches) === 1) {
            $this->buildMetaData = $matches[1];
            $versionString       = \str_replace($matches[0], '', $versionString);
        }
    }

    private function extractLabel(string &$versionString): void {
        if (\preg_match('/-(.*)/', $versionString, $matches) === 1) {
            $this->label   = $matches[1];
            $versionString = \str_replace($matches[0], '', $versionString);
        }
    }

    private function stripPotentialVPrefix(string &$versionString): void {
        if ($versionString[0] !== 'v') {
            return;
        }
        $versionString = \substr($versionString, 1);
    }
}
version/CHANGELOG.md000064400000007225151235471010010047 0ustar00# Changelog

All notable changes to phar-io/version are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

## [3.2.1] - 2022-02-21

### Fixed

- Have ExactVersionConstraint honor build metadata (added in 3.2.0)


## [3.2.0] - 2022-02-21

### Added

- Build metadata is now supported and considered for equality checks only


## [3.1.1] - 2022-02-07

### Fixed

- [#28](https://github.com/phar-io/version/issues/28): `VersionConstraintParser` does not support logical OR represented by single pipe (|) (Thanks @llaville)


## [3.1.0] - 2021-02-23

### Changed

- Internal Refactoring
- More scalar types

### Added

- [#24](https://github.com/phar-io/version/issues/24): `Version::getOriginalString()` added (Thanks @addshore)
- Version constraints using the caret operator (`^`) now honor pre-1.0 releases, e.g. `^0.3` translates to `0.3.*`)
- Various integration tests for version constraint processing

### Fixed

- [#23](https://github.com/phar-io/version/pull/23): Tilde operator without patch level



## [3.0.4] - 14.12.2020

### Fixed 

- [#22](https://github.com/phar-io/version/pull/22): make dev suffix rank works for uppercase too

## [3.0.3] - 30.11.2020

### Added

- Comparator method `Version::equals()` added


## [3.0.2] - 27.06.2020

This release now supports PHP 7.2+ and PHP ^8.0. No other changes included.


## [3.0.1] - 09.05.2020

__Potential BC Break Notice:__
`Version::getVersionString()` no longer returns `v` prefixes in case the "input"
string contained one. These are not part of the semver specs
(see https://semver.org/#is-v123-a-semantic-version) and get stripped out.
As of Version 3.1.0 `Version::getOriginalString()` can be used to still
retrieve it as given.

### Changed

- Internal Refactoring
- More scalar types

### Fixed

- Fixed Constraint processing Regression for ^1.2  and ~1.2


## [3.0.0] - 05.05.2020

### Changed

- Require PHP 7.2+
- All code now uses strict mode
- Scalar types have been added as needed

### Added

- The technically invalid format using 'v' prefix ("v1.2.3") is now properly supported 


## [2.0.1] - 08.07.2018

### Fixed

- Versions without a pre-release suffix are now always considered greater 
than versions with a pre-release suffix. Example: `3.0.0 > 3.0.0-alpha.1`  


## [2.0.0] - 23.06.2018

Changes to public API:

- `PreReleaseSuffix::construct()`: optional parameter `$number` removed
- `PreReleaseSuffix::isGreaterThan()`: introduced
- `Version::hasPreReleaseSuffix()`: introduced

### Added

- [#11](https://github.com/phar-io/version/issues/11): Added support for pre-release version suffixes. Supported values are:
  - `dev`
  - `beta` (also abbreviated form `b`)
  - `rc`
  - `alpha` (also abbreviated form `a`)
  - `patch` (also abbreviated form `p`)

  All values can be followed by a number, e.g. `beta3`. 

  When comparing versions, the pre-release suffix is taken into account. Example:
`1.5.0 > 1.5.0-beta1 > 1.5.0-alpha3 > 1.5.0-alpha2 > 1.5.0-dev11`

### Changed

- reorganized the source directories

### Fixed

- [#10](https://github.com/phar-io/version/issues/10): Version numbers containing 
a numeric suffix as seen in Debian packages are now supported.  


[3.1.0]: https://github.com/phar-io/version/compare/3.0.4...3.1.0
[3.0.4]: https://github.com/phar-io/version/compare/3.0.3...3.0.4
[3.0.3]: https://github.com/phar-io/version/compare/3.0.2...3.0.3
[3.0.2]: https://github.com/phar-io/version/compare/3.0.1...3.0.2
[3.0.1]: https://github.com/phar-io/version/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/phar-io/version/compare/2.0.1...3.0.0
[2.0.1]: https://github.com/phar-io/version/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/phar-io/version/compare/1.0.1...2.0.0
version/composer.json000064400000001241151235471010010750 0ustar00{
  "name": "phar-io/version",
  "description": "Library for handling version information and constraints",
  "license": "BSD-3-Clause",
  "authors": [
    {
      "name": "Arne Blankerts",
      "email": "arne@blankerts.de",
      "role": "Developer"
    },
    {
      "name": "Sebastian Heuer",
      "email": "sebastian@phpeople.de",
      "role": "Developer"
    },
    {
      "name": "Sebastian Bergmann",
      "email": "sebastian@phpunit.de",
      "role": "Developer"
    }
  ],
  "support": {
    "issues": "https://github.com/phar-io/version/issues"
  },
  "require": {
    "php": "^7.2 || ^8.0"
  },
  "autoload": {
    "classmap": [
      "src/"
    ]
  }
}

version/README.md000064400000004471151235471010007515 0ustar00# Version

Library for handling version information and constraints

[![Build Status](https://travis-ci.org/phar-io/version.svg?branch=master)](https://travis-ci.org/phar-io/version)

## Installation

You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):

    composer require phar-io/version

If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:

    composer require --dev phar-io/version

## Version constraints

A Version constraint describes a range of versions or a discrete version number. The format of version numbers follows the schema of [semantic versioning](http://semver.org): `<major>.<minor>.<patch>`. A constraint might contain an operator that describes the range.

Beside the typical mathematical operators like `<=`, `>=`, there are two special operators:

*Caret operator*: `^1.0`
can be written as `>=1.0.0 <2.0.0` and read as »every Version within major version `1`«.

*Tilde operator*: `~1.0.0`
can be written as `>=1.0.0 <1.1.0` and read as »every version within minor version `1.1`. The behavior of tilde operator depends on whether a patch level version is provided or not. If no patch level is provided, tilde operator behaves like the caret operator: `~1.0` is identical to `^1.0`.

## Usage examples

Parsing version constraints and check discrete versions for compliance:

```php

use PharIo\Version\Version;
use PharIo\Version\VersionConstraintParser;

$parser = new VersionConstraintParser();
$caret_constraint = $parser->parse( '^7.0' );

$caret_constraint->complies( new Version( '7.0.17' ) ); // true
$caret_constraint->complies( new Version( '7.1.0' ) ); // true
$caret_constraint->complies( new Version( '6.4.34' ) ); // false

$tilde_constraint = $parser->parse( '~1.1.0' );

$tilde_constraint->complies( new Version( '1.1.4' ) ); // true
$tilde_constraint->complies( new Version( '1.2.0' ) ); // false
```

As of version 2.0.0, pre-release labels are supported and taken into account when comparing versions:

```php

$leftVersion = new PharIo\Version\Version('3.0.0-alpha.1');
$rightVersion = new PharIo\Version\Version('3.0.0-alpha.2');

$leftVersion->isGreaterThan($rightVersion); // false
$rightVersion->isGreaterThan($leftVersion); // true

```