From f38f990f41cdfee630dd3405155c9ecaa2b6b936 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 11:01:43 +0330 Subject: [PATCH 01/92] Add README.md, with a general description about the project --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d731e89 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Phirs + +A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired mostly by [dirs-rs](https://github.com/dirs-dev/dirs-rs). From 9372310f60b65b17639d5cbf3b311e340bbfd71a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 11:23:11 +0330 Subject: [PATCH 02/92] Add Why section in README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index d731e89..34d92bb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ # Phirs A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired mostly by [dirs-rs](https://github.com/dirs-dev/dirs-rs). + +## Why? + +When writing a console application (or even graphical one; who knows, people might start writing graphical applications in PHP in near future), sometimes you need to have a location to: + +- store your configurations, and possibly re-use them in the future runs, +- make cache files and improve the performance of your application, +- create a media and put it somewhere reasonable, +- etc. + +For the best results, the location has to be cross-platform, permanent, well-known and non-relative. + +Phirs can to help you in these situations. From 7b078cc13acd59c7753226921f4e9aa826d3ef22 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 11:24:20 +0330 Subject: [PATCH 03/92] Add License section in README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 34d92bb..4d5c652 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,7 @@ When writing a console application (or even graphical one; who knows, people mig For the best results, the location has to be cross-platform, permanent, well-known and non-relative. Phirs can to help you in these situations. + +## License + +The project is licensed under [Apache 2.0 License](./LICENSE.md). From 0ba490b4ae4f6c593e66a1341a053c9227136724 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 11:26:45 +0330 Subject: [PATCH 04/92] Add Installation section in README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 4d5c652..233f963 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,14 @@ For the best results, the location has to be cross-platform, permanent, well-kno Phirs can to help you in these situations. +## Installation + +Easy like every other PHP library: + +``` +composer install machitgarha/phirs +``` + ## License The project is licensed under [Apache 2.0 License](./LICENSE.md). From 40450a828686af7bb54334c1f53be8f92faee5f2 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 11:38:44 +0330 Subject: [PATCH 05/92] Add Composer config files, ignore vendor/ directory --- .gitignore | 1 + composer.json | 22 ++++++++++++++++++++++ composer.lock | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 .gitignore create mode 100644 composer.json create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57872d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9f25ad6 --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "machitgarha/phirs", + "description": "Cross-platform user directory paths provider, such as config and cache", + "type": "library", + "license": "Apache-2.0", + "homepage": "https://github.com/machitgarha/phirs", + "authors": [ + { + "name": "Mohammad Amin Chitgarha", + "email": "machitgarha@outlook.com", + "homepage": "https://github.com/machitgarha" + } + ], + "autoload": { + "psr-4": { + "MAChitgarha\\Phirs\\": "src/" + } + }, + "require": { + "php": "^7.4|^8.0" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3895b89 --- /dev/null +++ b/composer.lock @@ -0,0 +1,20 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "ab645abed5f60f3b4909e6da4717607e", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.4|^8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.2.0" +} From 6d241be0251364eb4f5643e69fe8230d829c0b7a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 11 Feb 2022 18:33:16 +0330 Subject: [PATCH 06/92] Add DirectoryProviderInterface, including common paths --- src/DirectoryProviderInterface.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/DirectoryProviderInterface.php diff --git a/src/DirectoryProviderInterface.php b/src/DirectoryProviderInterface.php new file mode 100644 index 0000000..0762379 --- /dev/null +++ b/src/DirectoryProviderInterface.php @@ -0,0 +1,23 @@ + Date: Sun, 13 Feb 2022 00:39:04 +0330 Subject: [PATCH 07/92] Tell about why this library over alternatives in README.md --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 233f963..c860ce4 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,38 @@ # Phirs -A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired mostly by [dirs-rs](https://github.com/dirs-dev/dirs-rs). +A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired by [dirs-rs](https://github.com/dirs-dev/dirs-rs). ## Why? -When writing a console application (or even graphical one; who knows, people might start writing graphical applications in PHP in near future), sometimes you need to have a location to: +When writing a console application (or even a graphical one; who knows, people might start writing graphical applications in PHP in near future), sometimes you need to have a location to: - store your configurations, and possibly re-use them in the future runs, - make cache files and improve the performance of your application, - create a media and put it somewhere reasonable, - etc. -For the best results, the location has to be cross-platform, permanent, well-known and non-relative. +For the best results, the location has to be cross-platform, permanent, accessible, well-known and non-relative. Phirs can to help you in these situations. +### But There Is Another Library! + +Why not just using [Basedir](https://github.com/clue-labs/php-basedir)? + +The library is already good to be used. However, there are some reasons you might prefer this library: + +- With the help of simple abstractions, adding support for a specific platform should be easy. The abstractions are designed with performance in mind. + + **Note:** For having something like this in Basedir, a major rewrite and huge backward-compatibility break would be required. + +- If you want or have to, you can target a specific platform and stick to it. + +- Support for more platforms. + +- Support for more directories. + +- Basedir is [no longer available](https://packagist.org/search/?q=basedir) on Packagist for some reason. + ## Installation Easy like every other PHP library: From 062a82b8717a3eb590c24697bb22cb84035fa77c Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 01:40:36 +0330 Subject: [PATCH 08/92] Fix some method names in DirectoryProviderInterface --- src/DirectoryProviderInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DirectoryProviderInterface.php b/src/DirectoryProviderInterface.php index 0762379..b821251 100644 --- a/src/DirectoryProviderInterface.php +++ b/src/DirectoryProviderInterface.php @@ -13,11 +13,11 @@ public function getCachePath(): string; public function getConfigPath(): string; public function getDataPath(): string; - public function getDesktop(): string; + public function getDesktopPath(): string; public function getDocumentPath(): string; public function getDownloadPath(): string; public function getMusicPath(): string; public function getPicturePath(): string; - public function gePublicPath(): string; + public function getPublicPath(): string; public function getVideoPath(): string; } From 80fde9e3c952167497022f2223d6e1b1cecb7652 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 02:07:45 +0330 Subject: [PATCH 09/92] DirectoryProviderInterface -> Interfaces\StandardDirectoryProvider Rename the class. --- .../StandardDirectoryProvider.php} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/{DirectoryProviderInterface.php => Interfaces/StandardDirectoryProvider.php} (87%) diff --git a/src/DirectoryProviderInterface.php b/src/Interfaces/StandardDirectoryProvider.php similarity index 87% rename from src/DirectoryProviderInterface.php rename to src/Interfaces/StandardDirectoryProvider.php index b821251..585c7cf 100644 --- a/src/DirectoryProviderInterface.php +++ b/src/Interfaces/StandardDirectoryProvider.php @@ -1,11 +1,11 @@ Date: Sun, 13 Feb 2022 04:51:02 +0330 Subject: [PATCH 10/92] Add Traits\UnixLikeHomePath and Util\Env UnixLikeHomePath only provides getHomePath(). It first tries the $HOME environment variable, and as the fallback, it uses the POSIX uid thing. Env is also a helper class to work with environment variables. --- src/Traits/UnixLikeHomePath.php | 30 ++++++++++++++++++++++++++++++ src/Util/Env.php | 24 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Traits/UnixLikeHomePath.php create mode 100644 src/Util/Env.php diff --git a/src/Traits/UnixLikeHomePath.php b/src/Traits/UnixLikeHomePath.php new file mode 100644 index 0000000..3ad61e5 --- /dev/null +++ b/src/Traits/UnixLikeHomePath.php @@ -0,0 +1,30 @@ +getHomePathByPosixUid(); + } + + /** + * Thanks to https://stackoverflow.com/a/30926828/4215651. + */ + private function getHomePathByPosixUid(): ?string + { + if (!\function_exists('posix_getuid')) { + return null; + } + + $userInfo = posix_getpwuid(posix_getuid()); + if (!$userInfo) { + return null; + } + + return $userInfo['dir']; + } +} diff --git a/src/Util/Env.php b/src/Util/Env.php new file mode 100644 index 0000000..a80d76e --- /dev/null +++ b/src/Util/Env.php @@ -0,0 +1,24 @@ + Date: Sun, 13 Feb 2022 05:01:37 +0330 Subject: [PATCH 11/92] Make all return type of methods in StandardDirectoryPro... nullable --- src/Interfaces/StandardDirectoryProvider.php | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Interfaces/StandardDirectoryProvider.php b/src/Interfaces/StandardDirectoryProvider.php index 585c7cf..c384131 100644 --- a/src/Interfaces/StandardDirectoryProvider.php +++ b/src/Interfaces/StandardDirectoryProvider.php @@ -7,17 +7,17 @@ */ interface StandardDirectoryProvider { - public function getHomePath(): string; + public function getHomePath(): ?string; - public function getCachePath(): string; - public function getConfigPath(): string; - public function getDataPath(): string; + public function getCachePath(): ?string; + public function getConfigPath(): ?string; + public function getDataPath(): ?string; - public function getDesktopPath(): string; - public function getDocumentPath(): string; - public function getDownloadPath(): string; - public function getMusicPath(): string; - public function getPicturePath(): string; - public function getPublicPath(): string; - public function getVideoPath(): string; + public function getDesktopPath(): ?string; + public function getDocumentPath(): ?string; + public function getDownloadPath(): ?string; + public function getMusicPath(): ?string; + public function getPicturePath(): ?string; + public function getPublicPath(): ?string; + public function getVideoPath(): ?string; } From 00adca64bae7f8f8a2f38dd835cebda463a6273a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 05:11:04 +0330 Subject: [PATCH 12/92] Move home-specific path methods to new HomeDirectoryProvider iface Add a new HomeDirectoryProvider::getHomeChildPath(). --- src/Interfaces/HomeDirectoryProvider.php | 20 ++++++++++++++++++++ src/Interfaces/StandardDirectoryProvider.php | 4 +--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/Interfaces/HomeDirectoryProvider.php diff --git a/src/Interfaces/HomeDirectoryProvider.php b/src/Interfaces/HomeDirectoryProvider.php new file mode 100644 index 0000000..3a2944d --- /dev/null +++ b/src/Interfaces/HomeDirectoryProvider.php @@ -0,0 +1,20 @@ + Date: Sun, 13 Feb 2022 05:17:44 +0330 Subject: [PATCH 13/92] Add Provider suffix for trait UnixLikeHomePath, another improvement --- src/Interfaces/HomeDirectoryProvider.php | 2 +- .../{UnixLikeHomePath.php => UnixLikeHomePathProvider.php} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/Traits/{UnixLikeHomePath.php => UnixLikeHomePathProvider.php} (94%) diff --git a/src/Interfaces/HomeDirectoryProvider.php b/src/Interfaces/HomeDirectoryProvider.php index 3a2944d..65e846a 100644 --- a/src/Interfaces/HomeDirectoryProvider.php +++ b/src/Interfaces/HomeDirectoryProvider.php @@ -16,5 +16,5 @@ public function getHomePath(): ?string; * @param string ...$paths The directory names to be appended to the home * path, in order. */ - public function getHomeChildPath(string ...$paths): ?string; + public function getHomeChildPath(string ...$childPaths): ?string; } diff --git a/src/Traits/UnixLikeHomePath.php b/src/Traits/UnixLikeHomePathProvider.php similarity index 94% rename from src/Traits/UnixLikeHomePath.php rename to src/Traits/UnixLikeHomePathProvider.php index 3ad61e5..d22e276 100644 --- a/src/Traits/UnixLikeHomePath.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -4,7 +4,7 @@ use MAChitgarha\Phirs\Util\Env; -trait UnixLikeHomePath +trait UnixLikeHomePathProvider { public function getHomePath(): ?string { From ef18ddcaeee36bd7f889c8bafe6071f1d465d446 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 05:18:46 +0330 Subject: [PATCH 14/92] Add HomeChildPathProvider --- src/Traits/HomeChildPathProvider.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/Traits/HomeChildPathProvider.php diff --git a/src/Traits/HomeChildPathProvider.php b/src/Traits/HomeChildPathProvider.php new file mode 100644 index 0000000..e0edfd0 --- /dev/null +++ b/src/Traits/HomeChildPathProvider.php @@ -0,0 +1,23 @@ +getHomePath(); + + if ($homePath === null) { + return null; + } + return Path::join($homePath, ...$childPaths); + } +} From 07bf85d064af00a465c299be6d9acf5fe1638807 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 05:37:16 +0330 Subject: [PATCH 15/92] Add XDG Base Directory Spec as a trait Use HomeChildPathProvider in UnixLikeHomePathProvider. --- src/Traits/UnixLikeHomePathProvider.php | 2 + src/Traits/XdgBasedirSpec.php | 59 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/Traits/XdgBasedirSpec.php diff --git a/src/Traits/UnixLikeHomePathProvider.php b/src/Traits/UnixLikeHomePathProvider.php index d22e276..c4139c0 100644 --- a/src/Traits/UnixLikeHomePathProvider.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -6,6 +6,8 @@ trait UnixLikeHomePathProvider { + use HomeChildPathProvider; + public function getHomePath(): ?string { return Env::get('HOME') ?? $this->getHomePathByPosixUid(); diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php new file mode 100644 index 0000000..925617b --- /dev/null +++ b/src/Traits/XdgBasedirSpec.php @@ -0,0 +1,59 @@ +getHomeChildPath('.local', 'share'); + } + + public function getConfigPath(): ?string + { + return Env::get('XDG_CONFIG_HOME') ?? + $this->getHomeChildPath('.config'); + } + + public function getCachePath(): ?string + { + return Env::get('XDG_CACHE_DIRS') ?? + $this->getHomeChildPath('.cache'); + } + + public function getStatePath(): ?string + { + return Env::get('XDG_STATE_HOME') ?? + $this->getHomeChildPath('.local', 'state'); + } + + public function getExecutablePath(): ?string + { + return $this->getHomeChildPath('.local', 'bin'); + } + + public function getRuntimePath(): ?string + { + return Env::get('XDG_RUNTIME_DIR'); + } + + public function getDataPathSet(): ?array + { + return Env::getColonedArray('XDG_DATA_DIRS') ?? + ['/usr/local/share/', '/usr/share/']; + } + + public function getConfigPathSet(): ?array + { + return Env::getColonedArray('XDG_CONFIG_DIRS') ?? + ['/etc/xdg']; + } +} From a8f817cacfa39b80a390efafca4a57ef697fc0d4 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 05:38:51 +0330 Subject: [PATCH 16/92] Add symfony/filesystem dependency Used by one of the classes, but Composer files was not commited. --- composer.json | 3 +- composer.lock | 233 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 9f25ad6..d7f5ac2 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ } }, "require": { - "php": "^7.4|^8.0" + "php": "^7.4|^8.0", + "symfony/filesystem": "^6.0" } } diff --git a/composer.lock b/composer.lock index 3895b89..9b53dab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,237 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ab645abed5f60f3b4909e6da4717607e", - "packages": [], + "content-hash": "2da05820156e306aa537dc1115b02d88", + "packages": [ + { + "name": "symfony/filesystem", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "6ae49c4fda17322171a2b8dc5f70bc6edbc498e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6ae49c4fda17322171a2b8dc5f70bc6edbc498e1", + "reference": "6ae49c4fda17322171a2b8dc5f70bc6edbc498e1", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.0.3" + }, + "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": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.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": "2021-10-20T20:35:02+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.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": "2021-11-30T18:21:41+00:00" + } + ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", From 161117c8d5b8626915d698f30be7895e3f815e3a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 06:14:46 +0330 Subject: [PATCH 17/92] Move common user directories to CommonDirectoryProvider interface Some other fixes and improvements. --- src/Interfaces/CommonDirectoryProvider.php | 15 +++++++++++++++ src/Interfaces/StandardDirectoryProvider.php | 9 +++------ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/Interfaces/CommonDirectoryProvider.php diff --git a/src/Interfaces/CommonDirectoryProvider.php b/src/Interfaces/CommonDirectoryProvider.php new file mode 100644 index 0000000..937f197 --- /dev/null +++ b/src/Interfaces/CommonDirectoryProvider.php @@ -0,0 +1,15 @@ + Date: Sun, 13 Feb 2022 18:37:36 +0330 Subject: [PATCH 18/92] Move getDesktopPath() and getPublicPath() into two new interfaces The interfaces are {Public,Desktop}DirectoryProvider. Add an important comment in StandardDirectoryProvider, relating to the subject cross-platform-ability. --- src/Interfaces/DesktopDirectoryProvider.php | 8 ++++++++ src/Interfaces/PublicDirectoryProvider.php | 8 ++++++++ src/Interfaces/StandardDirectoryProvider.php | 13 +++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 src/Interfaces/DesktopDirectoryProvider.php create mode 100644 src/Interfaces/PublicDirectoryProvider.php diff --git a/src/Interfaces/DesktopDirectoryProvider.php b/src/Interfaces/DesktopDirectoryProvider.php new file mode 100644 index 0000000..69e8ae6 --- /dev/null +++ b/src/Interfaces/DesktopDirectoryProvider.php @@ -0,0 +1,8 @@ + Date: Sun, 13 Feb 2022 19:15:08 +0330 Subject: [PATCH 19/92] Add HomeBasedCommonPathProvider, a general impl for CommonDirProvider --- src/Traits/HomeBasedCommonPathProvider.php | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/Traits/HomeBasedCommonPathProvider.php diff --git a/src/Traits/HomeBasedCommonPathProvider.php b/src/Traits/HomeBasedCommonPathProvider.php new file mode 100644 index 0000000..07802ef --- /dev/null +++ b/src/Traits/HomeBasedCommonPathProvider.php @@ -0,0 +1,36 @@ +getHomeChildPath('Documents'); + } + + public function getDownloadsPath(): ?string + { + return $this->getHomeChildPath('Downloads'); + } + + public function getMusicPath(): ?string + { + return $this->getHomeChildPath('Music'); + } + + public function getPicturesPath(): ?string + { + return $this->getHomeChildPath('Pictures'); + } + + public function getVideosPath(): ?string + { + return $this->getHomeChildPath('Videos'); + } +} From 004585a4bbbab36f86d56098df4ba90574df218b Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 13 Feb 2022 19:16:19 +0330 Subject: [PATCH 20/92] Add LinuxDirectoryProvider Uses XdgBasedirSpec and HomeBasedCommonPathProvider traits. --- src/PlatformSpecific/LinuxDirectoryProvider.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/PlatformSpecific/LinuxDirectoryProvider.php diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php new file mode 100644 index 0000000..1ef977c --- /dev/null +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -0,0 +1,12 @@ + Date: Sun, 13 Feb 2022 19:22:00 +0330 Subject: [PATCH 21/92] Add TemplatesPathProvider trait, use it in LinuxDirectoryProvider --- src/PlatformSpecific/LinuxDirectoryProvider.php | 1 + src/Traits/TemplatesPathProvider.php | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/Traits/TemplatesPathProvider.php diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index 1ef977c..aebe221 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -9,4 +9,5 @@ class LinuxDirectoryProvider implements Interfaces\StandardDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBasedCommonPathProvider; + use Traits\TemplatesPathProvider; } diff --git a/src/Traits/TemplatesPathProvider.php b/src/Traits/TemplatesPathProvider.php new file mode 100644 index 0000000..a5542ff --- /dev/null +++ b/src/Traits/TemplatesPathProvider.php @@ -0,0 +1,13 @@ +getHomeChildPath('Templates'); + } +} From 32e1cd494fe13be1d9992c23a9a3fb79e1a4d575 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 11:15:28 +0330 Subject: [PATCH 22/92] Throw exceptions instead of returning null in the case of errors --- src/Interfaces/CommonDirectoryProvider.php | 10 ++-- src/Interfaces/DesktopDirectoryProvider.php | 2 +- src/Interfaces/HomeDirectoryProvider.php | 4 +- src/Interfaces/PublicDirectoryProvider.php | 2 +- src/Interfaces/StandardDirectoryProvider.php | 6 +- src/Traits/HomeBasedCommonPathProvider.php | 12 ++-- src/Traits/HomeChildPathProvider.php | 11 +--- src/Traits/TemplatesPathProvider.php | 4 +- src/Traits/UnixLikeHomePathProvider.php | 8 ++- src/Traits/XdgBasedirSpec.php | 63 ++++++++++++++------ src/Util/Env.php | 6 +- src/Util/Util.php | 25 ++++++++ 12 files changed, 103 insertions(+), 50 deletions(-) create mode 100644 src/Util/Util.php diff --git a/src/Interfaces/CommonDirectoryProvider.php b/src/Interfaces/CommonDirectoryProvider.php index 937f197..e6ead08 100644 --- a/src/Interfaces/CommonDirectoryProvider.php +++ b/src/Interfaces/CommonDirectoryProvider.php @@ -7,9 +7,9 @@ */ class CommonDirectoryProvider { - public function getDocumentsPath(): ?string; - public function getDownloadsPath(): ?string; - public function getMusicPath(): ?string; - public function getPicturesPath(): ?string; - public function getVideosPath(): ?string; + public function getDocumentsPath(): string; + public function getDownloadsPath(): string; + public function getMusicPath(): string; + public function getPicturesPath(): string; + public function getVideosPath(): string; } diff --git a/src/Interfaces/DesktopDirectoryProvider.php b/src/Interfaces/DesktopDirectoryProvider.php index 69e8ae6..bacca70 100644 --- a/src/Interfaces/DesktopDirectoryProvider.php +++ b/src/Interfaces/DesktopDirectoryProvider.php @@ -4,5 +4,5 @@ interface DesktopDirectoryProvider { - public function getDesktopPath(): ?string; + public function getDesktopPath(): string; } diff --git a/src/Interfaces/HomeDirectoryProvider.php b/src/Interfaces/HomeDirectoryProvider.php index 65e846a..1232c8a 100644 --- a/src/Interfaces/HomeDirectoryProvider.php +++ b/src/Interfaces/HomeDirectoryProvider.php @@ -4,7 +4,7 @@ interface HomeDirectoryProvider { - public function getHomePath(): ?string; + public function getHomePath(): string; /** * Return a child directory absolute path relative to user home path. @@ -16,5 +16,5 @@ public function getHomePath(): ?string; * @param string ...$paths The directory names to be appended to the home * path, in order. */ - public function getHomeChildPath(string ...$childPaths): ?string; + public function getHomeChildPath(string ...$childPaths): string; } diff --git a/src/Interfaces/PublicDirectoryProvider.php b/src/Interfaces/PublicDirectoryProvider.php index c1163ad..d75b89e 100644 --- a/src/Interfaces/PublicDirectoryProvider.php +++ b/src/Interfaces/PublicDirectoryProvider.php @@ -4,5 +4,5 @@ interface PublicDirectoryProvider { - public function getPublicPath(): ?string; + public function getPublicPath(): string; } diff --git a/src/Interfaces/StandardDirectoryProvider.php b/src/Interfaces/StandardDirectoryProvider.php index a2ac326..cf8bd1a 100644 --- a/src/Interfaces/StandardDirectoryProvider.php +++ b/src/Interfaces/StandardDirectoryProvider.php @@ -9,9 +9,9 @@ interface StandardDirectoryProvider extends HomeDirectoryProvider, CommonDirectoryProvider { - public function getCachePath(): ?string; - public function getConfigPath(): ?string; - public function getDataPath(): ?string; + public function getCachePath(): string; + public function getConfigPath(): string; + public function getDataPath(): string; } /* diff --git a/src/Traits/HomeBasedCommonPathProvider.php b/src/Traits/HomeBasedCommonPathProvider.php index 07802ef..7cdac39 100644 --- a/src/Traits/HomeBasedCommonPathProvider.php +++ b/src/Traits/HomeBasedCommonPathProvider.php @@ -7,29 +7,29 @@ */ trait HomeBasedCommonPathProvider { - abstract public function getHomeChildPath(string ...$childPaths): ?string; + abstract public function getHomeChildPath(string ...$childPaths): string; - public function getDocumentsPath(): ?string + public function getDocumentsPath(): string { return $this->getHomeChildPath('Documents'); } - public function getDownloadsPath(): ?string + public function getDownloadsPath(): string { return $this->getHomeChildPath('Downloads'); } - public function getMusicPath(): ?string + public function getMusicPath(): string { return $this->getHomeChildPath('Music'); } - public function getPicturesPath(): ?string + public function getPicturesPath(): string { return $this->getHomeChildPath('Pictures'); } - public function getVideosPath(): ?string + public function getVideosPath(): string { return $this->getHomeChildPath('Videos'); } diff --git a/src/Traits/HomeChildPathProvider.php b/src/Traits/HomeChildPathProvider.php index e0edfd0..9632592 100644 --- a/src/Traits/HomeChildPathProvider.php +++ b/src/Traits/HomeChildPathProvider.php @@ -9,15 +9,10 @@ */ trait HomeChildPathProvider { - abstract public function getHomePath(): ?string; + abstract public function getHomePath(): string; - public function getHomeChildPath(string ...$childPaths): ?string + public function getHomeChildPath(string ...$childPaths): string { - $homePath = $this->getHomePath(); - - if ($homePath === null) { - return null; - } - return Path::join($homePath, ...$childPaths); + return Path::join($this->getHomePath(), ...$childPaths); } } diff --git a/src/Traits/TemplatesPathProvider.php b/src/Traits/TemplatesPathProvider.php index a5542ff..8940827 100644 --- a/src/Traits/TemplatesPathProvider.php +++ b/src/Traits/TemplatesPathProvider.php @@ -4,9 +4,9 @@ trait TemplatesPathProvider { - abstract public function getHomeChildPath(string ...$childPaths): ?string; + abstract public function getHomeChildPath(string ...$childPaths): string; - public function getTemplatesPath(): ?string + public function getTemplatesPath(): string { return $this->getHomeChildPath('Templates'); } diff --git a/src/Traits/UnixLikeHomePathProvider.php b/src/Traits/UnixLikeHomePathProvider.php index c4139c0..63dab4e 100644 --- a/src/Traits/UnixLikeHomePathProvider.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -3,14 +3,18 @@ namespace MAChitgarha\Phirs\Traits; use MAChitgarha\Phirs\Util\Env; +use MAChitgarha\Phirs\Util\Util; trait UnixLikeHomePathProvider { use HomeChildPathProvider; - public function getHomePath(): ?string + public function getHomePath(): string { - return Env::get('HOME') ?? $this->getHomePathByPosixUid(); + return Util::returnNonNull( + Env::get('HOME') ?? $this->getHomePathByPosixUid(), + 'Cannot detect $HOME directory' + ); } /** diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index 925617b..57fc0ac 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -2,7 +2,9 @@ namespace MAChitgarha\Phirs\Traits; +use Exception; use MAChitgarha\Phirs\Util\Env; +use MAChitgarha\Phirs\Util\Util; /** * @todo Make sure paths are absolute (non-relative), to match the spec better. @@ -11,47 +13,74 @@ trait XdgBasedirSpec { use UnixLikeHomePathProvider; - public function getDataPath(): ?string + private function getEnvOrHomeChildPath( + string $envName, + array $childPaths + ): string { + /* + * Let's decide based on what happens. If the dedicated environment var + * is set, everything is good, otherwise, we refer to the fallback path. + * Here, if home directory is found, we have no problem, but else, we + * should tell in the exception that the environment variable is not + * set, plus the home directory cannot be found. + * + * So, obviously, the whole expression will not be null, so we don't + * need to check it with something like Util::returnNonNull(). + */ + try { + return Env::get($envName) ?? + $this->getHomeChildPath(...$childPaths); + } catch (Exception $e) { + throw new Exception( + "Cannot find a proper path for the requested directory " . + "(reasons: env $envName not set and {$e->getMessage()})" + ); + } + } + + public function getDataPath(): string { - return Env::get('XDG_DATA_HOME') ?? - $this->getHomeChildPath('.local', 'share'); + return $this->getEnvOrHomeChildPath( + 'XDG_DATA_HOME', + ['.local', 'share'] + ); } - public function getConfigPath(): ?string + public function getConfigPath(): string { - return Env::get('XDG_CONFIG_HOME') ?? - $this->getHomeChildPath('.config'); + return $this->getEnvOrHomeChildPath('XDG_CONFIG_HOME', ['.config']); } - public function getCachePath(): ?string + public function getCachePath(): string { - return Env::get('XDG_CACHE_DIRS') ?? - $this->getHomeChildPath('.cache'); + return $this->getEnvOrHomeChildPath('XDG_CACHE_HOME', ['.cache']); } - public function getStatePath(): ?string + public function getStatePath(): string { - return Env::get('XDG_STATE_HOME') ?? - $this->getHomeChildPath('.local', 'state'); + return $this->getEnvOrHomeChildPath( + 'XDG_STATE_HOME', + ['.local', 'state'], + ); } - public function getExecutablePath(): ?string + public function getExecutablePath(): string { return $this->getHomeChildPath('.local', 'bin'); } - public function getRuntimePath(): ?string + public function getRuntimePath(): string { - return Env::get('XDG_RUNTIME_DIR'); + return Util::returnNonNull(Env::get('XDG_RUNTIME_DIR')); } - public function getDataPathSet(): ?array + public function getDataPathSet(): array { return Env::getColonedArray('XDG_DATA_DIRS') ?? ['/usr/local/share/', '/usr/share/']; } - public function getConfigPathSet(): ?array + public function getConfigPathSet(): array { return Env::getColonedArray('XDG_CONFIG_DIRS') ?? ['/etc/xdg']; diff --git a/src/Util/Env.php b/src/Util/Env.php index a80d76e..00f7871 100644 --- a/src/Util/Env.php +++ b/src/Util/Env.php @@ -6,7 +6,7 @@ class Env { public static function get(string $name): ?string { - return getenv($name) ?: null; + return \getenv($name) ?: null; } /** @@ -14,11 +14,11 @@ public static function get(string $name): ?string */ public static function getColonedArray(string $name): ?array { - $rawValue = getenv($name); + $rawValue = \getenv($name); if (empty($rawValue)) { return null; } - return explode(':', $rawValue); + return \explode(':', $rawValue); } } diff --git a/src/Util/Util.php b/src/Util/Util.php new file mode 100644 index 0000000..054dfd2 --- /dev/null +++ b/src/Util/Util.php @@ -0,0 +1,25 @@ + Date: Mon, 14 Feb 2022 11:19:07 +0330 Subject: [PATCH 23/92] Add LinuxDirectoryProvider::get{Fonts,Executables}Path() --- src/PlatformSpecific/LinuxDirectoryProvider.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index aebe221..8d34b08 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -4,10 +4,21 @@ use MAChitgarha\Phirs\Interfaces; use MAChitgarha\Phirs\Traits; +use Symfony\Component\Filesystem\Path; class LinuxDirectoryProvider implements Interfaces\StandardDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBasedCommonPathProvider; use Traits\TemplatesPathProvider; + + public function getFontsPath(): string + { + return Path::join($this->getDataPath(), 'fonts'); + } + + public function getExecutablesPath(): string + { + return $this->getHomeChildPath('.local', 'bin'); + } } From a154e8a6d408a7f837c83084c46994f4c94db81a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 11:49:23 +0330 Subject: [PATCH 24/92] Move path providers relative to home into HomeBased namespace --- src/Interfaces/HomeDirectoryProvider.php | 4 ++-- src/PlatformSpecific/LinuxDirectoryProvider.php | 4 ++-- .../CommonPathProvider.php} | 4 ++-- src/Traits/{ => HomeBased}/TemplatesPathProvider.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/Traits/{HomeBasedCommonPathProvider.php => HomeBased/CommonPathProvider.php} (91%) rename src/Traits/{ => HomeBased}/TemplatesPathProvider.php (83%) diff --git a/src/Interfaces/HomeDirectoryProvider.php b/src/Interfaces/HomeDirectoryProvider.php index 1232c8a..87b549c 100644 --- a/src/Interfaces/HomeDirectoryProvider.php +++ b/src/Interfaces/HomeDirectoryProvider.php @@ -13,8 +13,8 @@ public function getHomePath(): string; * path be not null, otherwise return null (instead of a non-sense relative * path). * - * @param string ...$paths The directory names to be appended to the home - * path, in order. + * @param string ...$childPaths The directory names to be appended to the + * home path, in order. */ public function getHomeChildPath(string ...$childPaths): string; } diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index 8d34b08..2cccb1b 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -9,8 +9,8 @@ class LinuxDirectoryProvider implements Interfaces\StandardDirectoryProvider { use Traits\XdgBasedirSpec; - use Traits\HomeBasedCommonPathProvider; - use Traits\TemplatesPathProvider; + use Traits\HomeBased\CommonPathProvider; + use Traits\HomeBased\TemplatesPathProvider; public function getFontsPath(): string { diff --git a/src/Traits/HomeBasedCommonPathProvider.php b/src/Traits/HomeBased/CommonPathProvider.php similarity index 91% rename from src/Traits/HomeBasedCommonPathProvider.php rename to src/Traits/HomeBased/CommonPathProvider.php index 7cdac39..b4da89a 100644 --- a/src/Traits/HomeBasedCommonPathProvider.php +++ b/src/Traits/HomeBased/CommonPathProvider.php @@ -1,11 +1,11 @@ Date: Mon, 14 Feb 2022 12:05:00 +0330 Subject: [PATCH 25/92] Add DesktopPathProvider trait, use in LinuxDirectoryProvider --- src/PlatformSpecific/LinuxDirectoryProvider.php | 5 ++++- src/Traits/HomeBased/DesktopPathProvider.php | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/Traits/HomeBased/DesktopPathProvider.php diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index 2cccb1b..b8eefa5 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -6,10 +6,13 @@ use MAChitgarha\Phirs\Traits; use Symfony\Component\Filesystem\Path; -class LinuxDirectoryProvider implements Interfaces\StandardDirectoryProvider +class LinuxDirectoryProvider implements + Interfaces\StandardDirectoryProvider, + Interfaces\DesktopDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBased\CommonPathProvider; + use Traits\HomeBased\DesktopPathProvider; use Traits\HomeBased\TemplatesPathProvider; public function getFontsPath(): string diff --git a/src/Traits/HomeBased/DesktopPathProvider.php b/src/Traits/HomeBased/DesktopPathProvider.php new file mode 100644 index 0000000..ea5711a --- /dev/null +++ b/src/Traits/HomeBased/DesktopPathProvider.php @@ -0,0 +1,13 @@ +getHomeChildPath('Desktop'); + } +} From 4683e5140957196308053af03497da6e9c886b37 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 12:16:43 +0330 Subject: [PATCH 26/92] Add PublicPathProvider trait, add in LinuxDirectoryProvider --- src/PlatformSpecific/LinuxDirectoryProvider.php | 4 +++- src/Traits/HomeBased/PublicPathProvider.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/Traits/HomeBased/PublicPathProvider.php diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index b8eefa5..67a2c5d 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -8,11 +8,13 @@ class LinuxDirectoryProvider implements Interfaces\StandardDirectoryProvider, - Interfaces\DesktopDirectoryProvider + Interfaces\DesktopDirectoryProvider, + Interfaces\PublicDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; + use Traits\HomeBased\PublicPathProvider; use Traits\HomeBased\TemplatesPathProvider; public function getFontsPath(): string diff --git a/src/Traits/HomeBased/PublicPathProvider.php b/src/Traits/HomeBased/PublicPathProvider.php new file mode 100644 index 0000000..1c1a234 --- /dev/null +++ b/src/Traits/HomeBased/PublicPathProvider.php @@ -0,0 +1,13 @@ +getHomeChildPath('Public'); + } +} From 972b5e8f68e542ea876153a4844795eedbb35320 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 12:23:46 +0330 Subject: [PATCH 27/92] Remove {Desktop,Public}DirectoryProvider interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If it ain't be needed, remove it (© Mohammad Amin Chitgarha). :) Reason: In future, it might become an unnecessary BC break. --- src/Interfaces/DesktopDirectoryProvider.php | 8 -------- src/Interfaces/PublicDirectoryProvider.php | 8 -------- src/PlatformSpecific/LinuxDirectoryProvider.php | 5 +---- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 src/Interfaces/DesktopDirectoryProvider.php delete mode 100644 src/Interfaces/PublicDirectoryProvider.php diff --git a/src/Interfaces/DesktopDirectoryProvider.php b/src/Interfaces/DesktopDirectoryProvider.php deleted file mode 100644 index bacca70..0000000 --- a/src/Interfaces/DesktopDirectoryProvider.php +++ /dev/null @@ -1,8 +0,0 @@ - Date: Mon, 14 Feb 2022 13:34:32 +0330 Subject: [PATCH 28/92] Add WindowsDirectoryProvider, implementing StandardDirectoryProvider --- .../WindowsDirectoryProvider.php | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/PlatformSpecific/WindowsDirectoryProvider.php diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php new file mode 100644 index 0000000..464a4c4 --- /dev/null +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -0,0 +1,66 @@ +getHomeDriveHomePath(), + 'Cannot detect home folder', + ); + } + + private function getHomeDriveHomePath(): ?string + { + return \array_reduce( + [ + Env::get('HomeDrive'), + Env::get('HomePath'), + ], + fn(?string $carry, ?string $item) => + is_null($carry) || is_null($item) ? null : + Path::join($carry, $item), + // Prevent from halting at the very beginning + '' + ); + } + + public function getDataPath(): string + { + return Util::returnNonNull( + Env::get('AppData'), + 'Cannot find roaming application data folder path' + ); + } + + public function getLocalDataPath(): string + { + return Util::returnNonNull( + Env::get('LocalAppData'), + 'Could not find local application data folder path' + ); + } + + public function getCachePath(): string + { + return $this->getLocalDataPath(); + } + + public function getConfigPath(): string + { + return $this->getDataPath(); + } +} From 3998ab4308e18a35f6c88fcf87a90d5edbf25954 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 14:32:03 +0330 Subject: [PATCH 29/92] Set fallback path for windows cache path to %Temp% path Add ExceptionMessageFactory. --- .../WindowsDirectoryProvider.php | 30 +++++++++++++++---- src/Util/ExceptionMessageFactory.php | 11 +++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/Util/ExceptionMessageFactory.php diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index 464a4c4..8bc0d2e 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -5,6 +5,7 @@ use MAChitgarha\Phirs\Interfaces; use MAChitgarha\Phirs\Traits; use MAChitgarha\Phirs\Util\Env; +use MAChitgarha\Phirs\Util\ExceptionMessageFactory; use MAChitgarha\Phirs\Util\Util; use Symfony\Component\Filesystem\Path; @@ -19,7 +20,7 @@ public function getHomePath(): string { return Util::returnNonNull( Env::get('UserProfile') ?? $this->getHomeDriveHomePath(), - 'Cannot detect home folder', + ExceptionMessageFactory::buildCannotFindPath('home folder'), ); } @@ -42,21 +43,40 @@ public function getDataPath(): string { return Util::returnNonNull( Env::get('AppData'), - 'Cannot find roaming application data folder path' + ExceptionMessageFactory::buildCannotFindPath('AppData folder'), ); } + private function getLocalDataPathNullable(): ?string + { + return Env::get('LocalAppData'); + } + public function getLocalDataPath(): string { return Util::returnNonNull( - Env::get('LocalAppData'), - 'Could not find local application data folder path' + $this->getLocalDataPathNullable(), + ExceptionMessageFactory::buildCannotFindPath('LocalAppData folder'), + ); + } + + private function getTemporaryPathNullable(): ?string + { + return Env::get('Temp'); + } + + public function getTemporaryPath(): string + { + return Util::returnNonNull( + $this->getTemporaryPathNullable(), + ExceptionMessageFactory::buildCannotFindPath('temporary folder'), ); } public function getCachePath(): string { - return $this->getLocalDataPath(); + return $this->getLocalDataPathNullable() ?? + $this->getTemporaryPathNullable(); } public function getConfigPath(): string diff --git a/src/Util/ExceptionMessageFactory.php b/src/Util/ExceptionMessageFactory.php new file mode 100644 index 0000000..52e5311 --- /dev/null +++ b/src/Util/ExceptionMessageFactory.php @@ -0,0 +1,11 @@ + Date: Mon, 14 Feb 2022 14:38:58 +0330 Subject: [PATCH 30/92] Code improvements --- src/Traits/UnixLikeHomePathProvider.php | 3 ++- src/Traits/XdgBasedirSpec.php | 32 ++++++++++++------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Traits/UnixLikeHomePathProvider.php b/src/Traits/UnixLikeHomePathProvider.php index 63dab4e..741e94a 100644 --- a/src/Traits/UnixLikeHomePathProvider.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -4,6 +4,7 @@ use MAChitgarha\Phirs\Util\Env; use MAChitgarha\Phirs\Util\Util; +use MAChitgarha\Phirs\Util\ExceptionMessageFactory; trait UnixLikeHomePathProvider { @@ -13,7 +14,7 @@ public function getHomePath(): string { return Util::returnNonNull( Env::get('HOME') ?? $this->getHomePathByPosixUid(), - 'Cannot detect $HOME directory' + ExceptionMessageFactory::buildCannotFindPath('home directory'), ); } diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index 57fc0ac..f33badf 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -32,20 +32,12 @@ private function getEnvOrHomeChildPath( $this->getHomeChildPath(...$childPaths); } catch (Exception $e) { throw new Exception( - "Cannot find a proper path for the requested directory " . - "(reasons: env $envName not set and {$e->getMessage()})" + 'Cannot find a proper path for the requested directory ' . + "(reasons: Env $envName not set and {$e->getMessage()})" ); } } - public function getDataPath(): string - { - return $this->getEnvOrHomeChildPath( - 'XDG_DATA_HOME', - ['.local', 'share'] - ); - } - public function getConfigPath(): string { return $this->getEnvOrHomeChildPath('XDG_CONFIG_HOME', ['.config']); @@ -56,6 +48,14 @@ public function getCachePath(): string return $this->getEnvOrHomeChildPath('XDG_CACHE_HOME', ['.cache']); } + public function getDataPath(): string + { + return $this->getEnvOrHomeChildPath( + 'XDG_DATA_HOME', + ['.local', 'share'] + ); + } + public function getStatePath(): string { return $this->getEnvOrHomeChildPath( @@ -74,15 +74,15 @@ public function getRuntimePath(): string return Util::returnNonNull(Env::get('XDG_RUNTIME_DIR')); } - public function getDataPathSet(): array - { - return Env::getColonedArray('XDG_DATA_DIRS') ?? - ['/usr/local/share/', '/usr/share/']; - } - public function getConfigPathSet(): array { return Env::getColonedArray('XDG_CONFIG_DIRS') ?? ['/etc/xdg']; } + + public function getDataPathSet(): array + { + return Env::getColonedArray('XDG_DATA_DIRS') ?? + ['/usr/local/share/', '/usr/share/']; + } } From ba3c15215e39045a3cf96431daac165339f0747f Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 14:58:00 +0330 Subject: [PATCH 31/92] Add MacOsDirectoryProvider, implementing StandardDirectoryProvider Add MoviesPathProvider also. --- .../MacOsDirectoryProvider.php | 52 +++++++++++++++++++ src/Traits/HomeBased/MoviesPathProvider.php | 18 +++++++ 2 files changed, 70 insertions(+) create mode 100644 src/PlatformSpecific/MacOsDirectoryProvider.php create mode 100644 src/Traits/HomeBased/MoviesPathProvider.php diff --git a/src/PlatformSpecific/MacOsDirectoryProvider.php b/src/PlatformSpecific/MacOsDirectoryProvider.php new file mode 100644 index 0000000..2b9579b --- /dev/null +++ b/src/PlatformSpecific/MacOsDirectoryProvider.php @@ -0,0 +1,52 @@ +getHomeChildPath('Library', ...$childPaths); + } + + public function getCachePath(): string + { + return $this->getHomeLibraryChildPath('Caches'); + } + + private function getApplicationSupportPath(): string + { + return $this->getHomeLibraryChildPath('Application Support'); + } + + public function getConfigPath(): string + { + return $this->getApplicationSupportPath(); + } + + public function getDataPath(): string + { + return $this->getApplicationSupportPath(); + } + + public function getFontsPath(): string + { + return $this->getHomeLibraryChildPath('Fonts'); + } + + public function getPreferencesPath(): string + { + return $this->getHomeLibraryChildPath('Preferences'); + } +} diff --git a/src/Traits/HomeBased/MoviesPathProvider.php b/src/Traits/HomeBased/MoviesPathProvider.php new file mode 100644 index 0000000..56a2ca6 --- /dev/null +++ b/src/Traits/HomeBased/MoviesPathProvider.php @@ -0,0 +1,18 @@ +getHomeChildPath('Movies'); + } + + public function getVideosPath(): string + { + return $this->getMoviesPath(); + } +} From 4218cd0bba66aa1131373902c990138068fd4ced Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Mon, 14 Feb 2022 16:09:32 +0330 Subject: [PATCH 32/92] Add Features section in README.md Actually move it from 'But There Is Another Library!' section to the top and edited. --- README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c860ce4..ca3d05b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired by [dirs-rs](https://github.com/dirs-dev/dirs-rs). +## Features + +- **Cross-platform**. Supporting multiple platforms, including GNU/Linux, Windows and Mac OS. Providing paths available on all platforms, plus specific paths for each platform. This means, you could target a specific platform, stick to it and look nowhere else. + +- **Hackable**. Adding support for a specific platform [is easy](#). + +- **Well-designed**. Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). + ## Why? When writing a console application (or even a graphical one; who knows, people might start writing graphical applications in PHP in near future), sometimes you need to have a location to: @@ -19,19 +27,7 @@ Phirs can to help you in these situations. Why not just using [Basedir](https://github.com/clue-labs/php-basedir)? -The library is already good to be used. However, there are some reasons you might prefer this library: - -- With the help of simple abstractions, adding support for a specific platform should be easy. The abstractions are designed with performance in mind. - - **Note:** For having something like this in Basedir, a major rewrite and huge backward-compatibility break would be required. - -- If you want or have to, you can target a specific platform and stick to it. - -- Support for more platforms. - -- Support for more directories. - -- Basedir is [no longer available](https://packagist.org/search/?q=basedir) on Packagist for some reason. +Go back and see [features](#features). Having these there would require a major rewrite and huge backward-compatibility break. Plus, Basedir is [no longer available on Packagist](https://packagist.org/search/?q=basedir), for some unknown reason. ## Installation From 069198955c5f739b0fa0d743e19aed396f3eedb6 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Tue, 15 Feb 2022 15:32:51 +0330 Subject: [PATCH 33/92] Rename {MacOs->Darwin}DirectoryProvider --- ...acOsDirectoryProvider.php => DarwinDirectoryProvider.php} | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename src/PlatformSpecific/{MacOsDirectoryProvider.php => DarwinDirectoryProvider.php} (89%) diff --git a/src/PlatformSpecific/MacOsDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php similarity index 89% rename from src/PlatformSpecific/MacOsDirectoryProvider.php rename to src/PlatformSpecific/DarwinDirectoryProvider.php index 2b9579b..d129360 100644 --- a/src/PlatformSpecific/MacOsDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -5,7 +5,10 @@ use MAChitgarha\Phirs\Interfaces; use MAChitgarha\Phirs\Traits; -class MacOsDirectoryProvider implements Interfaces\StandardDirectoryProvider +/** + * Provider for Darwin-based OSes, such as MacOS and iOS. + */ +class DarwinDirectoryProvider implements Interfaces\StandardDirectoryProvider { use Traits\UnixLikeHomePathProvider; use Traits\HomeBased\CommonPathProvider; From 2c2bd55d6abecff0130d0fe5b91e73a2aedd2b03 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Tue, 15 Feb 2022 16:15:16 +0330 Subject: [PATCH 34/92] Add Platform Support section (moving from Features section) --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca3d05b..2dac740 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A library providing platform-specific user-accessible directory paths, such as c ## Features -- **Cross-platform**. Supporting multiple platforms, including GNU/Linux, Windows and Mac OS. Providing paths available on all platforms, plus specific paths for each platform. This means, you could target a specific platform, stick to it and look nowhere else. +- **Multiple platform**. Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. - **Hackable**. Adding support for a specific platform [is easy](#). @@ -37,6 +37,33 @@ Easy like every other PHP library: composer install machitgarha/phirs ``` +## Platform Support + +**Note:** The table below is only + +|Platform|Having a Provider?|Supported?|Working?|Having a Specialized Provider?| +|:-:|:-:|:-:|:-:|:-:| +|GNU/Linux distributions|✅|✅|✅|✅| +|Windows|✅|✅|✅|✅| +|Mac OS|✅|✅|✅|✅| +|[Termux](https://termux.com) on Android|✅|✅|✅❕|❌| +|BSD|✅|❌|❔|❌| +|Solaris|✅|❌|❔|❌| +|Android|✅|❌|❓|❌| +|iOS|✅|❌|❔|❌| + +❕: Have notes. +❔: Not known or depends on the environment. +❓: Like ❔, but most likely not working. + +### Notes + +- It might not be exactly what you or users expect; e.g. pictures directory path is inside Termux home, not the internal SDCard (i.e. `/sdcard`). + +### Fork and Improve It! + +By the way, if you can improve support for a specific platform, why not? + ## License The project is licensed under [Apache 2.0 License](./LICENSE.md). From 3a653f3ee157da4bce34b7ca1116bc1a139eb49a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Tue, 15 Feb 2022 16:36:21 +0330 Subject: [PATCH 35/92] Add Platform enum-like class with autoDetect() function --- src/Util/Platform.php | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/Util/Platform.php diff --git a/src/Util/Platform.php b/src/Util/Platform.php new file mode 100644 index 0000000..75e8f0e --- /dev/null +++ b/src/Util/Platform.php @@ -0,0 +1,58 @@ + Date: Thu, 17 Feb 2022 00:14:34 +0330 Subject: [PATCH 36/92] Rename namespace Interfaces to Definitions --- src/{Interfaces => Definitions}/CommonDirectoryProvider.php | 2 +- src/{Interfaces => Definitions}/HomeDirectoryProvider.php | 2 +- src/{Interfaces => Definitions}/StandardDirectoryProvider.php | 2 +- src/PlatformSpecific/DarwinDirectoryProvider.php | 4 ++-- src/PlatformSpecific/LinuxDirectoryProvider.php | 4 ++-- src/PlatformSpecific/WindowsDirectoryProvider.php | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/{Interfaces => Definitions}/CommonDirectoryProvider.php (89%) rename src/{Interfaces => Definitions}/HomeDirectoryProvider.php (92%) rename src/{Interfaces => Definitions}/StandardDirectoryProvider.php (93%) diff --git a/src/Interfaces/CommonDirectoryProvider.php b/src/Definitions/CommonDirectoryProvider.php similarity index 89% rename from src/Interfaces/CommonDirectoryProvider.php rename to src/Definitions/CommonDirectoryProvider.php index e6ead08..21d127e 100644 --- a/src/Interfaces/CommonDirectoryProvider.php +++ b/src/Definitions/CommonDirectoryProvider.php @@ -1,6 +1,6 @@ Date: Thu, 17 Feb 2022 00:40:19 +0330 Subject: [PATCH 37/92] Add Basic Usage section in README.md --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2dac740..04d60f6 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,27 @@ Easy like every other PHP library: composer install machitgarha/phirs ``` -## Platform Support +## Basic Usage + +A simple use for most common cases is the following: + +```php +use MAChitgarha\Phirs\DirectoryProviderFactory; +use MAChitgarha\Phirs\Util\Platform; + +// Get a directory provider for your platform, which is auto-detected +$dirProvider = DirectoryProviderFactory::createStandard( + Platform::autoDetect() +); -**Note:** The table below is only +// Let's get some paths! +$configPath = $dirProvider->getConfigPath(); +$docsPath = $dirProvider->getDocumentsPath(); + +// Load or save something…! +``` + +## Platform Support |Platform|Having a Provider?|Supported?|Working?|Having a Specialized Provider?| |:-:|:-:|:-:|:-:|:-:| From 2fe9344f6ee2f054676c748b66ead5dfce45ea83 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 01:14:54 +0330 Subject: [PATCH 38/92] Refer to Usage Guide page of the docs in README.md Add Requirements section also. --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 04d60f6..2b4f999 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ Why not just using [Basedir](https://github.com/clue-labs/php-basedir)? Go back and see [features](#features). Having these there would require a major rewrite and huge backward-compatibility break. Plus, Basedir is [no longer available on Packagist](https://packagist.org/search/?q=basedir), for some unknown reason. +## Requirements + +PHP 7.4+ only. + ## Installation Easy like every other PHP library: @@ -45,7 +49,7 @@ A simple use for most common cases is the following: use MAChitgarha\Phirs\DirectoryProviderFactory; use MAChitgarha\Phirs\Util\Platform; -// Get a directory provider for your platform, which is auto-detected +// Get a provider for the current platform $dirProvider = DirectoryProviderFactory::createStandard( Platform::autoDetect() ); @@ -57,6 +61,8 @@ $docsPath = $dirProvider->getDocumentsPath(); // Load or save something…! ``` +What a provider is? Why we use `createStandard`? Can I extend it and map a specific platform to my own provider? (Consider give your code back if you did it BTW.) See [Usage Guide](./docs/en/usage-guide.md) for more details. + ## Platform Support |Platform|Having a Provider?|Supported?|Working?|Having a Specialized Provider?| @@ -72,7 +78,7 @@ $docsPath = $dirProvider->getDocumentsPath(); ❕: Have notes. ❔: Not known or depends on the environment. -❓: Like ❔, but most likely not working. +❓: Like ❔, but most likely no. ### Notes From c0d5bbf698aeef437596aa9edbf2908bbb00e218 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 01:47:42 +0330 Subject: [PATCH 39/92] Rename Definitions namespace to Types Its meaning is more clear and not confusing and conflicting with other things (because telling definition makes implementation to come in mind, but we do not mean it). --- src/PlatformSpecific/DarwinDirectoryProvider.php | 4 ++-- src/PlatformSpecific/LinuxDirectoryProvider.php | 4 ++-- src/PlatformSpecific/WindowsDirectoryProvider.php | 4 ++-- src/{Definitions => Types}/CommonDirectoryProvider.php | 2 +- src/{Definitions => Types}/HomeDirectoryProvider.php | 2 +- src/{Definitions => Types}/StandardDirectoryProvider.php | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/{Definitions => Types}/CommonDirectoryProvider.php (89%) rename src/{Definitions => Types}/HomeDirectoryProvider.php (92%) rename src/{Definitions => Types}/StandardDirectoryProvider.php (93%) diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index fc17f2c..cded3f3 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -2,13 +2,13 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Definitions; +use MAChitgarha\Phirs\Types; use MAChitgarha\Phirs\Traits; /** * Provider for Darwin-based OSes, such as MacOS and iOS. */ -class DarwinDirectoryProvider implements Definitions\StandardDirectoryProvider +class DarwinDirectoryProvider implements Types\StandardDirectoryProvider { use Traits\UnixLikeHomePathProvider; use Traits\HomeBased\CommonPathProvider; diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index ed5c160..f53ff59 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -2,11 +2,11 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Definitions; +use MAChitgarha\Phirs\Types; use MAChitgarha\Phirs\Traits; use Symfony\Component\Filesystem\Path; -class LinuxDirectoryProvider implements Definitions\StandardDirectoryProvider +class LinuxDirectoryProvider implements Types\StandardDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBased\CommonPathProvider; diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index 0d7b1d2..579cc4d 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -2,14 +2,14 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Definitions; +use MAChitgarha\Phirs\Types; use MAChitgarha\Phirs\Traits; use MAChitgarha\Phirs\Util\Env; use MAChitgarha\Phirs\Util\ExceptionMessageFactory; use MAChitgarha\Phirs\Util\Util; use Symfony\Component\Filesystem\Path; -class WindowsDirectoryProvider implements Definitions\StandardDirectoryProvider +class WindowsDirectoryProvider implements Types\StandardDirectoryProvider { use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; diff --git a/src/Definitions/CommonDirectoryProvider.php b/src/Types/CommonDirectoryProvider.php similarity index 89% rename from src/Definitions/CommonDirectoryProvider.php rename to src/Types/CommonDirectoryProvider.php index 21d127e..887e91f 100644 --- a/src/Definitions/CommonDirectoryProvider.php +++ b/src/Types/CommonDirectoryProvider.php @@ -1,6 +1,6 @@ Date: Thu, 17 Feb 2022 02:32:17 +0330 Subject: [PATCH 40/92] Add Usage Guide page of docs, with an overview of the main concepts --- README.md | 2 +- docs/en/usage-guide.md | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 docs/en/usage-guide.md diff --git a/README.md b/README.md index 2b4f999..bf9d430 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ use MAChitgarha\Phirs\DirectoryProviderFactory; use MAChitgarha\Phirs\Util\Platform; // Get a provider for the current platform -$dirProvider = DirectoryProviderFactory::createStandard( +$dirProvider = DirectoryProviderFactory::new()->createStandard( Platform::autoDetect() ); diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md new file mode 100644 index 0000000..a0886b2 --- /dev/null +++ b/docs/en/usage-guide.md @@ -0,0 +1,15 @@ +# Usage Guide + +## Overview of the Main Concepts + +Let's start with defining two important concepts: + +- **(Directory) Provider**: A class providing the path of directories for one or more platforms. For instance, `LinuxDirectoryProvider` or `WindowsDirectoryProvider`. + +- **(Directory) Provider Type**: An interface defining what a provider must implement. In other words, it specifies what directories must a provider provide the path of. + + For example, `StandardDirectoryProvider` is a type enforcing providers to provide paths of directories available across (almost) all platforms. The term standard is in the context of the library, not a real standard or specification. You could call it `CrossPlatformDirectoryProvider` in your mind. + +In the examples above, Linux and Windows (and also Darwin) providers are all of standard type (i.e. implements `StandardDirectoryProvider` interface). + +**Note**: Providers and provider types are under namespaces `PlatformSpecific` and `Types`, respectively. From 4a2e3290e152e138468eb0bdbb2b1b650b4a5283 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 02:37:22 +0330 Subject: [PATCH 41/92] Make Types namespace singular and rename it to Type Type\StandardDirectoryProvider makes much more sense. --- src/PlatformSpecific/DarwinDirectoryProvider.php | 4 ++-- src/PlatformSpecific/LinuxDirectoryProvider.php | 4 ++-- src/PlatformSpecific/WindowsDirectoryProvider.php | 4 ++-- src/{Types => Type}/CommonDirectoryProvider.php | 2 +- src/{Types => Type}/HomeDirectoryProvider.php | 2 +- src/{Types => Type}/StandardDirectoryProvider.php | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/{Types => Type}/CommonDirectoryProvider.php (91%) rename src/{Types => Type}/HomeDirectoryProvider.php (93%) rename src/{Types => Type}/StandardDirectoryProvider.php (94%) diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index cded3f3..1857c32 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -2,13 +2,13 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Types; +use MAChitgarha\Phirs\Type; use MAChitgarha\Phirs\Traits; /** * Provider for Darwin-based OSes, such as MacOS and iOS. */ -class DarwinDirectoryProvider implements Types\StandardDirectoryProvider +class DarwinDirectoryProvider implements Type\StandardDirectoryProvider { use Traits\UnixLikeHomePathProvider; use Traits\HomeBased\CommonPathProvider; diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index f53ff59..f95ab84 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -2,11 +2,11 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Types; +use MAChitgarha\Phirs\Type; use MAChitgarha\Phirs\Traits; use Symfony\Component\Filesystem\Path; -class LinuxDirectoryProvider implements Types\StandardDirectoryProvider +class LinuxDirectoryProvider implements Type\StandardDirectoryProvider { use Traits\XdgBasedirSpec; use Traits\HomeBased\CommonPathProvider; diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index 579cc4d..b3c637d 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -2,14 +2,14 @@ namespace MAChitgarha\Phirs\PlatformSpecific; -use MAChitgarha\Phirs\Types; +use MAChitgarha\Phirs\Type; use MAChitgarha\Phirs\Traits; use MAChitgarha\Phirs\Util\Env; use MAChitgarha\Phirs\Util\ExceptionMessageFactory; use MAChitgarha\Phirs\Util\Util; use Symfony\Component\Filesystem\Path; -class WindowsDirectoryProvider implements Types\StandardDirectoryProvider +class WindowsDirectoryProvider implements Type\StandardDirectoryProvider { use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; diff --git a/src/Types/CommonDirectoryProvider.php b/src/Type/CommonDirectoryProvider.php similarity index 91% rename from src/Types/CommonDirectoryProvider.php rename to src/Type/CommonDirectoryProvider.php index 887e91f..a06ffc1 100644 --- a/src/Types/CommonDirectoryProvider.php +++ b/src/Type/CommonDirectoryProvider.php @@ -1,6 +1,6 @@ Date: Thu, 17 Feb 2022 12:36:45 +0330 Subject: [PATCH 42/92] =?UTF-8?q?Define=20custom=20exceptions=20and=20use?= =?UTF-8?q?=20them=20instead=20of=20Exce=E2=80=A6MessageFactory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move Util::returnNonNull() to Path::returnNonEmpty(), for better custom exception handling. Fix Windows provider getCachePath() not checking the path not to be empty. --- src/Exception/Exception.php | 7 +++++ src/Exception/PathNotFoundException.php | 18 +++++++++++ .../WindowsDirectoryProvider.php | 30 ++++++++++--------- src/Traits/UnixLikeHomePathProvider.php | 7 ++--- src/Traits/XdgBasedirSpec.php | 10 +++---- src/Util/ExceptionMessageFactory.php | 11 ------- src/Util/Path.php | 20 +++++++++++++ src/Util/Util.php | 25 ---------------- 8 files changed, 69 insertions(+), 59 deletions(-) create mode 100644 src/Exception/Exception.php create mode 100644 src/Exception/PathNotFoundException.php delete mode 100644 src/Util/ExceptionMessageFactory.php create mode 100644 src/Util/Path.php delete mode 100644 src/Util/Util.php diff --git a/src/Exception/Exception.php b/src/Exception/Exception.php new file mode 100644 index 0000000..fb14b6b --- /dev/null +++ b/src/Exception/Exception.php @@ -0,0 +1,7 @@ +getHomeDriveHomePath(), - ExceptionMessageFactory::buildCannotFindPath('home folder'), + 'home folder', ); } @@ -33,7 +32,7 @@ private function getHomeDriveHomePath(): ?string ], fn(?string $carry, ?string $item) => is_null($carry) || is_null($item) ? null : - Path::join($carry, $item), + SymfonyPath::join($carry, $item), // Prevent from halting at the very beginning '' ); @@ -41,9 +40,9 @@ private function getHomeDriveHomePath(): ?string public function getDataPath(): string { - return Util::returnNonNull( + return Path::returnNonEmpty( Env::get('AppData'), - ExceptionMessageFactory::buildCannotFindPath('AppData folder'), + 'AppData folder' ); } @@ -54,9 +53,9 @@ private function getLocalDataPathNullable(): ?string public function getLocalDataPath(): string { - return Util::returnNonNull( + return Path::returnNonEmpty( $this->getLocalDataPathNullable(), - ExceptionMessageFactory::buildCannotFindPath('LocalAppData folder'), + 'LocalAppData folder', ); } @@ -67,16 +66,19 @@ private function getTemporaryPathNullable(): ?string public function getTemporaryPath(): string { - return Util::returnNonNull( + return Path::returnNonEmpty( $this->getTemporaryPathNullable(), - ExceptionMessageFactory::buildCannotFindPath('temporary folder'), + 'temporary folder', ); } public function getCachePath(): string { - return $this->getLocalDataPathNullable() ?? - $this->getTemporaryPathNullable(); + return Path::returnNonEmpty( + $this->getLocalDataPathNullable() ?? + $this->getTemporaryPathNullable(), + 'cache folder (any of LocalAppData or temporary folders)' + ); } public function getConfigPath(): string diff --git a/src/Traits/UnixLikeHomePathProvider.php b/src/Traits/UnixLikeHomePathProvider.php index 741e94a..be02c4f 100644 --- a/src/Traits/UnixLikeHomePathProvider.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -3,8 +3,7 @@ namespace MAChitgarha\Phirs\Traits; use MAChitgarha\Phirs\Util\Env; -use MAChitgarha\Phirs\Util\Util; -use MAChitgarha\Phirs\Util\ExceptionMessageFactory; +use MAChitgarha\Phirs\Util\Path; trait UnixLikeHomePathProvider { @@ -12,9 +11,9 @@ trait UnixLikeHomePathProvider public function getHomePath(): string { - return Util::returnNonNull( + return Path::returnNonEmpty( Env::get('HOME') ?? $this->getHomePathByPosixUid(), - ExceptionMessageFactory::buildCannotFindPath('home directory'), + 'home directory', ); } diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index f33badf..baac432 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -2,7 +2,7 @@ namespace MAChitgarha\Phirs\Traits; -use Exception; +use MAChitgarha\Phirs\Exception\PathNotFoundException; use MAChitgarha\Phirs\Util\Env; use MAChitgarha\Phirs\Util\Util; @@ -30,10 +30,10 @@ private function getEnvOrHomeChildPath( try { return Env::get($envName) ?? $this->getHomeChildPath(...$childPaths); - } catch (Exception $e) { - throw new Exception( - 'Cannot find a proper path for the requested directory ' . - "(reasons: Env $envName not set and {$e->getMessage()})" + } catch (PathNotFoundException $e) { + throw new PathNotFoundException( + 'requested directory', + "env $envName not set and {$e->getMessage()}" ); } } diff --git a/src/Util/ExceptionMessageFactory.php b/src/Util/ExceptionMessageFactory.php deleted file mode 100644 index 52e5311..0000000 --- a/src/Util/ExceptionMessageFactory.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Thu, 17 Feb 2022 14:47:49 +0330 Subject: [PATCH 43/92] Add DirectoryProviderFactory class --- README.md | 2 +- src/DirectoryProviderFactory.php | 170 +++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 src/DirectoryProviderFactory.php diff --git a/README.md b/README.md index bf9d430..2b4f999 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ use MAChitgarha\Phirs\DirectoryProviderFactory; use MAChitgarha\Phirs\Util\Platform; // Get a provider for the current platform -$dirProvider = DirectoryProviderFactory::new()->createStandard( +$dirProvider = DirectoryProviderFactory::createStandard( Platform::autoDetect() ); diff --git a/src/DirectoryProviderFactory.php b/src/DirectoryProviderFactory.php new file mode 100644 index 0000000..f5d9946 --- /dev/null +++ b/src/DirectoryProviderFactory.php @@ -0,0 +1,170 @@ + [ + Platform::LINUX => LinuxDirectoryProvider::class, + Platform::DARWIN => DarwinDirectoryProvider::class, + Platform::WINDOWS => WindowsDirectoryProvider::class, + + // TODO: Maybe make a specialized provider for these systems? + Platform::BSD => LinuxDirectoryProvider::class, + Platform::SOLARIS => LinuxDirectoryProvider::class, + ], + ]; + + private static function validateType(string $type): string + { + if (\interface_exists($type)) { + throw new Exception("Type '$type' not defined as an interface"); + } + return self::class; + } + + private static function validateProvider(string $provider): string + { + if (\class_exists($provider)) { + throw new Exception("Provider '$provider' is not a defined class"); + } + return self::class; + } + + private static function validateProviderType( + string $provider, + string $type + ): string { + if (!\is_a($provider, $type)) { + throw new Exception( + "Provider '$provider' must be of type (i.e. implement) '$type'" + ); + } + return self::class; + } + + /** + * @param string $type Must an existing interface. + */ + private static function createInternal( + string $type, + string $platform + ): object { + $class = self::$providerMapper[$type][$platform] ?? null; + + if (\is_null($class)) { + throw new Exception( + "No provider of type '$type' set for " + ); + } + + /* + * No need to check if $class exists, $type is an interface and $class + * implements $type. Default mappings are correct, and any custom + * defined stuff is also checked in the mapInternal() method. + */ + + return new $class(); + } + + /** + * Create a provider of a specific type, targeting the specified platform. + * + * @return object A provider object implementing $type. + */ + public static function create(string $type, string $platform): object + { + self::validateType($type); + return self::createInternal($type, $platform); + } + + /** + * Create a provider of standard type, targeting the specified platform. + */ + public static function createStandard( + string $platform + ): StandardDirectoryProvider { + return self::createInternal( + StandardDirectoryProvider::class, + $platform + ); + } + + /** + * @param string $type Must an existing interface. + */ + private static function mapInternal( + string $type, + string $platform, + string $provider + ): string { + self::validateProvider($provider) + ::validateProviderType($provider, $type); + + self::$providerMapper[$type][$platform] = $provider; + + return self::class; + } + + /** + * Map a platform to a provider, for the specified provider type. + * + * @return string Self. + */ + public static function map( + string $type, + string $platform, + string $provider + ): string { + self::validateType($type); + return self::mapInternal($type, $platform, $provider); + } + + /** + * Map a platform to a provider, for the standard provider type. + * + * @return string Self. + */ + public static function mapStandard( + string $platform, + string $provider + ): string { + return self::mapInternal( + StandardDirectoryProvider::class, + $platform, + $provider + ); + } +} From 9a954e01a12bf70fdc999736c0a24cef6c1c5e97 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 17:25:28 +0330 Subject: [PATCH 44/92] Code improvements, including exception handling --- README.md | 4 +--- src/DirectoryProviderFactory.php | 21 ++++++++++++++------- src/Util/Platform.php | 27 +++++++++++++-------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 2b4f999..516aca3 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,7 @@ use MAChitgarha\Phirs\DirectoryProviderFactory; use MAChitgarha\Phirs\Util\Platform; // Get a provider for the current platform -$dirProvider = DirectoryProviderFactory::createStandard( - Platform::autoDetect() -); +$dirProvider = DirectoryProviderFactory::createStandard(Platform::autoDetect()); // Let's get some paths! $configPath = $dirProvider->getConfigPath(); diff --git a/src/DirectoryProviderFactory.php b/src/DirectoryProviderFactory.php index f5d9946..8b637e7 100644 --- a/src/DirectoryProviderFactory.php +++ b/src/DirectoryProviderFactory.php @@ -82,21 +82,28 @@ private static function createInternal( string $type, string $platform ): object { - $class = self::$providerMapper[$type][$platform] ?? null; + $providerMapperForType = self::$providerMapper[$type]; - if (\is_null($class)) { + if (\is_null($providerMapperForType)) { + throw new Exception("No provider defined for type '$type'"); + } + + $provider = $providerMapperForType[$platform] ?? null; + + if (\is_null($provider)) { throw new Exception( - "No provider of type '$type' set for " + "No provider of type '$type' set for $platform platform " . + '(maybe the running platform is not supported?)' ); } /* - * No need to check if $class exists, $type is an interface and $class - * implements $type. Default mappings are correct, and any custom - * defined stuff is also checked in the mapInternal() method. + * No need to check if $provider exists, $type is an interface and + * $provider implements $type. Default mappings are correct, and any + * custom defined stuff is also checked in the mapInternal() method. */ - return new $class(); + return new $provider(); } /** diff --git a/src/Util/Platform.php b/src/Util/Platform.php index 75e8f0e..d23ee55 100644 --- a/src/Util/Platform.php +++ b/src/Util/Platform.php @@ -11,23 +11,22 @@ class Platform public const SOLARIS = 'Solaris'; public const UNKNOWN = 'Unknown'; + private static $mapper = [ + static::LINUX => fn() => static::isLinux(), + static::DARWIN => fn() => static::isDarwin(), + static::WINDOWS => fn() => static::isWindows(), + static::BSD => fn() => static::isBsd(), + static::SOLARIS => fn() => static::isSolaris(), + ]; + public static function autoDetect(): string { - if (static::isLinux()) { - return static::LINUX; - } - if (static::isDarwin()) { - return static::MAC_OS; - } - if (static::isWindows()) { - return static::WINDOWS; - } - if (static::isBsd()) { - return static::BSD; - } - if (static::isSolaris()) { - return static::SOLARIS; + foreach (self::$mapper as $platform => $isPlatform) { + if ($isPlatform()) { + return $platform; + } } + return static::UNKNOWN; } From fcb1ba274365ec7da931080f2469dad7bba65fc3 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 17:58:05 +0330 Subject: [PATCH 45/92] Add Creating a Provider Object in Usage Guide page --- docs/en/usage-guide.md | 45 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index a0886b2..757025e 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -1,15 +1,56 @@ # Usage Guide +**Note**: In the examples, the `use` statements are eliminated. + ## Overview of the Main Concepts Let's start with defining two important concepts: - **(Directory) Provider**: A class providing the path of directories for one or more platforms. For instance, `LinuxDirectoryProvider` or `WindowsDirectoryProvider`. -- **(Directory) Provider Type**: An interface defining what a provider must implement. In other words, it specifies what directories must a provider provide the path of. +- **(Directory) Provider Type**: An interface defining what a provider must implement. In other words, it specifies what directories must a provider provide the path of. It may be referred to as type. For example, `StandardDirectoryProvider` is a type enforcing providers to provide paths of directories available across (almost) all platforms. The term standard is in the context of the library, not a real standard or specification. You could call it `CrossPlatformDirectoryProvider` in your mind. In the examples above, Linux and Windows (and also Darwin) providers are all of standard type (i.e. implements `StandardDirectoryProvider` interface). -**Note**: Providers and provider types are under namespaces `PlatformSpecific` and `Types`, respectively. +**Note**: Providers and provider types are under namespaces `PlatformSpecific` and `Type`, respectively. + +## Creating a Provider Object + +The main method to get a provider is via `DirectoryProviderFactory`. The other way is to instantiate the dedicated provider directly. + +**Tip**: Want to target a specific platform? Each method has its benefits. The first one makes porting your application to other platforms easy. The second one enables you to use paths of platform-specific directories confidently. + +### Using `DirectoryProviderFactory` Static Class + +The class helps you creating provider of a specific type, for a specific platform. For example, let's create a standard provider for Darwin (e.g. Mac OS) platform: + +```php +$dirProvider = DirectoryProviderFactory::createStandard(Platform::DARWIN); +``` + +A better approach is to get provider based on the current platform: + +```php +$dirProvider = DirectoryProviderFactory::createStandard(Platform::autoDetect()); +``` + +You can also pass the provider type manually to the `create()` method: + +```php +$dirProvider = DirectoryProviderFactory::create( + StandardDirectoryProvider::class, + Platform::autoDetect() +); +``` + +**Note**: By default, only standard provider type mappings are defined. However, you may extend the types using `map*()` methods. + +### Instantiaing Dedicated Provider + +Let's create a Linux provider directly: + +```php +$dirProvider = new LinuxDirectoryProvider(); +``` From a8f99a39837c547d8cf54209161602ead128863d Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 18:03:30 +0330 Subject: [PATCH 46/92] Add Getting Path of Directories secion of Usage Guide page --- docs/en/usage-guide.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 757025e..7d78779 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -47,10 +47,28 @@ $dirProvider = DirectoryProviderFactory::create( **Note**: By default, only standard provider type mappings are defined. However, you may extend the types using `map*()` methods. -### Instantiaing Dedicated Provider +### Instantiating Dedicated Provider Let's create a Linux provider directly: ```php $dirProvider = new LinuxDirectoryProvider(); ``` + +## Getting Path of Directories + +Based on which method you used to create a provider, you can use one of `get*Path()` methods to get path of a specific directory. + +```php +// Get cache directory path +$cacheDir = $dirProvider->getCachePath(); +``` + +If you instantiated a provider directly, e.g. Linux provider, you may use platform-specific path getters, however: + +```php +// Not available on Windows or Mac OS +$executables = $dirProvider->getExecutablesPath(); +``` + +**Important Note**: The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative), because different users may have different needs. From d34d726187a478d7fbe3b7863ff1c75d65daaed7 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 18:18:18 +0330 Subject: [PATCH 47/92] Add Exception Handling section in Usage Guide page --- docs/en/usage-guide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 7d78779..ea4f318 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -72,3 +72,9 @@ $executables = $dirProvider->getExecutablesPath(); ``` **Important Note**: The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative), because different users may have different needs. + +## Exception Handling + +All getter methods throw `PathNotFoundException` if the path cannot be built. There may be different reasons to this. For example, neither `%UserProfile%` nor `%HomeDrive%` environment variables defined on a Windows platform. + +`DirectoryProviderFactory` class throws `Exception`s (library-defined) in certain conditions, like wrong input arguments, or a provider not set for the requested platform and type. From 3a3cc51bd477e2894d75ca35e6433db0f270da15 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 22:57:20 +0330 Subject: [PATCH 48/92] Make Platform class extensible --- src/Util/Platform.php | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/Util/Platform.php b/src/Util/Platform.php index d23ee55..f2f9415 100644 --- a/src/Util/Platform.php +++ b/src/Util/Platform.php @@ -11,23 +11,35 @@ class Platform public const SOLARIS = 'Solaris'; public const UNKNOWN = 'Unknown'; - private static $mapper = [ - static::LINUX => fn() => static::isLinux(), - static::DARWIN => fn() => static::isDarwin(), - static::WINDOWS => fn() => static::isWindows(), - static::BSD => fn() => static::isBsd(), - static::SOLARIS => fn() => static::isSolaris(), + private static array $detectors = [ + self::LINUX => fn() => self::isLinux(), + self::DARWIN => fn() => self::isDarwin(), + self::WINDOWS => fn() => self::isWindows(), + self::BSD => fn() => self::isBsd(), + self::SOLARIS => fn() => self::isSolaris(), ]; + /** + * Custom-defined mappings of platforms (keys) to detectors (values). + * + * These detectors will run _before_ the defaults. This way, you can + * specialize an available platform as a new platform, or prepend rules for + * detecting a platform. + */ + protected static array $customDetectors = []; + public static function autoDetect(): string { - foreach (self::$mapper as $platform => $isPlatform) { - if ($isPlatform()) { + foreach ( + static::$customDetectors + self::$detectors + as $platform => $detector + ) { + if ($detector()) { return $platform; } } - return static::UNKNOWN; + return self::UNKNOWN; } private static function isLinux(): bool From 0d4872299778316e6962745d04e25857a7e23b4a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 23:10:47 +0330 Subject: [PATCH 49/92] Add Android platform and provider example in Usage Guide page --- docs/en/usage-guide.md | 86 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 9 deletions(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index ea4f318..15d0478 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -1,27 +1,25 @@ # Usage Guide -**Note**: In the examples, the `use` statements are eliminated. +**Note:** In the examples, the `use` statements are eliminated. ## Overview of the Main Concepts Let's start with defining two important concepts: -- **(Directory) Provider**: A class providing the path of directories for one or more platforms. For instance, `LinuxDirectoryProvider` or `WindowsDirectoryProvider`. +- **(Directory) Provider:** A class providing the path of directories for one or more platforms. For instance, `LinuxDirectoryProvider` or `WindowsDirectoryProvider`. -- **(Directory) Provider Type**: An interface defining what a provider must implement. In other words, it specifies what directories must a provider provide the path of. It may be referred to as type. +- **(Directory) Provider Type:** An interface defining what a provider must implement. In other words, it specifies what directories must a provider provide the path of. It may be referred to as type. For example, `StandardDirectoryProvider` is a type enforcing providers to provide paths of directories available across (almost) all platforms. The term standard is in the context of the library, not a real standard or specification. You could call it `CrossPlatformDirectoryProvider` in your mind. In the examples above, Linux and Windows (and also Darwin) providers are all of standard type (i.e. implements `StandardDirectoryProvider` interface). -**Note**: Providers and provider types are under namespaces `PlatformSpecific` and `Type`, respectively. +**Note:** Providers and provider types are under namespaces `PlatformSpecific` and `Type`, respectively. ## Creating a Provider Object The main method to get a provider is via `DirectoryProviderFactory`. The other way is to instantiate the dedicated provider directly. -**Tip**: Want to target a specific platform? Each method has its benefits. The first one makes porting your application to other platforms easy. The second one enables you to use paths of platform-specific directories confidently. - ### Using `DirectoryProviderFactory` Static Class The class helps you creating provider of a specific type, for a specific platform. For example, let's create a standard provider for Darwin (e.g. Mac OS) platform: @@ -45,7 +43,7 @@ $dirProvider = DirectoryProviderFactory::create( ); ``` -**Note**: By default, only standard provider type mappings are defined. However, you may extend the types using `map*()` methods. +**Note:** By default, only standard provider type mappings are defined. To extend the functionality, see [Extending `DirectoryProviderFactory`](#extending-directoryproviderfactory). ### Instantiating Dedicated Provider @@ -55,6 +53,8 @@ Let's create a Linux provider directly: $dirProvider = new LinuxDirectoryProvider(); ``` +**Tip:** If you want to target a specific platform, both previous and current methods work. However, each has its benefits. The first one makes porting your application to other platforms more easily. The second one enables you to use paths of platform-specific directories more confidently. + ## Getting Path of Directories Based on which method you used to create a provider, you can use one of `get*Path()` methods to get path of a specific directory. @@ -71,10 +71,78 @@ If you instantiated a provider directly, e.g. Linux provider, you may use platfo $executables = $dirProvider->getExecutablesPath(); ``` -**Important Note**: The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative), because different users may have different needs. +**Important Note:** The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative), because different users may have different needs. ## Exception Handling All getter methods throw `PathNotFoundException` if the path cannot be built. There may be different reasons to this. For example, neither `%UserProfile%` nor `%HomeDrive%` environment variables defined on a Windows platform. -`DirectoryProviderFactory` class throws `Exception`s (library-defined) in certain conditions, like wrong input arguments, or a provider not set for the requested platform and type. +`DirectoryProviderFactory` class throws `Exception`s (library-defined) in certain conditions, like wrong input arguments, or a provider not set for the requested platform and type. + +## Extending `DirectoryProviderFactory` + +Using `map*()` methods, you could introduce new providers and types, map them to platforms, or even bring support for a new custom platform. + +### Example: Android Platform Support + +Let's say you want to make a standard provider for Android platform, and set `DirectoryProviderFactory` if the platform is Android. Here are the steps: + +1. **Make a New Provider.** Create a class and put your provider logic there. As your provider is of a standard type, you must implement it. You may use traits defined by Phirs, or extend one of the existing providers. + + ```php + use MAChitgarha\Phirs\Type; + use MAChitgarha\Phirs\Traits; + + class AndroidDirectoryProvider implements Type\StandardDirectoryProvider + { + use Traits\HomeBased\CommonPathProvider; + + public function getHomePath(): string + { + // Get the home directory, e.g. /sdcard + } + + // ... + } + ``` + +1. **Introduce A New Platform.** For `Platform::autoDetect()` to work, you have to define a new platform. Currently, the only method is the following: + + ```php + class MyPlatform extends MAChitgarha\Phirs\Util\Platform + { + public const ANDROID = 'Android'; + + protected static array $customDetectors = [ + self::ANDROID => fn() => self::isAndroid() + ]; + + private static function isAndroid(): bool + { + // Logic to determine whether current platform is Android or not + } + } + ``` + + **Note:**Don't forget to use `MyPlatform::autoDetect` `insteadof` `Platform`! + +1. **Map the Platform to the Provider.** + + ```php + DirectoryProviderFactory::mapStandard( + MyPlatform::ANDROID, + AndroidDirectoryProvider::class, + ); + ``` + +1. **Use It and Enjoy!** + + ```php + $dirProvider = DirectoryProviderFactory::createStandard( + MyPlatform::autoDetect() + ); + ``` + + Now, if Android platform is detected by your `MyPlatform::isAndroid()`, a class instance of `AndroidDirectoryProvider` will be returned. + + But hey, if you really did this, or something cool alike, don't forget to merge changes back! From 3746ff9ea0d846656d2eb6c5832b4ca70ef70f22 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 23:31:49 +0330 Subject: [PATCH 50/92] Add DirectoryProviderFactory::mapMany() --- src/DirectoryProviderFactory.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/DirectoryProviderFactory.php b/src/DirectoryProviderFactory.php index 8b637e7..7a067ad 100644 --- a/src/DirectoryProviderFactory.php +++ b/src/DirectoryProviderFactory.php @@ -114,6 +114,7 @@ private static function createInternal( public static function create(string $type, string $platform): object { self::validateType($type); + return self::createInternal($type, $platform); } @@ -156,9 +157,23 @@ public static function map( string $provider ): string { self::validateType($type); + return self::mapInternal($type, $platform, $provider); } + public static function mapMany( + string $type, + array $mapping + ): string { + self::validateType($type); + + foreach ($mapping as $platform => $provider) { + self::mapInternal($type, $platform, $provider); + } + + return self::class; + } + /** * Map a platform to a provider, for the standard provider type. * From 909d7b0217b123bf3e19d36f6d7fe28a4b71a0fc Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 23:37:39 +0330 Subject: [PATCH 51/92] Add Define a Custom Provider Type section in Usage Guide page --- docs/en/usage-guide.md | 66 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 15d0478..34de875 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -1,6 +1,6 @@ # Usage Guide -**Note:** In the examples, the `use` statements are eliminated. +**Note:** In the examples, some of the `use` statements are eliminated. ## Overview of the Main Concepts @@ -87,7 +87,7 @@ Using `map*()` methods, you could introduce new providers and types, map them to Let's say you want to make a standard provider for Android platform, and set `DirectoryProviderFactory` if the platform is Android. Here are the steps: -1. **Make a New Provider.** Create a class and put your provider logic there. As your provider is of a standard type, you must implement it. You may use traits defined by Phirs, or extend one of the existing providers. +1. **Create a New Provider.** Create a class and put your provider logic there. As your provider is of a standard type, you must implement it. You may use traits defined by Phirs, or extend one of the existing providers. ```php use MAChitgarha\Phirs\Type; @@ -146,3 +146,65 @@ Let's say you want to make a standard provider for Android platform, and set `Di Now, if Android platform is detected by your `MyPlatform::isAndroid()`, a class instance of `AndroidDirectoryProvider` will be returned. But hey, if you really did this, or something cool alike, don't forget to merge changes back! + +### Example: Define a Custom Provider Type + +Suppose you want to make a desktop application. The standard provider type is not appropriate, as there may be some desktop-centric directories you want to use. The best example is the `Desktop` directory. So, what you should do? + +The steps are simple: + +1. **Create Your Custom Provider Type.** Your type may extend other types as well. + + ```php + use MAChitgarha\Phirs\Type; + + interface DesktopDirectoryProvider extends Type\StandardDirectoryProvider + { + public function getDesktopPath(): string; + } + ``` + +1. **Create New Providers and Platforms, If Needed.** Refer to the previous example for more details. + +1. **Register Your Mappings.** Using `DirectoryProviderFactory::map()`, introduce your new type and map your providers to platforms. Obviously, all your providers must implement your type, otherwise `map()` will throw an exception. You can use static method chaining trick also: + + ```php + DirectoryProviderFactory + ::map( + DesktopDirectoryProvider::class, + MyPlatform::WINDOWS, + WindowsDirectoryProvider::class, + ) + ::map( + DesktopDirectoryProvider::class, + MyPlatform::MAC_OS, + MacOsDirectoryProvider::class, + ) + ::map( + DesktopDirectoryProvider::class, + MyPlatform::LINUX, + LinuxDirectoryProvider::class, + ) + ; + ``` + + Or shorter with `DirectoryProviderFactory::mapMany()`: + + ```php + DirectoryProviderFactory::mapMany(DesktopDirectoryProvider::class, [ + MyPlatform::WINDOWS => WindowsDirectoryProvider::class, + MyPlatform::MAC_OS => MacOsDirectoryProvider::class, + MyPlatform::LINUX => LinuxDirectoryProvider::class, + ]); + ``` + +1. **Use It and Enjoy!** + + ```php + $dirProvider = DirectoryProviderFactory::create( + DesktopDirectoryProvider::class, + MyPlatform::autoDetect(), + ); + ``` + + And again, if you did something look like this, we ask you to share your code with us! From 72357f839259af7d1b322607079285034fec75ce Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 23:51:56 +0330 Subject: [PATCH 52/92] Add Ready to Contribute Also section in Usage Guide page --- docs/en/usage-guide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 34de875..1704574 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -208,3 +208,9 @@ The steps are simple: ``` And again, if you did something look like this, we ask you to share your code with us! + +## Ready to Contribute Also? + +After reading this page, chances are you are ready to contribute, because it covers most of the knowledge in order to master the source code, although the code is tiny and simple. + +Hey... Where did you go? Oh, thanks for forking...! From c1ab58cc74f23f220a661dbadba18d64b4cc7f77 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Thu, 17 Feb 2022 23:59:44 +0330 Subject: [PATCH 53/92] Add Contribute! section in README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 516aca3..d028f11 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ $docsPath = $dirProvider->getDocumentsPath(); // Load or save something…! ``` -What a provider is? Why we use `createStandard`? Can I extend it and map a specific platform to my own provider? (Consider give your code back if you did it BTW.) See [Usage Guide](./docs/en/usage-guide.md) for more details. +What a provider is? Why we use `createStandard()`? Can I extend it and map a specific platform to my own provider? See [Usage Guide](./docs/en/usage-guide.md) for more details. ## Platform Support @@ -82,9 +82,11 @@ What a provider is? Why we use `createStandard`? Can I extend it and map a speci - It might not be exactly what you or users expect; e.g. pictures directory path is inside Termux home, not the internal SDCard (i.e. `/sdcard`). -### Fork and Improve It! +## Contribute! -By the way, if you can improve support for a specific platform, why not? +In a world like this, everyone should be a contributor. So, start helping this project by creating an issue, forking and improving it, or simply introducing it to your PHP developer friends! + +If you want to get an overall overview of the code, go and read [Usage Guide](#usage-guide). ## License From e8e1de5da05405fe5a2020eec222096d71eacf1a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 00:12:42 +0330 Subject: [PATCH 54/92] Improve README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d028f11..48809fc 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # Phirs -A library providing platform-specific user-accessible directory paths, such as config and cache. Inspired by [dirs-rs](https://github.com/dirs-dev/dirs-rs). +A library providing platform-specific user directory paths, such as config and cache. Inspired by [dirs-rs](https://github.com/dirs-dev/dirs-rs). ## Features -- **Multiple platform**. Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. +- **Multiple Platform**. Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. -- **Hackable**. Adding support for a specific platform [is easy](#). +- **Hackable**. Adding support for a specific platform [is easy](./docs/en/usage-guide#example-android-platform-support). -- **Well-designed**. Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). +- **Well-Designed**. Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). ## Why? @@ -19,9 +19,9 @@ When writing a console application (or even a graphical one; who knows, people m - create a media and put it somewhere reasonable, - etc. -For the best results, the location has to be cross-platform, permanent, accessible, well-known and non-relative. +For the best results, the locations has to be cross-platform, permanent, accessible, well-known and non-relative. -Phirs can to help you in these situations. +Phirs can help you in these situations. ### But There Is Another Library! @@ -68,19 +68,19 @@ What a provider is? Why we use `createStandard()`? Can I extend it and map a spe |GNU/Linux distributions|✅|✅|✅|✅| |Windows|✅|✅|✅|✅| |Mac OS|✅|✅|✅|✅| -|[Termux](https://termux.com) on Android|✅|✅|✅❕|❌| +|[Termux](https://termux.com) on Android|✅|✅|✅❕(1)|❌| |BSD|✅|❌|❔|❌| |Solaris|✅|❌|❔|❌| |Android|✅|❌|❓|❌| |iOS|✅|❌|❔|❌| -❕: Have notes. -❔: Not known or depends on the environment. -❓: Like ❔, but most likely no. +- ❕: Has notes. +- ❔: Not known or depends on the environment. +- ❓: Like ❔, but most likely no. ### Notes -- It might not be exactly what you or users expect; e.g. pictures directory path is inside Termux home, not the internal SDCard (i.e. `/sdcard`). +1. It might not be exactly what you or users expect; e.g. pictures directory path is inside Termux home, not the internal SDCard (i.e. `/sdcard`). ## Contribute! From 92356ed5d135f5bebe448603fd54a5d88d866816 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 00:28:30 +0330 Subject: [PATCH 55/92] Add Phan static analyzer as dev dependency --- .phan/config.php | 12 + composer.json | 3 + composer.lock | 1394 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 1407 insertions(+), 2 deletions(-) create mode 100644 .phan/config.php diff --git a/.phan/config.php b/.phan/config.php new file mode 100644 index 0000000..24b2ba3 --- /dev/null +++ b/.phan/config.php @@ -0,0 +1,12 @@ + '7.4', + 'directory_list' => [ + 'src/', + 'vendor/', + ], + 'exclude_analysis_directory_list' => [ + 'vendor/', + ], +]; diff --git a/composer.json b/composer.json index d7f5ac2..cf745d9 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,8 @@ "require": { "php": "^7.4|^8.0", "symfony/filesystem": "^6.0" + }, + "require-dev": { + "phan/phan": "^5.3" } } diff --git a/composer.lock b/composer.lock index 9b53dab..bd86ef8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2da05820156e306aa537dc1115b02d88", + "content-hash": "3a1b1ae51438eb2d3b18d3f73490b66f", "packages": [ { "name": "symfony/filesystem", @@ -235,7 +235,1397 @@ "time": "2021-11-30T18:21:41+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.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": "2022-01-21T20:24:37+00:00" + }, + { + "name": "composer/semver", + "version": "3.2.9", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.9" + }, + "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": "2022-02-04T13:58:43+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "12f1b79476638a5615ed00ea6adbb269cec96fd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/12f1b79476638a5615ed00ea6adbb269cec96fd8", + "reference": "12f1b79476638a5615ed00ea6adbb269cec96fd8", + "shasum": "" + }, + "require": { + "composer/pcre": "^1", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "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/3.0.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": "2022-01-04T18:29:42+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/6a965617cf484355048ac6d2d3de7b6ec93abb16", + "reference": "6a965617cf484355048ac6d2d3de7b6ec93abb16", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "support": { + "issues": "https://github.com/microsoft/tolerant-php-parser/issues", + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.1" + }, + "time": "2021-07-16T21:28:12+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + }, + "time": "2020-12-01T19:48:11+00:00" + }, + { + "name": "phan/phan", + "version": "5.3.2", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/b7697eb811e912c038f709f8e1c4911c7ada3edc", + "reference": "b7697eb811e912c038f709f8e1c4911c7ada3edc", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4|^2.0|^3.0", + "composer/xdebug-handler": "^2.0|^3.0", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "^0.1.0", + "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", + "php": "^7.2.0|^8.0.0", + "sabre/event": "^5.1.3", + "symfony/console": "^3.2|^4.0|^5.0|^6.0", + "symfony/polyfill-mbstring": "^1.11.0", + "symfony/polyfill-php80": "^1.20.0", + "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.", + "ext-var_representation": "Suggested for converting values to strings in issue messages" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static" + ], + "support": { + "issues": "https://github.com/phan/phan/issues", + "source": "https://github.com/phan/phan/tree/5.3.2" + }, + "time": "2022-02-01T00:17:36+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "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.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + }, + "time": "2022-01-04T19:58:01+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d7da22897125d34d7eddf7977758191c06a74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", + "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2021-11-04T06:51:17+00:00" + }, + { + "name": "symfony/console", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "22e8efd019c3270c4f79376234a3f8752cd25490" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/22e8efd019c3270c4f79376234a3f8752cd25490", + "reference": "22e8efd019c3270c4f79376234a3f8752cd25490", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.0.3" + }, + "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": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.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": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.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": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.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": "2021-09-13T13:58:33+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.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": "2021-11-04T17:53:12+00:00" + }, + { + "name": "symfony/string", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.3" + }, + "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": "2022-01-02T09:55:41+00:00" + }, + { + "name": "tysonandre/var_representation_polyfill", + "version": "0.1.1", + "source": { + "type": "git", + "url": "https://github.com/TysonAndre/var_representation_polyfill.git", + "reference": "0a942e74e18af5514749895507bc6ca7ab96399a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/0a942e74e18af5514749895507bc6ca7ab96399a", + "reference": "0a942e74e18af5514749895507bc6ca7ab96399a", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.2.0|^8.0.0" + }, + "require-dev": { + "phan/phan": "^4.0", + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-var_representation": "*" + }, + "type": "library", + "autoload": { + "files": [ + "src/var_representation.php" + ], + "psr-4": { + "VarRepresentation\\": "src/VarRepresentation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + } + ], + "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export", + "keywords": [ + "var_export", + "var_representation" + ], + "support": { + "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.1" + }, + "time": "2021-08-16T00:12:50+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], From af82f78319a64e79a0218f5777d5868bea00014c Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 01:12:57 +0330 Subject: [PATCH 56/92] Fix using arrow functions in initializers, improve Phan config --- .phan/config.php | 3 ++- docs/en/usage-guide.md | 2 +- src/Util/Platform.php | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.phan/config.php b/.phan/config.php index 24b2ba3..a3e8563 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -4,7 +4,8 @@ 'target_php_version' => '7.4', 'directory_list' => [ 'src/', - 'vendor/', + 'vendor/phan/phan/src/Phan', + 'vendor/symfony/filesystem' ], 'exclude_analysis_directory_list' => [ 'vendor/', diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 1704574..f0a9731 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -114,7 +114,7 @@ Let's say you want to make a standard provider for Android platform, and set `Di public const ANDROID = 'Android'; protected static array $customDetectors = [ - self::ANDROID => fn() => self::isAndroid() + self::ANDROID => [self::class, 'isAndroid'], ]; private static function isAndroid(): bool diff --git a/src/Util/Platform.php b/src/Util/Platform.php index f2f9415..86dd001 100644 --- a/src/Util/Platform.php +++ b/src/Util/Platform.php @@ -12,11 +12,11 @@ class Platform public const UNKNOWN = 'Unknown'; private static array $detectors = [ - self::LINUX => fn() => self::isLinux(), - self::DARWIN => fn() => self::isDarwin(), - self::WINDOWS => fn() => self::isWindows(), - self::BSD => fn() => self::isBsd(), - self::SOLARIS => fn() => self::isSolaris(), + self::LINUX => [self::class, 'isLinux'], + self::DARWIN => [self::class, 'isDarwin'], + self::WINDOWS => [self::class, 'isWindows'], + self::BSD => [self::class, 'isBsd'], + self::SOLARIS => [self::class, 'isSolaris'], ]; /** From 83783f705d386c8edb1a1569e9d6cc00d381ec3d Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 01:14:57 +0330 Subject: [PATCH 57/92] Fix some Path::returnNonEmpty() usages --- src/Traits/XdgBasedirSpec.php | 7 +++++-- src/Util/Path.php | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index baac432..b02e60d 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -4,7 +4,7 @@ use MAChitgarha\Phirs\Exception\PathNotFoundException; use MAChitgarha\Phirs\Util\Env; -use MAChitgarha\Phirs\Util\Util; +use MAChitgarha\Phirs\Util\Path; /** * @todo Make sure paths are absolute (non-relative), to match the spec better. @@ -71,7 +71,10 @@ public function getExecutablePath(): string public function getRuntimePath(): string { - return Util::returnNonNull(Env::get('XDG_RUNTIME_DIR')); + return Path::returnNonEmpty( + Env::get('XDG_RUNTIME_DIR'), + 'runtime directory' + ); } public function getConfigPathSet(): array diff --git a/src/Util/Path.php b/src/Util/Path.php index 0d40f37..54f78bb 100644 --- a/src/Util/Path.php +++ b/src/Util/Path.php @@ -11,10 +11,13 @@ class Path * * @param string $pathName Name of the directory the path belongs to. */ - public static function returnNonEmpty(?string $path, string $pathName): void - { + public static function returnNonEmpty( + ?string $path, + string $pathName + ): string { if ($path === null || $path === '') { throw new PathNotFoundException($pathName); } + return $path; } } From e0ac0ff9628d6e18a59bd2c75ff333dd43dc543d Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 01:33:56 +0330 Subject: [PATCH 58/92] Some fixes and improvemnts in directory providers and types --- src/PlatformSpecific/DarwinDirectoryProvider.php | 5 +++-- src/PlatformSpecific/WindowsDirectoryProvider.php | 1 + src/Type/CommonDirectoryProvider.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index 1857c32..422d189 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -13,10 +13,11 @@ class DarwinDirectoryProvider implements Type\StandardDirectoryProvider use Traits\UnixLikeHomePathProvider; use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; + use Traits\HomeBased\PublicPathProvider; use Traits\HomeBased\MoviesPathProvider { - MoviesPathProvider::getVideosPath insteadof CommonPathProvider; + Traits\HomeBased\MoviesPathProvider::getVideosPath insteadof + Traits\HomeBased\CommonPathProvider; } - use Traits\HomeBased\PublicPathProvider; private function getHomeLibraryChildPath(string ...$childPaths): string { diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index 65627df..4652011 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -10,6 +10,7 @@ class WindowsDirectoryProvider implements Type\StandardDirectoryProvider { + use Traits\HomeChildPathProvider; use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; use Traits\HomeBased\PublicPathProvider; diff --git a/src/Type/CommonDirectoryProvider.php b/src/Type/CommonDirectoryProvider.php index a06ffc1..52472a4 100644 --- a/src/Type/CommonDirectoryProvider.php +++ b/src/Type/CommonDirectoryProvider.php @@ -5,7 +5,7 @@ /** * Provide common well-known paths for storing media files, documents, etc. */ -class CommonDirectoryProvider +interface CommonDirectoryProvider { public function getDocumentsPath(): string; public function getDownloadsPath(): string; From 30ed5015646e553aec05c097df1ae554982b8016 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 13:48:43 +0330 Subject: [PATCH 59/92] Introduce HomeChildPathProvider trait to user in Usage Guide page It will be useful in certain circumstances. --- docs/en/usage-guide.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index f0a9731..7af554a 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -95,6 +95,7 @@ Let's say you want to make a standard provider for Android platform, and set `Di class AndroidDirectoryProvider implements Type\StandardDirectoryProvider { + use Traits\HomeChildPathProvider; use Traits\HomeBased\CommonPathProvider; public function getHomePath(): string @@ -102,6 +103,12 @@ Let's say you want to make a standard provider for Android platform, and set `Di // Get the home directory, e.g. /sdcard } + public function getCameraPath(): string + { + // Using trait HomeChildPathProvider + return $this->getHomeChildPath('DCIM', 'Camera'); + } + // ... } ``` From 2d81bbbb834326f5ed56e07d0c755d05053e77e6 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 13:50:13 +0330 Subject: [PATCH 60/92] Remove LinuxDirectoryProvider::getExecutablesPath(), other improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because it is a duplicate of Traits\XdgBasedirSpec::getExec…Path(). --- docs/en/usage-guide.md | 2 +- src/PlatformSpecific/DarwinDirectoryProvider.php | 1 + src/PlatformSpecific/LinuxDirectoryProvider.php | 5 ----- src/Traits/UnixLikeHomePathProvider.php | 2 -- src/Traits/XdgBasedirSpec.php | 1 + 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 7af554a..9aa5484 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -171,7 +171,7 @@ The steps are simple: } ``` -1. **Create New Providers and Platforms, If Needed.** Refer to the previous example for more details. +1. **Create New Providers and Platforms, If Needed.** Refer to the previous example for more details. You can use already-defined traits like `DesktopPathProvider`. 1. **Register Your Mappings.** Using `DirectoryProviderFactory::map()`, introduce your new type and map your providers to platforms. Obviously, all your providers must implement your type, otherwise `map()` will throw an exception. You can use static method chaining trick also: diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index 422d189..3914c39 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -11,6 +11,7 @@ class DarwinDirectoryProvider implements Type\StandardDirectoryProvider { use Traits\UnixLikeHomePathProvider; + use Traits\HomeChildPathProvider; use Traits\HomeBased\CommonPathProvider; use Traits\HomeBased\DesktopPathProvider; use Traits\HomeBased\PublicPathProvider; diff --git a/src/PlatformSpecific/LinuxDirectoryProvider.php b/src/PlatformSpecific/LinuxDirectoryProvider.php index f95ab84..db68d5a 100644 --- a/src/PlatformSpecific/LinuxDirectoryProvider.php +++ b/src/PlatformSpecific/LinuxDirectoryProvider.php @@ -18,9 +18,4 @@ public function getFontsPath(): string { return Path::join($this->getDataPath(), 'fonts'); } - - public function getExecutablesPath(): string - { - return $this->getHomeChildPath('.local', 'bin'); - } } diff --git a/src/Traits/UnixLikeHomePathProvider.php b/src/Traits/UnixLikeHomePathProvider.php index be02c4f..97654d6 100644 --- a/src/Traits/UnixLikeHomePathProvider.php +++ b/src/Traits/UnixLikeHomePathProvider.php @@ -7,8 +7,6 @@ trait UnixLikeHomePathProvider { - use HomeChildPathProvider; - public function getHomePath(): string { return Path::returnNonEmpty( diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index b02e60d..748d9b5 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -12,6 +12,7 @@ trait XdgBasedirSpec { use UnixLikeHomePathProvider; + use HomeChildPathProvider; private function getEnvOrHomeChildPath( string $envName, From 3b43833ae8f91b5f3945c7309d74ade3b055a0ca Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 14:10:34 +0330 Subject: [PATCH 61/92] Add PHPUnit as dev dependency, make PHP 8.0 required for require-dev --- composer.json | 4 +- composer.lock | 2115 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 1957 insertions(+), 162 deletions(-) diff --git a/composer.json b/composer.json index cf745d9..b30dea7 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,8 @@ "symfony/filesystem": "^6.0" }, "require-dev": { - "phan/phan": "^5.3" + "php": "^8.0", + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5" } } diff --git a/composer.lock b/composer.lock index bd86ef8..3de69b2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3a1b1ae51438eb2d3b18d3f73490b66f", + "content-hash": "cea6271461eeb4e504dddc63d41d246f", "packages": [ { "name": "symfony/filesystem", @@ -454,6 +454,75 @@ ], "time": "2022-01-04T18:29:42+00:00" }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "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" + }, { "name": "felixfbecker/advanced-json-rpc", "version": "v3.2.1", @@ -544,6 +613,61 @@ }, "time": "2021-07-16T21:28:12+00:00" }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "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" + }, { "name": "netresearch/jsonmapper", "version": "v4.0.0", @@ -595,6 +719,62 @@ }, "time": "2020-12-01T19:48:11+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.13.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + }, + "time": "2021-11-30T19:35:32+00:00" + }, { "name": "phan/phan", "version": "5.3.2", @@ -674,6 +854,117 @@ }, "time": "2022-02-01T00:17:36+00:00" }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "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/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "15a90844ad40f127afd244c0cad228de2a80052a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a", + "reference": "15a90844ad40f127afd244c0cad228de2a80052a", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.1" + }, + "time": "2022-02-07T21:56:48+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -689,319 +980,1771 @@ "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "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.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + }, + "time": "2022-01-04T19:58:01+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-05T09:12:13+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "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" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "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" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "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" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.13", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "597cb647654ede35e43b137926dfdfef0fb11743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", + "reference": "597cb647654ede35e43b137926dfdfef0fb11743", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3.4", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-01-24T07:33:35+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d7da22897125d34d7eddf7977758191c06a74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", + "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2021-11-04T06:51:17+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/comparator", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "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" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "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" + }, + { + "name": "sebastian/environment", + "version": "5.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "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" + }, + { + "name": "sebastian/exporter", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T14:18:36+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, - "time": "2020-06-27T09:03:43+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "name": "sebastian/object-reflector", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" + "php": ">=7.3" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, - "time": "2021-10-19T17:43:47+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "1.6.0", + "name": "sebastian/recursion-context", + "version": "4.0.4", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "php": ">=7.3" }, "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" }, - "time": "2022-01-04T19:58:01+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" }, { - "name": "psr/container", - "version": "2.0.2", + "name": "sebastian/resource-operations", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], + "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/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" }, - "time": "2021-11-05T16:47:00+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" }, { - "name": "psr/log", - "version": "3.0.0", + "name": "sebastian/type", + "version": "2.3.4", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", "shasum": "" }, "require": { - "php": ">=8.0.0" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "2.3-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" }, - "time": "2021-07-14T16:46:02+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-15T12:49:02+00:00" }, { - "name": "sabre/event", - "version": "5.1.4", + "name": "sebastian/version", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sabre-io/event.git", - "reference": "d7da22897125d34d7eddf7977758191c06a74497" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", - "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + "php": ">=7.3" }, "type": "library", - "autoload": { - "files": [ - "lib/coroutine.php", - "lib/Loop/functions.php", - "lib/Promise/functions.php" - ], - "psr-4": { - "Sabre\\Event\\": "lib/" + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "sabre/event is a library for lightweight event-based programming", - "homepage": "http://sabre.io/event/", - "keywords": [ - "EventEmitter", - "async", - "coroutine", - "eventloop", - "events", - "hooks", - "plugin", - "promise", - "reactor", - "signal" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/event/issues", - "source": "https://github.com/fruux/sabre-event" + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, - "time": "2021-11-04T06:51:17+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" }, { "name": "symfony/console", @@ -1513,6 +3256,56 @@ ], "time": "2022-01-02T09:55:41+00:00" }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, { "name": "tysonandre/var_representation_polyfill", "version": "0.1.1", From a74ea9731d234d98e32ff59c0acef6734c8c3908 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 16:01:03 +0330 Subject: [PATCH 62/92] Make DarwinDirectoryProvider::getApplicationSupportPath() public --- src/PlatformSpecific/DarwinDirectoryProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index 3914c39..f03c709 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -30,7 +30,7 @@ public function getCachePath(): string return $this->getHomeLibraryChildPath('Caches'); } - private function getApplicationSupportPath(): string + public function getApplicationSupportPath(): string { return $this->getHomeLibraryChildPath('Application Support'); } From c9f0c339edfbf2ae2244a7109b600580cd2d8c51 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 16:21:21 +0330 Subject: [PATCH 63/92] Add a note in Why section about location paths conditions --- README.md | 4 +++- docs/en/usage-guide.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 48809fc..835127d 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,12 @@ When writing a console application (or even a graphical one; who knows, people m - create a media and put it somewhere reasonable, - etc. -For the best results, the locations has to be cross-platform, permanent, accessible, well-known and non-relative. +For the best results, the locations should be cross-platform, permanent, accessible, well-known and non-relative. Phirs can help you in these situations. +**Note:** The library does not guarantee that all provided paths meet all the conditions above, although it helps you achieving them; because of performance, and the fact that different users may have different needs (e.g. one may check for a path to exist, one may suppose it to exist). Theoretically, in a standard environment, all these conditions are met. + ### But There Is Another Library! Why not just using [Basedir](https://github.com/clue-labs/php-basedir)? diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 9aa5484..69f0224 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -71,7 +71,7 @@ If you instantiated a provider directly, e.g. Linux provider, you may use platfo $executables = $dirProvider->getExecutablesPath(); ``` -**Important Note:** The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative), because different users may have different needs. +**Important Note:** The returning paths are not checked to exist, be accessible (readable or writeable), or be absolute (i.e. not relative). ## Exception Handling From 023ff55fb28283384007a3c5727b3be232c788af Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 20:59:53 +0330 Subject: [PATCH 64/92] Add unit test for providers of all platforms Checking the paths being non-empty, existing, accessible (i.e. readable and writable), and absolute. --- composer.json | 3 +- phpunit.xml.dist | 7 +++ .../DarwinDirectoryProviderTest.php | 48 +++++++++++++++++ .../LinuxDirectoryProviderTest.php | 51 +++++++++++++++++++ .../Traits/IsAbsoluteAsserter.php | 15 ++++++ .../Traits/ProviderGetter.php | 11 ++++ .../Traits/ProviderPathTester.php | 47 +++++++++++++++++ .../WindowsDirectoryProviderTest.php | 47 +++++++++++++++++ 8 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 phpunit.xml.dist create mode 100644 tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php create mode 100644 tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php create mode 100644 tests/unit/PlatformSpecific/Traits/IsAbsoluteAsserter.php create mode 100644 tests/unit/PlatformSpecific/Traits/ProviderGetter.php create mode 100644 tests/unit/PlatformSpecific/Traits/ProviderPathTester.php create mode 100644 tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php diff --git a/composer.json b/composer.json index b30dea7..18d8f3c 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ ], "autoload": { "psr-4": { - "MAChitgarha\\Phirs\\": "src/" + "MAChitgarha\\Phirs\\": "src/", + "MAChitgarha\\Phirs\\Test\\Unit\\": "tests/unit" } }, "require": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..0f74fac --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,7 @@ + + + + tests/unit + + + diff --git a/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php new file mode 100644 index 0000000..9c3c1ff --- /dev/null +++ b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php @@ -0,0 +1,48 @@ +$pathGetter(); + + $this->assertNotEmpty($path); + $this->assertDirectoryExists($path); + $this->assertIsReadable($path); + $this->assertIsWritable($path); + $this->assertIsAbsolute($path); + } + } +} diff --git a/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php b/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php new file mode 100644 index 0000000..aae016d --- /dev/null +++ b/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php @@ -0,0 +1,47 @@ + Date: Fri, 18 Feb 2022 21:01:54 +0330 Subject: [PATCH 65/92] Ignore PHPUnit cache files, include tests in Phan config --- .gitignore | 3 +++ .phan/config.php | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 57872d0..7e16f06 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /vendor/ + +# Caches +/.phpunit.result.cache diff --git a/.phan/config.php b/.phan/config.php index a3e8563..b9c8535 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -4,8 +4,10 @@ 'target_php_version' => '7.4', 'directory_list' => [ 'src/', + 'tests/unit', 'vendor/phan/phan/src/Phan', - 'vendor/symfony/filesystem' + 'vendor/symfony/filesystem', + 'vendor/phpunit/phpunit', ], 'exclude_analysis_directory_list' => [ 'vendor/', From 9677cd957c1ab3596b1810922528c53bf2534cad Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 21:27:37 +0330 Subject: [PATCH 66/92] Remove assertion of providers returning path of existing directories A directory, although being standard, might not avaiable, even in a clean environment. So, make it if not exists. Improve README.md also. --- README.md | 4 ++-- .../Traits/ProviderPathTester.php | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 835127d..b4f9f9d 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ When writing a console application (or even a graphical one; who knows, people m - create a media and put it somewhere reasonable, - etc. -For the best results, the locations should be cross-platform, permanent, accessible, well-known and non-relative. +For the best results, the locations should be cross-platform, permanent, accessible (i.e. both readable and writable), well-known and non-relative. Phirs can help you in these situations. -**Note:** The library does not guarantee that all provided paths meet all the conditions above, although it helps you achieving them; because of performance, and the fact that different users may have different needs (e.g. one may check for a path to exist, one may suppose it to exist). Theoretically, in a standard environment, all these conditions are met. +**Note:** The library does not guarantee that all provided paths meet all the conditions above, although it helps you achieving them. The reason is performance, and the fact that different users may have different needs (e.g. one may check for a path to exist, one may suppose it to exist). Theoretically, in a standard environment and for standard paths, all these conditions are met (although the directories might not actually exist). ### But There Is Another Library! diff --git a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php index 94902f3..0573c26 100644 --- a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php +++ b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php @@ -14,21 +14,19 @@ abstract private static function getPathGetterMethods(): array; // PHPUnit TestCase methods abstract public static function assertNotEmpty($path): void; - abstract public static function assertDirectoryExists(string $path): void; abstract public static function assertIsReadable(string $path): void; abstract public static function assertIsWritable(string $path): void; // Custom-defined abstract public static function assertIsAbsolute(string $path): void; - /** * Test if the provider's path getter methods return a good path. * - * A good path must be non-empty, existing, readable, writable, and - * absolute. We suppose the tests are done in a clean and standard - * environments, so the conditions must be met. However, Phirs by default - * does not check these in its logic. + * A proper path must be non-empty, absolute, readable and writable. We + * We suppose the tests are done in a clean and standard environments, so + * the conditions must be met. Note that, however, Phirs by default does + * not check these in its logic. */ public function testProviderPaths(): void { @@ -38,10 +36,18 @@ public function testProviderPaths(): void $path = $provider->$pathGetter(); $this->assertNotEmpty($path); - $this->assertDirectoryExists($path); + $this->assertIsAbsolute($path); + + $this->makeDirectoryIfNotExists($path); $this->assertIsReadable($path); $this->assertIsWritable($path); - $this->assertIsAbsolute($path); + } + } + + private function makeDirectoryIfNotExists(string $path): void + { + if (!\is_dir($path) && !\mkdir($path, 0700, true)) { + throw new \Exception("Cannot make directory '$path'"); } } } From 5058c605a85eca2e744778684694b9ee055439e2 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 22:28:47 +0330 Subject: [PATCH 67/92] Add a test to modify XDG_* environment variables (Linux-only) Other improvements also. --- src/Traits/XdgBasedirSpec.php | 2 +- tests/unit/CustomEnv/XdgEnvTest.php | 63 +++++++++++++++++++ tests/unit/GlobalTraits/PlatformChecker.php | 37 +++++++++++ .../DarwinDirectoryProviderTest.php | 6 +- .../LinuxDirectoryProviderTest.php | 6 +- .../WindowsDirectoryProviderTest.php | 6 +- 6 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 tests/unit/CustomEnv/XdgEnvTest.php create mode 100644 tests/unit/GlobalTraits/PlatformChecker.php diff --git a/src/Traits/XdgBasedirSpec.php b/src/Traits/XdgBasedirSpec.php index 748d9b5..c55e656 100644 --- a/src/Traits/XdgBasedirSpec.php +++ b/src/Traits/XdgBasedirSpec.php @@ -87,6 +87,6 @@ public function getConfigPathSet(): array public function getDataPathSet(): array { return Env::getColonedArray('XDG_DATA_DIRS') ?? - ['/usr/local/share/', '/usr/share/']; + ['/usr/local/share', '/usr/share']; } } diff --git a/tests/unit/CustomEnv/XdgEnvTest.php b/tests/unit/CustomEnv/XdgEnvTest.php new file mode 100644 index 0000000..4599f26 --- /dev/null +++ b/tests/unit/CustomEnv/XdgEnvTest.php @@ -0,0 +1,63 @@ +assertEquals( + $envValue, + self::$provider->$pathGetterMethod(), + ); + } + } + + public function testMultiValueEnvs(): void + { + foreach ([ + ['XDG_CONFIG_DIRS', '/etc:/tmp/etc', 'getConfigPathSet'], + ['XDG_DATA_DIRS', '/var/local/share:/tmp/share', 'getDataPathSet'], + ] as [$envName, $envValue, $pathGetterMethod]) { + + \putenv("$envName=$envValue"); + + $this->assertEquals( + $envValue, + \join(':', self::$provider->$pathGetterMethod()), + ); + } + } +} diff --git a/tests/unit/GlobalTraits/PlatformChecker.php b/tests/unit/GlobalTraits/PlatformChecker.php new file mode 100644 index 0000000..549108d --- /dev/null +++ b/tests/unit/GlobalTraits/PlatformChecker.php @@ -0,0 +1,37 @@ + Date: Fri, 18 Feb 2022 22:35:59 +0330 Subject: [PATCH 68/92] Add a test for unix-like $HOME env --- tests/unit/CustomEnv/UnixLikeHomeEnvTest.php | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/unit/CustomEnv/UnixLikeHomeEnvTest.php diff --git a/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php new file mode 100644 index 0000000..909b257 --- /dev/null +++ b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php @@ -0,0 +1,39 @@ +assertEquals($envValue, self::$provider->getHomePath()); + } +} From bae3743976c385932a6c69cc3b81c4933c59cbec Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 23:28:30 +0330 Subject: [PATCH 69/92] Add WindowsEnvTest, some code improvements --- .../WindowsDirectoryProvider.php | 4 +- tests/unit/CustomEnv/WindowsEnvTest.php | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/unit/CustomEnv/WindowsEnvTest.php diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index 4652011..ed52c13 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -32,9 +32,7 @@ private function getHomeDriveHomePath(): ?string Env::get('HomePath'), ], fn(?string $carry, ?string $item) => - is_null($carry) || is_null($item) ? null : - SymfonyPath::join($carry, $item), - // Prevent from halting at the very beginning + is_null($item) ? null : SymfonyPath::join($carry, $item), '' ); } diff --git a/tests/unit/CustomEnv/WindowsEnvTest.php b/tests/unit/CustomEnv/WindowsEnvTest.php new file mode 100644 index 0000000..e0f3209 --- /dev/null +++ b/tests/unit/CustomEnv/WindowsEnvTest.php @@ -0,0 +1,40 @@ +assertEquals( + $envValue, + self::$provider->$pathGetterMethod(), + ); + } + } +} From 06f630934ea540b9a771b05be555b2c17d4877cf Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 23:34:34 +0330 Subject: [PATCH 70/92] Enable colors for Phan by default --- .phan/config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/.phan/config.php b/.phan/config.php index b9c8535..fdfea27 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -12,4 +12,5 @@ 'exclude_analysis_directory_list' => [ 'vendor/', ], + 'color_issue_messages_if_supported' => true, ]; From 52c59fa4746ff7ef720bfb37c5b94c8d99fadff0 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Fri, 18 Feb 2022 23:37:15 +0330 Subject: [PATCH 71/92] Revert a code improvement causing wrong home path for Windows --- src/PlatformSpecific/WindowsDirectoryProvider.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/PlatformSpecific/WindowsDirectoryProvider.php b/src/PlatformSpecific/WindowsDirectoryProvider.php index ed52c13..dd5ea23 100644 --- a/src/PlatformSpecific/WindowsDirectoryProvider.php +++ b/src/PlatformSpecific/WindowsDirectoryProvider.php @@ -31,8 +31,9 @@ private function getHomeDriveHomePath(): ?string Env::get('HomeDrive'), Env::get('HomePath'), ], - fn(?string $carry, ?string $item) => - is_null($item) ? null : SymfonyPath::join($carry, $item), + fn(string $carry, ?string $item) => + is_null($carry) || is_null($item) ? null : + SymfonyPath::join($carry, $item), '' ); } From fbff54bd5a8c3ef68d2aedf9d3a6c3acb0692d0c Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 00:11:23 +0330 Subject: [PATCH 72/92] Suppress a wrong Phan error, remove tests/ Phan analysis The src/ is the important part. Errors leaving in tests/unit will eventually be caught either when running them (using PHPUnit), or in a CI/CD workflow. --- .phan/config.php | 2 -- src/PlatformSpecific/DarwinDirectoryProvider.php | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.phan/config.php b/.phan/config.php index fdfea27..d0cdcb6 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -4,10 +4,8 @@ 'target_php_version' => '7.4', 'directory_list' => [ 'src/', - 'tests/unit', 'vendor/phan/phan/src/Phan', 'vendor/symfony/filesystem', - 'vendor/phpunit/phpunit', ], 'exclude_analysis_directory_list' => [ 'vendor/', diff --git a/src/PlatformSpecific/DarwinDirectoryProvider.php b/src/PlatformSpecific/DarwinDirectoryProvider.php index f03c709..d124fde 100644 --- a/src/PlatformSpecific/DarwinDirectoryProvider.php +++ b/src/PlatformSpecific/DarwinDirectoryProvider.php @@ -17,6 +17,7 @@ class DarwinDirectoryProvider implements Type\StandardDirectoryProvider use Traits\HomeBased\PublicPathProvider; use Traits\HomeBased\MoviesPathProvider { Traits\HomeBased\MoviesPathProvider::getVideosPath insteadof + // @phan-suppress-next-line PhanRequiredTraitNotAdded Traits\HomeBased\CommonPathProvider; } From 7d10999fd78d06fcca7921b3242dfa7fb753d144 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 00:13:38 +0330 Subject: [PATCH 73/92] Fix a missing function argument, convert assert{Equals->Same}() --- tests/unit/CustomEnv/UnixLikeHomeEnvTest.php | 2 +- tests/unit/CustomEnv/WindowsEnvTest.php | 2 +- tests/unit/CustomEnv/XdgEnvTest.php | 4 ++-- tests/unit/GlobalTraits/PlatformChecker.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php index 909b257..f3bac1b 100644 --- a/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php +++ b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php @@ -34,6 +34,6 @@ public function test(): void \putenv("$envName=$envValue"); - $this->assertEquals($envValue, self::$provider->getHomePath()); + $this->assertSame($envValue, self::$provider->getHomePath()); } } diff --git a/tests/unit/CustomEnv/WindowsEnvTest.php b/tests/unit/CustomEnv/WindowsEnvTest.php index e0f3209..dcc5b5d 100644 --- a/tests/unit/CustomEnv/WindowsEnvTest.php +++ b/tests/unit/CustomEnv/WindowsEnvTest.php @@ -31,7 +31,7 @@ public function test(): void \putenv("$envName=$envValue"); - $this->assertEquals( + $this->assertSame( $envValue, self::$provider->$pathGetterMethod(), ); diff --git a/tests/unit/CustomEnv/XdgEnvTest.php b/tests/unit/CustomEnv/XdgEnvTest.php index 4599f26..385bb6f 100644 --- a/tests/unit/CustomEnv/XdgEnvTest.php +++ b/tests/unit/CustomEnv/XdgEnvTest.php @@ -38,7 +38,7 @@ public function testSingleValueEnvs(): void \putenv("$envName=$envValue"); - $this->assertEquals( + $this->assertSame( $envValue, self::$provider->$pathGetterMethod(), ); @@ -54,7 +54,7 @@ public function testMultiValueEnvs(): void \putenv("$envName=$envValue"); - $this->assertEquals( + $this->assertSame( $envValue, \join(':', self::$provider->$pathGetterMethod()), ); diff --git a/tests/unit/GlobalTraits/PlatformChecker.php b/tests/unit/GlobalTraits/PlatformChecker.php index 549108d..27f01f0 100644 --- a/tests/unit/GlobalTraits/PlatformChecker.php +++ b/tests/unit/GlobalTraits/PlatformChecker.php @@ -6,7 +6,7 @@ trait PlatformChecker { - abstract public static function markTestSkipped(): void; + abstract public static function markTestSkipped(string $message): void; /** * Skips the test if the current platform is not among supported platforms. From 97798ca15fbf92e2813c04563c5595f5a3a721c6 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 00:37:21 +0330 Subject: [PATCH 74/92] Improve extensibility of Platform class Previously, a property is used to get custom detectors. Change it to a static protected function, as it is more flexible and does not require constant expressions, e.g. you can use arrow functions in it. Update documentation also. --- docs/en/usage-guide.md | 7 ++++--- src/Util/Platform.php | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/en/usage-guide.md b/docs/en/usage-guide.md index 69f0224..f556995 100644 --- a/docs/en/usage-guide.md +++ b/docs/en/usage-guide.md @@ -120,9 +120,10 @@ Let's say you want to make a standard provider for Android platform, and set `Di { public const ANDROID = 'Android'; - protected static array $customDetectors = [ - self::ANDROID => [self::class, 'isAndroid'], - ]; + protected static function getCustomDetectors(): array + { + return [self::ANDROID => fn() => self::isAndroid()]; + } private static function isAndroid(): bool { diff --git a/src/Util/Platform.php b/src/Util/Platform.php index 86dd001..163621e 100644 --- a/src/Util/Platform.php +++ b/src/Util/Platform.php @@ -26,12 +26,15 @@ class Platform * specialize an available platform as a new platform, or prepend rules for * detecting a platform. */ - protected static array $customDetectors = []; + protected static function getCustomDetectors(): array + { + return []; + } public static function autoDetect(): string { foreach ( - static::$customDetectors + self::$detectors + static::getCustomDetectors() + self::$detectors as $platform => $detector ) { if ($detector()) { From b61014e741e6ef830d487e57479592b143c9f561 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 00:52:53 +0330 Subject: [PATCH 75/92] Add a test for extending the class Platform --- tests/unit/Util/PlatformTest.php | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/unit/Util/PlatformTest.php diff --git a/tests/unit/Util/PlatformTest.php b/tests/unit/Util/PlatformTest.php new file mode 100644 index 0000000..a4b06ee --- /dev/null +++ b/tests/unit/Util/PlatformTest.php @@ -0,0 +1,50 @@ + fn() => true]; + } + }; + + $this->assertSame($myPlatform->autoDetect(), $myPlatform::UNKNOWN); + } + + public function testDefaultDetectorAsFallback(): void + { + $currentPlatform = Platform::autoDetect(); + + $myPlatform = new class extends Platform { + protected static function getCustomDetectors(): array + { + global $currentPlatform; + return [$currentPlatform => fn() => false]; + } + }; + + $this->assertSame($myPlatform->autoDetect(), $currentPlatform); + } + + public function testCustomPlatform(): void + { + $myPlatform = new class extends Platform { + public const MINIX = 'Minix'; + + protected static function getCustomDetectors(): array + { + return [self::MINIX => fn() => true]; + } + }; + + $this->assertSame($myPlatform->autoDetect(), $myPlatform::MINIX); + } +} From c5a202998e4e77409d2d3867c3f3258f89a22b65 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 02:32:02 +0330 Subject: [PATCH 76/92] Use data providers for testing path getters instead of manual loop --- .../DarwinDirectoryProviderTest.php | 46 +++++++++--------- .../LinuxDirectoryProviderTest.php | 48 +++++++++---------- .../Traits/ProviderPathTester.php | 27 ++++++----- .../WindowsDirectoryProviderTest.php | 44 ++++++++--------- 4 files changed, 83 insertions(+), 82 deletions(-) diff --git a/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php index dfa11ed..dcdbb63 100644 --- a/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php @@ -16,33 +16,33 @@ class DarwinDirectoryProviderTest extends TestCase private static DarwinDirectoryProvider $provider; - private static function getPathGetterMethods(): array - { - return [ - 'getHomePath', - - 'getApplicationSupportPath', - 'getCachePath', - 'getConfigPath', - 'getDataPath', - 'getPreferencesPath', - - 'getDesktopPath', - 'getDocumentsPath', - 'getDownloadsPath', - 'getFontsPath', - 'getMoviesPath', - 'getMusicPath', - 'getPicturesPath', - 'getPublicPath', - 'getVideosPath', - ]; - } - public static function setUpBeforeClass(): void { self::skipIfPlatformUnsupported(Platform::DARWIN); self::$provider = new DarwinDirectoryProvider(); } + + public static function pathGetterMethodNameProvider(): array + { + return [ + ['getHomePath'], + + ['getApplicationSupportPath'], + ['getCachePath'], + ['getConfigPath'], + ['getDataPath'], + ['getPreferencesPath'], + + ['getDesktopPath'], + ['getDocumentsPath'], + ['getDownloadsPath'], + ['getFontsPath'], + ['getMoviesPath'], + ['getMusicPath'], + ['getPicturesPath'], + ['getPublicPath'], + ['getVideosPath'], + ]; + } } diff --git a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php index e6be116..07533c7 100644 --- a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php @@ -16,30 +16,6 @@ class LinuxDirectoryProviderTest extends TestCase private static LinuxDirectoryProvider $provider; - private static function getPathGetterMethods(): array - { - return [ - 'getHomePath', - - 'getExecutablePath', - 'getCachePath', - 'getConfigPath', - 'getDataPath', - 'getStatePath', - 'getRuntimePath', - - 'getDesktopPath', - 'getDocumentsPath', - 'getDownloadsPath', - 'getFontsPath', - 'getMusicPath', - 'getPicturesPath', - 'getPublicPath', - 'getTemplatesPath', - 'getVideosPath', - ]; - } - public static function setUpBeforeClass(): void { self::skipIfPlatformUnsupported(Platform::LINUX); @@ -47,5 +23,29 @@ public static function setUpBeforeClass(): void self::$provider = new LinuxDirectoryProvider(); } + public static function pathGetterMethodNameProvider(): array + { + return [ + ['getHomePath'], + + ['getExecutablePath'], + ['getCachePath'], + ['getConfigPath'], + ['getDataPath'], + ['getStatePath'], + ['getRuntimePath'], + + ['getDesktopPath'], + ['getDocumentsPath'], + ['getDownloadsPath'], + ['getFontsPath'], + ['getMusicPath'], + ['getPicturesPath'], + ['getPublicPath'], + ['getTemplatesPath'], + ['getVideosPath'], + ]; + } + // TODO: Test get*PathSet() as well } diff --git a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php index 0573c26..b4391cf 100644 --- a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php +++ b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php @@ -7,10 +7,12 @@ trait ProviderPathTester abstract private static function getProvider(): object; /** - * Returns the names of path getter methods of the provider. - * @return array An array of function names (i.e. strings). + * Provide the names of path getter methods of the directory provider. + * + * Do not confuse the term provider in the end with providers in Phirs. This + * is a PHPUnit data provider. */ - abstract private static function getPathGetterMethods(): array; + abstract public static function pathGetterMethodNameProvider(): array; // PHPUnit TestCase methods abstract public static function assertNotEmpty($path): void; @@ -27,21 +29,20 @@ abstract public static function assertIsAbsolute(string $path): void; * We suppose the tests are done in a clean and standard environments, so * the conditions must be met. Note that, however, Phirs by default does * not check these in its logic. + * + * @dataProvider pathGetterMethodNameProvider */ - public function testProviderPaths(): void + public function testProviderPath(string $pathGetter): void { - $provider = self::getProvider(); + $path = self::getProvider()->$pathGetter(); - foreach (self::getPathGetterMethods() as $pathGetter) { - $path = $provider->$pathGetter(); + $this->assertNotEmpty($path); + $this->assertIsAbsolute($path); - $this->assertNotEmpty($path); - $this->assertIsAbsolute($path); + $this->makeDirectoryIfNotExists($path); - $this->makeDirectoryIfNotExists($path); - $this->assertIsReadable($path); - $this->assertIsWritable($path); - } + $this->assertIsReadable($path); + $this->assertIsWritable($path); } private function makeDirectoryIfNotExists(string $path): void diff --git a/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php b/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php index b6c0220..c2cf068 100644 --- a/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/WindowsDirectoryProviderTest.php @@ -16,32 +16,32 @@ class WindowsDirectoryProviderTest extends TestCase private static WindowsDirectoryProvider $provider; - private static function getPathGetterMethods(): array - { - return [ - 'getHomePath', - - 'getCachePath', - 'getConfigPath', - 'getDataPath', - 'getLocalDataPath', - 'getTemporaryPath', - - 'getDesktopPath', - 'getDocumentsPath', - 'getDownloadsPath', - 'getMusicPath', - 'getPicturesPath', - 'getPublicPath', - 'getTemplatesPath', - 'getVideosPath', - ]; - } - public static function setUpBeforeClass(): void { self::skipIfPlatformUnsupported(Platform::WINDOWS); self::$provider = new WindowsDirectoryProvider(); } + + public static function pathGetterMethodNameProvider(): array + { + return [ + ['getHomePath'], + + ['getCachePath'], + ['getConfigPath'], + ['getDataPath'], + ['getLocalDataPath'], + ['getTemporaryPath'], + + ['getDesktopPath'], + ['getDocumentsPath'], + ['getDownloadsPath'], + ['getMusicPath'], + ['getPicturesPath'], + ['getPublicPath'], + ['getTemplatesPath'], + ['getVideosPath'], + ]; + } } From 6ef24ee9f9e0bb52f23639f849d55b8cbc365cf5 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 02:34:25 +0330 Subject: [PATCH 77/92] Merge IsAbsoluteAsserter into ProviderPathTester Why creating a new trait without a need for it? --- .../DarwinDirectoryProviderTest.php | 1 - .../LinuxDirectoryProviderTest.php | 1 - .../Traits/IsAbsoluteAsserter.php | 15 --------------- .../Traits/ProviderPathTester.php | 7 +++++-- .../WindowsDirectoryProviderTest.php | 1 - 5 files changed, 5 insertions(+), 20 deletions(-) delete mode 100644 tests/unit/PlatformSpecific/Traits/IsAbsoluteAsserter.php diff --git a/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php index dcdbb63..c6e4b0d 100644 --- a/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/DarwinDirectoryProviderTest.php @@ -11,7 +11,6 @@ class DarwinDirectoryProviderTest extends TestCase { use Traits\ProviderPathTester; use Traits\ProviderGetter; - use Traits\IsAbsoluteAsserter; use GlobalTraits\PlatformChecker; private static DarwinDirectoryProvider $provider; diff --git a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php index 07533c7..f097ade 100644 --- a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php @@ -11,7 +11,6 @@ class LinuxDirectoryProviderTest extends TestCase { use Traits\ProviderPathTester; use Traits\ProviderGetter; - use Traits\IsAbsoluteAsserter; use GlobalTraits\PlatformChecker; private static LinuxDirectoryProvider $provider; diff --git a/tests/unit/PlatformSpecific/Traits/IsAbsoluteAsserter.php b/tests/unit/PlatformSpecific/Traits/IsAbsoluteAsserter.php deleted file mode 100644 index db2ba0c..0000000 --- a/tests/unit/PlatformSpecific/Traits/IsAbsoluteAsserter.php +++ /dev/null @@ -1,15 +0,0 @@ - Date: Sat, 19 Feb 2022 03:03:44 +0330 Subject: [PATCH 78/92] Rebuild some tests with traits and data providers These buildings make maintainance easier. :) --- .../Traits/ColonedArrayEnvTester.php | 30 ++++++++++++++ .../CustomEnv/Traits/SingleValueEnvTester.php | 30 ++++++++++++++ tests/unit/CustomEnv/UnixLikeHomeEnvTest.php | 13 +++---- tests/unit/CustomEnv/WindowsEnvTest.php | 18 +++------ tests/unit/CustomEnv/XdgEnvTest.php | 39 +++++++------------ .../ProviderGetter.php | 2 +- .../DarwinDirectoryProviderTest.php | 2 +- .../LinuxDirectoryProviderTest.php | 2 +- .../Traits/ProviderPathTester.php | 2 + .../WindowsDirectoryProviderTest.php | 2 +- 10 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php create mode 100644 tests/unit/CustomEnv/Traits/SingleValueEnvTester.php rename tests/unit/{PlatformSpecific/Traits => GlobalTraits}/ProviderGetter.php (66%) diff --git a/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php b/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php new file mode 100644 index 0000000..83ea25c --- /dev/null +++ b/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php @@ -0,0 +1,30 @@ +assertSame($envValue, self::getProvider()->$pathGetter()); + } +} diff --git a/tests/unit/CustomEnv/Traits/SingleValueEnvTester.php b/tests/unit/CustomEnv/Traits/SingleValueEnvTester.php new file mode 100644 index 0000000..58153d2 --- /dev/null +++ b/tests/unit/CustomEnv/Traits/SingleValueEnvTester.php @@ -0,0 +1,30 @@ +assertSame($envValue, self::getProvider()->$pathGetter()); + } +} diff --git a/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php index f3bac1b..0fb0c7c 100644 --- a/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php +++ b/tests/unit/CustomEnv/UnixLikeHomeEnvTest.php @@ -8,6 +8,8 @@ class UnixLikeHomeEnvTest extends TestCase { + use Traits\SingleValueEnvTester; + use GlobalTraits\ProviderGetter; use GlobalTraits\PlatformChecker; private static $provider; @@ -27,13 +29,10 @@ public static function setUpBeforeClass(): void }; } - public function test(): void + public function singleValueEnvProvider(): array { - $envName = 'HOME'; - $envValue = '/tmp/test'; - - \putenv("$envName=$envValue"); - - $this->assertSame($envValue, self::$provider->getHomePath()); + return [ + ['HOME', '/tmp/home/test', 'getHomePath'], + ]; } } diff --git a/tests/unit/CustomEnv/WindowsEnvTest.php b/tests/unit/CustomEnv/WindowsEnvTest.php index dcc5b5d..620bd11 100644 --- a/tests/unit/CustomEnv/WindowsEnvTest.php +++ b/tests/unit/CustomEnv/WindowsEnvTest.php @@ -9,6 +9,8 @@ class WindowsEnvTest extends TestCase { + use Traits\SingleValueEnvTester; + use GlobalTraits\ProviderGetter; use GlobalTraits\PlatformChecker; private static $provider; @@ -20,21 +22,13 @@ public static function setUpBeforeClass(): void self::$provider = new WindowsDirectoryProvider(); } - public function test(): void + public function singleValueEnvProvider(): array { - foreach ([ - ['UserProfile', 'E:\\', 'getHomePath'], + return [ + ['UserProfile', 'E:', 'getHomePath'], ['AppData', 'E:\\AppData', 'getDataPath'], ['LocalAppData', 'E:\\AppData\\Local', 'getLocalDataPath'], ['Temp', 'D:\\Temp', 'getTemporaryPath'], - ] as [$envName, $envValue, $pathGetterMethod]) { - - \putenv("$envName=$envValue"); - - $this->assertSame( - $envValue, - self::$provider->$pathGetterMethod(), - ); - } + ]; } } diff --git a/tests/unit/CustomEnv/XdgEnvTest.php b/tests/unit/CustomEnv/XdgEnvTest.php index 385bb6f..69832e4 100644 --- a/tests/unit/CustomEnv/XdgEnvTest.php +++ b/tests/unit/CustomEnv/XdgEnvTest.php @@ -7,11 +7,14 @@ use PHPUnit\Framework\TestCase; /** - * Test changing various XDG_* environment variables for a provider using - * XdgBasedirSpec trait. + * Test changing various XDG_* environment variables for a provider making use + * of XdgBasedirSpec trait. */ class XdgEnvTest extends TestCase { + use Traits\SingleValueEnvTester; + use Traits\ColonedArrayEnvTester; + use GlobalTraits\ProviderGetter; use GlobalTraits\PlatformChecker; private static $provider; @@ -26,38 +29,22 @@ public static function setUpBeforeClass(): void }; } - public function testSingleValueEnvs(): void + public function singleValueEnvProvider(): array { - foreach ([ + return [ ['XDG_CONFIG_HOME', '/tmp/test/.config', 'getConfigPath'], ['XDG_CACHE_HOME', '/tmp/test/.cache', 'getCachePath'], ['XDG_DATA_HOME', '/tmp/test/.local/share', 'getDataPath'], ['XDG_STATE_HOME', '/tmp/test/.local/state', 'getStatePath'], ['XDG_RUNTIME_DIR', '/tmp/test/.runtime', 'getRuntimePath'], - ] as [$envName, $envValue, $pathGetterMethod]) { - - \putenv("$envName=$envValue"); - - $this->assertSame( - $envValue, - self::$provider->$pathGetterMethod(), - ); - } + ]; } - public function testMultiValueEnvs(): void + public function colonedArrayEnvProvider(): array { - foreach ([ - ['XDG_CONFIG_DIRS', '/etc:/tmp/etc', 'getConfigPathSet'], - ['XDG_DATA_DIRS', '/var/local/share:/tmp/share', 'getDataPathSet'], - ] as [$envName, $envValue, $pathGetterMethod]) { - - \putenv("$envName=$envValue"); - - $this->assertSame( - $envValue, - \join(':', self::$provider->$pathGetterMethod()), - ); - } + return [ + ['XDG_CONFIG_DIRS', ['/etc', '/tmp/etc'], 'getConfigPathSet'], + ['XDG_DATA_DIRS', ['/var/local/share', '/tmp'], 'getDataPathSet'], + ]; } } diff --git a/tests/unit/PlatformSpecific/Traits/ProviderGetter.php b/tests/unit/GlobalTraits/ProviderGetter.php similarity index 66% rename from tests/unit/PlatformSpecific/Traits/ProviderGetter.php rename to tests/unit/GlobalTraits/ProviderGetter.php index 5aa25ca..f230109 100644 --- a/tests/unit/PlatformSpecific/Traits/ProviderGetter.php +++ b/tests/unit/GlobalTraits/ProviderGetter.php @@ -1,6 +1,6 @@ Date: Sat, 19 Feb 2022 04:40:46 +0330 Subject: [PATCH 79/92] Fix a wrong array access in DirectoryProviderFactory, improve its docs --- src/DirectoryProviderFactory.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/DirectoryProviderFactory.php b/src/DirectoryProviderFactory.php index 7a067ad..2053f70 100644 --- a/src/DirectoryProviderFactory.php +++ b/src/DirectoryProviderFactory.php @@ -76,16 +76,16 @@ private static function validateProviderType( } /** - * @param string $type Must an existing interface. + * @param string $type Must be an existing interface. */ private static function createInternal( string $type, string $platform ): object { - $providerMapperForType = self::$providerMapper[$type]; + $providerMapperForType = self::$providerMapper[$type] ?? null; if (\is_null($providerMapperForType)) { - throw new Exception("No provider defined for type '$type'"); + throw new Exception("Type '$type' not registered for any provider"); } $provider = $providerMapperForType[$platform] ?? null; @@ -131,7 +131,7 @@ public static function createStandard( } /** - * @param string $type Must an existing interface. + * @param string $type Must be an existing interface. */ private static function mapInternal( string $type, @@ -161,6 +161,13 @@ public static function map( return self::mapInternal($type, $platform, $provider); } + /** + * Map mulitple platforms to providers, for the specified provider type. + * + * @param array $mapping Platform (key) to provider class name (value) + * mapping. + * @return string Self. + */ public static function mapMany( string $type, array $mapping From af4a27e68bc37fa2549e905d15aa0fbdf064933b Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 04:59:42 +0330 Subject: [PATCH 80/92] Add exception test for DirectoryProviderFactory --- .../DirectoryProviderFactoryExceptionTest.php | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/unit/DirectoryProviderFactoryExceptionTest.php diff --git a/tests/unit/DirectoryProviderFactoryExceptionTest.php b/tests/unit/DirectoryProviderFactoryExceptionTest.php new file mode 100644 index 0000000..3e9f524 --- /dev/null +++ b/tests/unit/DirectoryProviderFactoryExceptionTest.php @@ -0,0 +1,119 @@ +expectException(Exception::class); + } + + /** + * @dataProvider undefinedTypeProvider + * @dataProvider unregisteredTypeProvider + */ + public function testCreatingWithInvalidType(string $type): void + { + DirectoryProviderFactory::create($type, Platform::autoDetect()); + } + + /** + * @dataProvider undefinedTypeProvider + */ + public function testMappingWithInvalidType(string $type): void + { + DirectoryProviderFactory::map( + $type, + Platform::LINUX, + LinuxDirectoryProvider::class + ); + } + + /** + * @dataProvider unmappedStandardTypePlatformProvider + */ + public function testCreatingStandardWithUnmappedPlatform( + string $platform + ): void { + DirectoryProviderFactory::createStandard($platform); + } + + /** + * @dataProvider undefinedProviderClassProvider + */ + public function testMappingStandardWithInvalidProvider( + string $provider + ): void { + DirectoryProviderFactory::mapStandard(Platform::WINDOWS, $provider); + } + + /** + * @dataProvider unimplementedStandardTypeProviderClassProvider + */ + public function testMappingStandardWithInvalidProviderType( + string $provider + ): void { + DirectoryProviderFactory::mapStandard(Platform::BSD, $provider); + } + + public function undefinedTypeProvider(): array + { + return [ + [TestCase::class], + ['StandardDirectoryProvider'], + ]; + } + + public function unregisteredTypeProvider(): array + { + return [ + [\DateTimeInterface::class], + ]; + } + + public function unmappedStandardTypePlatformProvider(): array + { + return [ + [Platform::UNKNOWN], + [\strtolower(Platform::BSD)], + ]; + } + + public function undefinedProviderClassProvider(): array + { + return [ + [Provider::class], + ['LinuxDirectoryProvider'], + ]; + } + + public function unimplementedStandardTypeProviderClassProvider(): array + { + return [ + [\stdClass::class], + [\get_class(new class implements CommonDirectoryProvider { + use \MAChitgarha\Phirs\Traits\HomeBased\CommonPathProvider; + + public function getHomeChildPath(string ...$childPaths): string + { + // Just for testing, has no special meaning + return '/home/test'; + } + })], + ]; + } +} From aaa320ae3f44f6341c9ea0fcc38ff3543e673261 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 05:02:19 +0330 Subject: [PATCH 81/92] Add Well-Tested feature to Features section in README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b4f9f9d..ac53afd 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ A library providing platform-specific user directory paths, such as config and c ## Features -- **Multiple Platform**. Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. +- **Multiple Platform.** Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. -- **Hackable**. Adding support for a specific platform [is easy](./docs/en/usage-guide#example-android-platform-support). +- **Hackable** Adding support for a specific platform [is easy](./docs/en/usage-guide#example-android-platform-support). -- **Well-Designed**. Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). +- **Well-Designed.** Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). + +- **Well-Tested.** Many pieces of the library are covered by unit tests. With the help of CI tools also, it is continuously tested againts major platforms. ## Why? From 139d83284be3c3bbb4dba0a4b4a209494811bd13 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 05:38:56 +0330 Subject: [PATCH 82/92] Fix some validation process in DirectoryProviderFactory --- src/DirectoryProviderFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DirectoryProviderFactory.php b/src/DirectoryProviderFactory.php index 2053f70..066cbe5 100644 --- a/src/DirectoryProviderFactory.php +++ b/src/DirectoryProviderFactory.php @@ -49,7 +49,7 @@ class DirectoryProviderFactory private static function validateType(string $type): string { - if (\interface_exists($type)) { + if (!\interface_exists($type)) { throw new Exception("Type '$type' not defined as an interface"); } return self::class; @@ -57,7 +57,7 @@ private static function validateType(string $type): string private static function validateProvider(string $provider): string { - if (\class_exists($provider)) { + if (!\class_exists($provider)) { throw new Exception("Provider '$provider' is not a defined class"); } return self::class; @@ -67,7 +67,7 @@ private static function validateProviderType( string $provider, string $type ): string { - if (!\is_a($provider, $type)) { + if (!\is_subclass_of($provider, $type)) { throw new Exception( "Provider '$provider' must be of type (i.e. implement) '$type'" ); From 3d6e9069521ed66c861a2a497ef96e3b454294d5 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 06:19:19 +0330 Subject: [PATCH 83/92] Add test for DirectoryProviderFactory class --- tests/unit/DirectoryProviderFactoryTest.php | 128 ++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 tests/unit/DirectoryProviderFactoryTest.php diff --git a/tests/unit/DirectoryProviderFactoryTest.php b/tests/unit/DirectoryProviderFactoryTest.php new file mode 100644 index 0000000..0d2e6f9 --- /dev/null +++ b/tests/unit/DirectoryProviderFactoryTest.php @@ -0,0 +1,128 @@ +assertInstanceOf( + StandardDirectoryProvider::class, + DirectoryProviderFactory::createStandard($platform), + ); + } + + /** + * @dataProvider mapArgProvider + * @depends testCreateStandard + */ + public function testMap( + string $type, + string $platform, + string $provider + ): void { + DirectoryProviderFactory::map($type, $platform, $provider); + + $this->assertInstanceOf( + $provider, + DirectoryProviderFactory::create($type, $platform), + ); + } + + /** + * @dataProvider mapManyArgProvider + * @depends testMap + */ + public function testMapMany(string $type, array $mapping): void + { + DirectoryProviderFactory::mapMany($type, $mapping); + + foreach ($mapping as $platform => $provider) { + $this->assertInstanceOf( + $provider, + DirectoryProviderFactory::create($type, $platform), + ); + } + } + + /** + * @dataProvider mapStandardArgProvider + * @depends testMapMany + */ + public function testMapStandard(string $platform, string $provider) + { + DirectoryProviderFactory::mapStandard($platform, $provider); + + $this->assertInstanceOf( + $provider, + DirectoryProviderFactory::createStandard($platform), + ); + } + + public function platformProvider(): array + { + return [ + [Platform::autoDetect()], + [Platform::LINUX], + [Platform::DARWIN], + [Platform::WINDOWS], + [Platform::BSD], + [Platform::SOLARIS], + ]; + } + + public function mapArgProvider(): array + { + // Fake data + return [ + [\Countable::class, Platform::LINUX, \ArrayObject::class], + [\Countable::class, Platform::WINDOWS, \WeakMap::class], + [\Countable::class, 'Unix', \WeakMap::class], + [ + StandardDirectoryProvider::class, + Platform::UNKNOWN, + WindowsDirectoryProvider::class + ], + [ + StandardDirectoryProvider::class, + 'Redox', + LinuxDirectoryProvider::class + ], + ]; + } + + public function mapManyArgProvider(): array + { + return [ + [\Traversable::class, [ + Platform::DARWIN => \ArrayObject::class, + Platform::BSD => \ArrayIterator::class, + ]], + [StandardDirectoryProvider::class, [ + Platform::UNKNOWN => LinuxDirectoryProvider::class, + 'iOS' => DarwinDirectoryProvider::class, + ]], + ]; + } + + public function mapStandardArgProvider(): array + { + return [ + [Platform::SOLARIS, LinuxDirectoryProvider::class], + [Platform::UNKNOWN, WindowsDirectoryProvider::class], + ]; + } +} From ed863cce238dbcba2e584c25560b954943e5f073 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 13:43:29 +0330 Subject: [PATCH 84/92] Add Contribution Guidelines and Code of Conduct --- .github/CODE_OF_CONDUCT.md | 42 +++++++++++++++++++++++++++++++ .github/CONTRIBUTING.md | 51 ++++++++++++++++++++++++++++++++++++++ README.md | 2 ++ 3 files changed, 95 insertions(+) create mode 100755 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100755 index 0000000..db8384b --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,42 @@ +# Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. +Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +# Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +# Scope + +This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +# Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at machitgarha@outlook.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership. + +# Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at + +For answers to common questions about this code of conduct, see diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..59451fd --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contribution Guidelines + +## Code of Conduct + +For a better community, please read and follow the [code of conduct](./CODE_OF_CONDUCT.md). + +## Issues + +It is great to include examples in your issues, like what fails or what you want to achieve. + +## Branching Model + +There are two branches available, `master` and `develop`. All stable changes will go into the `master`, and all unstables to `develop`. + +As a result, you always have to make changes on `develop`, and merge back to the same branch, in the case of any PRs. Any requests to merge into `master` directly is likely to be rejected. + +## Warming Up + +For the development process, install dev dependencies first: + +```bash +composer require --dev +``` + +## Tests, Tests and Tests + +Make unit-tests for the new code. Make sure all current tests pass by invoking PHPUnit: + +```bash +./vendor/bin/phpunit +``` + +## Documentation + +We will be thankful if you update the related documentations along with any changes. + +## Static Analysis + +We use [Phan](https://github.com/phan/phan) static analyser. + +Newly-added code must have no errors reported by Phan. You may suppress an error, if you think it's not applicable. Globally suppressing errors is not a good idea, so make sure you make the suppression as limited and small as possible. + +To run Phan, do: + +## Coding Guidelines + +You should use the [PSR-2](https://www.php-fig.org/psr/psr-2/) and [PSR-12](https://www.php-fig.org/psr/psr-12/) style guides in your code. + +## Versioning + +This project follows the [semantic versioning](https://semver.org/) guidelines. diff --git a/README.md b/README.md index ac53afd..e6ce5a0 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ In a world like this, everyone should be a contributor. So, start helping this p If you want to get an overall overview of the code, go and read [Usage Guide](#usage-guide). +For the best results, see [Contribution Guidelines](./.github/CONTRIBUTING.md). + ## License The project is licensed under [Apache 2.0 License](./LICENSE.md). From 084a20b951562039e8f82b0b3b293b0ef0d41a7f Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 13:52:31 +0330 Subject: [PATCH 85/92] Update dependencies, fix a contribution guide --- .github/CONTRIBUTING.md | 6 +++--- composer.lock | 30 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 59451fd..61e34f7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ For a better community, please read and follow the [code of conduct](./CODE_OF_C ## Issues -It is great to include examples in your issues, like what fails or what you want to achieve. +It is great to include examples in your issues, like what fails or what you want to achieve. ## Branching Model @@ -16,10 +16,10 @@ As a result, you always have to make changes on `develop`, and merge back to the ## Warming Up -For the development process, install dev dependencies first: +For the development process, install dependencies first: ```bash -composer require --dev +composer install ``` ## Tests, Tests and Tests diff --git a/composer.lock b/composer.lock index 3de69b2..815baf5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cea6271461eeb4e504dddc63d41d246f", + "content-hash": "38ab23139337461719b3cb5a50a45bce", "packages": [ { "name": "symfony/filesystem", @@ -1194,16 +1194,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.10", + "version": "9.2.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" + "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f", + "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f", "shasum": "" }, "require": { @@ -1259,7 +1259,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11" }, "funding": [ { @@ -1267,7 +1267,7 @@ "type": "github" } ], - "time": "2021-12-05T09:12:13+00:00" + "time": "2022-02-18T12:46:09+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1512,16 +1512,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.13", + "version": "9.5.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743" + "reference": "1883687169c017d6ae37c58883ca3994cfc34189" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", + "reference": "1883687169c017d6ae37c58883ca3994cfc34189", "shasum": "" }, "require": { @@ -1599,7 +1599,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14" }, "funding": [ { @@ -1611,7 +1611,7 @@ "type": "github" } ], - "time": "2022-01-24T07:33:35+00:00" + "time": "2022-02-18T12:54:07+00:00" }, { "name": "psr/container", @@ -3427,6 +3427,8 @@ "platform": { "php": "^7.4|^8.0" }, - "platform-dev": [], + "platform-dev": { + "php": "^8.0" + }, "plugin-api-version": "2.2.0" } From a3b2a6ecac76209d707a5d5c9e0dc56ab3c4537f Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 13:55:52 +0330 Subject: [PATCH 86/92] Add Github actions workflow file for CI (tests and static analysis) Improve composer.json description. --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ composer.json | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..27b1b4c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +name: Continuous Integration + +on: + push: + branches: [master, develop] + pull_request: + branches: [develop] + +jobs: + run-tests: + runs-on: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@v2 + - run: composer install + - run: ./vendor/bin/phpunit + + static-analysis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: composer install + - run: ./vendor/bin/phan diff --git a/composer.json b/composer.json index 18d8f3c..2dd7ee1 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "machitgarha/phirs", - "description": "Cross-platform user directory paths provider, such as config and cache", + "description": "Cross-platform user directory paths, such as config and cache", "type": "library", "license": "Apache-2.0", "homepage": "https://github.com/machitgarha/phirs", From a4a2ac169e330d530d3aa067ecf52628a25e4670 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 14:54:52 +0330 Subject: [PATCH 87/92] Decrease required PHP version for development (require-dev) to 7.4 --- composer.json | 2 +- tests/unit/GlobalTraits/PlatformChecker.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 2dd7ee1..fcb2fb6 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "symfony/filesystem": "^6.0" }, "require-dev": { - "php": "^8.0", + "php": "^7.4|^8.0", "phan/phan": "^5.3", "phpunit/phpunit": "^9.5" } diff --git a/tests/unit/GlobalTraits/PlatformChecker.php b/tests/unit/GlobalTraits/PlatformChecker.php index 27f01f0..26ef984 100644 --- a/tests/unit/GlobalTraits/PlatformChecker.php +++ b/tests/unit/GlobalTraits/PlatformChecker.php @@ -10,10 +10,11 @@ abstract public static function markTestSkipped(string $message): void; /** * Skips the test if the current platform is not among supported platforms. + * + * @param string|array supportedPlatforms */ - public static function skipIfPlatformUnsupported( - string|array $supportedPlatforms - ): void { + public static function skipIfPlatformUnsupported($supportedPlatforms): void + { $supportedPlatforms = (array)($supportedPlatforms); $currentPlatform = Platform::autoDetect(); From 60bdb135365d26ff7abdd5b1eafd04cebcf7f12a Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 15:20:27 +0330 Subject: [PATCH 88/92] Downgrade symfony/filesystem to 5.4, for supporting PHP 7.4 --- composer.json | 2 +- composer.lock | 187 +++++++++++++++++++++++++------------------------- 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/composer.json b/composer.json index fcb2fb6..33e58ea 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ }, "require": { "php": "^7.4|^8.0", - "symfony/filesystem": "^6.0" + "symfony/filesystem": "5.4" }, "require-dev": { "php": "^7.4|^8.0", diff --git a/composer.lock b/composer.lock index 815baf5..8e32ce3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,26 +4,27 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "38ab23139337461719b3cb5a50a45bce", + "content-hash": "5d98e8a9c26558ea9f58cc14e35df372", "packages": [ { "name": "symfony/filesystem", - "version": "v6.0.3", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "6ae49c4fda17322171a2b8dc5f70bc6edbc498e1" + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6ae49c4fda17322171a2b8dc5f70bc6edbc498e1", - "reference": "6ae49c4fda17322171a2b8dc5f70bc6edbc498e1", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -51,7 +52,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.3" + "source": "https://github.com/symfony/filesystem/tree/v5.4.0" }, "funding": [ { @@ -67,7 +68,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2021-10-28T13:39:27+00:00" }, { "name": "symfony/polyfill-ctype", @@ -233,6 +234,89 @@ } ], "time": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.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": "2021-09-13T13:58:33+00:00" } ], "packages-dev": [ @@ -3006,89 +3090,6 @@ ], "time": "2021-02-19T12:13:01+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.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": "2021-09-13T13:58:33+00:00" - }, { "name": "symfony/service-contracts", "version": "v3.0.0", @@ -3428,7 +3429,7 @@ "php": "^7.4|^8.0" }, "platform-dev": { - "php": "^8.0" + "php": "^7.4|^8.0" }, "plugin-api-version": "2.2.0" } From 42851dc38f3de7b29bd9369c05c2f7df64f48be6 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 15:49:06 +0330 Subject: [PATCH 89/92] Improve CI workflow, use Setup-PHP, use matrix strategy --- .github/workflows/ci.yml | 34 +++++++++++++++++++++++++++++----- README.md | 2 +- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27b1b4c..9e71c91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,15 +8,39 @@ on: jobs: run-tests: - runs-on: [ubuntu-latest, macos-latest, windows-latest] + name: Run PHPUnit Tests + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v2 - - run: composer install - - run: ./vendor/bin/phpunit + + - name: Prepare PHP 7.4 + uses: shivammathur/setup-php@v2 + with: + php-extension: '7.4' + + - name: Install Composer dependencies + run: composer install + + - name: Run PHPUnit + run: ./vendor/bin/phpunit --verbose static-analysis: + name: Static Analysis using Phan runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: composer install - - run: ./vendor/bin/phan + + - name: Prepare PHP 7.4 with Phan + uses: shivammathur/setup-php@v2 + with: + php-extension: '7.4' + tools: phan + + - name: Install Composer dependencies + run: composer install + + - name: Run Phan + run: phan diff --git a/README.md b/README.md index e6ce5a0..6532170 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A library providing platform-specific user directory paths, such as config and c - **Multiple Platform.** Providing cross-platform paths, plus platform-specific ones. Make your app run-everywhere or target a specific platform. See [Platform Support](#platform-support) for more details. -- **Hackable** Adding support for a specific platform [is easy](./docs/en/usage-guide#example-android-platform-support). +- **Hackable.** Adding support for a specific platform [is easy](./docs/en/usage-guide.md#example-android-platform-support). - **Well-Designed.** Provide good design and simple abstractions (with the help of powerful PHP interfaces and traits). From 8153608decbf8cf16d9f9fe3402c805d7c52912f Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sat, 19 Feb 2022 23:40:32 +0330 Subject: [PATCH 90/92] Save and restore env variables before and after the CustomEnv tests --- .../Traits/ColonedArrayEnvTester.php | 2 +- tests/unit/CustomEnv/Traits/EnvRestorer.php | 32 +++++++++++++++++++ .../CustomEnv/Traits/SingleValueEnvTester.php | 2 +- tests/unit/CustomEnv/UnixLikeHomeEnvTest.php | 15 ++++++++- tests/unit/CustomEnv/WindowsEnvTest.php | 15 ++++++++- tests/unit/CustomEnv/XdgEnvTest.php | 20 ++++++++++-- 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 tests/unit/CustomEnv/Traits/EnvRestorer.php diff --git a/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php b/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php index 83ea25c..6a8ecef 100644 --- a/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php +++ b/tests/unit/CustomEnv/Traits/ColonedArrayEnvTester.php @@ -13,7 +13,7 @@ abstract private static function getProvider(): object; * Just like SingleValueEnvTester::singleValueEnvProvider(), but the value * of an environment variable must be an array. */ - abstract public function colonedArrayEnvProvider(): array; + abstract public static function colonedArrayEnvProvider(): array; /** * @dataProvider colonedArrayEnvProvider diff --git a/tests/unit/CustomEnv/Traits/EnvRestorer.php b/tests/unit/CustomEnv/Traits/EnvRestorer.php new file mode 100644 index 0000000..8b634bc --- /dev/null +++ b/tests/unit/CustomEnv/Traits/EnvRestorer.php @@ -0,0 +1,32 @@ + Date: Sat, 19 Feb 2022 23:50:26 +0330 Subject: [PATCH 91/92] Don't test LinuxDirectoryProvider::getRuntimePath() It may throw exceptions for the reason written as a comment. --- tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php index d86712a..2c5a13c 100644 --- a/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php +++ b/tests/unit/PlatformSpecific/LinuxDirectoryProviderTest.php @@ -32,7 +32,9 @@ public static function pathGetterMethodNameProvider(): array ['getConfigPath'], ['getDataPath'], ['getStatePath'], - ['getRuntimePath'], + // Runtime path may not be set and it has not a fallback value, so + // ignore testing it here + // ['getRuntimePath'], ['getDesktopPath'], ['getDocumentsPath'], From be56cbc6070434e10d96afd64a34c0042d44a076 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Chitgarha Date: Sun, 20 Feb 2022 00:14:04 +0330 Subject: [PATCH 92/92] Fix directory permissions on Windows in the tests --- tests/unit/PlatformSpecific/Traits/ProviderPathTester.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php index e793942..7af5a68 100644 --- a/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php +++ b/tests/unit/PlatformSpecific/Traits/ProviderPathTester.php @@ -55,5 +55,8 @@ private function makeDirectoryIfNotExists(string $path): void if (!\is_dir($path) && !\mkdir($path, 0700, true)) { throw new \Exception("Cannot make directory '$path'"); } + + // For the paths on Windows platform to be writable + \chmod($path, 0777); } }