diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 72084f84961bcd23362441fb5277179f2e2fc64c..590c9593189d4036b3d1ecdc5114ee26dc853411 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -2,75 +2,131 @@ ## Our Pledge -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. ## Our Standards -Examples of behavior that contributes to creating a positive environment -include: +Examples of behavior that contributes to a positive environment for our +community include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community -Examples of unacceptable behavior by participants include: +Examples of unacceptable behavior include: -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission +* Publishing others' private information, such as a physical or email + address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a - professional setting + professional setting -## Our Responsibilities +## Enforcement Responsibilities -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. ## Scope -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at graham@alt-three.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +reported to the community leaders responsible for enforcement at +hello@gjcampbell.co.uk. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. -[homepage]: https://www.contributor-covenant.org +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 71030ce1be6a2ebcb8e61f20e621845ef72cfb04..c1f7ada2cc7185735e4ad33b017ee865528df835 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ We accept contributions via pull requests on Github. Please review these guideli ## Guidelines -* Please follow the [PSR-2 Coding Style Guide](https://www.php-fig.org/psr/psr-2/). +* Please follow the [PSR-12 Coding Style Guide](https://www.php-fig.org/psr/psr-12/). * Ensure that the current tests pass, and if you've added something new, add the tests where relevant. * Send a coherent commit history, making sure each individual commit in your pull request is meaningful. * You may need to [rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) to avoid merge conflicts. @@ -21,10 +21,10 @@ First, install the dependencies using [Composer](https://getcomposer.org/): $ make install ``` -Then run [PHPUnit](https://phpunit.de/): +Then run [PHPUnit](https://phpunit.de/) and the static analyzers: ```bash $ make test ``` -These will also be automatically run by [Travis CI](https://travis-ci.org/) and [GitHub Actions](https://github.com/features/actions) against pull requests. +These will also be automatically run by [GitHub Actions](https://github.com/features/actions) against pull requests. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 3b10d6da533e058a67b34589346a2046a78b87b8..a9b22039240a4b7e294d957fef83fc0ee7e0e712 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -9,10 +9,6 @@ are multiple supported versions at any given time. ## Reporting a Vulnerability If you discover a security vulnerability within this package, please send an -email to one of the security contacts: - -1. Johannes Schmitt (schmittjoh@gmail.com); -2. Graham Campbell (graham@alt-three.com). - -All security vulnerabilities will be promptly addressed. Please do not disclose -security-related issues publicly until a fix has been announced. +email to security@tidelift.com. All security vulnerabilities will be promptly +addressed. Please do not disclose security-related issues publicly until a fix +has been announced. diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 4fb26d214034550c61c9c430a28501ff79184fab..1f104e390bdaa96f3d375d6ad031e71c454fbd6b 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -99,4 +99,4 @@ jobs: command: composer bin psalm update --no-interaction --no-progress - name: Execute Psalm - run: vendor/bin/psalm --no-progress --output-format=github + run: vendor/bin/psalm.phar --no-progress --output-format=github diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d05425cbfb2b086b1cbfd99ffd7995d501891200..b4be72a5a53f58ab58ce862861ba10a31a31091a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] steps: - name: Checkout Code @@ -27,29 +27,12 @@ jobs: - name: Setup Problem Matchers run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - name: Install PHP 5/7 Dependencies + - name: Install PHP Dependencies uses: nick-invision/retry@v1 with: timeout_minutes: 5 max_attempts: 5 command: composer update --no-interaction --no-progress - if: "matrix.php < 8" - - - name: Setup PHP 8 Dependencies - uses: nick-invision/retry@v1 - with: - timeout_minutes: 5 - max_attempts: 5 - command: composer require "phpunit/phpunit:^9.3" --no-interaction --no-update - if: "matrix.php >= 8" - - - name: Install PHP 8 Dependencies - uses: nick-invision/retry@v1 - with: - timeout_minutes: 5 - max_attempts: 5 - command: composer update --no-interaction --no-progress --ignore-platform-reqs - if: "matrix.php >= 8" - name: Execute PHPUnit run: vendor/bin/phpunit diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f54d25bed2bd1ac62bac6517ad482a4220136927..0000000000000000000000000000000000000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -jobs: - include: - - name: PHP 5.5.9 - dist: trusty - language: php - php: 5.5.9 - before_install: travis_retry composer self-update --2 - install: travis_retry composer update --no-interaction --no-progress - script: vendor/bin/phpunit - - name: PHP 5.5 - dist: trusty - language: php - php: 5.5 - before_install: travis_retry composer self-update --2 - install: travis_retry composer update --no-interaction --no-progress - script: vendor/bin/phpunit diff --git a/Makefile b/Makefile index d8ccac183d11c03339e121a27fbaffe725990278..84d715d98b5c85ca9e6020e2eea17d1be66c67ec 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,14 @@ phpstan-analyze-src: phpstan-analyze-tests: @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:7.4-cli analyze tests -c phpstan.tests.neon.dist +phpstan-baseline: + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:7.4-cli analyze src -c phpstan.src.neon.dist --generate-baseline + psalm-analyze: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm --rm registry.gitlab.com/grahamcampbell/php:7.4-cli + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:7.4-cli psalm-show-info: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm --rm registry.gitlab.com/grahamcampbell/php:7.4-cli --show-info=true + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm .phar--rm registry.gitlab.com/grahamcampbell/php:7.4-cli --show-info=true test: phpunit phpstan-analyze-src phpstan-analyze-tests psalm-analyze diff --git a/README.md b/README.md index 4e9e5a482adb1d7cd59c59026c772d5c77bb79ee..b4f941273bc0d58027193236b5174ef76b82a916 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ your code some options! ## Security -If you discover a security vulnerability within this package, please send an email to one of the security contacts. All security vulnerabilities will be promptly addressed. You may view our full security policy [here](https://github.com/schmittjoh/php-option/security/policy). +If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. You may view our full security policy [here](https://github.com/schmittjoh/php-option/security/policy). ## License diff --git a/composer.json b/composer.json index 859838c4761589e077eba6b08883de18547c4ea8..3cff6ef8298161c8845c5676f712bb0c4523d8ce 100644 --- a/composer.json +++ b/composer.json @@ -6,19 +6,21 @@ "authors": [ { "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" }, { "name": "Graham Campbell", - "email": "graham@alt-three.com" + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], "require": { - "php": "^5.5.9 || ^7.0 || ^8.0" + "php": "^7.0 || ^8.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.4.1", - "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" }, "autoload": { "psr-4": { @@ -35,7 +37,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "1.8-dev" } }, "minimum-stability": "dev", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000000000000000000000000000000000000..97160f2f4cba79e02b39c14df6199177c5ae93a1 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,22 @@ +parameters: + ignoreErrors: + - + message: "#^Method PhpOption\\\\Option\\:\\:fromReturn\\(\\) should return PhpOption\\\\LazyOption\\<S\\> but returns PhpOption\\\\LazyOption\\<mixed\\>\\.$#" + count: 1 + path: src/PhpOption/Option.php + + - + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(PhpOption\\\\Option\\)\\: T given\\.$#" + count: 1 + path: src/PhpOption/Option.php + + - + message: "#^Parameter \\#2 \\$callback of function array_reduce expects callable\\(mixed, mixed\\)\\: mixed, Closure\\(mixed, PhpOption\\\\Option\\)\\: mixed given\\.$#" + count: 1 + path: src/PhpOption/Option.php + + - + message: "#^Template type S of method PhpOption\\\\Option\\:\\:lift\\(\\) is not referenced in a parameter\\.$#" + count: 1 + path: src/PhpOption/Option.php + diff --git a/phpstan.src.neon.dist b/phpstan.src.neon.dist index 6e76f271ed8349716b305b3f347aac9734e07400..214571aa4d6513ef2bb2f9ff73200bd2dde96abb 100644 --- a/phpstan.src.neon.dist +++ b/phpstan.src.neon.dist @@ -1,12 +1,11 @@ +includes: + - phpstan-baseline.neon + parameters: level: max + checkGenericClassInNonGenericObjectType: false ignoreErrors: - message: "#^Method PhpOption\\\\Option\\:\\:fromReturn\\(\\) has parameter \\$arguments with no value type specified in iterable type array\\.$#" count: 1 path: src/PhpOption/Option.php - - - - message: "#^Method PhpOption\\\\Option\\:\\:ensure\\(\\) should return PhpOption\\\\Option\\<S\\> but returns PhpOption\\\\Option\\<S\\|null\\>\\.$#" - count: 1 - path: src/PhpOption/Option.php diff --git a/phpstan.tests.neon.dist b/phpstan.tests.neon.dist index 0ce7f11448f64afd113ae0ccc98463f8c5a8873d..26cee6d85755b9663ff707f69a1122f9b2e50dde 100644 --- a/phpstan.tests.neon.dist +++ b/phpstan.tests.neon.dist @@ -32,7 +32,7 @@ parameters: path: tests/PhpOption/Tests/NoneTest.php - - message: "#^Parameter \\#1 \\$array of static method PhpOption\\\\Option\\<mixed\\>\\:\\:fromArraysValue\\(\\) expects array\\<int\\|string, mixed\\>\\|ArrayAccess\\<int\\|string, mixed\\>\\|null, string given\\.$#" + message: "#^Parameter \\#1 \\$array of static method PhpOption\\\\Option\\<mixed\\>\\:\\:fromArraysValue\\(\\) expects array\\<int\\|string, mixed\\>\\|ArrayAccess\\<int\\|string, mixed\\>\\|null, 'foo' given\\.$#" count: 1 path: tests/PhpOption/Tests/OptionTest.php diff --git a/src/PhpOption/LazyOption.php b/src/PhpOption/LazyOption.php index 6d0fcfb3dc7baef8fd7aa79a7b4d04c4404b62ee..9cb77c86486934b90e4c0e657a4b47f79716ead3 100644 --- a/src/PhpOption/LazyOption.php +++ b/src/PhpOption/LazyOption.php @@ -18,6 +18,8 @@ namespace PhpOption; +use Traversable; + /** * @template T * @@ -41,7 +43,7 @@ final class LazyOption extends Option * * @return LazyOption<S> */ - public static function create($callback, array $arguments = []) + public static function create($callback, array $arguments = []): self { return new self($callback, $arguments); } @@ -60,12 +62,12 @@ final class LazyOption extends Option $this->arguments = $arguments; } - public function isDefined() + public function isDefined(): bool { return $this->option()->isDefined(); } - public function isEmpty() + public function isEmpty(): bool { return $this->option()->isEmpty(); } @@ -135,7 +137,10 @@ final class LazyOption extends Option return $this->option()->reject($value); } - public function getIterator() + /** + * @return Traversable<T> + */ + public function getIterator(): Traversable { return $this->option()->getIterator(); } @@ -153,7 +158,7 @@ final class LazyOption extends Option /** * @return Option<T> */ - private function option() + private function option(): Option { if (null === $this->option) { /** @var mixed */ diff --git a/src/PhpOption/None.php b/src/PhpOption/None.php index 13b2b4e10706481145a8943f40e8233bde0c25a0..4b85d22d2f0832571613156686dd4ae3b3c40d07 100644 --- a/src/PhpOption/None.php +++ b/src/PhpOption/None.php @@ -31,7 +31,7 @@ final class None extends Option /** * @return None */ - public static function create() + public static function create(): self { if (null === self::$instance) { self::$instance = new self(); @@ -60,12 +60,12 @@ final class None extends Option throw $ex; } - public function isEmpty() + public function isEmpty(): bool { return true; } - public function isDefined() + public function isDefined(): bool { return false; } @@ -115,7 +115,7 @@ final class None extends Option return $this; } - public function getIterator() + public function getIterator(): EmptyIterator { return new EmptyIterator(); } diff --git a/src/PhpOption/Some.php b/src/PhpOption/Some.php index 0e9de94cdc6fcb449850b69ad86e5650105c2698..032632eaab07ce605cf6812d18dfd4291644fe40 100644 --- a/src/PhpOption/Some.php +++ b/src/PhpOption/Some.php @@ -45,17 +45,17 @@ final class Some extends Option * * @return Some<U> */ - public static function create($value) + public static function create($value): self { return new self($value); } - public function isDefined() + public function isDefined(): bool { return true; } - public function isEmpty() + public function isEmpty(): bool { return false; } @@ -149,7 +149,10 @@ final class Some extends Option return $this; } - public function getIterator() + /** + * @return ArrayIterator<int, T> + */ + public function getIterator(): ArrayIterator { return new ArrayIterator([$this->value]); } diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json index 0d6c39bcce88d06feeee7460f526e686f5876002..48d035208ddf41f931ab84555b20628e0a490cee 100644 --- a/vendor-bin/phpstan/composer.json +++ b/vendor-bin/phpstan/composer.json @@ -1,6 +1,6 @@ { "require": { - "phpstan/phpstan": "~0.12.33" + "phpstan/phpstan": "1.2.0" }, "config": { "preferred-install": "dist" diff --git a/vendor-bin/psalm/composer.json b/vendor-bin/psalm/composer.json index 92a7feef5093a8f2e89385c7d70adb555d49f3b6..7b9ba454e8d819fb351244d1344d8c938dcb9c92 100644 --- a/vendor-bin/psalm/composer.json +++ b/vendor-bin/psalm/composer.json @@ -1,6 +1,6 @@ { "require": { - "vimeo/psalm": "~3.12.2" + "psalm/phar": "4.14.0" }, "config": { "preferred-install": "dist"