diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd0aa10c..d2a27aca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # v1.7.0 ## mm/dd/2020 +1. [](#new) + * Auto-Escape enabled by default. Manually enable **Twig Compatibility** and disable **Auto-Escape** to use the old setting. + * Updated unit tests to use codeception 4.1 1. [](#bugfix) * Fixed potential error when upgrading Grav - * Updated unit tests to use codeception 4.1 - * Auto-Escape enabled by default. Manually enable **Twig Compatibility** to + * Fixed broken list in `bin/gpm index` [#3092](https://github.com/getgrav/grav/issues/3092) + * Fixed CLI/GPM command failures returning 0 (success) value [#3017](https://github.com/getgrav/grav/issues/3017) # v1.7.0-rc.19 ## 12/02/2020 diff --git a/composer.lock b/composer.lock index 28e8bb00c..67c8dd737 100644 --- a/composer.lock +++ b/composer.lock @@ -48,6 +48,10 @@ } ], "description": "Composer package for DOMWordsIterator and DOMLettersIterator", + "support": { + "issues": "https://github.com/antoligy/dom-string-iterators/issues", + "source": "https://github.com/antoligy/dom-string-iterators/tree/v1.0.1" + }, "time": "2018-02-03T16:01:11+00:00" }, { @@ -104,6 +108,25 @@ "ssl", "tls" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.2.8" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], "time": "2020-08-23T12:54:47+00:00" }, { @@ -186,6 +209,24 @@ "redis", "xcache" ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/1.10.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], "time": "2020-07-07T18:54:01+00:00" }, { @@ -251,6 +292,10 @@ "iterators", "php" ], + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.6.7" + }, "time": "2020-07-27T17:53:49+00:00" }, { @@ -305,6 +350,20 @@ "user agent", "useragent" ], + "support": { + "issues": "https://github.com/donatj/PhpUserAgent/issues", + "source": "https://github.com/donatj/PhpUserAgent/tree/master" + }, + "funding": [ + { + "url": "https://www.paypal.me/donatj/15", + "type": "custom" + }, + { + "url": "https://github.com/donatj", + "type": "github" + } + ], "time": "2020-09-01T16:13:00+00:00" }, { @@ -349,6 +408,9 @@ "cron", "schedule" ], + "support": { + "source": "https://github.com/dragonmantank/cron-expression/tree/v1.2.0" + }, "time": "2017-01-23T04:29:33+00:00" }, { @@ -556,6 +618,10 @@ "throwable", "whoops" ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.9.1" + }, "time": "2020-11-01T12:00:00+00:00" }, { @@ -726,6 +792,10 @@ "uri", "url" ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, "time": "2020-09-30T07:37:11+00:00" }, { @@ -789,6 +859,12 @@ "issues": "https://github.com/itsgoingd/clockwork/issues", "source": "https://github.com/itsgoingd/clockwork/tree/v5.0.4" }, + "funding": [ + { + "url": "https://github.com/itsgoingd", + "type": "github" + } + ], "time": "2020-12-01T22:36:41+00:00" }, { @@ -844,6 +920,9 @@ "psr-17", "psr-7" ], + "support": { + "source": "https://github.com/kodus/psr7-server/tree/master" + }, "time": "2019-06-17T10:48:13+00:00" }, { @@ -969,6 +1048,10 @@ "minifier", "minify" ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.63" + }, "time": "2020-01-21T20:21:08+00:00" }, { @@ -1018,6 +1101,10 @@ "paths", "relative" ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, "time": "2019-02-05T23:41:09+00:00" }, { @@ -1079,6 +1166,10 @@ "debug", "debugbar" ], + "support": { + "issues": "https://github.com/maximebf/php-debugbar/issues", + "source": "https://github.com/maximebf/php-debugbar/tree/v1.16.3" + }, "time": "2020-05-06T07:06:27+00:00" }, { @@ -1135,6 +1226,10 @@ "jpeg", "tiff" ], + "support": { + "issues": "https://github.com/PHPExif/php-exif/issues", + "source": "https://github.com/PHPExif/php-exif/tree/v0.6.5" + }, "time": "2019-02-11T13:47:52+00:00" }, { @@ -1212,6 +1307,20 @@ "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/1.25.5" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], "time": "2020-07-23T08:35:51+00:00" }, { @@ -1275,6 +1384,20 @@ "psr-17", "psr-7" ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.3.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], "time": "2020-11-14T17:35:34+00:00" }, { @@ -1318,6 +1441,16 @@ "lazy", "twig" ], + "support": { + "issues": "https://github.com/rybakit/twig-extensions-deferred-legacy/issues", + "source": "https://github.com/rybakit/twig-extensions-deferred-legacy/tree/v1.0.2" + }, + "funding": [ + { + "url": "https://github.com/rybakit", + "type": "github" + } + ], "time": "2017-03-17T21:39:21+00:00" }, { @@ -1368,6 +1501,10 @@ "stream", "uri" ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, "time": "2015-12-19T14:08:53+00:00" }, { @@ -1467,6 +1604,9 @@ "psr", "psr-6" ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, "time": "2016-08-06T20:24:11+00:00" }, { @@ -1516,6 +1656,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, "time": "2017-02-14T16:28:37+00:00" }, { @@ -1568,6 +1712,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, "time": "2019-04-30T12:38:16+00:00" }, { @@ -1618,6 +1765,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -1671,6 +1821,10 @@ "response", "server" ], + "support": { + "issues": "https://github.com/php-fig/http-server-handler/issues", + "source": "https://github.com/php-fig/http-server-handler/tree/master" + }, "time": "2018-10-30T16:46:14+00:00" }, { @@ -1724,6 +1878,10 @@ "request", "response" ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/master" + }, "time": "2018-10-30T17:12:04+00:00" }, { @@ -1771,6 +1929,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, "time": "2020-03-23T09:12:05+00:00" }, { @@ -1819,6 +1980,9 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { @@ -1859,6 +2023,10 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { @@ -1963,6 +2131,10 @@ "input", "prompt" ], + "support": { + "issues": "https://github.com/Seldaek/cli-prompt/issues", + "source": "https://github.com/Seldaek/cli-prompt/tree/master" + }, "time": "2017-03-18T11:32:45+00:00" }, { @@ -2038,6 +2210,20 @@ "support": { "source": "https://github.com/symfony/console/tree/v4.4.17" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-28T10:15:42+00:00" }, { @@ -2115,6 +2301,23 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/contracts/tree/v1.1.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-09-02T16:08:58+00:00" }, { @@ -2184,6 +2387,20 @@ "support": { "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.17" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-31T22:44:29+00:00" }, { @@ -2250,6 +2467,20 @@ "support": { "source": "https://github.com/symfony/http-client/tree/v4.4.17" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-28T13:23:02+00:00" }, { @@ -2312,6 +2543,23 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2375,6 +2623,23 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2438,6 +2703,23 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2497,6 +2779,23 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2559,6 +2858,23 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2625,6 +2941,20 @@ "support": { "source": "https://github.com/symfony/polyfill-php74/tree/v1.20.0" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2694,6 +3024,20 @@ "support": { "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T14:02:19+00:00" }, { @@ -2741,6 +3085,20 @@ "support": { "source": "https://github.com/symfony/process/tree/v4.4.17" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-02T15:10:16+00:00" }, { @@ -2816,6 +3174,20 @@ "support": { "source": "https://github.com/symfony/var-dumper/tree/v4.4.17" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-24T09:55:37+00:00" }, { @@ -2873,6 +3245,20 @@ "support": { "source": "https://github.com/symfony/yaml/tree/v4.4.16" }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-24T11:50:19+00:00" }, { @@ -2941,6 +3327,16 @@ "issues": "https://github.com/twigphp/Twig/issues", "source": "https://github.com/twigphp/Twig/tree/v1.44.1" }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], "time": "2020-10-27T19:22:48+00:00" }, { @@ -2993,6 +3389,10 @@ "header", "negotiation" ], + "support": { + "issues": "https://github.com/willdurand/Negotiation/issues", + "source": "https://github.com/willdurand/Negotiation/tree/3.0.0" + }, "time": "2020-09-25T08:01:41+00:00" } ], @@ -3054,6 +3454,10 @@ "gherkin", "parser" ], + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/master" + }, "time": "2020-03-17T14:03:26+00:00" }, { @@ -3139,6 +3543,16 @@ "functional testing", "unit testing" ], + "support": { + "issues": "https://github.com/Codeception/Codeception/issues", + "source": "https://github.com/Codeception/Codeception/tree/4.1.12" + }, + "funding": [ + { + "url": "https://opencollective.com/codeception", + "type": "open_collective" + } + ], "time": "2020-11-16T06:36:57+00:00" }, { @@ -3189,6 +3603,10 @@ "keywords": [ "codeception" ], + "support": { + "issues": "https://github.com/Codeception/lib-asserts/issues", + "source": "https://github.com/Codeception/lib-asserts/tree/1.13.2" + }, "time": "2020-10-21T16:26:20+00:00" }, { @@ -3242,6 +3660,10 @@ "asserts", "codeception" ], + "support": { + "issues": "https://github.com/Codeception/module-asserts/issues", + "source": "https://github.com/Codeception/module-asserts/tree/1.3.1" + }, "time": "2020-10-21T16:48:15+00:00" }, { @@ -3286,6 +3708,10 @@ } ], "description": "PHPUnit classes used by Codeception", + "support": { + "issues": "https://github.com/Codeception/phpunit-wrapper/issues", + "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.5" + }, "time": "2020-10-11T18:14:42+00:00" }, { @@ -3316,6 +3742,10 @@ "MIT" ], "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", + "support": { + "issues": "https://github.com/Codeception/Stub/issues", + "source": "https://github.com/Codeception/Stub/tree/3.7.0" + }, "time": "2020-07-03T15:54:43+00:00" }, { @@ -3371,6 +3801,24 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], "time": "2020-11-11T10:22:58+00:00" }, { @@ -3415,6 +3863,25 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], "time": "2020-11-13T08:04:11+00:00" }, { @@ -3466,6 +3933,24 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], "time": "2020-11-10T18:47:58+00:00" }, { @@ -3516,6 +4001,10 @@ "faker", "fixtures" ], + "support": { + "issues": "https://github.com/fzaninotto/Faker/issues", + "source": "https://github.com/fzaninotto/Faker/tree/v1.9.1" + }, "abandoned": true, "time": "2019-12-12T13:22:17+00:00" }, @@ -3568,6 +4057,10 @@ "release", "versions" ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/1.5.1" + }, "time": "2020-09-14T08:43:34+00:00" }, { @@ -3616,6 +4109,16 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], "time": "2020-11-13T09:40:50+00:00" }, { @@ -3693,6 +4196,10 @@ "configurator", "nette" ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/master" + }, "time": "2020-05-26T08:46:23+00:00" }, { @@ -3764,6 +4271,10 @@ "nette", "static" ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.0.6" + }, "time": "2020-11-25T22:42:55+00:00" }, { @@ -3827,6 +4338,10 @@ "iterator", "nette" ], + "support": { + "issues": "https://github.com/nette/finder/issues", + "source": "https://github.com/nette/finder/tree/v2.5.2" + }, "time": "2020-01-03T20:35:40+00:00" }, { @@ -3889,6 +4404,10 @@ "nette", "yaml" ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/master" + }, "time": "2020-07-31T12:28:05+00:00" }, { @@ -3953,6 +4472,10 @@ "php", "scaffolding" ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v3.5.1" + }, "time": "2020-11-04T11:26:26+00:00" }, { @@ -4016,6 +4539,10 @@ "nette", "trait" ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v3.3.1" + }, "time": "2020-09-15T15:14:17+00:00" }, { @@ -4074,6 +4601,10 @@ "config", "nette" ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.0.3" + }, "time": "2020-11-25T21:54:59+00:00" }, { @@ -4211,6 +4742,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.3" + }, "time": "2020-12-03T17:45:45+00:00" }, { @@ -4267,6 +4802,10 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, "time": "2020-06-27T14:33:11+00:00" }, { @@ -4314,6 +4853,10 @@ } ], "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.0.3" + }, "time": "2020-11-30T09:21:21+00:00" }, { @@ -4420,6 +4963,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.1.0" + }, "time": "2020-02-22T12:28:44+00:00" }, { @@ -4532,6 +5079,10 @@ "spy", "stub" ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/master" + }, "time": "2020-07-08T12:44:21+00:00" }, { @@ -4579,6 +5130,10 @@ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/master" + }, "time": "2019-06-07T19:13:52+00:00" }, { @@ -4654,6 +5209,24 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/0.11.20" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], "time": "2020-10-12T14:33:05+00:00" }, { @@ -4705,6 +5278,10 @@ "MIT" ], "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/0.11.2" + }, "time": "2019-05-28T19:54:04+00:00" }, { @@ -4772,6 +5349,16 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-28T06:44:49+00:00" }, { @@ -4822,6 +5409,16 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T05:57:25+00:00" }, { @@ -4875,6 +5472,16 @@ "keywords": [ "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T05:58:55+00:00" }, { @@ -4924,6 +5531,16 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T05:33:50+00:00" }, { @@ -4973,6 +5590,16 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:16:10+00:00" }, { @@ -5062,6 +5689,20 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.4.0" + }, + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-02T03:54:37+00:00" }, { @@ -5108,6 +5749,16 @@ ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T06:08:49+00:00" }, { @@ -5154,6 +5805,16 @@ ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:08:54+00:00" }, { @@ -5199,6 +5860,16 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T05:30:19+00:00" }, { @@ -5263,6 +5934,16 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T15:49:45+00:00" }, { @@ -5310,6 +5991,16 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T15:52:27+00:00" }, { @@ -5366,6 +6057,16 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:10:38+00:00" }, { @@ -5419,6 +6120,16 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T05:52:38+00:00" }, { @@ -5486,6 +6197,16 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T05:24:23+00:00" }, { @@ -5540,6 +6261,16 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T15:55:19+00:00" }, { @@ -5587,6 +6318,16 @@ ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-28T06:42:11+00:00" }, { @@ -5634,6 +6375,16 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:12:34+00:00" }, { @@ -5679,6 +6430,16 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:14:26+00:00" }, { @@ -5732,6 +6493,16 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:17:30+00:00" }, { @@ -5777,6 +6548,16 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T06:45:17+00:00" }, { @@ -5823,6 +6604,16 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-10-26T13:18:59+00:00" }, { @@ -5866,6 +6657,16 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-09-28T06:39:44+00:00" }, { @@ -5914,6 +6715,23 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-28T21:31:18+00:00" }, { @@ -5958,6 +6776,23 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.17" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-17T19:45:34+00:00" }, { @@ -6002,6 +6837,12 @@ "issues": "https://github.com/theseer/tokenizer/issues", "source": "https://github.com/theseer/tokenizer/tree/master" }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], "time": "2020-07-12T23:59:07+00:00" }, { @@ -6025,6 +6866,7 @@ "require-dev": { "phpunit/phpunit": "3.7.23" }, + "default-branch": true, "bin": [ "bin/phpdoc-md" ], @@ -6096,6 +6938,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, "time": "2020-04-18T12:12:48+00:00" } ], @@ -6120,5 +6966,6 @@ "platform-dev": [], "platform-overrides": { "php": "7.3.6" - } + }, + "plugin-api-version": "2.0.0" } diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index e6bb8b58a..a85e10933 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -16,7 +16,12 @@ use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function count; +/** + * Class BackupCommand + * @package Grav\Console\Cli + */ class BackupCommand extends ConsoleCommand { /** @var string $source */ @@ -25,7 +30,10 @@ class BackupCommand extends ConsoleCommand /** @var ProgressBar $progress */ protected $progress; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('backup') @@ -40,7 +48,10 @@ class BackupCommand extends ConsoleCommand $this->source = getcwd(); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->initializeGrav(); @@ -53,7 +64,7 @@ class BackupCommand extends ConsoleCommand if (!class_exists(\ZipArchive::class)) { $io->error('php-zip extension needs to be enabled!'); - exit; + return 1; } /** @var Backups $backups */ @@ -69,7 +80,7 @@ class BackupCommand extends ConsoleCommand } if (null === $id) { - if (\count($backups_list) > 1) { + if (count($backups_list) > 1) { $helper = $this->getHelper('question'); $question = new ChoiceQuestion( 'Choose a backup?', @@ -91,12 +102,15 @@ class BackupCommand extends ConsoleCommand $io->newline(2); $io->success('Backup Successfully Created: ' . $backup); + + return 0; } /** * @param array $args + * @return void */ - public function outputProgress($args) + public function outputProgress($args): void { switch ($args['type']) { case 'count': diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index 16f008812..ba03cb67b 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -15,6 +15,10 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Formatter\OutputFormatterStyle; +/** + * Class CleanCommand + * @package Grav\Console\Cli + */ class CleanCommand extends Command { /* @var InputInterface $output */ @@ -260,7 +264,10 @@ class CleanCommand extends Command 'cache/compiled/', ]; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('clean') @@ -271,15 +278,21 @@ class CleanCommand extends Command /** * @param InputInterface $input * @param OutputInterface $output + * @return int */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->setupConsole($input, $output); $this->cleanPaths(); + + return 0; } - private function cleanPaths() + /** + * @return void + */ + private function cleanPaths(): void { $this->output->writeln(''); $this->output->writeln('DELETING'); @@ -305,8 +318,9 @@ class CleanCommand extends Command * * @param InputInterface $input * @param OutputInterface $output + * @return void */ - public function setupConsole(InputInterface $input, OutputInterface $output) + public function setupConsole(InputInterface $input, OutputInterface $output): void { $this->input = $input; $this->output = $output; diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php index 6915eccd9..877127986 100644 --- a/system/src/Grav/Console/Cli/ClearCacheCommand.php +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -13,9 +13,16 @@ use Grav\Common\Cache; use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputOption; +/** + * Class ClearCacheCommand + * @package Grav\Console\Cli + */ class ClearCacheCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('cache') @@ -32,16 +39,23 @@ class ClearCacheCommand extends ConsoleCommand ->setHelp('The cache command allows you to interact with Grav cache'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->initializePlugins(); $this->cleanPaths(); + + return 0; } /** * loops over the array of paths and deletes the files/folders + * + * @return void */ - private function cleanPaths() + private function cleanPaths(): void { $this->output->writeln(''); diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php index 1dceb1f8e..1ff959fba 100644 --- a/system/src/Grav/Console/Cli/ComposerCommand.php +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -12,9 +12,16 @@ namespace Grav\Console\Cli; use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputOption; +/** + * Class ComposerCommand + * @package Grav\Console\Cli + */ class ComposerCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('composer') @@ -34,7 +41,10 @@ class ComposerCommand extends ConsoleCommand ->setHelp('The composer command updates the composer vendor dependencies needed by Grav'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $action = $this->input->getOption('install') ? 'install' : ($this->input->getOption('update') ? 'update' : 'install'); @@ -45,5 +55,7 @@ class ComposerCommand extends ConsoleCommand // Updates composer first $this->output->writeln("\nInstalling vendor dependencies"); $this->output->writeln($this->composerUpdate(GRAV_ROOT, $action)); + + return 0; } } diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index cd73c841e..eca0ff5b4 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -14,6 +14,10 @@ use RocketTheme\Toolbox\File\YamlFile; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +/** + * Class InstallCommand + * @package Grav\Console\Cli + */ class InstallCommand extends ConsoleCommand { /** @var array */ @@ -28,7 +32,10 @@ class InstallCommand extends ConsoleCommand /** @var string */ protected $user_path; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('install') @@ -47,7 +54,10 @@ class InstallCommand extends ConsoleCommand ->setHelp('The install command installs the dependencies needed by Grav. Optionally can create symbolic links'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $dependencies_file = '.dependencies'; $this->destination = $this->input->getArgument('destination') ?: ROOT_DIR; @@ -72,38 +82,46 @@ class InstallCommand extends ConsoleCommand $this->output->writeln('HINT Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.'); } - return; + return 1; } $this->config = $file->content(); $file->free(); - // If yaml config, process - if ($this->config) { - if (!$this->input->getOption('symlink')) { - // Updates composer first - $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln($this->composerUpdate(GRAV_ROOT, 'install')); - - $this->gitclone(); - } else { - $this->symlink(); - } - } else { + // If no config, fail. + if (!$this->config) { $this->output->writeln('ERROR invalid YAML in ' . $dependencies_file); + + return 1; } + + $error = 0; + if (!$this->input->getOption('symlink')) { + // Updates composer first + $this->output->writeln("\nInstalling vendor dependencies"); + $this->output->writeln($this->composerUpdate(GRAV_ROOT, 'install')); + + $error = $this->gitclone(); + } else { + $error = $this->symlink(); + } + + return $error; } /** * Clones from Git + * + * @return int */ - private function gitclone() + private function gitclone(): int { $this->output->writeln(''); $this->output->writeln('Cloning Bits'); $this->output->writeln('============'); $this->output->writeln(''); + $error = 0; foreach ($this->config['git'] as $repo => $data) { $this->destination = rtrim($this->destination, DS); $path = $this->destination . DS . $data['path']; @@ -114,6 +132,7 @@ class InstallCommand extends ConsoleCommand $this->output->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); } else { $this->output->writeln('ERROR cloning ' . $data['url']); + $error = 1; } $this->output->writeln(''); @@ -122,12 +141,16 @@ class InstallCommand extends ConsoleCommand $this->output->writeln(''); } } + + return $error; } /** * Symlinks + * + * @return int */ - private function symlink() + private function symlink(): int { $this->output->writeln(''); $this->output->writeln('Symlinking Bits'); @@ -137,9 +160,11 @@ class InstallCommand extends ConsoleCommand if (!$this->local_config) { $this->output->writeln('No local configuration available, aborting...'); $this->output->writeln(''); - return; + + return 1; } + $error = 0; exec('cd ' . $this->destination); foreach ($this->config['links'] as $repo => $data) { $repos = (array) $this->local_config[$data['scm'] . '_repos']; @@ -157,16 +182,17 @@ class InstallCommand extends ConsoleCommand if (!$from) { $this->output->writeln('source for ' . $data['src'] . ' does not exists, skipping...'); $this->output->writeln(''); + $error = 1; + } elseif (!file_exists($to)) { + symlink($from, $to); + $this->output->writeln('SUCCESS symlinked ' . $data['src'] . ' -> ' . $data['path'] . ''); + $this->output->writeln(''); } else { - if (!file_exists($to)) { - symlink($from, $to); - $this->output->writeln('SUCCESS symlinked ' . $data['src'] . ' -> ' . $data['path'] . ''); - $this->output->writeln(''); - } else { - $this->output->writeln('destination: ' . $to . ' already exists, skipping...'); - $this->output->writeln(''); - } + $this->output->writeln('destination: ' . $to . ' already exists, skipping...'); + $this->output->writeln(''); } } + + return $error; } } diff --git a/system/src/Grav/Console/Cli/LogViewerCommand.php b/system/src/Grav/Console/Cli/LogViewerCommand.php index 75ea79dc2..ca0845247 100644 --- a/system/src/Grav/Console/Cli/LogViewerCommand.php +++ b/system/src/Grav/Console/Cli/LogViewerCommand.php @@ -9,15 +9,23 @@ namespace Grav\Console\Cli; +use DateTime; use Grav\Common\Grav; use Grav\Common\Helpers\LogViewer; use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Style\SymfonyStyle; +/** + * Class LogViewerCommand + * @package Grav\Console\Cli + */ class LogViewerCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('logviewer') @@ -34,14 +42,17 @@ class LogViewerCommand extends ConsoleCommand 'number of lines (default = 10)' ) ->setDescription('Display the last few entries of Grav log') - ->setHelp("Display the last few entries of Grav log"); + ->setHelp('Display the last few entries of Grav log'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $file = $this->input->getOption('file') ?? 'grav.log'; $lines = $this->input->getOption('lines') ?? 20; - $verbose = $this->input->getOption('verbose', false); + $verbose = $this->input->getOption('verbose') ?? false; $io = new SymfonyStyle($this->input, $this->output); @@ -53,29 +64,33 @@ class LogViewerCommand extends ConsoleCommand $viewer = new LogViewer(); $grav = Grav::instance(); + $logfile = $grav['locator']->findResource('log://' . $file); - - if ($logfile) { - $rows = $viewer->objectTail($logfile, $lines, true); - foreach ($rows as $log) { - $date = $log['date']; - $level_color = LogViewer::levelColor($log['level']); - - if ($date instanceof \DateTime) { - $output = "{$log['date']->format('Y-m-d h:i:s')} [<{$level_color}>{$log['level']}]"; - if ($log['trace'] && $verbose) { - $output .= " {$log['message']}\n"; - foreach ((array) $log['trace'] as $index => $tracerow) { - $output .= "{$index}${tracerow}\n"; - } - } else { - $output .= " {$log['message']}"; - } - $io->writeln($output); - } - } - } else { + if (!$logfile) { $io->error('cannot find the log file: logs/' . $file); + + return 1; } + + $rows = $viewer->objectTail($logfile, $lines, true); + foreach ($rows as $log) { + $date = $log['date']; + $level_color = LogViewer::levelColor($log['level']); + + if ($date instanceof DateTime) { + $output = "{$log['date']->format('Y-m-d h:i:s')} [<{$level_color}>{$log['level']}]"; + if ($log['trace'] && $verbose) { + $output .= " {$log['message']}\n"; + foreach ((array) $log['trace'] as $index => $tracerow) { + $output .= "{$index}${tracerow}\n"; + } + } else { + $output .= " {$log['message']}"; + } + $io->writeln($output); + } + } + + return 0; } } diff --git a/system/src/Grav/Console/Cli/NewProjectCommand.php b/system/src/Grav/Console/Cli/NewProjectCommand.php index b1527227c..9eb651c8a 100644 --- a/system/src/Grav/Console/Cli/NewProjectCommand.php +++ b/system/src/Grav/Console/Cli/NewProjectCommand.php @@ -14,9 +14,16 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +/** + * Class NewProjectCommand + * @package Grav\Console\Cli + */ class NewProjectCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('new-project') @@ -36,7 +43,10 @@ class NewProjectCommand extends ConsoleCommand ->setHelp("The new-project command is a combination of the `setup` and `install` commands.\nCreates a new Grav instance and performs the installation of all the required dependencies."); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $sandboxCommand = $this->getApplication()->find('sandbox'); $installCommand = $this->getApplication()->find('install'); @@ -53,7 +63,11 @@ class NewProjectCommand extends ConsoleCommand '-s' => $this->input->getOption('symlink') ]); - $sandboxCommand->run($sandboxArguments, $this->output); - $installCommand->run($installArguments, $this->output); + $error = $sandboxCommand->run($sandboxArguments, $this->output); + if ($error === 0) { + $error = $installCommand->run($installArguments, $this->output); + } + + return $error; } } diff --git a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php index 8046b70f5..eab501381 100644 --- a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php +++ b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php @@ -17,7 +17,13 @@ use Grav\Common\Page\Pages; use Grav\Console\ConsoleCommand; use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Input\InputOption; +use function in_array; +use function is_object; +/** + * Class PageSystemValidatorCommand + * @package Grav\Console\Cli + */ class PageSystemValidatorCommand extends ConsoleCommand { /** @var array */ @@ -125,7 +131,10 @@ class PageSystemValidatorCommand extends ConsoleCommand /** @var Grav */ protected $grav; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('page-system-validator') @@ -135,7 +144,10 @@ class PageSystemValidatorCommand extends ConsoleCommand ->setHelp('The page-system-validator command can be used to test the pages before and after upgrade'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->setLanguage('en'); $this->initializePages(); @@ -182,8 +194,13 @@ class PageSystemValidatorCommand extends ConsoleCommand $this->output->writeln('page-system-validator [-r|--record] [-c|--check]'); } $this->output->writeln(''); + + return 0; } + /** + * @return array + */ private function record() { /** @var Pages $pages */ @@ -243,7 +260,12 @@ class PageSystemValidatorCommand extends ConsoleCommand return $results; } - private function check(array $old, array $new) + /** + * @param array $old + * @param array $new + * @return array + */ + private function check(array $old, array $new): array { $errors = []; foreach ($old as $path => $page) { diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index f7dc0a90d..9a0b40310 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -11,9 +11,15 @@ namespace Grav\Console\Cli; use Grav\Console\ConsoleCommand; use Grav\Common\Filesystem\Folder; +use RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +use function count; +/** + * Class SandboxCommand + * @package Grav\Console\Cli + */ class SandboxCommand extends ConsoleCommand { /** @var array */ @@ -61,7 +67,10 @@ class SandboxCommand extends ConsoleCommand /** @var string */ protected $destination; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('sandbox') @@ -81,38 +90,52 @@ class SandboxCommand extends ConsoleCommand $source = getcwd(); if ($source === false) { - throw new \RuntimeException('Internal Error'); + throw new RuntimeException('Internal Error'); } $this->source = $source; } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->destination = $this->input->getArgument('destination'); - // Symlink the Core Stuff - if ($this->input->getOption('symlink')) { - // Create Some core stuff if it doesn't exist - $this->createDirectories(); - - // Loop through the symlink mappings and create the symlinks - $this->symlink(); - - // Copy the Core STuff - } else { - // Create Some core stuff if it doesn't exist - $this->createDirectories(); - - // Loop through the symlink mappings and copy what otherwise would be symlinks - $this->copy(); + // Create Some core stuff if it doesn't exist + $error = $this->createDirectories(); + if ($error) { + return $error; } - $this->pages(); - $this->initFiles(); - $this->perms(); + // Copy files or create symlinks + $error = $this->input->getOption('symlink') ? $this->symlink() : $this->copy(); + if ($error) { + return $error; + } + + $error = $this->pages(); + if ($error) { + return $error; + } + + $error = $this->initFiles(); + if ($error) { + return $error; + } + + $error = $this->perms(); + if ($error) { + return $error; + } + + return 0; } - private function createDirectories() + /** + * @return int + */ + private function createDirectories(): int { $this->output->writeln(''); $this->output->writeln('Creating Directories'); @@ -133,9 +156,14 @@ class SandboxCommand extends ConsoleCommand if (!$dirs_created) { $this->output->writeln(' Directories already exist'); } + + return 0; } - private function copy() + /** + * @return int + */ + private function copy(): int { $this->output->writeln(''); $this->output->writeln('Copying Files'); @@ -152,9 +180,14 @@ class SandboxCommand extends ConsoleCommand $this->output->writeln(' ' . $source . ' -> ' . $to); @Folder::rcopy($from, $to); } + + return 0; } - private function symlink() + /** + * @return int + */ + private function symlink(): int { $this->output->writeln(''); $this->output->writeln('Resetting Symbolic Links'); @@ -177,11 +210,39 @@ class SandboxCommand extends ConsoleCommand } symlink($from, $to); } + + return 0; } - private function initFiles() + /** + * @return int + */ + private function pages(): int { - $this->check(); + $this->output->writeln(''); + $this->output->writeln('Pages Initializing'); + + // get pages files and initialize if no pages exist + $pages_dir = $this->destination . '/user/pages'; + $pages_files = array_diff(scandir($pages_dir), ['..', '.']); + + if (count($pages_files) === 0) { + $destination = $this->source . '/user/pages'; + Folder::rcopy($destination, $pages_dir); + $this->output->writeln(' ' . $destination . ' -> Created'); + } + + return 0; + } + + /** + * @return int + */ + private function initFiles(): int + { + if (!$this->check()) { + return 1; + } $this->output->writeln(''); $this->output->writeln('File Initializing'); @@ -206,25 +267,14 @@ class SandboxCommand extends ConsoleCommand if (!$files_init) { $this->output->writeln(' Files already exist'); } + + return 0; } - private function pages() - { - $this->output->writeln(''); - $this->output->writeln('Pages Initializing'); - - // get pages files and initialize if no pages exist - $pages_dir = $this->destination . '/user/pages'; - $pages_files = array_diff(scandir($pages_dir), ['..', '.']); - - if (\count($pages_files) === 0) { - $destination = $this->source . '/user/pages'; - Folder::rcopy($destination, $pages_dir); - $this->output->writeln(' ' . $destination . ' -> Created'); - } - } - - private function perms() + /** + * @return int + */ + private function perms(): int { $this->output->writeln(''); $this->output->writeln('Permissions Initializing'); @@ -239,14 +289,19 @@ class SandboxCommand extends ConsoleCommand } $this->output->writeln(""); + + return 0; } - private function check() + /** + * @return bool + */ + private function check(): bool { $success = true; if (!file_exists($this->destination)) { - $this->output->writeln(' file: $this->destination does not exist!'); + $this->output->writeln(' file: ' . $this->destination . ' does not exist!'); $success = false; } @@ -267,7 +322,8 @@ class SandboxCommand extends ConsoleCommand if (!$success) { $this->output->writeln(''); $this->output->writeln('install should be run with --symlink|--s to symlink first'); - exit; } + + return $success; } } diff --git a/system/src/Grav/Console/Cli/SchedulerCommand.php b/system/src/Grav/Console/Cli/SchedulerCommand.php index 41c855f03..0cba71be9 100644 --- a/system/src/Grav/Console/Cli/SchedulerCommand.php +++ b/system/src/Grav/Console/Cli/SchedulerCommand.php @@ -18,10 +18,18 @@ use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Style\SymfonyStyle; +use function is_null; +/** + * Class SchedulerCommand + * @package Grav\Console\Cli + */ class SchedulerCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('scheduler') @@ -53,11 +61,13 @@ class SchedulerCommand extends ConsoleCommand ->setHelp("Running without any options will force the Scheduler to run through it's jobs and process them"); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->initializePlugins(); -// error_reporting(1); $grav = Grav::instance(); $grav['backups']->init(); @@ -68,6 +78,7 @@ class SchedulerCommand extends ConsoleCommand $this->setHelp('foo'); $io = new SymfonyStyle($this->input, $this->output); + $error = 0; if ($this->input->getOption('jobs')) { // Show jobs list @@ -159,6 +170,7 @@ class SchedulerCommand extends ConsoleCommand if ($job->isSuccessful()) { $io->success('Job ran successfully...'); } else { + $error = 1; $io->error('Job failed to run successfully...'); } @@ -168,6 +180,7 @@ class SchedulerCommand extends ConsoleCommand $this->output->write($output); } } else { + $error = 1; $io->error('Could not find a job with id: ' . $jobid); } } elseif ($this->input->getOption('install')) { @@ -180,6 +193,7 @@ class SchedulerCommand extends ConsoleCommand $verb = 'reinstall'; } else { $user = $scheduler->whoami(); + $error = 1; $io->error('Can\'t find a crontab for ' . $user . '. You need to set up Grav\'s Scheduler in your crontab'); } if (!Utils::isWindows()) { @@ -199,5 +213,7 @@ class SchedulerCommand extends ConsoleCommand $io->text($scheduler->getVerboseOutput()); } } + + return $error; } } diff --git a/system/src/Grav/Console/Cli/SecurityCommand.php b/system/src/Grav/Console/Cli/SecurityCommand.php index f936c8624..1922fe3cf 100644 --- a/system/src/Grav/Console/Cli/SecurityCommand.php +++ b/system/src/Grav/Console/Cli/SecurityCommand.php @@ -14,13 +14,21 @@ use Grav\Common\Security; use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Style\SymfonyStyle; +use function count; +/** + * Class SecurityCommand + * @package Grav\Console\Cli + */ class SecurityCommand extends ConsoleCommand { /** @var ProgressBar $progress */ protected $progress; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('security') @@ -28,13 +36,16 @@ class SecurityCommand extends ConsoleCommand ->setHelp('The security runs various security checks on your Grav site'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->initializePages(); /** @var Grav $grav */ $grav = Grav::instance(); - $this->progress = new ProgressBar($this->output, \count($grav['pages']->routes()) - 1); + $this->progress = new ProgressBar($this->output, count($grav['pages']->routes()) - 1); $this->progress->setFormat('Scanning %current% pages [%bar%] %percent:3s%% %elapsed:6s%'); $this->progress->setBarWidth(100); @@ -45,28 +56,33 @@ class SecurityCommand extends ConsoleCommand $io->newline(2); + $error = 0; if (!empty($output)) { $counter = 1; foreach ($output as $route => $results) { - $results_parts = array_map(function ($value, $key) { + $results_parts = array_map(static function ($value, $key) { return $key.': \''.$value . '\''; }, array_values($results), array_keys($results)); $io->writeln($counter++ .' - ' . $route . '' . implode(', ', $results_parts) . ''); } - $io->error('Security Scan complete: ' . \count($output) . ' potential XSS issues found...'); + $error = 1; + $io->error('Security Scan complete: ' . count($output) . ' potential XSS issues found...'); } else { $io->success('Security Scan complete: No issues found...'); } $io->newline(1); + + return $error; } /** * @param array $args + * @return void */ - public function outputProgress($args) + public function outputProgress($args): void { switch ($args['type']) { case 'count': diff --git a/system/src/Grav/Console/Cli/ServerCommand.php b/system/src/Grav/Console/Cli/ServerCommand.php index 478f24d8d..41da25080 100644 --- a/system/src/Grav/Console/Cli/ServerCommand.php +++ b/system/src/Grav/Console/Cli/ServerCommand.php @@ -16,6 +16,10 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; +/** + * Class ServerCommand + * @package Grav\Console\Cli + */ class ServerCommand extends ConsoleCommand { const SYMFONY_SERVER = 'Symfony Server'; @@ -28,7 +32,10 @@ class ServerCommand extends ConsoleCommand /** @var SymfonyStyle */ protected $io; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('server') @@ -39,7 +46,10 @@ class ServerCommand extends ConsoleCommand ->setHelp("Runs built-in web-server, Symfony first, then tries PHP's"); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $io = $this->io = new SymfonyStyle($this->input, $this->output); @@ -59,7 +69,6 @@ class ServerCommand extends ConsoleCommand $this->ip = '127.0.0.1'; $this->port = (int)($this->input->getOption('port') ?? 8000); - // Get an open port while (!$this->portAvailable($this->ip, $this->port)) { $this->port++; @@ -80,6 +89,7 @@ class ServerCommand extends ConsoleCommand unset($commands[self::SYMFONY_SERVER]); } + $error = 0; foreach ($commands as $name => $command) { $process = $this->runProcess($name, $command); @@ -92,18 +102,26 @@ class ServerCommand extends ConsoleCommand ($name === self::SYMFONY_SERVER && $force_symfony) || ($name === self::PHP_SERVER) )) { + $error = 1; $io->error('Could not start ' . $name); } } + + return $error; } + /** + * @param string $name + * @param string $cmd + * @return Process + */ protected function runProcess($name, $cmd) { - $process = new Process($cmd); + $process = new Process([$cmd]); $process->setTimeout(0); $process->start(); - if ($name == self::SYMFONY_SERVER && Utils::contains($process->getErrorOutput(), 'symfony: not found')) { + if ($name === self::SYMFONY_SERVER && Utils::contains($process->getErrorOutput(), 'symfony: not found')) { $this->io->error('The symfony binary could not be found, please install the CLI tools: https://symfony.com/download'); $this->io->warning('Falling back to PHP web server...'); } @@ -126,7 +144,7 @@ class ServerCommand extends ConsoleCommand * @param int $port * @return bool */ - protected function portAvailable($ip, $port) + protected function portAvailable($ip, $port): bool { $fp = @fsockopen($ip, $port, $errno, $errstr, 0.1); if (!$fp) { @@ -134,6 +152,7 @@ class ServerCommand extends ConsoleCommand } fclose($fp); + return false; } } diff --git a/system/src/Grav/Console/Cli/YamlLinterCommand.php b/system/src/Grav/Console/Cli/YamlLinterCommand.php index ddd738ab2..e02460a6b 100644 --- a/system/src/Grav/Console/Cli/YamlLinterCommand.php +++ b/system/src/Grav/Console/Cli/YamlLinterCommand.php @@ -14,9 +14,16 @@ use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Style\SymfonyStyle; +/** + * Class YamlLinterCommand + * @package Grav\Console\Cli + */ class YamlLinterCommand extends ConsoleCommand { - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('yamllinter') @@ -39,15 +46,19 @@ class YamlLinterCommand extends ConsoleCommand 'Go through specific folder' ) ->setDescription('Checks various files for YAML errors') - ->setHelp("Checks various files for YAML errors"); + ->setHelp('Checks various files for YAML errors'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $io = new SymfonyStyle($this->input, $this->output); $io->title('Yaml Linter'); + $error = 0; if ($this->input->getOption('all')) { $io->section('All'); $errors = YamlLinter::lint(''); @@ -55,6 +66,7 @@ class YamlLinterCommand extends ConsoleCommand if (empty($errors)) { $io->success('No YAML Linting issues found'); } else { + $error = 1; $this->displayErrors($errors, $io); } } elseif ($folder = $this->input->getOption('folder')) { @@ -64,6 +76,7 @@ class YamlLinterCommand extends ConsoleCommand if (empty($errors)) { $io->success('No YAML Linting issues found'); } else { + $error = 1; $this->displayErrors($errors, $io); } } else { @@ -73,6 +86,7 @@ class YamlLinterCommand extends ConsoleCommand if (empty($errors)) { $io->success('No YAML Linting issues with configuration'); } else { + $error = 1; $this->displayErrors($errors, $io); } @@ -82,6 +96,7 @@ class YamlLinterCommand extends ConsoleCommand if (empty($errors)) { $io->success('No YAML Linting issues with pages'); } else { + $error = 1; $this->displayErrors($errors, $io); } @@ -91,12 +106,20 @@ class YamlLinterCommand extends ConsoleCommand if (empty($errors)) { $io->success('No YAML Linting issues with blueprints'); } else { + $error = 1; $this->displayErrors($errors, $io); } } + + return $error; } - protected function displayErrors($errors, SymfonyStyle $io) + /** + * @param array $errors + * @param SymfonyStyle $io + * @return void + */ + protected function displayErrors($errors, SymfonyStyle $io): void { $io->error('YAML Linting issues found...'); foreach ($errors as $path => $error) { diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index 02aade956..542794f5d 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -11,13 +11,16 @@ namespace Grav\Console; use Grav\Common\Grav; use Grav\Common\Language\Language; -use Grav\Common\Page\Page; use Grav\Common\Processors\InitializeProcessor; use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +/** + * Class ConsoleCommand + * @package Grav\Console + */ class ConsoleCommand extends Command { use ConsoleTrait; @@ -38,14 +41,19 @@ class ConsoleCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { $this->setupConsole($input, $output); - $this->serve(); + + return $this->serve(); } /** * Override with your implementation. + * + * @return int */ protected function serve() { + // Return error. + return 1; } /** @@ -73,6 +81,7 @@ class ConsoleCommand extends Command * Set language to be used in CLI. * * @param string|null $code + * @return $this */ final protected function setLanguage(string $code = null) { @@ -88,6 +97,8 @@ class ConsoleCommand extends Command $language->setActive($language->getDefault()); } } + + return $this; } /** @@ -178,6 +189,9 @@ class ConsoleCommand extends Command return $this; } + /** + * @return void + */ protected function displayGPMRelease() { $this->output->writeln(''); diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php index 4276d350a..954995f50 100644 --- a/system/src/Grav/Console/ConsoleTrait.php +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -9,10 +9,10 @@ namespace Grav\Console; +use Exception; use Grav\Common\Cache; use Grav\Common\Grav; use Grav\Common\Composer; -use Grav\Common\GravTrait; use Grav\Console\Cli\ClearCacheCommand; use RocketTheme\Toolbox\File\YamlFile; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -20,6 +20,10 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +/** + * Trait ConsoleTrait + * @package Grav\Console + */ trait ConsoleTrait { /** @var string */ @@ -39,6 +43,7 @@ trait ConsoleTrait * * @param InputInterface $input * @param OutputInterface $output + * @return void */ public function setupConsole(InputInterface $input, OutputInterface $output) { @@ -61,6 +66,7 @@ trait ConsoleTrait /** * @param string $path + * @return void */ public function isGravInstance($path) { @@ -89,6 +95,11 @@ trait ConsoleTrait } } + /** + * @param string $path + * @param string $action + * @return string|false + */ public function composerUpdate($path, $action = 'install') { $composer = Composer::getComposerExecutor(); @@ -100,7 +111,7 @@ trait ConsoleTrait * @param array $all * * @return int - * @throws \Exception + * @throws Exception */ public function clearCache($all = []) { @@ -113,6 +124,9 @@ trait ConsoleTrait return $command->run($input, $this->output); } + /** + * @return void + */ public function invalidateCache() { Cache::invalidateCache(); @@ -121,7 +135,7 @@ trait ConsoleTrait /** * Load the local config file * - * @return mixed string the local config file name. false if local config does not exist + * @return string|false The local config file name. false if local config does not exist */ public function loadLocalConfig() { diff --git a/system/src/Grav/Console/Gpm/DirectInstallCommand.php b/system/src/Grav/Console/Gpm/DirectInstallCommand.php index b5758d893..795fbf123 100644 --- a/system/src/Grav/Console/Gpm/DirectInstallCommand.php +++ b/system/src/Grav/Console/Gpm/DirectInstallCommand.php @@ -9,6 +9,7 @@ namespace Grav\Console\Gpm; +use Exception; use Grav\Common\Cache; use Grav\Common\Grav; use Grav\Common\Filesystem\Folder; @@ -16,11 +17,18 @@ use Grav\Common\GPM\GPM; use Grav\Common\GPM\Installer; use Grav\Common\GPM\Response; use Grav\Console\ConsoleCommand; +use RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function is_array; +use function is_callable; +/** + * Class DirectInstallCommand + * @package Grav\Console\Gpm + */ class DirectInstallCommand extends ConsoleCommand { /** @var string */ @@ -29,7 +37,10 @@ class DirectInstallCommand extends ConsoleCommand /** @var string */ protected $destination; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('direct-install') @@ -57,15 +68,16 @@ class DirectInstallCommand extends ConsoleCommand } /** - * @return bool + * @return int */ - protected function serve() + protected function serve(): int { if (!class_exists(\ZipArchive::class)) { $io = new SymfonyStyle($this->input, $this->output); $io->title('Direct Install'); $io->error('php-zip extension needs to be enabled!'); - exit; + + return 1; } // Making sure the destination is usable @@ -75,9 +87,9 @@ class DirectInstallCommand extends ConsoleCommand !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) ) { $this->output->writeln('ERROR: ' . Installer::lastErrorMsg()); - exit; - } + return 1; + } $this->all_yes = $this->input->getOption('all-yes'); @@ -91,7 +103,8 @@ class DirectInstallCommand extends ConsoleCommand if (!$answer) { $this->output->writeln('exiting...'); $this->output->writeln(''); - exit; + + return 1; } $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); @@ -105,11 +118,12 @@ class DirectInstallCommand extends ConsoleCommand $this->output->write(' |- Downloading package... 0%'); try { $zip = GPM::downloadPackage($package_file, $tmp_zip); - } catch (\RuntimeException $e) { + } catch (RuntimeException $e) { $this->output->writeln(''); $this->output->writeln(" `- ERROR: {$e->getMessage()}"); $this->output->writeln(''); - exit; + + return 1; } if ($zip) { @@ -138,7 +152,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(' |- Extracting package... failed'); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } $this->output->write("\x0D"); @@ -152,7 +167,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(''); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } $blueprint = GPM::getBlueprints($extracted); @@ -181,7 +197,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(''); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } } } @@ -196,7 +213,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(''); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } $this->output->write("\x0D"); @@ -204,7 +222,7 @@ class DirectInstallCommand extends ConsoleCommand $this->output->write(' |- Installing package... '); - static::upgradeGrav($zip, $extracted); + $this->upgradeGrav($zip, $extracted); } else { $name = GPM::getPackageName($extracted); @@ -213,7 +231,8 @@ class DirectInstallCommand extends ConsoleCommand $this->output->writeln(''); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } $install_path = GPM::getInstallPath($type, $name); @@ -222,14 +241,15 @@ class DirectInstallCommand extends ConsoleCommand $this->output->write(' |- Checking destination... '); Installer::isValidDestination(GRAV_ROOT . DS . $install_path); - if (Installer::lastErrorCode() == Installer::IS_LINK) { + if (Installer::lastErrorCode() === Installer::IS_LINK) { $this->output->write("\x0D"); $this->output->writeln(' |- Checking destination... symbolic link'); $this->output->writeln(" '- ERROR: symlink found... " . GRAV_ROOT . DS . $install_path . ''); $this->output->writeln(''); Folder::delete($tmp_source); Folder::delete($tmp_zip); - exit; + + return 1; } $this->output->write("\x0D"); @@ -263,6 +283,9 @@ class DirectInstallCommand extends ConsoleCommand } } else { $this->output->writeln(" '- ERROR: ZIP package could not be found"); + Folder::delete($tmp_zip); + + return 1; } Folder::delete($tmp_zip); @@ -270,9 +293,14 @@ class DirectInstallCommand extends ConsoleCommand // clear cache after successful upgrade $this->clearCache(); - return true; + return 0; } + /** + * @param string $zip + * @param string $folder + * @param false $keepFolder + */ private function upgradeGrav($zip, $folder, $keepFolder = false) { static $ignores = [ @@ -306,7 +334,7 @@ class DirectInstallCommand extends ConsoleCommand Cache::clearCache(); } - } catch (\Exception $e) { + } catch (Exception $e) { Installer::setError($e->getMessage()); } } diff --git a/system/src/Grav/Console/Gpm/IndexCommand.php b/system/src/Grav/Console/Gpm/IndexCommand.php index 754d54255..f178d8f2b 100644 --- a/system/src/Grav/Console/Gpm/IndexCommand.php +++ b/system/src/Grav/Console/Gpm/IndexCommand.php @@ -14,9 +14,15 @@ use Grav\Common\GPM\GPM; use Grav\Common\GPM\Remote\Packages; use Grav\Common\Utils; use Grav\Console\ConsoleCommand; -use League\CLImate\CLImate; +use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Style\SymfonyStyle; +use function count; +/** + * Class IndexCommand + * @package Grav\Console\Gpm + */ class IndexCommand extends ConsoleCommand { /** @var Packages */ @@ -28,7 +34,10 @@ class IndexCommand extends ConsoleCommand /** @var array */ protected $options; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('index') @@ -86,7 +95,10 @@ class IndexCommand extends ConsoleCommand ; } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->options = $this->input->getOptions(); $this->gpm = new GPM($this->options['force']); @@ -95,28 +107,30 @@ class IndexCommand extends ConsoleCommand $data = $this->filter($this->data); - $climate = new CLImate; - $climate->extend('Grav\Console\TerminalObjects\Table'); + $io = new SymfonyStyle($this->input, $this->output); - if (!$data) { - $this->output->writeln('No data was found in the GPM repository stored locally.'); - $this->output->writeln('Please try clearing cache and running the bin/gpm index -f command again'); - $this->output->writeln('If this doesn\'t work try tweaking your GPM system settings.'); - $this->output->writeln(''); - $this->output->writeln('For more help go to:'); - $this->output->writeln(' -> https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm'); + if (count($data) === 0) { + $io->writeln('No data was found in the GPM repository stored locally.'); + $io->writeln('Please try clearing cache and running the bin/gpm index -f command again'); + $io->writeln('If this doesn\'t work try tweaking your GPM system settings.'); + $io->writeln(''); + $io->writeln('For more help go to:'); + $io->writeln(' -> https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm'); - die; + return 1; } foreach ($data as $type => $packages) { - $this->output->writeln('' . strtoupper($type) . ' [ ' . \count($packages) . ' ]'); + $io->writeln('' . strtoupper($type) . ' [ ' . count($packages) . ' ]'); + $packages = $this->sort($packages); if (!empty($packages)) { - $table = []; - $index = 0; + $section = $this->output->section('Packages table'); + $table = new Table($section); + $table->setHeaders(['Count', 'Name', 'Slug', 'Version', 'Installed']); + $index = 0; foreach ($packages as $slug => $package) { $row = [ 'Count' => $index++ + 1, @@ -125,21 +139,24 @@ class IndexCommand extends ConsoleCommand 'Version'=> $this->version($package), 'Installed' => $this->installed($package) ]; - $table[] = $row; + + $table->addRow($row); } - $climate->table($table); + $table->render(); } - $this->output->writeln(''); + $io->writeln(''); } - $this->output->writeln('You can either get more informations about a package by typing:'); - $this->output->writeln(" {$this->argv} info "); - $this->output->writeln(''); - $this->output->writeln('Or you can install a package by typing:'); - $this->output->writeln(" {$this->argv} install "); - $this->output->writeln(''); + $io->writeln('You can either get more informations about a package by typing:'); + $io->writeln(" {$this->argv} info "); + $io->writeln(''); + $io->writeln('Or you can install a package by typing:'); + $io->writeln(" {$this->argv} install "); + $io->writeln(''); + + return 0; } /** @@ -205,7 +222,7 @@ class IndexCommand extends ConsoleCommand $this->options['desc'] ]; - if (\count(array_filter($filter))) { + if (count(array_filter($filter))) { foreach ($data as $type => $packages) { foreach ($packages as $slug => $package) { $filter = true; diff --git a/system/src/Grav/Console/Gpm/InfoCommand.php b/system/src/Grav/Console/Gpm/InfoCommand.php index 30e1ad49d..0093e0f8f 100644 --- a/system/src/Grav/Console/Gpm/InfoCommand.php +++ b/system/src/Grav/Console/Gpm/InfoCommand.php @@ -15,6 +15,10 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; +/** + * Class InfoCommand + * @package Grav\Console\Gpm + */ class InfoCommand extends ConsoleCommand { /** @var array */ @@ -26,7 +30,10 @@ class InfoCommand extends ConsoleCommand /** @var string */ protected $all_yes; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('info') @@ -48,13 +55,13 @@ class InfoCommand extends ConsoleCommand 'The package of which more informations are desired. Use the "index" command for a list of packages' ) ->setDescription('Shows more informations about a package') - ->setHelp('The info shows more informations about a package'); + ->setHelp('The info shows more information about a package'); } /** - * @return int|null|void + * @return int */ - protected function serve() + protected function serve(): int { $this->gpm = new GPM($this->input->getOption('force')); @@ -70,7 +77,8 @@ class InfoCommand extends ConsoleCommand $this->output->writeln('You can list all the available packages by typing:'); $this->output->writeln(" {$this->argv} index"); $this->output->writeln(''); - exit; + + return 1; } $this->output->writeln("Found package '{$this->input->getArgument('package')}' under the '" . ucfirst($foundPackage->package_type) . "' section"); @@ -147,7 +155,7 @@ class InfoCommand extends ConsoleCommand $this->output->writeln(''); foreach ($changelog as $version => $log) { $title = $version . ' [' . $log['date'] . ']'; - $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', function ($match) { + $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { return "\n" . ucfirst($match[1]) . ':'; }, $log['content']); @@ -176,5 +184,7 @@ class InfoCommand extends ConsoleCommand } $this->output->writeln(''); + + return 0; } } diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 2ba357a34..fc2ad4755 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -9,6 +9,7 @@ namespace Grav\Console\Gpm; +use Exception; use Grav\Common\Filesystem\Folder; use Grav\Common\GPM\GPM; use Grav\Common\GPM\Installer; @@ -22,9 +23,15 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_key_exists; +use function count; \define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/'); +/** + * Class InstallCommand + * @package Grav\Console\Gpm + */ class InstallCommand extends ConsoleCommand { /** @var array */ @@ -54,7 +61,10 @@ class InstallCommand extends ConsoleCommand /** @var string */ protected $all_yes; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('install') @@ -97,15 +107,16 @@ class InstallCommand extends ConsoleCommand } /** - * @return bool + * @return int */ - protected function serve() + protected function serve(): int { if (!class_exists(\ZipArchive::class)) { $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Install'); $io->error('php-zip extension needs to be enabled!'); - exit; + + return 1; } $this->gpm = new GPM($this->input->getOption('force')); @@ -124,7 +135,8 @@ class InstallCommand extends ConsoleCommand !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) ) { $this->output->writeln('ERROR: ' . Installer::lastErrorMsg()); - exit; + + return 1; } $this->output->writeln(''); @@ -132,10 +144,11 @@ class InstallCommand extends ConsoleCommand if (!$this->data['total']) { $this->output->writeln('Nothing to install.'); $this->output->writeln(''); - exit; + + return 0; } - if (\count($this->data['not_found'])) { + if (count($this->data['not_found'])) { $this->output->writeln('These packages were not found on Grav: ' . implode( ', ', array_keys($this->data['not_found']) @@ -161,11 +174,12 @@ class InstallCommand extends ConsoleCommand try { $dependencies = $this->gpm->getDependencies($packages); - } catch (\Exception $e) { + } catch (Exception $e) { //Error out if there are incompatible packages requirements and tell which ones, and what to do //Error out if there is any error in parsing the dependencies and their versions, and tell which one is broken $this->output->writeln("{$e->getMessage()}"); - return false; + + return 1; } if ($dependencies) { @@ -173,9 +187,10 @@ class InstallCommand extends ConsoleCommand $this->installDependencies($dependencies, 'install', 'The following dependencies need to be installed...'); $this->installDependencies($dependencies, 'update', 'The following dependencies need to be updated...'); $this->installDependencies($dependencies, 'ignore', "The following dependencies can be updated as there is a newer version, but it's not mandatory...", false); - } catch (\Exception $e) { + } catch (Exception $e) { $this->output->writeln('Installation aborted'); - return false; + + return 1; } $this->output->writeln('Dependencies are OK'); @@ -197,9 +212,10 @@ class InstallCommand extends ConsoleCommand try { $this->askConfirmationIfMajorVersionUpdated($package); $this->gpm->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package->slug, $package->available, array_keys($data)); - } catch (\Exception $e) { + } catch (Exception $e) { $this->output->writeln("{$e->getMessage()}"); - return false; + + return 1; } $helper = $this->getHelper('question'); @@ -223,7 +239,7 @@ class InstallCommand extends ConsoleCommand } } - if (\count($this->demo_processing) > 0) { + if (count($this->demo_processing) > 0) { foreach ($this->demo_processing as $package) { $this->installDemoContent($package); } @@ -232,15 +248,16 @@ class InstallCommand extends ConsoleCommand // clear cache after successful upgrade $this->clearCache(); - return true; + return 0; } /** * If the package is updated from an older major release, show warning and ask confirmation * * @param Package $package + * @return void */ - public function askConfirmationIfMajorVersionUpdated($package) + public function askConfirmationIfMajorVersionUpdated($package): void { $helper = $this->getHelper('question'); $package_name = $package->name; @@ -273,15 +290,15 @@ class InstallCommand extends ConsoleCommand * @param string $type The type of dependency to show: install, update, ignore * @param string $message A message to be shown prior to listing the dependencies * @param bool $required A flag that determines if the installation is required or optional - * - * @throws \Exception + * @return void + * @throws Exception */ - public function installDependencies($dependencies, $type, $message, $required = true) + public function installDependencies($dependencies, $type, $message, $required = true): void { - $packages = array_filter($dependencies, function ($action) use ($type) { + $packages = array_filter($dependencies, static function ($action) use ($type) { return $action === $type; }); - if (\count($packages) > 0) { + if (count($packages) > 0) { $this->output->writeln($message); foreach ($packages as $dependencyName => $dependencyVersion) { @@ -298,13 +315,13 @@ class InstallCommand extends ConsoleCommand $questionAction = 'Update'; } - if (\count($packages) === 1) { + if (count($packages) === 1) { $questionArticle = 'this'; } else { $questionArticle = 'these'; } - if (\count($packages) === 1) { + if (count($packages) === 1) { $questionNoun = 'package'; } else { $questionNoun = 'packages'; @@ -319,10 +336,8 @@ class InstallCommand extends ConsoleCommand $this->processPackage($package, $type === 'update'); } $this->output->writeln(''); - } else { - if ($required) { - throw new \Exception(); - } + } elseif ($required) { + throw new Exception(); } } } @@ -330,8 +345,9 @@ class InstallCommand extends ConsoleCommand /** * @param Package|null $package * @param bool $is_update True if the package is an update + * @return void */ - private function processPackage($package, $is_update = false) + private function processPackage($package, $is_update = false): void { if (!$package) { $this->output->writeln('Package not found on the GPM!'); @@ -355,8 +371,9 @@ class InstallCommand extends ConsoleCommand * Add package to the queue to process the demo content, if demo content exists * * @param Package $package + * @return void */ - private function processDemo($package) + private function processDemo($package): void { $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; if (file_exists($demo_dir)) { @@ -368,8 +385,9 @@ class InstallCommand extends ConsoleCommand * Prompt to install the demo content of a package * * @param Package $package + * @return void */ - private function installDemoContent($package) + private function installDemoContent($package): void { $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; @@ -424,8 +442,7 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package - * - * @return array|bool + * @return array|false */ private function getGitRegexMatches($package) { @@ -442,8 +459,7 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package - * - * @return bool|string + * @return string|false */ private function getSymlinkSource($package) { @@ -470,10 +486,10 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package + * @return void */ - private function processSymlink($package) + private function processSymlink($package): void { - exec('cd ' . $this->destination); $to = $this->destination . DS . $package->install_path; @@ -491,18 +507,16 @@ class InstallCommand extends ConsoleCommand if (!$checks) { $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); + } elseif (file_exists($to)) { + $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); + $this->output->writeln(''); } else { - if (file_exists($to)) { - $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); - $this->output->writeln(''); - } else { - symlink($from, $to); + symlink($from, $to); - // extra white spaces to clear out the buffer properly - $this->output->writeln(' |- Symlinking package... ok '); - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); - } + // extra white spaces to clear out the buffer properly + $this->output->writeln(' |- Symlinking package... ok '); + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); } return; @@ -515,12 +529,11 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package * @param bool $is_update - * * @return bool */ private function processGpm($package, $is_update = false) { - $version = isset($package->available) ? $package->available : $package->version; + $version = $package->available ?? $package->version; $license = Licenses::get($package->slug); $this->output->writeln("Preparing to install {$package->name} [v{$version}]"); @@ -561,7 +574,6 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package * @param string|null $license - * * @return string|null */ private function downloadPackage($package, $license = null) @@ -573,7 +585,7 @@ class InstallCommand extends ConsoleCommand $query = ''; if (!empty($package->premium)) { - $query = \json_encode(array_merge( + $query = json_encode(array_merge( $package->premium, [ 'slug' => $package->slug, @@ -588,7 +600,7 @@ class InstallCommand extends ConsoleCommand try { $output = Response::get($package->zipball_url . $query, [], [$this, 'progress']); - } catch (\Exception $e) { + } catch (Exception $e) { $error = str_replace("\n", "\n | '- ", $e->getMessage()); $this->output->write("\x0D"); // extra white spaces to clear out the buffer properly @@ -611,16 +623,15 @@ class InstallCommand extends ConsoleCommand /** * @param Package $package - * * @return bool */ - private function checkDestination($package) + private function checkDestination($package): bool { $question_helper = $this->getHelper('question'); Installer::isValidDestination($this->destination . DS . $package->install_path); - if (Installer::lastErrorCode() == Installer::IS_LINK) { + if (Installer::lastErrorCode() === Installer::IS_LINK) { $this->output->write("\x0D"); $this->output->writeln(' |- Checking destination... symbolic link'); @@ -656,7 +667,6 @@ class InstallCommand extends ConsoleCommand * * @param Package $package * @param bool $is_update True if it's an update. False if it's an install - * * @return bool */ private function installPackage($package, $is_update = false) @@ -692,8 +702,9 @@ class InstallCommand extends ConsoleCommand /** * @param array $progress + * @return void */ - public function progress($progress) + public function progress($progress): void { $this->output->write("\x0D"); $this->output->write(' |- Downloading package... ' . str_pad( diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 9b1b012ce..6288bb80b 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -9,6 +9,7 @@ namespace Grav\Console\Gpm; +use Exception; use Grav\Common\Cache; use Grav\Common\Filesystem\Folder; use Grav\Common\GPM\Installer; @@ -20,7 +21,13 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function is_callable; +use function strlen; +/** + * Class SelfupgradeCommand + * @package Grav\Console\Gpm + */ class SelfupgradeCommand extends ConsoleCommand { /** @var array */ @@ -47,7 +54,10 @@ class SelfupgradeCommand extends ConsoleCommand /** @var int */ protected $timeout; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('self-upgrade') @@ -81,13 +91,17 @@ class SelfupgradeCommand extends ConsoleCommand ->setHelp('The update command updates Grav itself when a new version is available'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { if (!class_exists(\ZipArchive::class)) { $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Self Upgrade'); $io->error('php-zip extension needs to be enabled!'); - exit; + + return 1; } $this->upgrader = new Upgrader($this->input->getOption('force')); @@ -111,12 +125,14 @@ class SelfupgradeCommand extends ConsoleCommand $this->output->writeln(''); $this->output->writeln('Selfupgrade aborted.'); $this->output->writeln(''); - exit; + + return 1; } if (!$this->overwrite && !$this->upgrader->isUpgradable()) { $this->output->writeln("You are already running the latest version of Grav (v{$local}) released on {$release}"); - exit; + + return 0; } Installer::isValidDestination(GRAV_ROOT . '/system'); @@ -124,7 +140,8 @@ class SelfupgradeCommand extends ConsoleCommand $this->output->writeln('ATTENTION: Grav is symlinked, cannot upgrade, aborting...'); $this->output->writeln(''); $this->output->writeln("You are currently running a symbolically linked Grav v{$local}. Latest available is v{$remote}."); - exit; + + return 1; } // not used but preloaded just in case! @@ -148,12 +165,12 @@ class SelfupgradeCommand extends ConsoleCommand $this->output->writeln(''); foreach ($changelog as $version => $log) { $title = $version . ' [' . $log['date'] . ']'; - $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', function ($match) { + $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { return "\n" . ucfirst($match[1]) . ':'; }, $log['content']); $this->output->writeln($title); - $this->output->writeln(str_repeat('-', \strlen($title))); + $this->output->writeln(str_repeat('-', strlen($title))); $this->output->writeln($content); $this->output->writeln(''); } @@ -168,7 +185,7 @@ class SelfupgradeCommand extends ConsoleCommand if (!$answer) { $this->output->writeln('Aborting...'); - exit; + return 1; } } @@ -181,9 +198,11 @@ class SelfupgradeCommand extends ConsoleCommand $this->output->write(' |- Installing upgrade... '); $installation = $this->upgrade(); + $error = 0; if (!$installation) { $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); + $error = 1; } else { $this->output->writeln(" '- Success! "); $this->output->writeln(''); @@ -191,11 +210,12 @@ class SelfupgradeCommand extends ConsoleCommand // clear cache after successful upgrade $this->clearCache(['all']); + + return $error; } /** * @param array $package - * * @return string */ private function download($package) @@ -235,7 +255,7 @@ class SelfupgradeCommand extends ConsoleCommand $folder = false; } - static::upgradeGrav($this->file, $folder); + $this->upgradeGrav($this->file, $folder); $errorCode = Installer::lastErrorCode(); @@ -261,8 +281,9 @@ class SelfupgradeCommand extends ConsoleCommand /** * @param array $progress + * @return void */ - public function progress($progress) + public function progress($progress): void { $this->output->write("\x0D"); $this->output->write(" |- Downloading upgrade [{$this->formatBytes($progress['filesize']) }]... " . str_pad( @@ -276,7 +297,6 @@ class SelfupgradeCommand extends ConsoleCommand /** * @param int|float $size * @param int $precision - * * @return string */ public function formatBytes($size, $precision = 2) @@ -287,6 +307,11 @@ class SelfupgradeCommand extends ConsoleCommand return round(1024 ** ($base - floor($base)), $precision) . $suffixes[(int)floor($base)]; } + /** + * @param string $zip + * @param string $folder + * @param false $keepFolder + */ private function upgradeGrav($zip, $folder, $keepFolder = false) { static $ignores = [ @@ -320,7 +345,7 @@ class SelfupgradeCommand extends ConsoleCommand Cache::clearCache(); } - } catch (\Exception $e) { + } catch (Exception $e) { Installer::setError($e->getMessage()); } } diff --git a/system/src/Grav/Console/Gpm/UninstallCommand.php b/system/src/Grav/Console/Gpm/UninstallCommand.php index d41438ff1..fcfd3420f 100644 --- a/system/src/Grav/Console/Gpm/UninstallCommand.php +++ b/system/src/Grav/Console/Gpm/UninstallCommand.php @@ -17,7 +17,14 @@ use Grav\Console\ConsoleCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; +use function count; +use function in_array; +use function is_array; +/** + * Class UninstallCommand + * @package Grav\Console\Gpm + */ class UninstallCommand extends ConsoleCommand { /** @var array */ @@ -41,7 +48,10 @@ class UninstallCommand extends ConsoleCommand /** @var string */ protected $all_yes; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('uninstall') @@ -60,7 +70,10 @@ class UninstallCommand extends ConsoleCommand ->setHelp('The uninstall command allows to uninstall plugins and themes'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { $this->gpm = new GPM(); @@ -87,7 +100,8 @@ class UninstallCommand extends ConsoleCommand if (!$this->data['total']) { $this->output->writeln('Nothing to uninstall.'); $this->output->writeln(''); - exit; + + return 0; } if (count($this->data['not_found'])) { @@ -99,6 +113,7 @@ class UninstallCommand extends ConsoleCommand unset($this->data['not_found'], $this->data['total']); + $error = 0; foreach ($this->data as $slug => $package) { $this->output->writeln("Preparing to uninstall {$package->name} [v{$package->version}]"); @@ -108,11 +123,13 @@ class UninstallCommand extends ConsoleCommand if (!$checks) { $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); + $error = 1; } else { $uninstall = $this->uninstallPackage($slug, $package); if (!$uninstall) { $this->output->writeln(" '- Uninstallation failed or aborted."); + $error = 1; } else { $this->output->writeln(" '- Success! "); } @@ -121,13 +138,13 @@ class UninstallCommand extends ConsoleCommand // clear cache after successful upgrade $this->clearCache(); - } + return $error; + } /** * @param string $slug * @param Package $package - * * @return bool */ private function uninstallPackage($slug, $package, $is_dependency = false) @@ -143,7 +160,7 @@ class UninstallCommand extends ConsoleCommand $this->output->writeln(''); $this->output->writeln('Uninstallation failed.'); $this->output->writeln(''); - if (\count($dependent_packages) > ($is_dependency ? 2 : 1)) { + if (count($dependent_packages) > ($is_dependency ? 2 : 1)) { $this->output->writeln('The installed packages ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove those first.'); } else { $this->output->writeln('The installed package ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove it first.'); @@ -158,15 +175,13 @@ class UninstallCommand extends ConsoleCommand if ($is_dependency) { foreach ($dependencies as $key => $dependency) { - if (\in_array($dependency['name'], $this->dependencies, true)) { + if (in_array($dependency['name'], $this->dependencies, true)) { unset($dependencies[$key]); } } - } else { - if (\count($dependencies) > 0) { - $this->output->writeln(' `- Dependencies found...'); - $this->output->writeln(''); - } + } elseif (count($dependencies) > 0) { + $this->output->writeln(' `- Dependencies found...'); + $this->output->writeln(''); } $questionHelper = $this->getHelper('question'); @@ -174,7 +189,7 @@ class UninstallCommand extends ConsoleCommand foreach ($dependencies as $dependency) { $this->dependencies[] = $dependency['name']; - if (\is_array($dependency)) { + if (is_array($dependency)) { $dependency = $dependency['name']; } if ($dependency === 'grav' || $dependency === 'php') { @@ -239,10 +254,8 @@ class UninstallCommand extends ConsoleCommand /** * @param string $slug * @param Package $package - * * @return bool */ - private function checkDestination($slug, $package) { $questionHelper = $this->getHelper('question'); @@ -289,6 +302,7 @@ class UninstallCommand extends ConsoleCommand { $path = Grav::instance()['locator']->findResource($package->package_type . '://' . $slug); Installer::isValidDestination($path); + return Installer::lastErrorCode(); } } diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php index 68f5b3f95..2ea5ad467 100644 --- a/system/src/Grav/Console/Gpm/UpdateCommand.php +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -18,7 +18,13 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_key_exists; +use function count; +/** + * Class UpdateCommand + * @package Grav\Console\Gpm + */ class UpdateCommand extends ConsoleCommand { /** @var array */ @@ -45,7 +51,10 @@ class UpdateCommand extends ConsoleCommand /** @var Upgrader */ protected $upgrader; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('update') @@ -95,13 +104,17 @@ class UpdateCommand extends ConsoleCommand ->setHelp('The update command updates plugins and themes when a new version is available'); } - protected function serve() + /** + * @return int + */ + protected function serve(): int { if (!class_exists(\ZipArchive::class)) { $io = new SymfonyStyle($this->input, $this->output); $io->title('GPM Update'); $io->error('php-zip extension needs to be enabled!'); - exit; + + return 1; } $this->upgrader = new Upgrader($this->input->getOption('force')); @@ -116,7 +129,8 @@ class UpdateCommand extends ConsoleCommand if (!$answer) { $this->output->writeln('Update aborted. Exiting...'); - exit; + + return 1; } } @@ -152,7 +166,8 @@ class UpdateCommand extends ConsoleCommand if (!$this->overwrite && !$this->data['total']) { $this->output->writeln('Nothing to update.'); - exit; + + return 0; } $this->output->write("Found {$this->gpm->countInstalled()} packages installed of which {$this->data['total']}{$description}"); @@ -170,7 +185,7 @@ class UpdateCommand extends ConsoleCommand $index = 0; foreach ($this->data as $packages) { foreach ($packages as $slug => $package) { - if (!array_key_exists($slug, $limit_to) && \count($only_packages)) { + if (!array_key_exists($slug, $limit_to) && count($only_packages)) { continue; } @@ -199,7 +214,8 @@ class UpdateCommand extends ConsoleCommand if (!$answer) { $this->output->writeln('Update aborted. Exiting...'); - exit; + + return 1; } } @@ -217,13 +233,15 @@ class UpdateCommand extends ConsoleCommand if ($command_exec != 0) { $this->output->writeln('Error: An error occurred while trying to install the packages'); - exit; + + return 1; } + + return 0; } /** * @param array $only_packages - * * @return array */ private function userInputPackages($only_packages) @@ -231,7 +249,7 @@ class UpdateCommand extends ConsoleCommand $found = ['total' => 0]; $ignore = []; - if (!\count($only_packages)) { + if (!count($only_packages)) { $this->output->writeln(''); } else { foreach ($only_packages as $only_package) { @@ -262,7 +280,7 @@ class UpdateCommand extends ConsoleCommand ) . ''); } - if (\count($ignore)) { + if (count($ignore)) { $this->output->writeln(''); $this->output->writeln('Packages not found or not requiring updates: ' . implode( ', ', diff --git a/system/src/Grav/Console/Gpm/VersionCommand.php b/system/src/Grav/Console/Gpm/VersionCommand.php index 4dc1ebb72..910e96eb8 100644 --- a/system/src/Grav/Console/Gpm/VersionCommand.php +++ b/system/src/Grav/Console/Gpm/VersionCommand.php @@ -11,17 +11,26 @@ namespace Grav\Console\Gpm; use Grav\Common\GPM\GPM; use Grav\Common\GPM\Upgrader; +use Grav\Common\Grav; use Grav\Console\ConsoleCommand; use RocketTheme\Toolbox\File\YamlFile; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +use function count; +/** + * Class VersionCommand + * @package Grav\Console\Gpm + */ class VersionCommand extends ConsoleCommand { /** @var GPM */ protected $gpm; - protected function configure() + /** + * @return void + */ + protected function configure(): void { $this ->setName('version') @@ -41,9 +50,9 @@ class VersionCommand extends ConsoleCommand } /** - * @return int|null|void + * @return int */ - protected function serve() + protected function serve(): int { $this->gpm = new GPM($this->input->getOption('force')); $packages = $this->input->getArgument('package'); @@ -70,7 +79,7 @@ class VersionCommand extends ConsoleCommand } } else { // get currently installed version - $locator = \Grav\Common\Grav::instance()['locator']; + $locator = Grav::instance()['locator']; $blueprints_path = $locator->findResource('plugins://' . $package . DS . 'blueprints.yaml'); if (!file_exists($blueprints_path)) { // theme? $blueprints_path = $locator->findResource('themes://' . $package . DS . 'blueprints.yaml'); @@ -107,5 +116,7 @@ class VersionCommand extends ConsoleCommand $this->output->writeln("Package {$package} not found"); } } + + return 0; } } diff --git a/system/src/Grav/Console/TerminalObjects/Table.php b/system/src/Grav/Console/TerminalObjects/Table.php index 23fc2c930..4f5123381 100644 --- a/system/src/Grav/Console/TerminalObjects/Table.php +++ b/system/src/Grav/Console/TerminalObjects/Table.php @@ -9,8 +9,15 @@ namespace Grav\Console\TerminalObjects; +/** + * Class Table + * @package Grav\Console\TerminalObjects + */ class Table extends \League\CLImate\TerminalObject\Basic\Table { + /** + * @return array + */ public function result() { $this->column_widths = $this->getColumnWidths();