From 8989b36b4e1a27bde76f695a20e594ae0b83cf03 Mon Sep 17 00:00:00 2001 From: Jaapio Date: Tue, 21 Jan 2025 22:59:45 +0100 Subject: [PATCH] Introduce filesystem component The filesystem component makes an abstraction between guides and flysystem. This makes it easier to maintain the project when external dependencies are introducing breaking changes. The filesystem component is just focused on the needs of phpDocumentor and shall not be seen as a stand alone component to be used by other projects. (cherry picked from commit b281d2d8e911863edfbe4240294722857d135de9) # Conflicts: # composer.json # composer.lock # packages/guides/composer.json --- composer.json | 21 ++ composer.lock | 303 ++++++++++++------ config.subsplit-publish.json | 5 + packages/filesystem/.gitattributes | 5 + .../.github/pull_request_template.md | 18 ++ packages/filesystem/.gitignore | 1 + packages/filesystem/CONTRIBUTING.rst | 23 ++ .../Flysystem/FilesystemInterface.php | 297 +++++++++++++++++ packages/filesystem/LICENSE | 21 ++ packages/filesystem/README.rst | 34 ++ packages/filesystem/composer.json | 34 ++ .../filesystem/src/FileNotFoundException.php | 20 ++ packages/filesystem/src/FileSystem.php | 54 ++++ packages/filesystem/src/FlySystemAdapter.php | 89 +++++ .../src/FlysystemV1/FlysystemV1.php | 72 +++++ .../src/FlysystemV1/StorageAttributes.php | 45 +++ .../src/FlysystemV3/FileAttributes.php | 67 ++++ .../src/FlysystemV3/FlysystemV3.php | 71 ++++ .../src/MethodNotAllowedException.php | 20 ++ packages/filesystem/src/StorageAttributes.php | 23 ++ packages/guides-cli/src/Command/Run.php | 10 +- packages/guides/composer.json | 8 + packages/guides/src/FileCollector.php | 18 +- packages/guides/src/Files.php | 2 + .../src/Handlers/ParseDirectoryCommand.php | 5 +- .../src/Handlers/ParseDirectoryHandler.php | 3 +- .../guides/src/Handlers/ParseFileCommand.php | 5 +- .../guides/src/Handlers/ParseFileHandler.php | 5 +- .../guides/src/Handlers/RenderCommand.php | 9 +- packages/guides/src/Parser.php | 10 +- packages/guides/src/ParserContext.php | 5 +- packages/guides/src/RenderContext.php | 17 +- packages/guides/src/Twig/AssetsExtension.php | 5 +- phpcs.xml.dist | 1 + phpstan.neon | 3 +- tests/Functional/FunctionalTest.php | 15 +- 36 files changed, 1191 insertions(+), 153 deletions(-) create mode 100644 packages/filesystem/.gitattributes create mode 100644 packages/filesystem/.github/pull_request_template.md create mode 100644 packages/filesystem/.gitignore create mode 100644 packages/filesystem/CONTRIBUTING.rst create mode 100644 packages/filesystem/Flysystem/FilesystemInterface.php create mode 100644 packages/filesystem/LICENSE create mode 100644 packages/filesystem/README.rst create mode 100644 packages/filesystem/composer.json create mode 100644 packages/filesystem/src/FileNotFoundException.php create mode 100644 packages/filesystem/src/FileSystem.php create mode 100644 packages/filesystem/src/FlySystemAdapter.php create mode 100644 packages/filesystem/src/FlysystemV1/FlysystemV1.php create mode 100644 packages/filesystem/src/FlysystemV1/StorageAttributes.php create mode 100644 packages/filesystem/src/FlysystemV3/FileAttributes.php create mode 100644 packages/filesystem/src/FlysystemV3/FlysystemV3.php create mode 100644 packages/filesystem/src/MethodNotAllowedException.php create mode 100644 packages/filesystem/src/StorageAttributes.php diff --git a/composer.json b/composer.json index 5051000d9..cec89fb0a 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "ext-json": "*", "ext-mbstring": "*", "doctrine/deprecations": "^1.1", +<<<<<<< HEAD "phpdocumentor/guides": "^1.0@dev || ^0.3", "phpdocumentor/guides-cli": "^1.0@dev || ^0.3", "phpdocumentor/guides-code": "^1.0@dev || ^0.3", @@ -46,6 +47,18 @@ "phpdocumentor/guides-restructured-text": "^1.0@dev || ^0.3", "phpdocumentor/guides-theme-bootstrap": "^1.0@dev || ^0.3", "phpdocumentor/guides-theme-rst": "^1.0@dev || ^1.0" +======= + "phpdocumentor/filesystem": "^2.0@dev", + "phpdocumentor/flyfinder": "^1.1 || ^2.0", + "phpdocumentor/guides": "^2.0@dev || ^1.0", + "phpdocumentor/guides-cli": "^2.0@dev || ^1.0", + "phpdocumentor/guides-code": "^2.0@dev || ^1.0", + "phpdocumentor/guides-graphs": "^2.0@dev || ^1.0", + "phpdocumentor/guides-markdown": "^2.0@dev || ^1.0", + "phpdocumentor/guides-restructured-text": "^2.0@dev || ^1.0", + "phpdocumentor/guides-theme-bootstrap": "^2.0@dev || ^1.0", + "phpdocumentor/guides-theme-rst": "^2.0@dev || ^1.0" +>>>>>>> b281d2d8 (Introduce filesystem component) }, "require-dev": { "ext-dom": "*", @@ -57,11 +70,19 @@ "gajus/dindent": "^2.0.1", "jangregor/phpstan-prophecy": "^1.0", "league/csv": "^9.0", +<<<<<<< HEAD "league/flysystem-memory": "^1.0", "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.3", "phpstan/phpstan": "^1.10", "phpstan/phpstan-strict-rules": "^1.5", +======= + "league/flysystem-memory": "^1.0 || ^3.29", + "phpbench/phpbench": "^1.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-strict-rules": "^1.6", +>>>>>>> b281d2d8 (Introduce filesystem component) "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^10.5", "qossmic/deptrac-shim": "^1.0.2", diff --git a/composer.lock b/composer.lock index 8380c4ccd..cd53febfe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,11 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], +<<<<<<< HEAD "content-hash": "eb95a2a8f7aed69ef9b8326d947a6bbf", +======= + "content-hash": "33da623596e5b8f0bc0f7adc297a3434", +>>>>>>> b281d2d8 (Introduce filesystem component) "packages": [ { "name": "dflydev/dot-access-data", @@ -537,54 +541,55 @@ }, { "name": "league/flysystem", - "version": "1.1.10", + "version": "3.29.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3", - "php": "^7.2.5 || ^8.0" + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" }, "conflict": { - "league/flysystem-sftp": "<1.0.6" + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" }, "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" - }, - "suggest": { - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, "autoload": { "psr-4": { - "League\\Flysystem\\": "src/" + "League\\Flysystem\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -594,40 +599,77 @@ "authors": [ { "name": "Frank de Jonge", - "email": "info@frenky.net" + "email": "info@frankdejonge.nl" } ], - "description": "Filesystem abstraction: Many filesystems, one API.", + "description": "File storage abstraction for PHP", "keywords": [ - "Cloud Files", "WebDAV", - "abstraction", "aws", "cloud", - "copy.com", - "dropbox", - "file systems", + "file", "files", "filesystem", "filesystems", "ftp", - "rackspace", - "remote", "s3", "sftp", "storage" ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" + "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" }, - "funding": [ + "time": "2024-10-08T08:58:34+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.29.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://offset.earth/frankdejonge", - "type": "other" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "time": "2022-10-04T09:16:37+00:00" + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" + }, + "time": "2024-08-09T21:24:39+00:00" }, { "name": "league/mime-type-detection", @@ -742,20 +784,20 @@ }, { "name": "league/uri", - "version": "7.4.1", + "version": "7.5.1", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4" + "reference": "81fb5145d2644324614cc532b28efd0215bda430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/bedb6e55eff0c933668addaa7efa1e1f2c417cc4", - "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.3", + "league/uri-interfaces": "^7.5", "php": "^8.1" }, "conflict": { @@ -820,7 +862,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.4.1" + "source": "https://github.com/thephpleague/uri/tree/7.5.1" }, "funding": [ { @@ -828,20 +870,20 @@ "type": "github" } ], - "time": "2024-03-23T07:42:40+00:00" + "time": "2024-12-08T08:40:02+00:00" }, { "name": "league/uri-interfaces", - "version": "7.4.1", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "8d43ef5c841032c87e2de015972c06f3865ef718" + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/8d43ef5c841032c87e2de015972c06f3865ef718", - "reference": "8d43ef5c841032c87e2de015972c06f3865ef718", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", "shasum": "" }, "require": { @@ -904,7 +946,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.1" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" }, "funding": [ { @@ -912,7 +954,7 @@ "type": "github" } ], - "time": "2024-03-23T07:42:40+00:00" + "time": "2024-12-08T08:18:47+00:00" }, { "name": "masterminds/html5", @@ -1230,32 +1272,78 @@ }, "time": "2024-01-17T16:50:36+00:00" }, + { + "name": "phpdocumentor/filesystem", + "version": "dev-main", + "dist": { + "type": "path", + "url": "./packages/filesystem", + "reference": "51ec44c29420664e31d26a16fd86303fc6748560" + }, + "require": { + "php": "^8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\FileSystem\\": "src/" + }, + "classmap": [ + "Flysystem/" + ] + }, + "autoload-dev": { + "psr-4": { + "phpDocumentor\\FileSystem\\": [ + "tests/unit/" + ] + } + }, + "license": [ + "MIT" + ], + "description": "Filesystem abstraction for phpdocumentor projects.", + "homepage": "https://www.phpdoc.org", + "transport-options": { + "relative": true + } + }, { "name": "phpdocumentor/flyfinder", - "version": "1.1.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/FlyFinder.git", - "reference": "6e145e676d9fbade7527fd8d4c99ab36b687b958" + "reference": "92f5c407f63952fb66a6bb8c0489935b9c605888" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/FlyFinder/zipball/6e145e676d9fbade7527fd8d4c99ab36b687b958", - "reference": "6e145e676d9fbade7527fd8d4c99ab36b687b958", + "url": "https://api.github.com/repos/phpDocumentor/FlyFinder/zipball/92f5c407f63952fb66a6bb8c0489935b9c605888", + "reference": "92f5c407f63952fb66a6bb8c0489935b9c605888", "shasum": "" }, "require": { - "league/flysystem": "^1.0", - "php": "^7.2||^8.0" + "league/flysystem": "^3.0", + "php": "^8.0||^8.1||^8.2||^8.3" }, "require-dev": { - "league/flysystem-memory": "~1", - "mockery/mockery": "^1.3" + "league/flysystem-memory": "~3", + "mockery/mockery": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-phpunit": "^1.4", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "^5.26" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -1277,9 +1365,9 @@ ], "support": { "issues": "https://github.com/phpDocumentor/FlyFinder/issues", - "source": "https://github.com/phpDocumentor/FlyFinder/tree/1.1.0" + "source": "https://github.com/phpDocumentor/FlyFinder/tree/2.0.0" }, - "time": "2021-06-04T13:44:40+00:00" + "time": "2024-09-15T19:58:36+00:00" }, { "name": "phpdocumentor/guides", @@ -1287,23 +1375,36 @@ "dist": { "type": "path", "url": "./packages/guides", +<<<<<<< HEAD "reference": "5c52cdbadaa5de7a1db4c5d972c45ed5a911ecb5" +======= + "reference": "92a5f85dcc3c60476e37a1784b2acb2071f863e5" +>>>>>>> b281d2d8 (Introduce filesystem component) }, "require": { "doctrine/deprecations": "^1.0", "ext-json": "*", "ext-zlib": "*", - "league/flysystem": "^1.1", + "league/flysystem": "^1.1 || ^3.0", "league/tactician": "^1.1", +<<<<<<< HEAD "league/uri": "^6.5 || ^7.0", +======= + "league/uri": "^7.5.1", +>>>>>>> b281d2d8 (Introduce filesystem component) "php": "^8.1", - "phpdocumentor/flyfinder": "^1.1", + "phpdocumentor/flyfinder": "^1.1 || ^2.0", "psr/event-dispatcher": "^1.0", "symfony/clock": "^6.4.3", "symfony/html-sanitizer": "^6.4.8", "symfony/http-client": "^6.4.9", +<<<<<<< HEAD "symfony/string": "^5.4 || ^6.3 || ^7.0", "symfony/translation-contracts": "^3.4.1", +======= + "symfony/string": "^6.4.9", + "symfony/translation-contracts": "^3.5.1", +>>>>>>> b281d2d8 (Introduce filesystem component) "twig/twig": "~2.15 || ^3.0", "webmozart/assert": "^1.11" }, @@ -3617,16 +3718,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -3634,12 +3735,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3675,7 +3776,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -3691,7 +3792,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/var-exporter", @@ -4342,33 +4443,27 @@ }, { "name": "league/flysystem-memory", - "version": "1.0.2", + "version": "3.29.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-memory.git", - "reference": "d0e87477c32e29f999b4de05e64c1adcddb51757" + "reference": "219c79ad8b1d614a58ac17b775bfb3a6b7228126" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-memory/zipball/d0e87477c32e29f999b4de05e64c1adcddb51757", - "reference": "d0e87477c32e29f999b4de05e64c1adcddb51757", + "url": "https://api.github.com/repos/thephpleague/flysystem-memory/zipball/219c79ad8b1d614a58ac17b775bfb3a6b7228126", + "reference": "219c79ad8b1d614a58ac17b775bfb3a6b7228126", "shasum": "" }, "require": { - "league/flysystem": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.10" + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "php": "^8.0.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { "psr-4": { - "League\\Flysystem\\Memory\\": "src/" + "League\\Flysystem\\InMemory\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4377,23 +4472,22 @@ ], "authors": [ { - "name": "Chris Leppanen", - "email": "chris.leppanen@gmail.com", - "role": "Developer" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "description": "An in-memory adapter for Flysystem.", - "homepage": "https://github.com/thephpleague/flysystem-memory", + "description": "In-memory filesystem adapter for Flysystem.", "keywords": [ "Flysystem", - "adapter", + "file", + "files", + "filesystem", "memory" ], "support": { - "issues": "https://github.com/thephpleague/flysystem-memory/issues", - "source": "https://github.com/thephpleague/flysystem-memory/tree/1.0.2" + "source": "https://github.com/thephpleague/flysystem-memory/tree/3.29.0" }, - "time": "2019-05-30T21:34:13+00:00" + "time": "2024-08-09T21:24:39+00:00" }, { "name": "myclabs/deep-copy", @@ -7069,6 +7163,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "phpdocumentor/filesystem": 20, "phpdocumentor/guides": 20, "phpdocumentor/guides-cli": 20, "phpdocumentor/guides-code": 20, diff --git a/config.subsplit-publish.json b/config.subsplit-publish.json index 6fae2ecd2..15b95c95f 100644 --- a/config.subsplit-publish.json +++ b/config.subsplit-publish.json @@ -39,6 +39,11 @@ "name": "guides-theme-rst", "directory": "packages/guides-theme-rst", "target": "git@github.com:phpDocumentor/guides-theme-rst.git" + }, + { + "name": "filesystem", + "directory": "packages/filesystem", + "target": "git@github.com:phpDocumentor/filesystem.git" } ] } diff --git a/packages/filesystem/.gitattributes b/packages/filesystem/.gitattributes new file mode 100644 index 000000000..3017e2ae5 --- /dev/null +++ b/packages/filesystem/.gitattributes @@ -0,0 +1,5 @@ +/.gitattributes export-ignore +/docs export-ignore +/tests export-ignore +/.gitignore export-ignore +.github export-ignore diff --git a/packages/filesystem/.github/pull_request_template.md b/packages/filesystem/.github/pull_request_template.md new file mode 100644 index 000000000..744740692 --- /dev/null +++ b/packages/filesystem/.github/pull_request_template.md @@ -0,0 +1,18 @@ +# Contribute to the phpDocumentor Guides + +## Go to the mono-repository + +This project is developed in the mono-repository `phpDocumentor Guides `__. +The repository you are currently in gets auto-created by splitting the mono-repository. You **must not** contribute +to this repository directly but always to the mono-repository linked above. + +## Create Issues + +* If you find something missing or something is wrong in this library, you are welcome to write an issue + describing the problem: `Issues on GitHub `__. +* If you can, please try to fix the problem yourself. + +# Make changes (create pull requests) + +See the `Contribution chapter `__ in the +`Documentation` `__. diff --git a/packages/filesystem/.gitignore b/packages/filesystem/.gitignore new file mode 100644 index 000000000..140fada73 --- /dev/null +++ b/packages/filesystem/.gitignore @@ -0,0 +1 @@ +vendor/* diff --git a/packages/filesystem/CONTRIBUTING.rst b/packages/filesystem/CONTRIBUTING.rst new file mode 100644 index 000000000..63feae677 --- /dev/null +++ b/packages/filesystem/CONTRIBUTING.rst @@ -0,0 +1,23 @@ +====================================== +Contribute to the phpDocumentor Guides +====================================== + +Go to the mono-repository +========================= + +This project is developed in the mono-repository `phpDocumentor Guides `__. +The repository you are currently in gets auto-created by splitting the mono-repository. You **must not** contribute +to this repository directly but always to the mono-repository linked above. + +Create Issues +============= + +* If you find something missing or something is wrong in this library, you are welcome to write an issue + describing the problem: `Issues on GitHub `__. +* If you can, please try to fix the problem yourself. + +Make changes (create pull requests) +=================================== + +See the `Contribution chapter `__ in the +`Documentation` `__. diff --git a/packages/filesystem/Flysystem/FilesystemInterface.php b/packages/filesystem/Flysystem/FilesystemInterface.php new file mode 100644 index 000000000..4ee9bfadc --- /dev/null +++ b/packages/filesystem/Flysystem/FilesystemInterface.php @@ -0,0 +1,297 @@ +`__. + +The package `phpdocumentor/filesystem `__ provides +filesystem abstractions for phpDocumentor libraries. + +:Mono-Repository: https://github.com/phpDocumentor/guides +:Documentation: https://docs.phpdoc.org/components/guides/guides/index.html +:Packagist: https://packagist.org/packages/phpdocumentor/filesystem +:Contribution: https://github.com/phpDocumentor/guides/tree/main/CONTRIBUTING.rst diff --git a/packages/filesystem/composer.json b/packages/filesystem/composer.json new file mode 100644 index 000000000..cc3c29097 --- /dev/null +++ b/packages/filesystem/composer.json @@ -0,0 +1,34 @@ +{ + "name": "phpdocumentor/filesystem", + "description": "Filesystem abstraction for phpdocumentor projects.", + "type": "library", + "license": "MIT", + "homepage": "https://www.phpdoc.org", + "config": { + "sort-packages": true + }, + "autoload": { + "psr-4": { + "phpDocumentor\\FileSystem\\": "src/" + }, + "classmap": [ + "Flysystem/" + ] + }, + "autoload-dev": { + "psr-4": { + "phpDocumentor\\FileSystem\\": [ + "tests/unit/" + ] + } + }, + "minimum-stability": "stable", + "require": { + "php": "^8.1" + }, + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + } +} diff --git a/packages/filesystem/src/FileNotFoundException.php b/packages/filesystem/src/FileNotFoundException.php new file mode 100644 index 000000000..f3f3171d8 --- /dev/null +++ b/packages/filesystem/src/FileNotFoundException.php @@ -0,0 +1,20 @@ +filesystem->has($path); + } + + public function readStream(string $path): mixed + { + return $this->filesystem->readStream($path); + } + + public function read(string $path): string|false + { + return $this->filesystem->read($path); + } + + public function put(string $path, string $contents): bool + { + return $this->filesystem->put($path, $contents); + } + + /** @return StorageAttributes[] */ + public function listContents(string $directory = '', bool $recursive = false): array + { + return $this->filesystem->listContents($directory, $recursive); + } + + /** @return StorageAttributes[] */ + public function find(SpecificationInterface $specification): iterable + { + return $this->filesystem->find($specification); + } +} diff --git a/packages/filesystem/src/FlysystemV1/FlysystemV1.php b/packages/filesystem/src/FlysystemV1/FlysystemV1.php new file mode 100644 index 000000000..c8515bb2d --- /dev/null +++ b/packages/filesystem/src/FlysystemV1/FlysystemV1.php @@ -0,0 +1,72 @@ +filesystem = $wrappedFilesystem; + /** @phpstan-ignore-next-line */ + $this->filesystem->addPlugin(new Finder()); + } + + public function has(string $path): bool + { + return $this->filesystem->has($path); + } + + public function readStream(string $path): mixed + { + return $this->filesystem->readStream($path); + } + + public function read(string $path): string|false + { + return $this->filesystem->read($path); + } + + public function put(string $path, string $contents): bool + { + return $this->filesystem->put($path, $contents); + } + + /** @return StorageAttributes[] */ + public function listContents(string $directory = '', bool $recursive = false): array + { + return array_map( + static fn (array $attr) => new \phpDocumentor\FileSystem\FlysystemV1\StorageAttributes($attr), + $this->filesystem->listContents($directory, $recursive), + ); + } + + /** @return StorageAttributes[] */ + public function find(SpecificationInterface $specification): iterable + { + /** @phpstan-ignore-next-line */ + foreach ($this->filesystem->find($specification) as $file) { + yield new \phpDocumentor\FileSystem\FlysystemV1\StorageAttributes($file); + } + } +} diff --git a/packages/filesystem/src/FlysystemV1/StorageAttributes.php b/packages/filesystem/src/FlysystemV1/StorageAttributes.php new file mode 100644 index 000000000..733f5bad3 --- /dev/null +++ b/packages/filesystem/src/FlysystemV1/StorageAttributes.php @@ -0,0 +1,45 @@ +attributes[$offset]); + } + + public function offsetGet(mixed $offset): mixed + { + return $this->attributes[$offset]; + } + + public function offsetSet(mixed $offset, mixed $value): void + { + throw new MethodNotAllowedException(); + } + + public function offsetUnset(mixed $offset): void + { + throw new MethodNotAllowedException(); + } +} diff --git a/packages/filesystem/src/FlysystemV3/FileAttributes.php b/packages/filesystem/src/FlysystemV3/FileAttributes.php new file mode 100644 index 000000000..61d0fb26a --- /dev/null +++ b/packages/filesystem/src/FlysystemV3/FileAttributes.php @@ -0,0 +1,67 @@ +attributes->offsetExists($offset); + } + + public function offsetGet(mixed $offset): mixed + { + if ($offset === 'basename') { + return basename($this->attributes->path()); + } + + if ($offset === 'dirname') { + $dirname = dirname($this->attributes->path()); + if ($dirname === '.') { + return ''; + } + + return $dirname; + } + + if (in_array($offset, ['filename'], true)) { + return pathinfo($this->attributes->path())[$offset]; + } + + return $this->attributes->offsetGet($offset); + } + + public function offsetSet(mixed $offset, mixed $value): void + { + throw new MethodNotAllowedException('Cannot set attributes on storage attributes'); + } + + public function offsetUnset(mixed $offset): void + { + throw new MethodNotAllowedException('Cannot unset attributes on storage attributes'); + } +} diff --git a/packages/filesystem/src/FlysystemV3/FlysystemV3.php b/packages/filesystem/src/FlysystemV3/FlysystemV3.php new file mode 100644 index 000000000..0d1bdeb11 --- /dev/null +++ b/packages/filesystem/src/FlysystemV3/FlysystemV3.php @@ -0,0 +1,71 @@ +filesystem = $wrappedFilesystem; + $this->finder = new Finder($this->filesystem); + } + + public function has(string $path): bool + { + return $this->filesystem->has($path); + } + + public function readStream(string $path): mixed + { + return $this->filesystem->readStream($path); + } + + public function read(string $path): string|false + { + return $this->filesystem->read($path); + } + + public function put(string $path, string $contents): bool + { + $this->filesystem->write($path, $contents); + + return true; + } + + /** @return FileAttributes[] */ + public function listContents(string $directory = '', bool $recursive = false): array + { + return $this->filesystem->listContents($directory, $recursive)->map( + static fn (StorageAttributes $attributes) => new FileAttributes($attributes), + )->toArray(); + } + + /** @return FileAttributes[] */ + public function find(SpecificationInterface $specification): iterable + { + foreach ($this->finder->find($specification) as $file) { + /** @phpstan-ignore-next-line */ + yield new FileAttributes($file); + } + } +} diff --git a/packages/filesystem/src/MethodNotAllowedException.php b/packages/filesystem/src/MethodNotAllowedException.php new file mode 100644 index 000000000..58cc7c380 --- /dev/null +++ b/packages/filesystem/src/MethodNotAllowedException.php @@ -0,0 +1,20 @@ + */ +interface StorageAttributes extends ArrayAccess +{ + /** @return ($offset is 'filename' ? string : mixed) */ + public function offsetGet(mixed $offset): mixed; +} diff --git a/packages/guides-cli/src/Command/Run.php b/packages/guides-cli/src/Command/Run.php index b1804f7fc..0efa85793 100644 --- a/packages/guides-cli/src/Command/Run.php +++ b/packages/guides-cli/src/Command/Run.php @@ -13,18 +13,16 @@ namespace phpDocumentor\Guides\Cli\Command; -use Flyfinder\Finder; use Flyfinder\Path; use Flyfinder\Specification\InPath; use Flyfinder\Specification\NotSpecification; use Flyfinder\Specification\OrSpecification; use Flyfinder\Specification\SpecificationInterface; -use League\Flysystem\Adapter\Local; -use League\Flysystem\Filesystem; use League\Tactician\CommandBus; use Monolog\Handler\ErrorLogHandler; use Monolog\Handler\StreamHandler; use Monolog\Logger; +use phpDocumentor\FileSystem\FlySystemAdapter; use phpDocumentor\Guides\Cli\Logger\SpyProcessor; use phpDocumentor\Guides\Compiler\CompilerContext; use phpDocumentor\Guides\Event\PostCollectFilesForParsingEvent; @@ -306,8 +304,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $settings = $event->getSettings(); $outputDir = $settings->getOutput(); - $sourceFileSystem = new Filesystem(new Local($settings->getInput())); - $sourceFileSystem->addPlugin(new Finder()); + $sourceFileSystem = FlySystemAdapter::createForPath($settings->getInput()); + $logPath = $settings->getLogPath(); if ($logPath === 'php://stder') { $this->logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::WARNING)); @@ -371,7 +369,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $documents = $this->commandBus->handle(new CompileDocumentsCommand($documents, new CompilerContext($projectNode))); - $destinationFileSystem = new Filesystem(new Local($outputDir)); + $destinationFileSystem = FlySystemAdapter::createForPath($outputDir); $outputFormats = $settings->getOutputFormats(); diff --git a/packages/guides/composer.json b/packages/guides/composer.json index 77fb628f5..5e75a49c0 100644 --- a/packages/guides/composer.json +++ b/packages/guides/composer.json @@ -24,11 +24,19 @@ "php": "^8.1", "ext-json": "*", "ext-zlib": "*", +<<<<<<< HEAD "doctrine/deprecations": "^1.0", "league/flysystem": "^1.1", "league/tactician": "^1.1", "league/uri": "^6.5 || ^7.0", "phpdocumentor/flyfinder": "^1.1", +======= + "doctrine/deprecations": "^1.1", + "league/flysystem": "^1.1 || ^3.0", + "league/tactician": "^1.1", + "league/uri": "^7.5.1", + "phpdocumentor/flyfinder": "^1.1 || ^2.0", +>>>>>>> b281d2d8 (Introduce filesystem component) "psr/event-dispatcher": "^1.0", "symfony/clock": "^6.4.3", "symfony/html-sanitizer": "^6.4.8", diff --git a/packages/guides/src/FileCollector.php b/packages/guides/src/FileCollector.php index b062a28a6..70610b117 100644 --- a/packages/guides/src/FileCollector.php +++ b/packages/guides/src/FileCollector.php @@ -21,6 +21,7 @@ use Flyfinder\Specification\SpecificationInterface; use InvalidArgumentException; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem; use function sprintf; use function strlen; @@ -41,7 +42,7 @@ final class FileCollector * * @param SpecificationInterface|null $excludedSpecification specification that is used to exclude specific files/directories */ - public function collect(FilesystemInterface $filesystem, string $directory, string $extension, SpecificationInterface|null $excludedSpecification = null): Files + public function collect(FilesystemInterface|FileSystem $filesystem, string $directory, string $extension, SpecificationInterface|null $excludedSpecification = null): Files { $directory = trim($directory, '/'); $specification = new AndSpecification(new InPath(new Path($directory)), new HasExtension([$extension])); @@ -55,13 +56,14 @@ public function collect(FilesystemInterface $filesystem, string $directory, stri // completely populate the splFileInfos property $this->fileInfos = []; foreach ($files as $fileInfo) { + $dirname = $fileInfo['dirname']; + if (strlen($directory) > 0) { // Make paths relative to the provided source folder - $fileInfo['path'] = substr($fileInfo['path'], strlen($directory) + 1); - $fileInfo['dirname'] = substr($fileInfo['dirname'], strlen($directory) + 1) ?: ''; + $dirname = substr($fileInfo['dirname'], strlen($directory) + 1) ?: ''; } - $documentPath = $this->getFilenameFromFile($fileInfo); + $documentPath = $this->getFilenameFromFile($fileInfo['filename'], $dirname); $this->fileInfos[$documentPath] = $fileInfo; } @@ -133,13 +135,11 @@ private function doesFileRequireParsing(string $filename): bool /** * Converts foo/bar.rst to foo/bar (the document filename) - * - * @param array $fileInfo */ - private function getFilenameFromFile(array $fileInfo): string + private function getFilenameFromFile(string $filename, string $dirname): string { - $directory = $fileInfo['dirname'] ? $fileInfo['dirname'] . '/' : ''; + $directory = $dirname ? $dirname . '/' : ''; - return $directory . $fileInfo['filename']; + return $directory . $filename; } } diff --git a/packages/guides/src/Files.php b/packages/guides/src/Files.php index 43b4a5aa9..bfd09601c 100644 --- a/packages/guides/src/Files.php +++ b/packages/guides/src/Files.php @@ -20,6 +20,7 @@ use function count; use function in_array; +use function sort; /** @implements IteratorAggregate */ final class Files implements IteratorAggregate, Countable @@ -34,6 +35,7 @@ public function add(string $filename): void } $this->files[] = $filename; + sort($this->files); } /** @return Iterator */ diff --git a/packages/guides/src/Handlers/ParseDirectoryCommand.php b/packages/guides/src/Handlers/ParseDirectoryCommand.php index 87a8c63ce..369d54ccc 100644 --- a/packages/guides/src/Handlers/ParseDirectoryCommand.php +++ b/packages/guides/src/Handlers/ParseDirectoryCommand.php @@ -15,12 +15,13 @@ use Flyfinder\Specification\SpecificationInterface; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Nodes\ProjectNode; final class ParseDirectoryCommand { public function __construct( - private readonly FilesystemInterface $origin, + private readonly FilesystemInterface|FileSystem $origin, private readonly string $directory, private readonly string $inputFormat, private readonly ProjectNode $projectNode, @@ -28,7 +29,7 @@ public function __construct( ) { } - public function getOrigin(): FilesystemInterface + public function getOrigin(): FilesystemInterface|FileSystem { return $this->origin; } diff --git a/packages/guides/src/Handlers/ParseDirectoryHandler.php b/packages/guides/src/Handlers/ParseDirectoryHandler.php index 8851e4b80..870943191 100644 --- a/packages/guides/src/Handlers/ParseDirectoryHandler.php +++ b/packages/guides/src/Handlers/ParseDirectoryHandler.php @@ -16,6 +16,7 @@ use InvalidArgumentException; use League\Flysystem\FilesystemInterface; use League\Tactician\CommandBus; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Event\PostCollectFilesForParsingEvent; use phpDocumentor\Guides\Event\PostParseProcess; use phpDocumentor\Guides\Event\PreParseProcess; @@ -87,7 +88,7 @@ public function handle(ParseDirectoryCommand $command): array } private function getDirectoryIndexFile( - FilesystemInterface $filesystem, + FilesystemInterface|FileSystem $filesystem, string $directory, string $sourceFormat, ): string { diff --git a/packages/guides/src/Handlers/ParseFileCommand.php b/packages/guides/src/Handlers/ParseFileCommand.php index fd406ccbf..276a5bd67 100644 --- a/packages/guides/src/Handlers/ParseFileCommand.php +++ b/packages/guides/src/Handlers/ParseFileCommand.php @@ -14,12 +14,13 @@ namespace phpDocumentor\Guides\Handlers; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Nodes\ProjectNode; final class ParseFileCommand { public function __construct( - private readonly FilesystemInterface $origin, + private readonly FilesystemInterface|FileSystem $origin, private readonly string $directory, private readonly string $file, private readonly string $extension, @@ -29,7 +30,7 @@ public function __construct( ) { } - public function getOrigin(): FilesystemInterface + public function getOrigin(): FilesystemInterface|FileSystem { return $this->origin; } diff --git a/packages/guides/src/Handlers/ParseFileHandler.php b/packages/guides/src/Handlers/ParseFileHandler.php index f68262caf..a26bab570 100644 --- a/packages/guides/src/Handlers/ParseFileHandler.php +++ b/packages/guides/src/Handlers/ParseFileHandler.php @@ -15,6 +15,7 @@ use InvalidArgumentException; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Event\PostParseDocument; use phpDocumentor\Guides\Event\PreParseDocument; use phpDocumentor\Guides\Nodes\DocumentNode; @@ -53,7 +54,7 @@ public function handle(ParseFileCommand $command): DocumentNode|null ); } - private function getFileContents(FilesystemInterface $origin, string $file): string + private function getFileContents(FilesystemInterface|FileSystem $origin, string $file): string { if (!$origin->has($file)) { throw new InvalidArgumentException(sprintf('File at path %s does not exist', $file)); @@ -69,7 +70,7 @@ private function getFileContents(FilesystemInterface $origin, string $file): str } private function createDocument( - FilesystemInterface $origin, + FilesystemInterface|FileSystem $origin, string $documentFolder, string $fileName, string $extension, diff --git a/packages/guides/src/Handlers/RenderCommand.php b/packages/guides/src/Handlers/RenderCommand.php index 0f61f3f8f..175b28544 100644 --- a/packages/guides/src/Handlers/RenderCommand.php +++ b/packages/guides/src/Handlers/RenderCommand.php @@ -14,6 +14,7 @@ namespace phpDocumentor\Guides\Handlers; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Nodes\DocumentNode; use phpDocumentor\Guides\Nodes\ProjectNode; use phpDocumentor\Guides\Renderer\DocumentListIterator; @@ -27,8 +28,8 @@ final class RenderCommand public function __construct( private readonly string $outputFormat, private readonly array $documentArray, - private readonly FilesystemInterface $origin, - private readonly FilesystemInterface $destination, + private readonly FilesystemInterface|FileSystem $origin, + private readonly FilesystemInterface|FileSystem $destination, private readonly ProjectNode $projectNode, private readonly string $destinationPath = '/', ) { @@ -57,12 +58,12 @@ public function getDocumentIterator(): DocumentListIterator return $this->documentIterator; } - public function getOrigin(): FilesystemInterface + public function getOrigin(): FilesystemInterface|FileSystem { return $this->origin; } - public function getDestination(): FilesystemInterface + public function getDestination(): FilesystemInterface|FileSystem { return $this->destination; } diff --git a/packages/guides/src/Parser.php b/packages/guides/src/Parser.php index 7c5bb3ef6..c04ad7bfb 100644 --- a/packages/guides/src/Parser.php +++ b/packages/guides/src/Parser.php @@ -13,9 +13,9 @@ namespace phpDocumentor\Guides; -use League\Flysystem\Adapter\Local; -use League\Flysystem\Filesystem; use League\Flysystem\FilesystemInterface; +use phpDocumentor\FileSystem\FileSystem as FileSystemAlias; +use phpDocumentor\FileSystem\FlySystemAdapter; use phpDocumentor\Guides\Nodes\DocumentNode; use phpDocumentor\Guides\Nodes\ProjectNode; use phpDocumentor\Guides\ReferenceResolvers\DocumentNameResolverInterface; @@ -52,7 +52,7 @@ public function registerStrategy(MarkupLanguageParser $strategy): void /** @psalm-assert ParserContext $this->parserContext */ public function prepare( - FilesystemInterface|null $origin, + FilesystemInterface|FileSystemAlias|null $origin, string $sourcePath, string $fileName, ProjectNode $projectNode, @@ -61,7 +61,7 @@ public function prepare( if ($origin === null) { $cwd = getcwd(); Assert::string($cwd); - $origin = new Filesystem(new Local($cwd)); + $origin = FlySystemAdapter::createForPath($cwd); } $this->parserContext = $this->createParserContext( @@ -106,7 +106,7 @@ private function determineParser(string $fileExtension): MarkupLanguageParser private function createParserContext( string $sourcePath, string $file, - FilesystemInterface $origin, + FilesystemInterface|FileSystemAlias $origin, int $initialHeaderLevel, ProjectNode $projectNode, ): ParserContext { diff --git a/packages/guides/src/ParserContext.php b/packages/guides/src/ParserContext.php index 04de44364..fc4311406 100644 --- a/packages/guides/src/ParserContext.php +++ b/packages/guides/src/ParserContext.php @@ -16,6 +16,7 @@ use League\Flysystem\FilesystemInterface; use League\Uri\Uri; use League\Uri\UriInfo; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Nodes\ProjectNode; use phpDocumentor\Guides\ReferenceResolvers\DocumentNameResolverInterface; @@ -29,7 +30,7 @@ public function __construct( private readonly string $currentFileName, private readonly string $currentDirectory, private readonly int $initialHeaderLevel, - private readonly FilesystemInterface $origin, + private readonly FilesystemInterface|FileSystem $origin, private readonly DocumentNameResolverInterface $documentNameResolver, ) { } @@ -78,7 +79,7 @@ public function getLoggerInformation(): array ]; } - public function getOrigin(): FilesystemInterface + public function getOrigin(): FilesystemInterface|FileSystem { return $this->origin; } diff --git a/packages/guides/src/RenderContext.php b/packages/guides/src/RenderContext.php index 813100ad7..bc8e52b64 100644 --- a/packages/guides/src/RenderContext.php +++ b/packages/guides/src/RenderContext.php @@ -16,6 +16,7 @@ use Exception; use League\Flysystem\FilesystemInterface; use LogicException; +use phpDocumentor\FileSystem\FileSystem; use phpDocumentor\Guides\Nodes\DocumentNode; use phpDocumentor\Guides\Nodes\DocumentTree\DocumentEntryNode; use phpDocumentor\Guides\Nodes\Node; @@ -36,8 +37,8 @@ class RenderContext private function __construct( private readonly string $destinationPath, private readonly string|null $currentFileName, - private readonly FilesystemInterface $origin, - private readonly FilesystemInterface $destination, + private readonly FilesystemInterface|FileSystem $origin, + private readonly FilesystemInterface|FileSystem $destination, private readonly string $outputFormat, private readonly ProjectNode $projectNode, ) { @@ -47,8 +48,8 @@ private function __construct( public static function forDocument( DocumentNode $documentNode, array $allDocumentNodes, - FilesystemInterface $origin, - FilesystemInterface $destination, + FilesystemInterface|FileSystem $origin, + FilesystemInterface|FileSystem $destination, string $destinationPath, string $ouputFormat, ProjectNode $projectNode, @@ -105,8 +106,8 @@ public function withIterator(Renderer\DocumentListIterator $iterator): self public static function forProject( ProjectNode $projectNode, array $allDocumentNodes, - FilesystemInterface $origin, - FilesystemInterface $destination, + FilesystemInterface|FileSystem $origin, + FilesystemInterface|FileSystem $destination, string $destinationPath, string $ouputFormat, ): self { @@ -194,7 +195,7 @@ public function getLoggerInformation(): array ]; } - public function getOrigin(): FilesystemInterface + public function getOrigin(): FilesystemInterface|FileSystem { return $this->origin; } @@ -209,7 +210,7 @@ public function getDestinationPath(): string return $this->destinationPath; } - public function getDestination(): FilesystemInterface + public function getDestination(): FilesystemInterface|FileSystem { return $this->destination; } diff --git a/packages/guides/src/Twig/AssetsExtension.php b/packages/guides/src/Twig/AssetsExtension.php index 1bcb3fee3..070d79f7e 100644 --- a/packages/guides/src/Twig/AssetsExtension.php +++ b/packages/guides/src/Twig/AssetsExtension.php @@ -13,10 +13,8 @@ namespace phpDocumentor\Guides\Twig; -use League\Flysystem\Exception; use League\Uri\Uri; use League\Uri\UriInfo; -use LogicException; use phpDocumentor\Guides\Meta\InternalTarget; use phpDocumentor\Guides\Meta\Target; use phpDocumentor\Guides\NodeRenderers\NodeRenderer; @@ -28,6 +26,7 @@ use Psr\Log\LoggerInterface; use RuntimeException; use Stringable; +use Throwable; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; use Twig\TwigTest; @@ -190,7 +189,7 @@ private function copyAsset( $renderContext->getLoggerInformation(), ); } - } catch (LogicException | Exception $e) { + } catch (Throwable $e) { $this->logger->error( sprintf('Unable to write file "%s", %s', $outputPath, $e->getMessage()), $renderContext->getLoggerInformation(), diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 19d28e63c..b4dc0dbf8 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -7,6 +7,7 @@ + */packages/filesystem/Flysystem/FilesystemInterface.php packages/*/examples/* tests/*/_* diff --git a/phpstan.neon b/phpstan.neon index dd4993788..b84317f89 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -15,7 +15,7 @@ parameters: treatPhpDocTypesAsCertain: false ignoreErrors: # FlyFinder plugin adds a find method to FlySystem's Filesystem - - '#Call to an undefined method League\\Flysystem\\FilesystemInterface::find\(\)#' + - '#Call to an undefined method League\\Flysystem\\FilesystemInterface\|phpDocumentor\\FileSystem\\FileSystem::find\(\)#' - message: '#Unreachable statement - code above always terminates\.#' @@ -35,6 +35,7 @@ parameters: - packages/guides-restructured-text/src/RestructuredText/Parser/Productions/InlineRules/VariableInlineRule.php paths: + - packages/filesystem/src - packages/guides/src - packages/guides-code/src - packages/guides-cli/src diff --git a/tests/Functional/FunctionalTest.php b/tests/Functional/FunctionalTest.php index ac5103041..e4e688cf2 100644 --- a/tests/Functional/FunctionalTest.php +++ b/tests/Functional/FunctionalTest.php @@ -16,10 +16,11 @@ use Exception; use Gajus\Dindent\Indenter; use League\Flysystem\Filesystem; -use League\Flysystem\Memory\MemoryAdapter; +use League\Flysystem\InMemory\InMemoryFilesystemAdapter; use Monolog\Handler\TestHandler; use Monolog\Logger; use Monolog\LogRecord; +use phpDocumentor\FileSystem\FlySystemAdapter; use phpDocumentor\Guides\ApplicationTestCase; use phpDocumentor\Guides\Compiler\Compiler; use phpDocumentor\Guides\Compiler\CompilerContext; @@ -42,6 +43,8 @@ use function array_shift; use function array_values; use function assert; +use function class_alias; +use function class_exists; use function explode; use function file; use function file_exists; @@ -58,6 +61,10 @@ use const LC_ALL; +if (class_exists('League\Flysystem\Memory\MemoryAdapter')) { + class_alias('League\Flysystem\Memory\MemoryAdapter', 'League\Flysystem\InMemory\InMemoryFilesystemAdapter'); +} + final class FunctionalTest extends ApplicationTestCase { private const SKIP_INDENTER_FILES = ['code-block-diff']; @@ -112,8 +119,8 @@ public function testFunctional( $projectNode->setDocumentEntries([$documentEntry]); $compiler->run([$document], new CompilerContext($projectNode)); - $inputFilesystem = new Filesystem(new MemoryAdapter()); - $inputFilesystem->write('img/test-image.jpg', 'Some image'); + $inputFilesystem = FlySystemAdapter::createFromFileSystem(new Filesystem(new InMemoryFilesystemAdapter())); + $inputFilesystem->put('img/test-image.jpg', 'Some image'); $projectSettings = new ProjectSettings(); @@ -128,7 +135,7 @@ public function testFunctional( $document, [$document], $inputFilesystem, - $outfs = new Filesystem(new MemoryAdapter()), + FlySystemAdapter::createFromFileSystem(new Filesystem(new InMemoryFilesystemAdapter())), '', $format, $projectNode,