diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 32a1a00..c0fbc53 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -18,6 +18,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" steps: - name: Checkout diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index dc4b6fa..9976515 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -18,6 +18,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" steps: - name: Checkout diff --git a/.laminas-ci.json b/.laminas-ci.json index 82cd446..d7d1ae0 100644 --- a/.laminas-ci.json +++ b/.laminas-ci.json @@ -1,6 +1,6 @@ { "ignore_php_platform_requirements": { - "8.4": true + "8.5": true }, "backwardCompatibilityCheck": true } diff --git a/README.md b/README.md index e258b0c..7d4568c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Documentation is available at: https://docs.dotkernel.org/dot-cli/. ## Badges ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-cli) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.9.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.10.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-cli)](https://github.com/dotkernel/dot-cli/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-cli)](https://github.com/dotkernel/dot-cli/network) @@ -24,7 +24,7 @@ Documentation is available at: https://docs.dotkernel.org/dot-cli/. ## Requirements -- **PHP**: 8.2, 8.3 or 8.4 +- **PHP**: 8.2, 8.3, 8.4 or 8.5 - **laminas/laminas-servicemanager**: >= 3.11 || >= 4.0, - **laminas/laminas-cli**: >= 1.4 @@ -91,7 +91,7 @@ Available commands: As shown in `config/autoload/cli.global.php`, dot-cli includes a demo command `demo:command` that will help you understand the basics of creating a new command. For more information, see [laminas-cli documentation](https://docs.laminas.dev/laminas-cli/). -## Setting up as cronjob +## Setting up as a cronjob ```text * * * * * /opt/plesk/php/7.4/bin/php /var/www/vhosts/example.com/httpdocs/bin/cli.php demo:command -q diff --git a/SECURITY.md b/SECURITY.md index 4c5da79..4497fe9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -3,10 +3,10 @@ ## Supported Versions -| Version | Supported | PHP Version | -|---------|--------------------|---------------------------------------------------------------------------------------------------------| -| 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.4.2) | -| <= 2.x | :x: | | +| Version | Supported | PHP Version | +|---------|--------------------|----------------------------------------------------------------------------------------------------------| +| 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.10.0) | +| <= 2.x | :x: | | ## Reporting Potential Security Issues diff --git a/composer.json b/composer.json index a99af41..69fdefc 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ } }, "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "laminas/laminas-cli": "^1.4.0", "laminas/laminas-servicemanager": "^3.11.1 || ^4.0" }, @@ -35,8 +35,8 @@ "require-dev": { "laminas/laminas-coding-standard": "^3.0", "mikey179/vfsstream": "^1.6.7", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan": "^2.1.17", + "phpstan/phpstan-phpunit": "^2.0.6", "phpunit/phpunit": "^10.2" }, "autoload-dev": { @@ -52,7 +52,8 @@ ], "cs-check": "phpcs", "cs-fix": "phpcbf", + "static-analysis": "phpstan analyse --memory-limit 1G", "test": "phpunit --colors=always", - "static-analysis": "phpstan analyse --memory-limit 1G" + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" } } diff --git a/docs/book/v3/overview.md b/docs/book/v3/overview.md index b18d4e6..77b193f 100644 --- a/docs/book/v3/overview.md +++ b/docs/book/v3/overview.md @@ -1,13 +1,10 @@ # Overview -Dotkernel component to build console applications based on [laminas-cli](https://github.com/laminas/laminas-cli). - +> [!IMPORTANT] > dot-cli is a wrapper on top of [laminas-cli](https://github.com/laminas/laminas-cli) -## Badges - ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-cli) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.9.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-cli/3.10.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-cli)](https://github.com/dotkernel/dot-cli/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-cli)](https://github.com/dotkernel/dot-cli/network) @@ -16,4 +13,3 @@ Dotkernel component to build console applications based on [laminas-cli](https:/ [![Build Static](https://github.com/dotkernel/dot-cli/actions/workflows/continuous-integration.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-cli/actions/workflows/continuous-integration.yml) [![codecov](https://codecov.io/gh/dotkernel/dot-cli/graph/badge.svg?token=0DFCK2GUBT)](https://codecov.io/gh/dotkernel/dot-cli) -[![PHPStan](https://github.com/dotkernel/dot-cli/actions/workflows/static-analysis.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-cli/actions/workflows/static-analysis.yml) diff --git a/docs/book/v3/setting-up-as-cronjob.md b/docs/book/v3/setting-up-as-cronjob.md index 5312129..7c8861d 100644 --- a/docs/book/v3/setting-up-as-cronjob.md +++ b/docs/book/v3/setting-up-as-cronjob.md @@ -1,4 +1,4 @@ -# Setting up as cronjob +# Setting up as a cronjob ```text * * * * * php /var/www/vhosts/example.com/httpdocs/bin/cli.php demo:command -q diff --git a/docs/book/v3/usage.md b/docs/book/v3/usage.md index 08e5915..8e93b4a 100644 --- a/docs/book/v3/usage.md +++ b/docs/book/v3/usage.md @@ -1,7 +1,7 @@ # Usage Use `src/Command/DemoCommand.php` as an example when creating a new command. -Update the name & description in the `AsCommand` attribute as needed. +Update the name and description in the `AsCommand` attribute as needed. Also update the `$defaultName` property and the description set inside the `configure` method to match the `AsCommand` attribute. ## Running diff --git a/test/Command/DemoCommandTest.php b/test/Command/DemoCommandTest.php index 956256a..2ff0c22 100644 --- a/test/Command/DemoCommandTest.php +++ b/test/Command/DemoCommandTest.php @@ -20,7 +20,7 @@ class DemoCommandTest extends TestCase public function testWillCreateCommand(): void { $command = new DemoCommand(); - $this->assertSame(DemoCommand::class, $command::class); + $this->assertContainsOnlyInstancesOf(DemoCommand::class, [$command]); } /** diff --git a/test/FileLockerTest.php b/test/FileLockerTest.php index 4027d47..a9fa075 100644 --- a/test/FileLockerTest.php +++ b/test/FileLockerTest.php @@ -32,28 +32,28 @@ public function testAccessors(): void $fileLocker = new FileLocker(); $this->assertFalse($fileLocker->isEnabled()); $fileLocker->enable(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertTrue($fileLocker->isEnabled()); $fileLocker->disable(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertFalse($fileLocker->isEnabled()); $fileLocker->setEnabled(true); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertTrue($fileLocker->isEnabled()); $fileLocker->setEnabled(false); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertFalse($fileLocker->isEnabled()); $this->assertNull($fileLocker->getDirPath()); $fileLocker->setDirPath('test'); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertSame('test', $fileLocker->getDirPath()); $this->assertNull($fileLocker->getCommandName()); $fileLocker->setCommandName('test'); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertSame('test', $fileLocker->getCommandName()); $this->assertNull($fileLocker->getLockFile()); $fileLocker->setLockFile('test'); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertSame('test', $fileLocker->getLockFile()); $this->assertSame('test/command-test.lock', $fileLocker->getLockFilePath()); } @@ -65,7 +65,7 @@ public function testWillInitLockFile(): void $fileLocker = new FileLocker(true, $config['dirPath'], 'test'); $this->assertNull($fileLocker->getLockFile()); $fileLocker->initLockFile(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertIsResource($fileLocker->getLockFile()); } @@ -79,7 +79,7 @@ public function testWillNotLockWhenDisabled(): void $fileLocker = new FileLocker(false, $config['dirPath'], 'test'); $this->assertNull($fileLocker->getLockFile()); $fileLocker->lock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertNull($fileLocker->getLockFile()); } @@ -93,7 +93,7 @@ public function testWillNotLockWithoutValidCommandName(): void $fileLocker = new FileLocker(true, $config['dirPath']); $this->assertNull($fileLocker->getLockFile()); $fileLocker->lock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertNull($fileLocker->getLockFile()); } @@ -107,7 +107,7 @@ public function testWillLockWhenLockedAndEnabledAndHasValidCommandName(): void $fileLocker = new FileLocker(true, $config['dirPath'], 'test'); $this->assertNull($fileLocker->getLockFile()); $fileLocker->lock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertIsResource($fileLocker->getLockFile()); $this->assertFileExists($fileLocker->getLockFilePath()); } @@ -119,7 +119,7 @@ public function testWillNotUnlockWhenDisabled(): void $fileLocker = new FileLocker(false, $config['dirPath'], 'test'); $this->assertNull($fileLocker->getLockFile()); $fileLocker->unlock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertNull($fileLocker->getLockFile()); } @@ -130,7 +130,7 @@ public function testWillNotUnlockWithoutValidCommandName(): void $fileLocker = new FileLocker(false, $config['dirPath']); $this->assertNull($fileLocker->getLockFile()); $fileLocker->unlock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertNull($fileLocker->getLockFile()); } @@ -141,7 +141,7 @@ public function testWillNotUnlockWhenEnabledAndWithoutValidCommandName(): void $fileLocker = new FileLocker(true, $config['dirPath']); $this->assertNull($fileLocker->getLockFile()); $fileLocker->unlock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertNull($fileLocker->getLockFile()); } @@ -154,11 +154,11 @@ public function testWillUnlockWhenLockedAndEnabledAndHasValidCommandName(): void $fileLocker = new FileLocker(true, $config['dirPath'], 'test'); $fileLocker->lock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertIsResource($fileLocker->getLockFile()); $this->assertFileExists($fileLocker->getLockFilePath()); $fileLocker->unlock(); - $this->assertSame(FileLocker::class, $fileLocker::class); + $this->assertContainsOnlyInstancesOf(FileLocker::class, [$fileLocker]); $this->assertFileIsReadable($fileLocker->getLockFilePath()); $this->assertFileIsWritable($fileLocker->getLockFilePath()); }