diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 0000000..ae05cbe --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,50 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + + phpunit: + name: PHPUnit with PHP ${{ matrix.php }} (${{ matrix.operating-system }}) + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: true + matrix: + operating-system: [macOS-latest, ubuntu-latest ] + php: [ '7.4', '8.0' ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + + - name: Install composer dependencies + uses: ramsey/composer-install@v2 + + - name: Run test suite on PHP ${{ matrix.php }} + run: vendor/bin/phpunit --testdox + + ecs: + name: Easy Coding Standard + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ramsey/composer-install@v2 + - run: vendor/bin/ecs + + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ramsey/composer-install@v2 + - run: vendor/bin/phpstan diff --git a/composer.json b/composer.json index 3f38096..6628021 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,10 @@ "type": "project", "license": "MIT", "bin": ["bin/pure"], + "scripts": { + "test": "vendor/bin/phpunit", + "ecs": "vendor/bin/ecs" + }, "autoload": { "psr-4": { "Pureware\\PurewareCli\\": "src/" @@ -16,15 +20,17 @@ "guzzlehttp/guzzle": "^7", "symfony/console": "^5.0|^6.0", "symfony/process": "^5.0|^6.0", - "symfony/string": "^6.0", + "symfony/string": "^6.0|^5.0", "ext-json": "*", "shopware/core": "^6.4", "shopware/storefront": "^6.4", - "pureware/template-generator": "0.1.0" + "pureware/template-generator": "^0.2.1" }, "require-dev": { "phpunit/phpunit": "^8.0|^9.3", - "symfony/var-dumper": "^6.0", - "phpstan/phpstan": "^1.9" + "symfony/var-dumper": "^6.0|^5.0", + "phpstan/phpstan": "^1.9", + "rector/rector": "^0.14.8", + "symplify/easy-coding-standard": "^11.1" } } diff --git a/composer.lock b/composer.lock index 897671e..fcc75c8 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": "ae3f8b07892d777d1abfbab47b58e953", + "content-hash": "8896c0bcc2705df1592f5993d60782cd", "packages": [ { "name": "aws/aws-crt-php", @@ -58,16 +58,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.242.0", + "version": "3.246.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "cab6d4f830ce275a1742a3e35e2625917b006dd2" + "reference": "90859d0b704d80a7f5b0743766562f956e43c79d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cab6d4f830ce275a1742a3e35e2625917b006dd2", - "reference": "cab6d4f830ce275a1742a3e35e2625917b006dd2", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/90859d0b704d80a7f5b0743766562f956e43c79d", + "reference": "90859d0b704d80a7f5b0743766562f956e43c79d", "shasum": "" }, "require": { @@ -146,32 +146,32 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.242.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.246.0" }, - "time": "2022-11-10T19:15:37+00:00" + "time": "2022-11-18T19:56:22+00:00" }, { "name": "brick/math", - "version": "0.10.2", + "version": "0.9.3", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.4 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.0", - "vimeo/psalm": "4.25.0" + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.9.2" }, "type": "library", "autoload": { @@ -196,15 +196,19 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.10.2" + "source": "https://github.com/brick/math/tree/0.9.3" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" } ], - "time": "2022-08-10T22:54:19+00:00" + "time": "2021-08-15T20:50:18+00:00" }, { "name": "cocur/slugify", @@ -2930,31 +2934,30 @@ }, { "name": "illuminate/collections", - "version": "v9.39.0", + "version": "v8.83.26", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "1729899f8e37840738d1c37bb110da5b09509990" + "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/1729899f8e37840738d1c37bb110da5b09509990", - "reference": "1729899f8e37840738d1c37bb110da5b09509990", + "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", + "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", "shasum": "" }, "require": { - "illuminate/conditionable": "^9.0", - "illuminate/contracts": "^9.0", - "illuminate/macroable": "^9.0", - "php": "^8.0.2" + "illuminate/contracts": "^8.0", + "illuminate/macroable": "^8.0", + "php": "^7.3|^8.0" }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^6.0)." + "symfony/var-dumper": "Required to use the dump method (^5.4)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { @@ -2981,77 +2984,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-11-07T11:40:33+00:00" - }, - { - "name": "illuminate/conditionable", - "version": "v9.39.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/conditionable.git", - "reference": "5b40f51ccb07e0e7b1ec5559d8db9e0e2dc51883" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/conditionable/zipball/5b40f51ccb07e0e7b1ec5559d8db9e0e2dc51883", - "reference": "5b40f51ccb07e0e7b1ec5559d8db9e0e2dc51883", - "shasum": "" - }, - "require": { - "php": "^8.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Conditionable package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2022-07-29T19:44:19+00:00" + "time": "2022-06-23T15:29:49+00:00" }, { "name": "illuminate/contracts", - "version": "v9.39.0", + "version": "v8.83.26", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "c7cc6e6198cac6dfdead111f9758de25413188b7" + "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/c7cc6e6198cac6dfdead111f9758de25413188b7", - "reference": "c7cc6e6198cac6dfdead111f9758de25413188b7", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", + "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", "shasum": "" }, "require": { - "php": "^8.0.2", - "psr/container": "^1.1.1|^2.0.1", - "psr/simple-cache": "^1.0|^2.0|^3.0" + "php": "^7.3|^8.0", + "psr/container": "^1.0", + "psr/simple-cache": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { @@ -3075,29 +3032,29 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-10-31T22:25:40+00:00" + "time": "2022-01-13T14:47:47+00:00" }, { "name": "illuminate/macroable", - "version": "v9.39.0", + "version": "v8.83.26", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a" + "reference": "aed81891a6e046fdee72edd497f822190f61c162" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/e3bfaf6401742a9c6abca61b9b10e998e5b6449a", - "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", + "reference": "aed81891a6e046fdee72edd497f822190f61c162", "shasum": "" }, "require": { - "php": "^8.0.2" + "php": "^7.3|^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { @@ -3121,7 +3078,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-08-09T13:29:29+00:00" + "time": "2021-11-16T13:57:03+00:00" }, { "name": "jdorn/sql-formatter", @@ -3315,31 +3272,31 @@ }, { "name": "lcobucci/clock", - "version": "2.2.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3" + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/fb533e093fd61321bfcbac08b131ce805fe183d3", - "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/353d83fe2e6ae95745b16b3d911813df6a05bfb3", + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3", "shasum": "" }, "require": { - "php": "^8.0", - "stella-maris/clock": "^0.1.4" + "php": "^7.4 || ^8.0" }, "require-dev": { - "infection/infection": "^0.26", - "lcobucci/coding-standard": "^8.0", - "phpstan/extension-installer": "^1.1", + "infection/infection": "^0.17", + "lcobucci/coding-standard": "^6.0", + "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-deprecation-rules": "^0.12", "phpstan/phpstan-phpunit": "^0.12", "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^9.5" + "phpunit/php-code-coverage": "9.1.4", + "phpunit/phpunit": "9.3.7" }, "type": "library", "autoload": { @@ -3360,7 +3317,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/2.2.0" + "source": "https://github.com/lcobucci/clock/tree/2.0.x" }, "funding": [ { @@ -3372,7 +3329,7 @@ "type": "patreon" } ], - "time": "2022-04-19T19:34:17+00:00" + "time": "2020-08-27T18:56:02+00:00" }, { "name": "lcobucci/jwt", @@ -3774,16 +3731,16 @@ }, { "name": "league/oauth2-server", - "version": "8.3.5", + "version": "8.3.6", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-server.git", - "reference": "7aeb7c42b463b1a6fe4d084d3145e2fa22436876" + "reference": "28c5441716c10d0c936bd731860dc385d0f6d1a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/7aeb7c42b463b1a6fe4d084d3145e2fa22436876", - "reference": "7aeb7c42b463b1a6fe4d084d3145e2fa22436876", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/28c5441716c10d0c936bd731860dc385d0f6d1a8", + "reference": "28c5441716c10d0c936bd731860dc385d0f6d1a8", "shasum": "" }, "require": { @@ -3850,7 +3807,7 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-server/issues", - "source": "https://github.com/thephpleague/oauth2-server/tree/8.3.5" + "source": "https://github.com/thephpleague/oauth2-server/tree/8.3.6" }, "funding": [ { @@ -3858,7 +3815,7 @@ "type": "github" } ], - "time": "2022-05-03T21:21:28+00:00" + "time": "2022-11-14T19:42:00+00:00" }, { "name": "league/uri", @@ -4975,25 +4932,25 @@ }, { "name": "psr/simple-cache", - "version": "3.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", "shasum": "" }, "require": { - "php": ">=8.0.0" + "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -5008,7 +4965,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interfaces for simple caching", @@ -5020,34 +4977,35 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + "source": "https://github.com/php-fig/simple-cache/tree/master" }, - "time": "2021-10-29T13:26:27+00:00" + "time": "2017-10-23T01:57:42+00:00" }, { "name": "pureware/template-generator", - "version": "0.1.0", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/pureware/template-generator.git", - "reference": "d0118308db8b3c461ae9b769f0254fd934510fbb" + "reference": "ba63d7ac70ecf1b28150f55c809290f59c367677" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pureware/template-generator/zipball/d0118308db8b3c461ae9b769f0254fd934510fbb", - "reference": "d0118308db8b3c461ae9b769f0254fd934510fbb", + "url": "https://api.github.com/repos/pureware/template-generator/zipball/ba63d7ac70ecf1b28150f55c809290f59c367677", + "reference": "ba63d7ac70ecf1b28150f55c809290f59c367677", "shasum": "" }, "require": { - "illuminate/collections": "^9.30", - "php": "^8.0", + "illuminate/collections": "^9.30|^8.83", + "php": "^7.4|^8.0", "symfony/filesystem": "~5.4.0", "symfony/finder": "~5.4.0", "twig/string-extra": "~3.3.5" }, "require-dev": { "phpunit/phpunit": "^9.5", - "symfony/var-dumper": "^6.0" + "rector/rector": "^0.14.8", + "symfony/var-dumper": "^6.0|^5.0" }, "type": "twig", "autoload": { @@ -5068,9 +5026,9 @@ "description": "PHP based file generator with twig templates", "support": { "issues": "https://github.com/pureware/template-generator/issues", - "source": "https://github.com/pureware/template-generator/tree/0.1.0" + "source": "https://github.com/pureware/template-generator/tree/0.2.1" }, - "time": "2022-11-02T11:12:08+00:00" + "time": "2022-11-19T15:00:41+00:00" }, { "name": "queue-interop/amqp-interop", @@ -5291,23 +5249,25 @@ }, { "name": "ramsey/uuid", - "version": "4.6.0", + "version": "4.2.3", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f" + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/ad63bc700e7d021039e30ce464eba384c4a1d40f", - "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10", + "brick/math": "^0.8 || ^0.9", "ext-json": "*", - "php": "^8.0", - "ramsey/collection": "^1.0" + "php": "^7.2 || ^8.0", + "ramsey/collection": "^1.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-php80": "^1.14" }, "replace": { "rhumsaa/uuid": "self.version" @@ -5319,23 +5279,24 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", + "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -5343,6 +5304,9 @@ }, "type": "library", "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + }, "captainhook": { "force-install": true } @@ -5367,7 +5331,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.6.0" + "source": "https://github.com/ramsey/uuid/tree/4.2.3" }, "funding": [ { @@ -5379,7 +5343,7 @@ "type": "tidelift" } ], - "time": "2022-11-05T23:03:38+00:00" + "time": "2021-09-25T23:10:38+00:00" }, { "name": "react/promise", @@ -6315,53 +6279,6 @@ }, "time": "2020-01-22T14:45:26+00:00" }, - { - "name": "stella-maris/clock", - "version": "0.1.6", - "source": { - "type": "git", - "url": "https://github.com/stella-maris-solutions/clock.git", - "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/a94228dac03c9a8411198ce8c8dacbbe99c930c3", - "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3", - "shasum": "" - }, - "require": { - "php": "^7.0|^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "StellaMaris\\Clock\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andreas Heigl", - "role": "Maintainer" - } - ], - "description": "A pre-release of the proposed PSR-20 Clock-Interface", - "homepage": "https://gitlab.com/stella-maris/clock", - "keywords": [ - "clock", - "datetime", - "point in time", - "psr20" - ], - "support": { - "issues": "https://github.com/stella-maris-solutions/clock/issues", - "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.6" - }, - "time": "2022-09-27T15:03:11+00:00" - }, { "name": "superbalist/flysystem-google-storage", "version": "7.2.2", @@ -7147,31 +7064,32 @@ }, { "name": "symfony/doctrine-messenger", - "version": "v6.0.12", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "d1ee96c9b765da63a0f422b17a038dba974176ec" + "reference": "7649a80e917b47c5072480a2d763c2422da239d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/d1ee96c9b765da63a0f422b17a038dba974176ec", - "reference": "d1ee96c9b765da63a0f422b17a038dba974176ec", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/7649a80e917b47c5072480a2d763c2422da239d2", + "reference": "7649a80e917b47c5072480a2d763c2422da239d2", "shasum": "" }, "require": { - "doctrine/dbal": "^2.13|^3.0", - "php": ">=8.0.2", - "symfony/messenger": "^5.4|^6.0", + "php": ">=7.2.5", + "symfony/messenger": "^5.1|^6.0", "symfony/service-contracts": "^1.1|^2|^3" }, "conflict": { + "doctrine/dbal": "<2.13", "doctrine/persistence": "<1.3" }, "require-dev": { + "doctrine/dbal": "^2.13|^3.0", "doctrine/persistence": "^1.3|^2|^3", - "symfony/property-access": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/property-access": "^4.4|^5.0|^6.0", + "symfony/serializer": "^4.4|^5.0|^6.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -7199,7 +7117,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v6.0.12" + "source": "https://github.com/symfony/doctrine-messenger/tree/v5.4.12" }, "funding": [ { @@ -7215,7 +7133,7 @@ "type": "tidelift" } ], - "time": "2022-08-12T13:08:57+00:00" + "time": "2022-08-09T12:54:00+00:00" }, { "name": "symfony/dotenv", @@ -8064,29 +7982,37 @@ }, { "name": "symfony/intl", - "version": "v6.0.15", + "version": "v5.4.15", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "3377841a596c69da08086c50e09a37f2b5b1b598" + "reference": "2cb39da7f6e7b7344d7d5317dbee8db9d12cc714" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/3377841a596c69da08086c50e09a37f2b5b1b598", - "reference": "3377841a596c69da08086c50e09a37f2b5b1b598", + "url": "https://api.github.com/repos/symfony/intl/zipball/2cb39da7f6e7b7344d7d5317dbee8db9d12cc714", + "reference": "2cb39da7f6e7b7344d7d5317dbee8db9d12cc714", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "symfony/filesystem": "^5.4|^6.0" + "symfony/filesystem": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Symfony\\Component\\Intl\\": "" }, + "classmap": [ + "Resources/stubs" + ], "exclude-from-classmap": [ "/Tests/" ] @@ -8124,7 +8050,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.0.15" + "source": "https://github.com/symfony/intl/tree/v5.4.15" }, "funding": [ { @@ -8140,25 +8066,27 @@ "type": "tidelift" } ], - "time": "2022-10-23T10:33:07+00:00" + "time": "2022-10-19T14:28:49+00:00" }, { "name": "symfony/lock", - "version": "v6.0.15", + "version": "v5.4.15", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "5fcddddbfb46917d457d51f31914a4ca630bea7e" + "reference": "109a20faa6119578b46457ef8cffb9389e20e5ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/5fcddddbfb46917d457d51f31914a4ca630bea7e", - "reference": "5fcddddbfb46917d457d51f31914a4ca630bea7e", + "url": "https://api.github.com/repos/symfony/lock/zipball/109a20faa6119578b46457ef8cffb9389e20e5ca", + "reference": "109a20faa6119578b46457ef8cffb9389e20e5ca", "shasum": "" }, "require": { - "php": ">=8.0.2", - "psr/log": "^1|^2|^3" + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "doctrine/dbal": "<2.13" @@ -8201,7 +8129,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v6.0.15" + "source": "https://github.com/symfony/lock/tree/v5.4.15" }, "funding": [ { @@ -8217,7 +8145,7 @@ "type": "tidelift" } ], - "time": "2022-10-28T16:22:58+00:00" + "time": "2022-10-27T07:55:40+00:00" }, { "name": "symfony/mailer", @@ -8705,27 +8633,28 @@ }, { "name": "symfony/password-hasher", - "version": "v6.0.11", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "7ff6706266cbe55310d029b42299eb6e2bebe849" + "reference": "b0169ed8f09a4ae39eb119218ea1685079a9b179" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/7ff6706266cbe55310d029b42299eb6e2bebe849", - "reference": "7ff6706266cbe55310d029b42299eb6e2bebe849", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/b0169ed8f09a4ae39eb119218ea1685079a9b179", + "reference": "b0169ed8f09a4ae39eb119218ea1685079a9b179", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/security-core": "<5.4" + "symfony/security-core": "<5.3" }, "require-dev": { - "symfony/console": "^5.4|^6.0", - "symfony/security-core": "^5.4|^6.0" + "symfony/console": "^5.3|^6.0", + "symfony/security-core": "^5.3|^6.0" }, "type": "library", "autoload": { @@ -8757,7 +8686,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v6.0.11" + "source": "https://github.com/symfony/password-hasher/tree/v5.4.11" }, "funding": [ { @@ -8773,7 +8702,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T14:06:08+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "symfony/polyfill-ctype", @@ -10290,78 +10219,6 @@ ], "time": "2022-07-20T13:00:38+00:00" }, - { - "name": "symfony/security-csrf", - "version": "v5.4.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/security-csrf.git", - "reference": "b97ab244b6dda80abb84a4a236d682871695db4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/b97ab244b6dda80abb84a4a236d682871695db4a", - "reference": "b97ab244b6dda80abb84a4a236d682871695db4a", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16", - "symfony/security-core": "^4.4|^5.0|^6.0" - }, - "conflict": { - "symfony/http-foundation": "<5.3" - }, - "require-dev": { - "symfony/http-foundation": "^5.3|^6.0" - }, - "suggest": { - "symfony/http-foundation": "For using the class SessionTokenStorage." - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Security\\Csrf\\": "" - }, - "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": "Symfony Security Component - CSRF Library", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/security-csrf/tree/v5.4.11" - }, - "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-07-20T13:00:38+00:00" - }, { "name": "symfony/serializer", "version": "v5.4.15", @@ -10608,33 +10465,34 @@ }, { "name": "symfony/string", - "version": "v6.0.15", + "version": "v5.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771" + "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/51ac0fa0ccf132a00519b87c97e8f775fa14e771", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771", + "url": "https://api.github.com/repos/symfony/string/zipball/571334ce9f687e3e6af72db4d3b2a9431e4fd9ed", + "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": ">=3.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" + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -10673,7 +10531,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.15" + "source": "https://github.com/symfony/string/tree/v5.4.15" }, "funding": [ { @@ -10689,7 +10547,7 @@ "type": "tidelift" } ], - "time": "2022-10-10T09:34:08+00:00" + "time": "2022-10-05T15:16:54+00:00" }, { "name": "symfony/translation", @@ -11191,31 +11049,32 @@ }, { "name": "symfony/var-dumper", - "version": "v6.0.14", + "version": "v5.4.14", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "72af925ddd41ca0372d166d004bc38a00c4608cc" + "reference": "6894d06145fefebd9a4c7272baa026a1c394a430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/72af925ddd41ca0372d166d004bc38a00c4608cc", - "reference": "72af925ddd41ca0372d166d004bc38a00c4608cc", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6894d06145fefebd9a4c7272baa026a1c394a430", + "reference": "6894d06145fefebd9a4c7272baa026a1c394a430", "shasum": "" }, "require": { - "php": ">=8.0.2", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "phpunit/phpunit": "<5.4.3", - "symfony/console": "<5.4" + "symfony/console": "<4.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/uid": "^5.1|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -11259,7 +11118,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.14" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.14" }, "funding": [ { @@ -11275,7 +11134,7 @@ "type": "tidelift" } ], - "time": "2022-10-07T08:02:12+00:00" + "time": "2022-10-07T08:01:20+00:00" }, { "name": "symfony/var-exporter", @@ -11899,16 +11758,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", "shasum": "" }, "require": { @@ -11949,9 +11808,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-11-12T15:38:23+00:00" }, { "name": "phar-io/manifest", @@ -12125,16 +11984,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.18", + "version": "9.2.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", "shasum": "" }, "require": { @@ -12190,7 +12049,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" }, "funding": [ { @@ -12198,7 +12057,7 @@ "type": "github" } ], - "time": "2022-10-27T13:35:33+00:00" + "time": "2022-11-18T07:47:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12543,6 +12402,63 @@ ], "time": "2022-10-28T06:00:21+00:00" }, + { + "name": "rector/rector", + "version": "0.14.8", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "46ee9a173a2b2645ca92a75ffc17460139fa226e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/46ee9a173a2b2645ca92a75ffc17460139fa226e", + "reference": "46ee9a173a2b2645ca92a75ffc17460139fa226e", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-php-parser": "*", + "rector/rector-phpoffice": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.14-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.14.8" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-11-14T14:09:49+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.1", @@ -13507,6 +13423,61 @@ ], "time": "2020-09-28T06:39:44+00:00" }, + { + "name": "symplify/easy-coding-standard", + "version": "11.1.17", + "source": { + "type": "git", + "url": "https://github.com/symplify/easy-coding-standard.git", + "reference": "2a98e5b976a3ab573d8e5604d6eb39d9f5783760" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/2a98e5b976a3ab573d8e5604d6eb39d9f5783760", + "reference": "2a98e5b976a3ab573d8e5604d6eb39d9f5783760", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "friendsofphp/php-cs-fixer": "<3.0", + "squizlabs/php_codesniffer": "<3.6" + }, + "bin": [ + "bin/ecs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.3-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Prefixed scoped version of ECS package", + "support": { + "source": "https://github.com/symplify/easy-coding-standard/tree/11.1.17" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-11-10T15:20:49+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.1", @@ -13568,5 +13539,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..9b6492d --- /dev/null +++ b/ecs.php @@ -0,0 +1,24 @@ +paths([__DIR__ . '/src', __DIR__ . '/tests']); + + $ecsConfig->ruleWithConfiguration(ArraySyntaxFixer::class, [ + 'syntax' => 'short', + ]); + + $ecsConfig->sets([ + SetList::SPACES, + SetList::ARRAY, + SetList::DOCBLOCK, + SetList::PSR_12, + ]); + + $ecsConfig->skip([__DIR__ . '/src/Resources']); +}; diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..d43cee2 --- /dev/null +++ b/rector.php @@ -0,0 +1,28 @@ +sets([ + SetList::DEAD_CODE, + SetList::PHP_74 + ]); + $rectorConfig->paths( + [ + __DIR__ . '/src', + __DIR__ . '/tests' + ] + ); + $rectorConfig->skip( + [ + __DIR__ . '/src/Resources' + ] + ); +}; diff --git a/src/Command/AbstractMakeCommand.php b/src/Command/AbstractMakeCommand.php index 80162e5..69994e8 100644 --- a/src/Command/AbstractMakeCommand.php +++ b/src/Command/AbstractMakeCommand.php @@ -1,4 +1,5 @@ addOption('force', 'f', InputOption::VALUE_NONE, 'Override files. Be careful when using!') - ->addOption('workingDir', null, InputOption::VALUE_OPTIONAL, 'The path where you want to create the new plugin', null); + ->addOption('workingDir', null, InputOption::VALUE_OPTIONAL, 'The path where you want to create the data', null); parent::configure(); } - protected function getNamespaceResolver(): NamespaceResolverInterface { + protected function getNamespaceResolver(): NamespaceResolverInterface + { $pluginNamespaceResolver = new PluginNamespaceResolver(); $composerJson = null; $composerJsonPath = getcwd() . DIRECTORY_SEPARATOR . 'composer.json'; @@ -44,8 +43,8 @@ protected function getNamespaceResolver(): NamespaceResolverInterface { return $pluginNamespaceResolver; } - protected function renderMaker(DirectoryCollection $dirs, InputInterface $input, OutputInterface $output, NamespaceResolverInterface $namespaceResolver): void { - + protected function renderMaker(DirectoryCollection $dirs, InputInterface $input, OutputInterface $output, NamespaceResolverInterface $namespaceResolver): void + { $io = new SymfonyStyle($input, $output); $workingPath = $namespaceResolver->getWorkingDir(); $home = $_SERVER['HOME']; @@ -58,14 +57,14 @@ protected function renderMaker(DirectoryCollection $dirs, InputInterface $input, } } - protected function renderDir(Directory $directory, SymfonyStyle $io, int $depth = 0): void { - + protected function renderDir(Directory $directory, SymfonyStyle $io, int $depth = 0): void + { /** @var File $file */ foreach ($directory->getFiles() as $file) { $this->addFile($io, $file->getParsedFileName(), $depth + 1); } - if (!$directory->getDirectories()) { + if ($directory->getDirectories() === null) { return; } @@ -74,9 +73,9 @@ protected function renderDir(Directory $directory, SymfonyStyle $io, int $depth } } - protected function addFile(SymfonyStyle $io, string $path, int $depth = 0): void { + protected function addFile(SymfonyStyle $io, string $path, int $depth = 0): void + { $space = str_repeat(" ", $depth); $io->writeln(sprintf('|%s -- %s', $space, $path)); } - } diff --git a/src/Command/Admin/MakeAdminComponentCommand.php b/src/Command/Admin/MakeAdminComponentCommand.php index ea8ac6d..cbb1d6c 100644 --- a/src/Command/Admin/MakeAdminComponentCommand.php +++ b/src/Command/Admin/MakeAdminComponentCommand.php @@ -1,8 +1,11 @@ setName(self::$defaultName) ->setDescription('Create new component for a given Admin Module') ->addArgument('name', InputArgument::REQUIRED, 'The name of the Admin Component in PascalCase or camelCase') - ->addOption('module', 'm',InputOption::VALUE_REQUIRED, 'Name of a given module like sw-cms', null); + ->addOption('module', 'm', InputOption::VALUE_REQUIRED, 'Name of a given module like sw-cms', null); parent::configure(); } @@ -31,6 +36,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $dirs = (new AdminComponentMaker())->make($namespaceResolver, $input); $this->renderMaker($dirs, $input, $output, $namespaceResolver); + MainJsImportGenerator::instance()->generate($input, $output, $namespaceResolver); + return Command::SUCCESS; } } diff --git a/src/Command/Admin/MakeAdminComponentOverrideCommand.php b/src/Command/Admin/MakeAdminComponentOverrideCommand.php index da8cd60..397d7ad 100644 --- a/src/Command/Admin/MakeAdminComponentOverrideCommand.php +++ b/src/Command/Admin/MakeAdminComponentOverrideCommand.php @@ -3,6 +3,7 @@ namespace Pureware\PurewareCli\Command\Admin; use Pureware\PurewareCli\Command\AbstractMakeCommand; +use Pureware\PurewareCli\Generator\MainJs\MainJsImportGenerator; use Pureware\PurewareCli\Maker\Admin\AdminComponentMaker; use Pureware\PurewareCli\Maker\Admin\AdminComponentOverrideMaker; use Symfony\Component\Console\Command\Command; @@ -13,7 +14,9 @@ class MakeAdminComponentOverrideCommand extends AbstractMakeCommand { - /** @var string */ + /** + * @var string + */ protected static $defaultName = 'make:admin-component-override'; protected function configure(): void @@ -30,6 +33,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new AdminComponentOverrideMaker())->make($namespaceResolver, $input); $this->renderMaker($dirs, $input, $output, $namespaceResolver); + (MainJsImportGenerator::instance())->generate($input, $output, $namespaceResolver); return Command::SUCCESS; } diff --git a/src/Command/Admin/MakeAdminModuleCommand.php b/src/Command/Admin/MakeAdminModuleCommand.php index 203265d..23101f2 100644 --- a/src/Command/Admin/MakeAdminModuleCommand.php +++ b/src/Command/Admin/MakeAdminModuleCommand.php @@ -3,6 +3,8 @@ namespace Pureware\PurewareCli\Command\Admin; use Pureware\PurewareCli\Command\AbstractMakeCommand; +use Pureware\PurewareCli\Generator\MainJs\MainJsImport; +use Pureware\PurewareCli\Generator\MainJs\MainJsImportGenerator; use Pureware\PurewareCli\Maker\Admin\AdminComponentMaker; use Pureware\PurewareCli\Maker\Admin\AdminModuleMaker; use Symfony\Component\Console\Command\Command; @@ -13,7 +15,9 @@ class MakeAdminModuleCommand extends AbstractMakeCommand { - /** @var string */ + /** + * @var string + */ protected static $defaultName = 'make:admin-module'; protected function configure(): void @@ -25,7 +29,7 @@ protected function configure(): void ->addOption('prefix', null, InputOption::VALUE_REQUIRED, 'The prefix for the module', '') ->addOption('navigationParent', null, InputOption::VALUE_REQUIRED, 'The menu entry you want to add link the new module', 'sw-catalogue') ->addOption('moduleColor', null, InputOption::VALUE_OPTIONAL, 'The color for the module', '#ff3d58') - ->addOption('snippetLanguages', 's',InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); + ->addOption('snippetLanguages', 's', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); parent::configure(); } @@ -34,8 +38,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new AdminModuleMaker())->make($namespaceResolver, $input); $this->renderMaker($dirs, $input, $output, $namespaceResolver); + (MainJsImportGenerator::instance())->generate($input, $output, $namespaceResolver); return Command::SUCCESS; } } - diff --git a/src/Command/CliCommand/MakeCliCommandCommand.php b/src/Command/CliCommand/MakeCliCommandCommand.php new file mode 100644 index 0000000..0230edf --- /dev/null +++ b/src/Command/CliCommand/MakeCliCommandCommand.php @@ -0,0 +1,41 @@ +setName(self::$defaultName) + ->addArgument('name', InputArgument::REQUIRED, 'The name of the Command') + ->addOption('prefix', null, InputOption::VALUE_OPTIONAL, 'The vendor prefix for command name in cli', '') + ->addOption('cliName', 'c', InputOption::VALUE_OPTIONAL, 'The name to run inside the terminal', null) + ->setDescription('Create a CLI Command'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $namespaceResolver = $this->getNamespaceResolver(); + $dirs = (new CliCommandMaker())->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); + $this->renderMaker($dirs, $input, $output, $namespaceResolver); + + return Command::SUCCESS; + } +} diff --git a/src/Command/Cms/MakeCmsBlockCommand.php b/src/Command/Cms/MakeCmsBlockCommand.php index f28a2e1..61b7f8c 100644 --- a/src/Command/Cms/MakeCmsBlockCommand.php +++ b/src/Command/Cms/MakeCmsBlockCommand.php @@ -3,6 +3,7 @@ namespace Pureware\PurewareCli\Command\Cms; use Pureware\PurewareCli\Command\AbstractMakeCommand; +use Pureware\PurewareCli\Generator\MainJs\MainJsImportGenerator; use Pureware\PurewareCli\Maker\Cms\CmsBlockMaker; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -12,7 +13,9 @@ class MakeCmsBlockCommand extends AbstractMakeCommand { - /** @var string */ + /** + * @var string + */ protected static $defaultName = 'make:cms-block'; protected function configure(): void @@ -22,8 +25,8 @@ protected function configure(): void ->setName(self::$defaultName) ->setDescription('Create new CMS Block') ->addArgument('name', InputArgument::REQUIRED, 'The name of the CMS Block') - ->addOption('category', 'c',InputOption::VALUE_OPTIONAL, 'Choose one Category for the CMS Block ' . $categories, 'commerce') - ->addOption('snippetLanguages', 's',InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); + ->addOption('category', 'c', InputOption::VALUE_OPTIONAL, 'Choose one Category for the CMS Block ' . $categories, 'commerce') + ->addOption('snippetLanguages', 's', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); parent::configure(); } @@ -32,6 +35,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new CmsBlockMaker())->make($namespaceResolver, $input); $this->renderMaker($dirs, $input, $output, $namespaceResolver); + (MainJsImportGenerator::instance())->generate($input, $output, $namespaceResolver); return Command::SUCCESS; } diff --git a/src/Command/Cms/MakeCmsElementCommand.php b/src/Command/Cms/MakeCmsElementCommand.php index 8df4601..5eddef7 100644 --- a/src/Command/Cms/MakeCmsElementCommand.php +++ b/src/Command/Cms/MakeCmsElementCommand.php @@ -3,6 +3,7 @@ namespace Pureware\PurewareCli\Command\Cms; use Pureware\PurewareCli\Command\AbstractMakeCommand; +use Pureware\PurewareCli\Generator\MainJs\MainJsImportGenerator; use Pureware\PurewareCli\Maker\Cms\CmsElementMaker; use Pureware\PurewareCli\Maker\Cms\CmsElementResolverMaker; use Symfony\Component\Console\Command\Command; @@ -13,7 +14,9 @@ class MakeCmsElementCommand extends AbstractMakeCommand { - /** @var string */ + /** + * @var string + */ protected static $defaultName = 'make:cms-element'; protected function configure(): void @@ -23,7 +26,7 @@ protected function configure(): void ->addArgument('name', InputArgument::REQUIRED, 'The name of the CMS Element') ->setDescription('Create new CMS Element') ->addOption('resolver', 'r', InputOption::VALUE_NONE, 'Generate ams resolver', null) - ->addOption('snippetLanguages', 's',InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); + ->addOption('snippetLanguages', 's', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Additional migration name', ['de-DE', 'en-GB']); parent::configure(); } @@ -32,6 +35,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new CmsElementMaker(new CmsElementResolverMaker()))->make($namespaceResolver, $input); $this->renderMaker($dirs, $input, $output, $namespaceResolver); + (MainJsImportGenerator::instance())->generate($input, $output, $namespaceResolver); return Command::SUCCESS; } diff --git a/src/Command/Cms/MakeCmsElementResolverCommand.php b/src/Command/Cms/MakeCmsElementResolverCommand.php index 77cd073..0431a1e 100644 --- a/src/Command/Cms/MakeCmsElementResolverCommand.php +++ b/src/Command/Cms/MakeCmsElementResolverCommand.php @@ -2,6 +2,7 @@ namespace Pureware\PurewareCli\Command\Cms; +use Pureware\PurewareCli\Generator\ContainerConfig\ServiceTagGenerator; use Pureware\PurewareCli\Maker\Cms\CmsElementResolverMaker; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -10,7 +11,9 @@ class MakeCmsElementResolverCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { - /** @var string */ + /** + * @var string + */ protected static $defaultName = 'make:cms-resolver'; protected function configure(): void @@ -26,6 +29,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new CmsElementResolverMaker())->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); $this->renderMaker($dirs, $input, $output, $namespaceResolver); return Command::SUCCESS; diff --git a/src/Command/Common/ExecInContainerCommand.php b/src/Command/Common/ExecInContainerCommand.php new file mode 100644 index 0000000..5ca26ba --- /dev/null +++ b/src/Command/Common/ExecInContainerCommand.php @@ -0,0 +1,54 @@ +setName(self::$defaultName) + ->setDescription('Execute bash inside container') + ->addOption('dockerImage', 'd', InputOption::VALUE_OPTIONAL, 'The docker image name', 'shop'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $command = sprintf('docker compose exec %s bash', $input->getOption('dockerImage')); + + $cli = Process::fromShellCommandline($command, null, null, null, null); + $cli->setTty(true); + + $cli->run(function ($type, $line) use ($output) { + $output->write($line); + }); + + return Command::SUCCESS; + } +} diff --git a/src/Command/Common/RunPhpStanCommand.php b/src/Command/Common/RunPhpStanCommand.php index fe6c0f3..3ac59d9 100644 --- a/src/Command/Common/RunPhpStanCommand.php +++ b/src/Command/Common/RunPhpStanCommand.php @@ -24,14 +24,12 @@ class RunPhpStanCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'phpstan'; - public function __construct(string $name = null) - { - parent::__construct($name); - } - - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -53,5 +51,4 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } - } diff --git a/src/Command/Common/RunPhpUnitCommand.php b/src/Command/Common/RunPhpUnitCommand.php index ce199bc..9dc43ca 100644 --- a/src/Command/Common/RunPhpUnitCommand.php +++ b/src/Command/Common/RunPhpUnitCommand.php @@ -24,45 +24,40 @@ class RunPhpUnitCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'test:phpunit'; - public function __construct(string $name = null) - { - parent::__construct($name); - } - - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) ->setDescription('Run PHP Unit inside the docker container') ->addArgument('pluginName', InputArgument::OPTIONAL, 'The name of the plugin you want to test. (optional, default will be the current plugin)', null) - ->addOption('container', 'c', InputOption::VALUE_OPTIONAL , 'The docker container name', 'shop_plugin') - ->addOption('options', null, InputOption::VALUE_OPTIONAL , 'The options that are added to the phpunit command as string i.e. --options="--testdox"', '--colors=always --testdox'); + ->addOption('dockerImage', 'd', InputOption::VALUE_OPTIONAL, 'The docker image name', 'shop') + ->addOption('options', null, InputOption::VALUE_OPTIONAL, 'The options that are added to the phpunit command as string i.e. --options="--testdox"', '--colors=always --testdox'); parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output): int { - $pluginName = $input->getArgument('pluginName'); - if (!$input->getArgument('pluginName')) { + if (! $input->getArgument('pluginName')) { $resolver = $this->getNamespaceResolver(); $pluginName = $resolver->getPluginName(); } - $command = sprintf('docker exec %s vendor/bin/phpunit --configuration="%s" %s', $input->getOption('container'), 'custom/plugins/' . $pluginName, $input->getOption('options')); + $command = sprintf('docker compose exec %s vendor/bin/phpunit --configuration="%s" %s', $input->getOption('dockerImage'), 'custom/plugins/' . $pluginName, $input->getOption('options')); + // $command = sprintf('docker exec %s vendor/bin/phpunit --configuration="%s" %s', $input->getOption('container'), ); - $cli = Process::fromShellCommandline($command, null, null, null, 240); + $cli = Process::fromShellCommandline($command, null, null, null, null); $cli->setTty(true); $cli->run(function ($type, $line) use ($output) { $output->write($line); }); - - return Command::SUCCESS; } - } diff --git a/src/Command/Controller/MakeControllerCommand.php b/src/Command/Controller/MakeControllerCommand.php new file mode 100644 index 0000000..b67a7ee --- /dev/null +++ b/src/Command/Controller/MakeControllerCommand.php @@ -0,0 +1,47 @@ +setName(self::$defaultName) + ->setDescription('Create new controller either for storefront or admin api') + ->addArgument('name', InputArgument::REQUIRED, 'The name of the Controller') + ->addOption('routeScope', 's', InputOption::VALUE_REQUIRED, 'Name of the routeScope. Can be storefront or api', 'storefront') + ->addOption('basicRoute', 'r', InputOption::VALUE_REQUIRED, 'Name of a route inside the controller', 'exampleRoute') + ->addOption('method', 'm', InputOption::VALUE_REQUIRED, 'Http Method. Can be: GET, POST, PUT, HEAD, DELETE, PATCH, OPTIONS, CONNECT, TRACE', 'GET') + ->addOption('isAjax', 'x', InputOption::VALUE_NONE, 'Add XmlHttpRequest to annotation'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $namespaceResolver = $this->getNamespaceResolver(); + $dirs = (new ControllerMaker())->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); + RouteImportGenerator::instance()->generate($input, $output, $namespaceResolver); + $this->renderMaker($dirs, $input, $output, $namespaceResolver); + + return Command::SUCCESS; + } +} diff --git a/src/Command/Entity/MakeEntityCommand.php b/src/Command/Entity/MakeEntityCommand.php index e82df45..be8fd53 100644 --- a/src/Command/Entity/MakeEntityCommand.php +++ b/src/Command/Entity/MakeEntityCommand.php @@ -2,6 +2,7 @@ namespace Pureware\PurewareCli\Command\Entity; +use Pureware\PurewareCli\Generator\ContainerConfig\ServiceTagGenerator; use Pureware\PurewareCli\Maker\Entity\EntityMaker; use Pureware\PurewareCli\Maker\Entity\HydratorMaker; use Pureware\PurewareCli\Maker\Entity\Many2ManyMaker; @@ -23,14 +24,12 @@ class MakeEntityCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'make:entity'; - public function __construct(string $name = null) - { - parent::__construct($name); - } - - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -48,9 +47,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new EntityMaker(new MigrationMaker(), new HydratorMaker(), new Many2ManyMaker(), new TranslationMaker()))->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); $this->renderMaker($dirs, $input, $output, $namespaceResolver); return Command::SUCCESS; } - } diff --git a/src/Command/Entity/MakeEntityExtensionCommand.php b/src/Command/Entity/MakeEntityExtensionCommand.php new file mode 100644 index 0000000..897ce39 --- /dev/null +++ b/src/Command/Entity/MakeEntityExtensionCommand.php @@ -0,0 +1,37 @@ +setName(self::$defaultName) + ->setDescription('Create new entity extension') + ->addArgument('name', InputArgument::REQUIRED, 'The entity name in PascalCase'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $namespaceResolver = $this->getNamespaceResolver(); + $dirs = (new EntityExtensionMaker())->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); + $this->renderMaker($dirs, $input, $output, $namespaceResolver); + + return Command::SUCCESS; + } +} diff --git a/src/Command/Entity/MakeEntityHydratorCommand.php b/src/Command/Entity/MakeEntityHydratorCommand.php index 33f9fbc..8c4bb77 100644 --- a/src/Command/Entity/MakeEntityHydratorCommand.php +++ b/src/Command/Entity/MakeEntityHydratorCommand.php @@ -21,9 +21,12 @@ class MakeEntityHydratorCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'make:entity:hydrator'; - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -37,11 +40,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $namespaceResolver = $this->getNamespaceResolver(); $dirs = (new HydratorMaker())->make($namespaceResolver, $input, [ 'entityName' => $input->getArgument('name'), - 'workingDir' => $input->getOption('workingDir') + 'workingDir' => $input->getOption('workingDir'), ]); $this->renderMaker($dirs, $input, $output, $namespaceResolver); return Command::SUCCESS; } - } diff --git a/src/Command/Entity/MakeEntityMany2ManyMappingCommand.php b/src/Command/Entity/MakeEntityMany2ManyMappingCommand.php index 6571414..d830689 100644 --- a/src/Command/Entity/MakeEntityMany2ManyMappingCommand.php +++ b/src/Command/Entity/MakeEntityMany2ManyMappingCommand.php @@ -22,9 +22,12 @@ class MakeEntityMany2ManyMappingCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'make:entity:many2many'; - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -40,11 +43,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $dirs = (new Many2ManyMaker())->make($namespaceResolver, $input, [ 'entityName' => $input->getArgument('name'), 'workingDir' => $input->getOption('workingDir'), - 'prefix' => $input->getOption('prefix') + 'prefix' => $input->getOption('prefix'), ]); $this->renderMaker($dirs, $input, $output, $namespaceResolver); return Command::SUCCESS; } - } diff --git a/src/Command/Entity/MakeEntityTranslationCommand.php b/src/Command/Entity/MakeEntityTranslationCommand.php index 90d7776..17391f7 100644 --- a/src/Command/Entity/MakeEntityTranslationCommand.php +++ b/src/Command/Entity/MakeEntityTranslationCommand.php @@ -22,9 +22,12 @@ class MakeEntityTranslationCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'make:entity:translation'; - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -42,25 +45,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int 'parentClass' => $namespaceResolver->getFullNamespace($input->getArgument('parentEntity')), 'entityName' => $this->resolveEntityName($input, $namespaceResolver), 'workingDir' => $this->resolveWorkingDir($input, $namespaceResolver), - 'entityPrefix' => $input->getOption('prefix') + 'entityPrefix' => $input->getOption('prefix'), ]); $this->renderMaker($dirs, $input, $output, $namespaceResolver); return Command::SUCCESS; } - protected function resolveEntityName(InputInterface $input, NamespaceResolverInterface $namespaceResolver): string { + protected function resolveEntityName(InputInterface $input, NamespaceResolverInterface $namespaceResolver): string + { $path = $namespaceResolver->getWorkingDir($input->getArgument('parentEntity')); return basename($path); } - protected function resolveWorkingDir(InputInterface $input, NamespaceResolverInterface $namespaceResolver): string { + protected function resolveWorkingDir(InputInterface $input, NamespaceResolverInterface $namespaceResolver): string + { if ($input->getOption('workingDir')) { return $namespaceResolver->getWorkingDir($input->getOption('workingDir')); } $inputEntity = str_replace('\\', '/', $input->getArgument('parentEntity')); - $directory = explode( '/', $inputEntity); + $directory = explode('/', $inputEntity); array_pop($directory); $entityDirectory = implode('/', $directory); @@ -70,5 +75,4 @@ protected function resolveWorkingDir(InputInterface $input, NamespaceResolverInt return $entityDirectory; } - } diff --git a/src/Command/New/NewPluginCommand.php b/src/Command/Generators/NewPluginCommand.php similarity index 84% rename from src/Command/New/NewPluginCommand.php rename to src/Command/Generators/NewPluginCommand.php index 8873359..2474117 100644 --- a/src/Command/New/NewPluginCommand.php +++ b/src/Command/Generators/NewPluginCommand.php @@ -1,5 +1,6 @@ setName('new:plugin') @@ -28,18 +27,16 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output): int { - $output->writeln(PHP_EOL." + $output->writeln(PHP_EOL . " _____ _ _ _____ ______ | __ \| | | | __ \| ____| | |__) | | | | |__) | |__ | ___/| | | | _ /| __| | | | |__| | | \ \| |____ -|_| \____/|_| \_\______| ".PHP_EOL.PHP_EOL); +|_| \____/|_| \_\______| " . PHP_EOL . PHP_EOL); - $output->writeln('Pure installer'); + $output->writeln(PHP_EOL); return (new PluginGenerator())->generate($input, $output); - - return self::SUCCESS; } } diff --git a/src/Command/Migration/MakeMigrationCommand.php b/src/Command/Migration/MakeMigrationCommand.php index 2503889..8e6d88e 100644 --- a/src/Command/Migration/MakeMigrationCommand.php +++ b/src/Command/Migration/MakeMigrationCommand.php @@ -20,9 +20,12 @@ class MakeMigrationCommand extends \Pureware\PurewareCli\Command\AbstractMakeCommand { + /** + * @var string + */ protected static $defaultName = 'make:migration'; - protected function configure() + protected function configure(): void { $this ->setName(self::$defaultName) @@ -36,10 +39,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int $input->setOption('force', true); $suffix = (new UnicodeString(implode(' ', $input->getArgument('suffix'))))->camel()->title(); $namespaceResolver = $this->getNamespaceResolver(); - $dirs = (new MigrationMaker())->make($namespaceResolver, $input, ['suffix' => $suffix]); + $dirs = (new MigrationMaker())->make($namespaceResolver, $input, [ + 'suffix' => $suffix, + ]); $this->renderMaker($dirs, $input, $output, $namespaceResolver); - return Command::SUCCESS; } } diff --git a/src/Command/ScheduledTask/MakeScheduledTaskCommand.php b/src/Command/ScheduledTask/MakeScheduledTaskCommand.php new file mode 100644 index 0000000..caf7af6 --- /dev/null +++ b/src/Command/ScheduledTask/MakeScheduledTaskCommand.php @@ -0,0 +1,40 @@ +setName(self::$defaultName) + ->addArgument('name', InputArgument::REQUIRED, 'The name of the Scheduled Task') + ->addOption('prefix', null, InputOption::VALUE_OPTIONAL, 'The vendor prefix to your custom task, to prevent collisions with other plugins scheduled tasks', '') + ->addOption('interval', null, InputOption::VALUE_REQUIRED, 'The interval in seconds at which your scheduled task should be executed', '300') + ->setDescription('Create a Scheduled Task and a Scheduled Task Handler'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $namespaceResolver = $this->getNamespaceResolver(); + $dirs = (new ScheduledTaskMaker())->make($namespaceResolver, $input); + ServiceTagGenerator::instance()->generate($input, $output, $namespaceResolver); + $this->renderMaker($dirs, $input, $output, $namespaceResolver); + + return Command::SUCCESS; + } +} diff --git a/src/DependencyInjection/CommandsToApplicationCompilerPass.php b/src/DependencyInjection/CommandsToApplicationCompilerPass.php index a10feb3..7a134f6 100644 --- a/src/DependencyInjection/CommandsToApplicationCompilerPass.php +++ b/src/DependencyInjection/CommandsToApplicationCompilerPass.php @@ -1,4 +1,5 @@ getDefinition(Application::class); + $applicationDefinition = $container->getDefinition(Application::class); - foreach ($containerBuilder->getDefinitions() as $name => $definition) { - if (is_a($definition->getClass(), Command::class, true)) { + foreach ($container->getDefinitions() as $name => $definition) { + if (is_a($definition->getClass() ?: '', Command::class, true)) { $applicationDefinition->addMethodCall('add', [new Reference($name)]); } } diff --git a/src/Generator/ContainerConfig/AbstractService.php b/src/Generator/ContainerConfig/AbstractService.php new file mode 100644 index 0000000..0a53d91 --- /dev/null +++ b/src/Generator/ContainerConfig/AbstractService.php @@ -0,0 +1,24 @@ +xmlNode = $xmlNode; + return $this; + } + + public function setServiceId(string $serviceId): ServiceInterface + { + $this->serviceId = $serviceId; + return $this; + } +} diff --git a/src/Generator/ContainerConfig/ScheduledTask.php b/src/Generator/ContainerConfig/ScheduledTask.php new file mode 100644 index 0000000..521a498 --- /dev/null +++ b/src/Generator/ContainerConfig/ScheduledTask.php @@ -0,0 +1,39 @@ + + + + + + + + '; + + return sprintf($template, $this->serviceId, $this->handlerServiceId); + } + + public function getIdentifier(): string + { + return sprintf('<%s id="%s"', $this->xmlNode, $this->serviceId); + } + + public function getHandlerServiceId(): string + { + return $this->handlerServiceId; + } + + public function setHandlerServiceId(string $handlerServiceId): self + { + $this->handlerServiceId = $handlerServiceId; + return $this; + } +} diff --git a/src/Generator/ContainerConfig/ServiceController.php b/src/Generator/ContainerConfig/ServiceController.php new file mode 100644 index 0000000..d359780 --- /dev/null +++ b/src/Generator/ContainerConfig/ServiceController.php @@ -0,0 +1,23 @@ + + + + + '; + + return sprintf($template, $this->xmlNode, $this->serviceId, $this->xmlNode); + } + + public function getIdentifier(): string + { + return sprintf('<%s id="%s"', $this->xmlNode, $this->serviceId); + } +} diff --git a/src/Generator/ContainerConfig/ServiceEntityTag.php b/src/Generator/ContainerConfig/ServiceEntityTag.php new file mode 100644 index 0000000..cd17d17 --- /dev/null +++ b/src/Generator/ContainerConfig/ServiceEntityTag.php @@ -0,0 +1,60 @@ + + + '; + + return sprintf($template, $this->xmlNode, $this->serviceId, $this->tag, $this->entityName, $this->xmlNode); + } + + public function getIdentifier(): string + { + return sprintf('<%s id="%s">', $this->xmlNode, $this->serviceId); + } + + public function setXmlNode(string $xmlNode): self + { + $this->xmlNode = $xmlNode; + return $this; + } + + public function setServiceId(string $serviceId): self + { + $this->serviceId = $serviceId; + return $this; + } + + public function setTag(string $tag): self + { + $this->tag = $tag; + return $this; + } + + public function getEntityName(): string + { + return $this->entityName; + } + + public function setEntityName(string $entityId): self + { + $this->entityName = $entityId; + return $this; + } +} diff --git a/src/Generator/ContainerConfig/ServiceFactory.php b/src/Generator/ContainerConfig/ServiceFactory.php new file mode 100644 index 0000000..dda137e --- /dev/null +++ b/src/Generator/ContainerConfig/ServiceFactory.php @@ -0,0 +1,36 @@ +setServiceId($namespace) + ->setTag($tag); + } + + public function generateEntityServiceTag(string $namespace, string $tag, string $entity): ServiceInterface + { + return (new ServiceEntityTag()) + ->setEntityName($entity) + ->setServiceId($namespace) + ->setTag($tag); + } + + public function generateServiceController(string $namespace): ServiceInterface + { + return (new ServiceController()) + ->setServiceId($namespace); + } + + public function generateScheduledTask(string $taskNamespace, string $handlerNamespace): ServiceInterface + { + return (new ScheduledTask()) + ->setHandlerServiceId($handlerNamespace) + ->setServiceId($taskNamespace); + } +} diff --git a/src/Generator/ContainerConfig/ServiceInterface.php b/src/Generator/ContainerConfig/ServiceInterface.php new file mode 100644 index 0000000..36fc8bb --- /dev/null +++ b/src/Generator/ContainerConfig/ServiceInterface.php @@ -0,0 +1,12 @@ + + + '; + + return sprintf($template, $this->xmlNode, $this->serviceId, $this->tag, $this->xmlNode); + } + + public function getIdentifier(): string + { + return sprintf('<%s id="%s">', $this->xmlNode, $this->serviceId); + } + + public function setXmlNode(string $xmlNode): self + { + $this->xmlNode = $xmlNode; + return $this; + } + + public function setServiceId(string $serviceId): self + { + $this->serviceId = $serviceId; + return $this; + } + + public function setTag(string $tag): self + { + $this->tag = $tag; + return $this; + } +} diff --git a/src/Generator/ContainerConfig/ServiceTagGenerator.php b/src/Generator/ContainerConfig/ServiceTagGenerator.php new file mode 100644 index 0000000..b8aa72e --- /dev/null +++ b/src/Generator/ContainerConfig/ServiceTagGenerator.php @@ -0,0 +1,88 @@ + + */ + private array $services = []; + + protected function __construct() + { + } + + public function __wakeup() + { + throw new \Exception("Cannot unserialize a singleton."); + } + + public static function instance(): ServiceTagGenerator + { + if (! isset(self::$instance)) { + self::$instance = new ServiceTagGenerator(); + } + + return self::$instance; + } + + public function generate(InputInterface $input, OutputInterface $output, NamespaceResolverInterface $namespaceResolver): void + { + $path = $namespaceResolver->getWorkingDir('Resources/Config/services.xml'); + // @todo output message that trying to add service tag in this file + + if (! file_exists($path)) { + return; + } + + if (file_get_contents($path)) { + $servicesFile = file_get_contents($path); + } else { + throw new \RuntimeException('Could not read servicesFile ' . $path); + } + $newContent = ''; + + foreach ($this->services as $service) { + if (str_contains($servicesFile, $service->getIdentifier())) { + // @todo output message service tag already included + continue; + } + + $newContent .= str_repeat(' ', 4) . trim($service->getTemplate()); + } + + if ('' === $newContent) { + // @todo output message not new service added + return; + } + + $endTag = ''; + if (! str_contains($endTag, $servicesFile)) { + $output->writeln(sprintf('Could not add service tag automatically. No Tag found in file %s', $path)); + $output->writeln('Register following services to DI Container'); + $output->writeln($newContent); + return; + } + $servicesFile = str_replace($endTag, $newContent . PHP_EOL . PHP_EOL . str_repeat(' ', 4) . $endTag, $servicesFile); + + $fileSystem = new Filesystem(); + $fileSystem->dumpFile($path, $servicesFile); //@todo catch error + } + + public function addService(ServiceInterface $service): self + { + $this->services[] = $service; + + return $this; + } +} diff --git a/src/Generator/MainJs/ImportInterface.php b/src/Generator/MainJs/ImportInterface.php new file mode 100644 index 0000000..9bbc08c --- /dev/null +++ b/src/Generator/MainJs/ImportInterface.php @@ -0,0 +1,12 @@ +importPath + ); + } + + public function getIdentifier(): string + { + return $this->importPath; + } + + public function getImportPath(): string + { + return $this->importPath; + } + + public function setImportPath(string $importPath): self + { + $this->importPath = $importPath; + return $this; + } +} diff --git a/src/Generator/MainJs/MainJsImportFactory.php b/src/Generator/MainJs/MainJsImportFactory.php new file mode 100644 index 0000000..a9b0c86 --- /dev/null +++ b/src/Generator/MainJs/MainJsImportFactory.php @@ -0,0 +1,13 @@ +setImportPath($path); + } +} diff --git a/src/Generator/MainJs/MainJsImportGenerator.php b/src/Generator/MainJs/MainJsImportGenerator.php new file mode 100644 index 0000000..45f9e69 --- /dev/null +++ b/src/Generator/MainJs/MainJsImportGenerator.php @@ -0,0 +1,82 @@ + + */ + private array $imports = []; + + protected function __construct() + { + } + + public function __wakeup() + { + throw new \Exception("Cannot unserialize a singleton."); + } + + public static function instance(): MainJsImportGenerator + { + if (! isset(self::$instance)) { + self::$instance = new MainJsImportGenerator(); + } + + return self::$instance; + } + + public function generate(InputInterface $input, OutputInterface $output, NamespaceResolverInterface $namespaceResolver): void + { + $path = $namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'); + // @todo output message that trying to add import + $fileSystem = new Filesystem(); + + if (! file_exists($path)) { + $fileSystem->touch($path); + return; + } + + if (file_get_contents($path)) { + $mainJsFileContent = file_get_contents($path); + } else { + throw new \RuntimeException('Could not read servicesFile ' . $path); + } + $newContent = ''; + + foreach ($this->imports as $import) { + if (str_contains($mainJsFileContent, $import->getIdentifier())) { + // @todo output message service tag already included + continue; + } + + $newContent .= trim($import->getTemplate()); + } + + if ('' === $newContent) { + // @todo output message not new service added + return; + } + + $content = $mainJsFileContent . PHP_EOL . $newContent; + + $fileSystem->dumpFile($path, $content); + } + + public function addImport(ImportInterface $service): self + { + $this->imports[] = $service; + + return $this; + } +} diff --git a/src/Generator/Plugin/PluginGenerator.php b/src/Generator/Plugin/PluginGenerator.php index 43e22df..7b1d761 100644 --- a/src/Generator/Plugin/PluginGenerator.php +++ b/src/Generator/Plugin/PluginGenerator.php @@ -8,6 +8,7 @@ use Pureware\TemplateGenerator\TreeBuilder\TreeBuilder; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\Input; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; @@ -19,25 +20,43 @@ class PluginGenerator implements GeneratorInterface { public const DEFAULT_VERSION = '6.4.15.0'; + private ?string $pluginName = null; + private ?string $workingDir = null; + private string $namespace; + private string $composerName; + private string $shopwareVersion; - public function generate(Input $input, Output $output): int + public function generate(InputInterface $input, OutputInterface $output): int { $this->pluginName = $input->getArgument('pluginName'); $io = new SymfonyStyle($input, $output); - $io->progressStart(4); - if (!$this->pluginName) { - $this->pluginName = $io->ask('Name of the plugin'); + $io->progressStart($this->pluginName ? 3 : 4); + if (! $this->pluginName) { + $this->pluginName = $io->ask('Name of the plugin in PascalCase'); + $io->writeln(''); + $io->progressAdvance(1); + } + + + if (empty($this->pluginName)) { + throw new \RuntimeException('You need to pass a plugin name'); } + $this->resolveNamespace(); + $io->writeln(''); + $this->namespace = $io->ask('Base namespace (leave empty to accept)', $this->namespace); /** @todo validate input */ + $io->progressAdvance(1); + $this->shopwareVersion = $input->getOption('shopwareVersion') ?? $this->getLatestShopwareVersion(); $dockwareVersion = $this->getDockwareVersion($input->getOption('shopwareVersion')); - if (version_compare($this->shopwareVersion, $dockwareVersion, '==') === false) { + $io->info('Checking shopware and dockware version...'); + if (! version_compare($this->shopwareVersion, $dockwareVersion, '==')) { $io->warning(sprintf('Could not match the dockware version for shopware v%s. Latest dockware is %s', $this->shopwareVersion, $dockwareVersion)); if ($io->askQuestion(new ConfirmationQuestion('Do you want to choose a dockware and shopware version manually'))) { $dockwareVersion = $io->ask('Input a dockware and shopware version', $dockwareVersion); @@ -45,13 +64,12 @@ public function generate(Input $input, Output $output): int } } - if (version_compare($this->shopwareVersion, '6', '>=') === false) { + if (! version_compare($this->shopwareVersion, '6', '>=')) { throw new \RuntimeException('The Plugin Generator only works for shopware 6'); } + $io->progressAdvance(1); - $this->resolveNamespace(); - - $this->namespace = $io->ask('Base namespace', $this->namespace); /** @todo validate input */ + $io->info('Generating plugin...'); $workingDir = $input->getOption('workingDir') ?? getcwd(); $this->workingDir = rtrim($workingDir, DIRECTORY_SEPARATOR); @@ -68,29 +86,26 @@ public function generate(Input $input, Output $output): int 'composerDescriptionDe' => $this->pluginName, 'phpVersion' => version_compare('6.5', $this->shopwareVersion) > 0 ? '^7.4.3 || ^8.0' : '^8.0', 'dockwarePhpVersion' => version_compare('6.5', $this->shopwareVersion) > 0 ? '7.4' : '8.0', - 'shopwareVersion' => '~' . pathinfo( $this->shopwareVersion, PATHINFO_FILENAME), + 'shopwareVersion' => '~' . pathinfo($this->shopwareVersion, PATHINFO_FILENAME), 'dockwareVersion' => $dockwareVersion, - 'containerName' => 'shop_plugin' + 'containerName' => 'shop_plugin', ] ); - $io->progressAdvance(1); $generator = new DirectoryGenerator($pluginPath, $parser); if ($input->getOption('force')) { $generator->setForce(true); } - $directory = (new TreeBuilder())->buildTree(__DIR__ . '/../../Resources/skeleton/Plugin', $this->pluginName); - $io->progressAdvance(1); + $directory = (new TreeBuilder())->buildTree(__DIR__ . '/../../Resources/skeleton/Plugin', $this->pluginName ?: ''); $generator->generate($directory); + $io->info('Installing composer dependencies...'); + $commands = [ - $this->findComposer() . ' install --working-dir=' . $pluginPath, - $this->findComposer() . ' require --dev phpstan/phpstan phpunit/phpunit --working-dir=' . $pluginPath, - sprintf('echo "%s"' - , 'PURE installed composer dependencies'), - sprintf('ls -la %s', $pluginPath) + $this->findComposer() . ' install -q --working-dir=' . $pluginPath, + $this->findComposer() . ' require -q --dev phpstan/phpstan phpunit/phpunit --working-dir=' . $pluginPath ]; $this->executeCommands($commands, $output); @@ -99,8 +114,8 @@ public function generate(Input $input, Output $output): int $messages = [ '', - sprintf(' ✓ %s %s: %s', $this->pluginName, 'Plugin created. Change directory', str_replace($_SERVER['HOME'], '~', $pluginPath)), - '✓ Installed composer dependencies' + sprintf('✓ %s %s: %s', $this->pluginName, 'Plugin created. Change directory', str_replace($_SERVER['HOME'], '~', $pluginPath)), + '✓ Installed composer dependencies', ]; if ($input->getOption('git')) { @@ -111,12 +126,11 @@ public function generate(Input $input, Output $output): int $io->success($messages); return Command::SUCCESS; - } - public function resolveNamespace(): void { - - $snakeCase = (new UnicodeString($this->pluginName))->camel()->title()->snake(); + public function resolveNamespace(): void + { + $snakeCase = (new UnicodeString($this->pluginName ?: ''))->camel()->title()->snake(); $strings = explode('_', $snakeCase); if (count($strings) < 2) { throw new \RuntimeException('Could not resolve a namespace for this plugin name. Provide a name with a prefix i.e. SwagPlugin'); @@ -135,13 +149,14 @@ protected function findComposer(): string $composerPath = getcwd() . '/composer.phar'; if (file_exists($composerPath)) { - return '"'.PHP_BINARY.'" '.$composerPath; + return '"' . PHP_BINARY . '" ' . $composerPath; } return 'composer'; } - private function initGit(OutputInterface $output, string $branch): void { + private function initGit(OutputInterface $output, string $branch): void + { if (file_exists($this->workingDir . DIRECTORY_SEPARATOR . $this->pluginName . DIRECTORY_SEPARATOR . '.git')) { $output->write('Git already exists. Skipping.'); return; @@ -158,10 +173,14 @@ private function initGit(OutputInterface $output, string $branch): void { $this->executeCommands($commands, $output); } - protected function executeCommands($commands, OutputInterface $output): Process + /** + * @param array $commands + */ + protected function executeCommands(array $commands, OutputInterface $output): Process { - $cli = Process::fromShellCommandline(implode(' && ', $commands)); - $cli->setTty(true); + $cli = Process::fromShellCommandline(implode(' && ', $commands), null, null,null,280 ); + $cli->disableOutput(); + $cli->setTty(false); $cli->run(function ($type, $line) use ($output) { $output->write($line); @@ -170,39 +189,36 @@ protected function executeCommands($commands, OutputInterface $output): Process return $cli; } - protected function getLatestShopwareVersion(): string { - + protected function getLatestShopwareVersion(): string + { try { $client = new \GuzzleHttp\Client(); $get = $client->get('https://api.github.com/repos/shopware/platform/releases/latest', [ - 'content-type' => 'application/json' + 'content-type' => 'application/json', ]); $content = $get->getBody()->getContents(); $json = json_decode($content, true); return str_replace('v', '', $json['tag_name']); - } catch (\Exception $exception) { - return self::DEFAULT_VERSION; + return self::DEFAULT_VERSION; } } /** * @param string|null $inputShopwareVersion | if version is not set or not found the latest version tag is returned - * @return string * @throws \GuzzleHttp\Exception\GuzzleException */ private function getDockwareVersion(?string $inputShopwareVersion = null): string { - $client = new \GuzzleHttp\Client(); - $url = 'https://hub.docker.com/v2/repositories/dockware/dev/tags/?page_size=1&page=1'; + $url = 'https://hub.docker.com/v2/repositories/dockware/dev/tags/?page_size=2&page=1'; - if (!is_null($inputShopwareVersion)) { - $url .= '&name=' . $inputShopwareVersion; + if (! is_null($inputShopwareVersion)) { + $url .= '&name=' . $inputShopwareVersion; } $get = $client->get($url, [ - 'content-type' => 'application/json' + 'content-type' => 'application/json', ]); $content = $get->getBody()->getContents(); $json = json_decode($content, true); @@ -211,6 +227,10 @@ private function getDockwareVersion(?string $inputShopwareVersion = null): strin return $this->getDockwareVersion(); } + if ($json['results'][0]['name'] === 'latest') { + return $json['results'][1]['name']; + } + return $json['results'][0]['name']; } } diff --git a/src/Generator/RouteConfig/Route.php b/src/Generator/RouteConfig/Route.php new file mode 100644 index 0000000..c0336e8 --- /dev/null +++ b/src/Generator/RouteConfig/Route.php @@ -0,0 +1,29 @@ +'; + + return sprintf($template, $this->route); + } + + public function getIdentifier(): string + { + return $this->getTemplate(); + } + + public function setRoute(string $route): self + { + $this->route = $route; + + return $this; + } +} diff --git a/src/Generator/RouteConfig/RouteFactory.php b/src/Generator/RouteConfig/RouteFactory.php new file mode 100644 index 0000000..e46abcd --- /dev/null +++ b/src/Generator/RouteConfig/RouteFactory.php @@ -0,0 +1,15 @@ +setRoute($route); + } +} diff --git a/src/Generator/RouteConfig/RouteImportGenerator.php b/src/Generator/RouteConfig/RouteImportGenerator.php new file mode 100644 index 0000000..55bc717 --- /dev/null +++ b/src/Generator/RouteConfig/RouteImportGenerator.php @@ -0,0 +1,99 @@ + + */ + private array $routes = []; + + protected function __construct() + { + } + + public function __wakeup() + { + throw new \Exception("Cannot unserialize a singleton."); + } + + public static function instance(): RouteImportGenerator + { + if (! isset(self::$instance)) { + self::$instance = new RouteImportGenerator(); + } + + return self::$instance; + } + + public function generate(InputInterface $input, OutputInterface $output, NamespaceResolverInterface $namespaceResolver): void + { + if ($input->getOption('workingDir')) { + return; + } + $path = $namespaceResolver->getWorkingDir('Resources/Config/routes.xml'); + + if (! file_exists($path)) { + $this->createRoutesFile($namespaceResolver); + } + + if (file_get_contents($path)) { + $routesFile = file_get_contents($path); + } else { + throw new \RuntimeException('Could not read routesFile ' . $path); + } + $newContent = ''; + + foreach ($this->routes as $route) { + if (str_contains($routesFile, $route->getIdentifier())) { + // @todo output message route already included + continue; + } + + $newContent .= str_repeat(' ', 4) . trim($route->getTemplate()); + } + + if ('' === $newContent) { + // @todo output message no new route added + return; + } + + $endTag = ''; + $routesFile = str_replace($endTag, $newContent . PHP_EOL . $endTag, $routesFile); + + $fileSystem = new Filesystem(); + $fileSystem->dumpFile($path, $routesFile); //@todo catch error + } + + public function addRoute(ServiceInterface $service): self + { + $this->routes[] = $service; + + return $this; + } + + private function createRoutesFile(NamespaceResolverInterface $namespaceResolver): void + { + $twig = new TwigParser(); + $twig->setTemplateData([]); + $generator = new DirectoryGenerator($namespaceResolver->getWorkingDir('Resources/config'), $twig); + + $templatePath = __DIR__ . sprintf('/../../Resources/skeleton/%s', 'Config/Routes'); + $directory = (new TreeBuilder())->buildTree($templatePath, ''); + $generator->generate($directory); + } +} diff --git a/src/Maker/AbstractMaker.php b/src/Maker/AbstractMaker.php index fca2ab6..97da559 100644 --- a/src/Maker/AbstractMaker.php +++ b/src/Maker/AbstractMaker.php @@ -14,20 +14,21 @@ class AbstractMaker implements \Pureware\PurewareCli\Maker\MakerInterface { - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { throw new \RuntimeException('make() method not implemented.'); } - protected function getDirectoryGenerator(NamespaceResolverInterface $namespaceResolver, InputInterface $input, string $directory): GeneratorInterface { + protected function getDirectoryGenerator(NamespaceResolverInterface $namespaceResolver, InputInterface $input, string $directory): GeneratorInterface + { $generator = new DirectoryGenerator($namespaceResolver->getWorkingDir($directory), new TwigParser()); $generator->setForce((bool) $input->getOption('force')); return $generator; } - protected function getTemplatePath(string $subPath): string { + protected function getTemplatePath(string $subPath): string + { return __DIR__ . sprintf('/../Resources/skeleton/%s', $subPath); } @@ -36,11 +37,11 @@ protected function getTemplatePath(string $subPath): string { */ protected function makeSnippetFiles(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - if (!$options['subDirectory']) { + if ($options['subDirectory'] === '' || $options['subDirectory'] === '0') { throw new \RuntimeException('You need to pass a subDirectory to create snippet files'); } - if (!$options['moduleName']) { + if ($options['moduleName'] === '' || $options['moduleName'] === '0') { throw new \RuntimeException('You need to pass a moduleName to create snippet files'); } @@ -52,7 +53,7 @@ protected function makeSnippetFiles(NamespaceResolverInterface $namespaceResolve [ 'locale' => $locale, 'moduleName' => $options['moduleName'], - 'baseSnippet' => $options['baseSnippet'] ?? '' + 'baseSnippet' => $options['baseSnippet'] ?? '', ] ); $generator->setForce(false); // do not override snippet files because the< share data between different components @@ -66,15 +67,13 @@ protected function makeSnippetFiles(NamespaceResolverInterface $namespaceResolve } /** - * @param InputInterface $input - * @param array $options - * @param string|null $default - * @return string + * @param array $options */ - protected function getSubDirectory(InputInterface $input, array $options, ?string $default = null): string { + protected function getSubDirectory(InputInterface $input, array $options, ?string $default = null): string + { $subDirectory = $input->getOption('workingDir') ?? $options['workingDir'] ?? $default; - if (!$subDirectory) { + if (! $subDirectory) { throw new \RuntimeException('You need to pass a workingDir'); } diff --git a/src/Maker/Admin/AdminComponentMaker.php b/src/Maker/Admin/AdminComponentMaker.php index cb6bbd9..bee60d1 100644 --- a/src/Maker/Admin/AdminComponentMaker.php +++ b/src/Maker/Admin/AdminComponentMaker.php @@ -1,24 +1,30 @@ -getOption('workingDir') ?? $options['workingDir'] ?? 'Resources/app/administration/src'; $componentName = $options['componentName'] ?? $input->getArgument('name'); $moduleName = $options['moduleName'] ?? $input->getOption('module'); - if (!$componentName || !$moduleName) { + if (! $componentName || ! $moduleName) { throw new \RuntimeException('You need a componentName and a moduleName to create a component.'); } @@ -27,7 +33,6 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa [ 'moduleName' => $moduleName, 'componentName' => $componentName, - 'mainJsContent' => $this->getMainJsContent($namespaceResolver) ] ); @@ -39,17 +44,13 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $directory = (new TreeBuilder())->buildTree($this->getTemplatePath($templatePath), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($directory); - return (new DirectoryCollection([$directory])); - } - - protected function getMainJsContent(NamespaceResolverInterface $namespaceResolver): string { - $content = ''; + $importModuleName = (new AsciiSlugger())->slug((new UnicodeString($moduleName))->snake()->toString())->toString(); + $importComponentName = (new AsciiSlugger())->slug((new UnicodeString($componentName))->snake()->toString())->toString(); - if (file_exists($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'))) { - $content = file_get_contents($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js')); - } + MainJsImportGenerator::instance()->addImport( + (new MainJsImportFactory())->createImport(sprintf('module/%s/components/%s', $importModuleName, $importComponentName)) + ); - return is_string($content) ? $content : ''; + return (new DirectoryCollection([$directory])); } - } diff --git a/src/Maker/Admin/AdminComponentOverrideMaker.php b/src/Maker/Admin/AdminComponentOverrideMaker.php index 990fd96..0481989 100644 --- a/src/Maker/Admin/AdminComponentOverrideMaker.php +++ b/src/Maker/Admin/AdminComponentOverrideMaker.php @@ -1,23 +1,29 @@ -getArgument('name'); - if (!$componentName) { + if (! $componentName) { throw new \RuntimeException('You need a componentName to override a component.'); } @@ -25,24 +31,17 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $generator->getParser()->setTemplateData( [ 'componentName' => $componentName, - 'mainJsContent' => $this->getMainJsContent($namespaceResolver) ] ); $directory = (new TreeBuilder())->buildTree($this->getTemplatePath('Admin/ComponentOverride'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($directory); - return (new DirectoryCollection([$directory])); - } - - protected function getMainJsContent(NamespaceResolverInterface $namespaceResolver): string { - $content = ''; - - if (file_exists($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'))) { - $content = file_get_contents($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js')); - } + $importComponentName = (new AsciiSlugger())->slug((new UnicodeString($componentName))->snake()->toString())->toString(); + MainJsImportGenerator::instance()->addImport( + (new MainJsImportFactory())->createImport(sprintf('module/%s-override', $importComponentName)) + ); - return is_string($content) ? $content : ''; + return (new DirectoryCollection([$directory])); } - } diff --git a/src/Maker/Admin/AdminModuleMaker.php b/src/Maker/Admin/AdminModuleMaker.php index 2238388..909e4bd 100644 --- a/src/Maker/Admin/AdminModuleMaker.php +++ b/src/Maker/Admin/AdminModuleMaker.php @@ -1,7 +1,11 @@ -getArgument('name'); $prefixedModuleName = $input->getOption('prefix') ? $input->getOption('prefix') . '-' . $input->getArgument('name') : $input->getArgument('name'); @@ -28,8 +32,7 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa 'prefix' => $input->getOption('prefix'), 'moduleColor' => $input->getOption('moduleColor'), 'navigationParent' => $input->getOption('navigationParent'), - 'mainJsContent' => $this->getMainJsContent($namespaceResolver), - 'snippetLanguages' => $input->getOption('snippetLanguages') + 'snippetLanguages' => $input->getOption('snippetLanguages'), ] ); @@ -42,48 +45,41 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa 'moduleName' => $prefixedModuleName, 'componentName' => $prefixedModuleName . '-list', 'componentsOnly' => true, - 'workingDir' => $workingDir + 'workingDir' => $workingDir, ]); $detailPage = (new AdminComponentMaker())->make($namespaceResolver, $input, [ 'moduleName' => $prefixedModuleName, 'componentName' => $prefixedModuleName . '-detail', 'componentsOnly' => true, - 'workingDir' => $workingDir + 'workingDir' => $workingDir, ]); $createPage = (new AdminComponentMaker())->make($namespaceResolver, $input, [ 'moduleName' => $prefixedModuleName, 'componentName' => $prefixedModuleName . '-create', 'componentsOnly' => true, - 'workingDir' => $workingDir + 'workingDir' => $workingDir, ]); $snippetData = [ $prefixedModuleName => [ 'general' => [ - 'mainMenuItemGeneral' => 'PURE Menu Item' - ] - ] + 'mainMenuItemGeneral' => 'PURE Menu Item', + ], + ], ]; $snippets = $this->makeSnippetFiles($namespaceResolver, $input, [ 'subDirectory' => $subDirectory . '/module/', 'moduleName' => $prefixedModuleName, - 'baseSnippet' => json_encode($snippetData, JSON_PRETTY_PRINT) ?: '' + 'baseSnippet' => json_encode($snippetData, JSON_PRETTY_PRINT) ?: '', ]); - return (new DirectoryCollection([$directory]))->merge($listPage)->merge($detailPage)->merge($createPage)->merge($snippets); - } - - protected function getMainJsContent(NamespaceResolverInterface $namespaceResolver): string { - $content = ''; - - if (file_exists($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'))) { - $content = file_get_contents($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js')); - } + MainJsImportGenerator::instance()->addImport( + (new MainJsImportFactory())->createImport('module/' . $prefixedModuleName) + ); - return is_string($content) ? $content : ''; + return (new DirectoryCollection([$directory]))->merge($listPage)->merge($detailPage)->merge($createPage)->merge($snippets); } - } diff --git a/src/Maker/CliCommand/CliCommandMaker.php b/src/Maker/CliCommand/CliCommandMaker.php new file mode 100644 index 0000000..6947dd3 --- /dev/null +++ b/src/Maker/CliCommand/CliCommandMaker.php @@ -0,0 +1,62 @@ +getSubDirectory($input, $options, 'Command'); + + $commandName = (new UnicodeString($input->getArgument('name')))->camel()->title()->toString(); + $commandName = preg_replace('/Command$/', '', $commandName); + + if (is_null($commandName)) { + throw new \RuntimeException('Could not find command name'); + } + + if ($input->getOption('cliName')) { + $cliCommandName = (new AsciiSlugger())->slug((new UnicodeString($input->getOption('cliName')))->snake()->toString()); + } else { + $cliCommandName = (new AsciiSlugger())->slug((new UnicodeString($commandName))->snake()->toString()); + + if ($input->getOption('prefix')) { + $cliCommandName = $input->getOption('prefix') . ':' . $cliCommandName; + } + } + $commandName .= 'Command'; + + $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); + $generator->getParser()->setTemplateData( + [ + 'commandName' => $commandName, + 'cliCommandName' => $cliCommandName, + ] + ); + + $directory = (new TreeBuilder())->buildTree($this->getTemplatePath('CliCommand'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); + $generator->generate($directory); + + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateServiceTag( + $namespaceResolver->getFullNamespace($subDirectory . '/' . $commandName), + 'console.command' + ) + ); + + return (new DirectoryCollection([$directory])); + } +} diff --git a/src/Maker/Cms/CmsBlockMaker.php b/src/Maker/Cms/CmsBlockMaker.php index 268147b..a47eeea 100644 --- a/src/Maker/Cms/CmsBlockMaker.php +++ b/src/Maker/Cms/CmsBlockMaker.php @@ -1,7 +1,11 @@ -getArgument('name'); @@ -24,55 +29,57 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa 'blockName' => $cmsBlockName, 'moduleName' => 'sw-cms', 'blockCategory' => $input->getOption('category'), - 'mainJsContent' => $this->getMainJsContent($namespaceResolver) ] ); - $builder = new TreeBuilder(); $builder->skip(['module/{{moduleName}}/elements']); + MainJsImportGenerator::instance()->addImport( + (new MainJsImportFactory())->createImport( + sprintf( + 'module/sw-cms/blocks/%s/%s', + (new AsciiSlugger())->slug((new UnicodeString($input->getOption('category')))->snake()->toString())->toString(), + (new AsciiSlugger())->slug((new UnicodeString($cmsBlockName))->snake()->toString())->toString() + ) + ) + ); + $directory = $builder->buildTree($this->getTemplatePath('Cms/Element'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($directory); $snippetDirectory = 'Resources/app/administration/src/module/'; $moduleName = 'sw-cms'; - // like: sw-cms.elements.camelCaseCmsElementName.label => YouCustomLabel $baseSnippet = [ 'sw-cms' => [ 'blocks' => [ ( new UnicodeString($options['cmsBlockName'] ?? $input->getArgument('name')))->camel()->toString() => [ - 'label' => 'Your Custom Label' - ] - ] - ] + 'label' => 'Your Custom Label', + ], + ], + ], ]; - $snippetCollection = $this->makeSnippetFiles($namespaceResolver, $input, ['subDirectory' => $snippetDirectory, 'moduleName' => $moduleName, 'baseSnippet' => json_encode($baseSnippet, JSON_PRETTY_PRINT) ?: '']); - $storefrontCollection = $this->makeStorefrontElementFile($namespaceResolver, $input, ['blockName' => $cmsBlockName]); + $snippetCollection = $this->makeSnippetFiles($namespaceResolver, $input, [ + 'subDirectory' => $snippetDirectory, + 'moduleName' => $moduleName, + 'baseSnippet' => json_encode($baseSnippet, JSON_PRETTY_PRINT) ?: '', + ]); + $storefrontCollection = $this->makeStorefrontElementFile($namespaceResolver, $input, [ + 'blockName' => $cmsBlockName, + ]); return (new DirectoryCollection([$directory]))->merge($snippetCollection)->merge($storefrontCollection); } - protected function getMainJsContent(NamespaceResolverInterface $namespaceResolver): string { - $content = ''; - - if (file_exists($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'))) { - $content = file_get_contents($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js')); - } - - return is_string($content) ? $content : ''; - } - /** * @param array $options */ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - - if (!$options['blockName']) { + if ($options['blockName'] === '' || $options['blockName'] === '0') { throw new \RuntimeException('You need to pass a blockName to create storefront file'); } @@ -81,7 +88,7 @@ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespa $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subdirectory); $generator->getParser()->setTemplateData( [ - 'blockName' => $options['blockName'] + 'blockName' => $options['blockName'], ] ); @@ -91,7 +98,4 @@ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespa return $collection; } - - - } diff --git a/src/Maker/Cms/CmsElementMaker.php b/src/Maker/Cms/CmsElementMaker.php index bde5feb..ef703ac 100644 --- a/src/Maker/Cms/CmsElementMaker.php +++ b/src/Maker/Cms/CmsElementMaker.php @@ -1,7 +1,11 @@ -cmsElementResolverMaker = $cmsElementResolverMaker; } - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { $subDirectory = 'Resources/app/administration/src'; $cmsElementName = $options['elementName'] ?? $input->getArgument('name'); @@ -31,7 +36,6 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa [ 'elementName' => $cmsElementName, 'moduleName' => 'sw-cms', - 'mainJsContent' => $this->getMainJsContent($namespaceResolver) ] ); @@ -41,26 +45,42 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $directory = $builder->buildTree($this->getTemplatePath('Cms/Element'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($directory); + MainJsImportGenerator::instance()->addImport( + (new MainJsImportFactory())->createImport( + sprintf( + 'module/sw-cms/elements/%s', + (new AsciiSlugger())->slug((new UnicodeString($cmsElementName))->snake()->toString())->toString() + ) + ) + ); + $snippetDirectory = 'Resources/app/administration/src/module/'; $moduleName = 'sw-cms'; - // like: sw-cms.elements.camelCaseCmsElementName.label => YouCustomLabel $baseSnippet = [ 'sw-cms' => [ 'elements' => [ ( new UnicodeString($options['elementName'] ?? $input->getArgument('name')))->camel()->toString() => [ - 'label' => 'Your Custom Label' - ] - ] - ] + 'label' => 'Your Custom Label', + ], + ], + ], ]; - $snippetCollection = $this->makeSnippetFiles($namespaceResolver, $input, ['subDirectory' => $snippetDirectory, 'moduleName' => $moduleName, 'baseSnippet' => json_encode($baseSnippet, JSON_PRETTY_PRINT) ?: '']); - $storefrontCollection = $this->makeStorefrontElementFile($namespaceResolver, $input, ['elementName' => $cmsElementName]); + $snippetCollection = $this->makeSnippetFiles($namespaceResolver, $input, [ + 'subDirectory' => $snippetDirectory, + 'moduleName' => $moduleName, + 'baseSnippet' => json_encode($baseSnippet, JSON_PRETTY_PRINT) ?: '', + ]); + $storefrontCollection = $this->makeStorefrontElementFile($namespaceResolver, $input, [ + 'elementName' => $cmsElementName, + ]); if ($input->getOption('resolver')) { - $resolver = $this->cmsElementResolverMaker->make($namespaceResolver, $input, ['elementName' => $cmsElementName]); + $resolver = $this->cmsElementResolverMaker->make($namespaceResolver, $input, [ + 'elementName' => $cmsElementName, + ]); return (new DirectoryCollection([$directory]))->merge($snippetCollection)->merge($storefrontCollection)->merge($resolver); } @@ -68,23 +88,12 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa return (new DirectoryCollection([$directory]))->merge($snippetCollection)->merge($storefrontCollection); } - protected function getMainJsContent(NamespaceResolverInterface $namespaceResolver): string { - $content = ''; - - if (file_exists($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js'))) { - $content = file_get_contents($namespaceResolver->getWorkingDir('Resources/app/administration/src/main.js')); - } - - return is_string($content) ? $content : ''; - } - /** * @param array $options */ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - - if (!$options['elementName']) { + if ($options['elementName'] === '' || $options['elementName'] === '0') { throw new \RuntimeException('You need to pass a elementName to create storefront file'); } @@ -93,7 +102,7 @@ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespa $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subdirectory); $generator->getParser()->setTemplateData( [ - 'elementName' => $options['elementName'] + 'elementName' => $options['elementName'], ] ); @@ -103,7 +112,4 @@ protected function makeStorefrontElementFile(NamespaceResolverInterface $namespa return $collection; } - - - } diff --git a/src/Maker/Cms/CmsElementResolverMaker.php b/src/Maker/Cms/CmsElementResolverMaker.php index 0ba3f24..7603465 100644 --- a/src/Maker/Cms/CmsElementResolverMaker.php +++ b/src/Maker/Cms/CmsElementResolverMaker.php @@ -1,7 +1,11 @@ -getSubDirectory($input, $options, 'DataResolver'); + $elementName = $input->getArgument('name') ?? $options['elementName']; $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); $generator->getParser()->setTemplateData( [ - 'elementName' => $input->getArgument('name') ?? $options['elementName'] + 'elementName' => $elementName, ] ); $directory = (new TreeBuilder())->buildTree($this->getTemplatePath('Cms/Resolver'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($directory); - $this->addServiceTag($namespaceResolver); + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateServiceTag($namespaceResolver->getFullNamespace($subDirectory . '/' . $elementName . 'CmsElementResolver'), 'shopware.cms.data_resolver') + ); return (new DirectoryCollection([$directory])); } - } diff --git a/src/Maker/Controller/ControllerMaker.php b/src/Maker/Controller/ControllerMaker.php new file mode 100644 index 0000000..143b39d --- /dev/null +++ b/src/Maker/Controller/ControllerMaker.php @@ -0,0 +1,79 @@ +getOption('routeScope') ?? $options['routeScope']; + $httpMethod = $input->getOption('method') ?? $options['method']; + + if (! in_array($routeScope, ['storefront', 'api'])) { + throw new \RuntimeException('Route Scope has to be storefront or api'); + } + + if (! in_array($httpMethod, ['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'PATCH', 'OPTIONS', 'CONNECT', 'TRACE'])) { + throw new \RuntimeException('Unknown http method passed.'); + } + + $defaultDirectory = $routeScope === 'storefront' ? 'Storefront/Controller' : 'Api/Controller'; + $subDirectory = $input->getOption('workingDir') ?? $options['workingDir'] ?? $defaultDirectory; + + $controllerName = $options['controllerName'] ?? $input->getArgument('name'); + + if (! $controllerName) { + throw new \RuntimeException('You need a controller name to creat a controller.'); + } + + $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); + + $isStorefront = $routeScope === 'storefront'; + $basicRoute = $input->getOption('basicRoute') ?? $options['basicRoutes']; + $routeName = $isStorefront ? 'frontend' : 'api'; + $routeName .= '-' . (new UnicodeString($basicRoute))->camel()->toString(); + $routeName = (new AsciiSlugger())->slug($routeName, '.'); + $generator->getParser()->setTemplateData( + [ + 'controllerName' => $controllerName . 'Controller', + 'routeScope' => $routeScope, + 'method' => $httpMethod, + 'basicRoute' => $basicRoute, + 'routeName' => $routeName, + 'isAjax' => $input->getOption('isAjax'), + 'isStorefront' => $isStorefront, + ] + ); + + $directory = (new TreeBuilder())->buildTree($this->getTemplatePath('Controller'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); + $generator->generate($directory); + + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateServiceController($namespaceResolver->getFullNamespace($subDirectory . '/' . $controllerName . 'Controller')) + ); + + if (! $input->getOption('workingDir')) { + $route = $isStorefront ? '../../Storefront/Controller/*Controller.php' : '../../Api/Controller/*Controller.php'; + RouteImportGenerator::instance()->addRoute( + (new RouteFactory())->generateRoute($route) + ); + } + + return (new DirectoryCollection([$directory])); + } +} diff --git a/src/Maker/Entity/EntityDependentMaker.php b/src/Maker/Entity/EntityDependentMaker.php index e49e7c1..1b5ff78 100644 --- a/src/Maker/Entity/EntityDependentMaker.php +++ b/src/Maker/Entity/EntityDependentMaker.php @@ -12,42 +12,20 @@ class EntityDependentMaker extends AbstractMaker implements MakerInterface { - - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { throw new \RuntimeException('make() method not implemented.'); - - $subDirectory = $input->getOption('workingDir') ?? $options['workingDir']; - if (!$subDirectory) { - throw new \RuntimeException('You need to pass a workingDir'); - } - - $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); - - $generator->getParser()->setTemplateData( - [ - 'entityName' => $options['entityName'] ?? $input->getOptions('entityName'), - 'entityPrefix' => $options['entityPrefix'] ?? $input->getOptions('entityPrefix') - ] - ); - - - - $treeBuilder = new TreeBuilder(); - $treeBuilder->skip($skipPaths); - $hydratorDirectory = $treeBuilder->buildTree($this->getTemplatePath('Entity'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); - $generator->generate($hydratorDirectory); - - return new DirectoryCollection([$hydratorDirectory]); } - protected function getSkipPaths() { + /** + * @return string[] + */ + protected function getSkipPaths(): array + { return [ '{{entityName|u.camel.title}}Definition.php', '{{entityName|u.camel.title}}Entity.php', '{{entityName|u.camel.title}}Collection.php', ]; } - - } diff --git a/src/Maker/Entity/EntityExtensionMaker.php b/src/Maker/Entity/EntityExtensionMaker.php new file mode 100644 index 0000000..01780a8 --- /dev/null +++ b/src/Maker/Entity/EntityExtensionMaker.php @@ -0,0 +1,45 @@ +getArgument('name'); + $extensionName .= str_replace('Extension', '', $extensionName) . 'Extension'; + $extensionName = (new UnicodeString($extensionName))->camel()->title()->toString(); + + $subDirectory = $this->getSubDirectory($input, $options, 'Content/Extension'); + $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); + $generator->getParser()->setTemplateData( + [ + 'extensionName' => $extensionName, + ] + ); + + $treeBuilder = new TreeBuilder(); + $directory = $treeBuilder->buildTree($this->getTemplatePath('EntityExtension'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); + $generator->generate($directory); + + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateServiceTag( + $namespaceResolver->getFullNamespace($subDirectory . '/' . $extensionName), + 'shopware.entity.extension' + ) + ); + + return new DirectoryCollection([$directory]); + } +} diff --git a/src/Maker/Entity/EntityMaker.php b/src/Maker/Entity/EntityMaker.php index fed4d79..ffa8c93 100644 --- a/src/Maker/Entity/EntityMaker.php +++ b/src/Maker/Entity/EntityMaker.php @@ -1,6 +1,9 @@ migrationMaker = $migrationMaker; $this->hydratorMaker = $hydratorMaker; $this->many2manyMaker = $many2manyMaker; @@ -39,10 +42,10 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $skiPaths = [ '{{entityName|u.camel.title}}Hydrator.php', '{{entityName|u.camel.title}}MappingDefinition.php', - 'Aggregate' + 'Aggregate', ]; $subDirPath = $input->getOption('workingDir') ?? 'Content' . DIRECTORY_SEPARATOR . $entityName; - $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirPath); + $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirPath); $parser = $generator->getParser(); $treeBuilder = new TreeBuilder(); @@ -50,36 +53,46 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa [ 'entityName' => $entityName, 'entityPrefix' => $input->getOption('prefix'), - 'hasTranslation' => (bool) $input->getOption('translation') + 'hasTranslation' => (bool) $input->getOption('translation'), ] ); $treeBuilder->skip($skiPaths); - $entityDirectory = $treeBuilder->buildTree(__DIR__ . '/../../Resources/skeleton/entity', $namespaceResolver->getFullNamespace($subDirPath), $entityName); + $entityDirectory = $treeBuilder->buildTree(__DIR__ . '/../../Resources/skeleton/Entity', $namespaceResolver->getFullNamespace($subDirPath), $entityName); $generator->generate($entityDirectory); $subDir = new Directory($subDirPath); $subDir->setDirectories(new DirectoryCollection([$entityDirectory])); $createdDirectories = new DirectoryCollection([$subDir]); + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateEntityServiceTag( + $namespaceResolver->getFullNamespace($subDirPath . '/' . $entityName . 'Definition'), + 'shopware.entity.definition', + (new UnicodeString($input->getOption('prefix') . $entityName))->snake()->toString() + ) + ); + if ($input->getOption('translation')) { $createdDirectories = $createdDirectories->merge($this->translationMaker->make($namespaceResolver, $input, array_merge([ 'entityName' => $entityName, 'entityPrefix' => $input->getOption('prefix'), 'workingDir' => $subDirPath . DIRECTORY_SEPARATOR . 'Aggregate' . DIRECTORY_SEPARATOR . 'Translation', - 'parentClass' => $namespaceResolver->getFullNamespace($subDirPath . DIRECTORY_SEPARATOR . $entityName) + 'parentClass' => $namespaceResolver->getFullNamespace($subDirPath . DIRECTORY_SEPARATOR . $entityName), ], $options))); } if ($input->getOption('migration')) { - $createdDirectories = $createdDirectories->merge($this->migrationMaker->make($namespaceResolver, $input, array_merge(['suffix' => $entityName], $options))); + $createdDirectories = $createdDirectories->merge($this->migrationMaker->make($namespaceResolver, $input, array_merge([ + 'suffix' => $entityName, + ], $options))); } if ($input->getOption('hydrator')) { $createdDirectories = $createdDirectories->merge($this->hydratorMaker->make($namespaceResolver, $input, array_merge([ 'entityName' => $entityName, - 'workingDir' => $subDirPath + 'workingDir' => $subDirPath, ], $options))); } @@ -87,7 +100,7 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $createdDirectories = $createdDirectories->merge($this->many2manyMaker->make($namespaceResolver, $input, array_merge([ 'entityName' => $entityName, 'entityPrefix' => $input->getOption('prefix'), - 'workingDir' => $subDirPath + 'workingDir' => $subDirPath, ], $options))); } diff --git a/src/Maker/Entity/HydratorMaker.php b/src/Maker/Entity/HydratorMaker.php index 5bbe8d9..a7fab42 100644 --- a/src/Maker/Entity/HydratorMaker.php +++ b/src/Maker/Entity/HydratorMaker.php @@ -12,14 +12,13 @@ class HydratorMaker extends EntityDependentMaker implements MakerInterface { - - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { $subDirectory = $this->getSubDirectory($input, $options); $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); $generator->getParser()->setTemplateData( [ - 'entityName' => $options['entityName'] ?? $input->getOption('entityName') + 'entityName' => $options['entityName'] ?? $input->getOption('entityName'), ] ); @@ -34,5 +33,4 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa return new DirectoryCollection([$hydratorDirectory]); } - } diff --git a/src/Maker/Entity/Many2ManyMaker.php b/src/Maker/Entity/Many2ManyMaker.php index aaf6738..743d2b9 100644 --- a/src/Maker/Entity/Many2ManyMaker.php +++ b/src/Maker/Entity/Many2ManyMaker.php @@ -12,15 +12,14 @@ class Many2ManyMaker extends EntityDependentMaker implements MakerInterface { - - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { $subDirectory = $this->getSubDirectory($input, $options); $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); $generator->getParser()->setTemplateData( [ 'entityName' => $options['entityName'] ?? $input->getArgument('entityName'), - 'entityPrefix' => $options['entityPrefix'] ?? $input->getOption('prefix') + 'entityPrefix' => $options['entityPrefix'] ?? $input->getOption('prefix'), ] ); @@ -35,5 +34,4 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa return new DirectoryCollection([$directory]); } - } diff --git a/src/Maker/Entity/TranslationMaker.php b/src/Maker/Entity/TranslationMaker.php index ea6bbe3..c729d89 100644 --- a/src/Maker/Entity/TranslationMaker.php +++ b/src/Maker/Entity/TranslationMaker.php @@ -10,9 +10,8 @@ class TranslationMaker extends EntityDependentMaker implements MakerInterface { - - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { - + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { $subDirectory = $this->getSubDirectory($input, $options); $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); @@ -20,7 +19,7 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa [ 'entityName' => $options['entityName'] ?? $input->getOption('entityName'), 'entityPrefix' => $options['entityPrefix'] ?? $input->getOption('prefix'), - 'parentClassNamespace' => $this->resolveParentClassNamespace($namespaceResolver, $input, $options) + 'parentClassNamespace' => $this->resolveParentClassNamespace($namespaceResolver, $input, $options), ] ); @@ -30,12 +29,19 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa return new DirectoryCollection([$hydratorDirectory]); } - private function resolveParentClassNamespace(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options): string { + /** + * @param array $options + */ + private function resolveParentClassNamespace(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options): string + { if ($input->hasOption('parentClass') && $input->getOption('parentClass')) { return $namespaceResolver->getFullNamespace($input->getOption('parentClass')); } else { - return $options['parentClass'] ?? throw new \RuntimeException('You need to pass a parentClass definition. e.g. Content/EntityName/EntityNameDefinition'); + if (isset($options['parentClass']) && is_string($options['parentClass'])) { + return $options['parentClass']; + } else { + throw new \RuntimeException('You need to pass a parentClass definition. e.g. Content/EntityName/EntityNameDefinition'); + } } } - } diff --git a/src/Maker/MakerInterface.php b/src/Maker/MakerInterface.php index 2e8b51b..098d8da 100644 --- a/src/Maker/MakerInterface.php +++ b/src/Maker/MakerInterface.php @@ -1,4 +1,5 @@ $options - * @return DirectoryCollection */ public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection; } diff --git a/src/Maker/Migration/MigrationMaker.php b/src/Maker/Migration/MigrationMaker.php index 8fee6dd..728c44e 100644 --- a/src/Maker/Migration/MigrationMaker.php +++ b/src/Maker/Migration/MigrationMaker.php @@ -12,8 +12,8 @@ class MigrationMaker extends AbstractMaker implements MakerInterface { - - public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection { + public function make(NamespaceResolverInterface $namespaceResolver, InputInterface $input, array $options = []): DirectoryCollection + { $subDirectory = 'Migration'; $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); @@ -21,11 +21,11 @@ public function make(NamespaceResolverInterface $namespaceResolver, InputInterfa $generator->getParser()->setTemplateData( [ 'suffix' => $options['suffix'] ?? '', - 'timestamp' => $options['timestamp'] ?? $this->getTimestamp() + 'timestamp' => $options['timestamp'] ?? $this->getTimestamp(), ] ); - $migrationDirectory = (new TreeBuilder())->buildTree($this->getTemplatePath('migration'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); + $migrationDirectory = (new TreeBuilder())->buildTree($this->getTemplatePath('Migration'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); $generator->generate($migrationDirectory); return new DirectoryCollection([$migrationDirectory]); diff --git a/src/Maker/ScheduledTask/ScheduledTaskMaker.php b/src/Maker/ScheduledTask/ScheduledTaskMaker.php new file mode 100644 index 0000000..232de4c --- /dev/null +++ b/src/Maker/ScheduledTask/ScheduledTaskMaker.php @@ -0,0 +1,47 @@ +getSubDirectory($input, $options, 'Service/ScheduledTask'); + + $taskName = (new UnicodeString($input->getArgument('name')))->camel()->title()->toString(); + $taskName = preg_replace('/Task$/', '', $taskName) . 'Task'; + + $generator = $this->getDirectoryGenerator($namespaceResolver, $input, $subDirectory); + $generator->getParser()->setTemplateData( + [ + 'taskName' => $taskName, + 'prefix' => $input->getOption('prefix'), + 'defaultInterval' => $input->getOption('interval'), + ] + ); + + $directory = (new TreeBuilder())->buildTree($this->getTemplatePath('ScheduledTask'), $namespaceResolver->getFullNamespace($subDirectory), $subDirectory); + $generator->generate($directory); + + ServiceTagGenerator::instance()->addService( + (new ServiceFactory())->generateScheduledTask( + $namespaceResolver->getFullNamespace($subDirectory . '/' . $taskName), + $namespaceResolver->getFullNamespace($subDirectory . '/' . $taskName . 'Handler') + ) + ); + + return (new DirectoryCollection([$directory])); + } +} diff --git a/src/PureKernel.php b/src/PureKernel.php index 3e93418..0677548 100644 --- a/src/PureKernel.php +++ b/src/PureKernel.php @@ -1,27 +1,28 @@ addCompilerPass(new CommandsToApplicationCompilerPass()); + $container->addCompilerPass(new CommandsToApplicationCompilerPass()); } - /** * Load all services */ diff --git a/src/Resolver/NamespaceResolverInterface.php b/src/Resolver/NamespaceResolverInterface.php index ba01cc7..9205cdc 100644 --- a/src/Resolver/NamespaceResolverInterface.php +++ b/src/Resolver/NamespaceResolverInterface.php @@ -4,9 +4,7 @@ interface NamespaceResolverInterface { - - - public function resolvePluginNamespace(string $composerJson); + public function resolvePluginNamespace(string $composerJson): void; public function getFullNamespace(?string $additional = null): string; diff --git a/src/Resolver/PluginNamespaceResolver.php b/src/Resolver/PluginNamespaceResolver.php index 754e26e..ba17efd 100644 --- a/src/Resolver/PluginNamespaceResolver.php +++ b/src/Resolver/PluginNamespaceResolver.php @@ -4,14 +4,13 @@ class PluginNamespaceResolver implements NamespaceResolverInterface { - protected string $pluginBaseNamespace; protected string $pluginSrcPath; protected string $pluginName; - public function resolvePluginNamespace(string $composerJson) + public function resolvePluginNamespace(string $composerJson): void { $separator = '_NAMESPACE_SEPARATOR_'; $composer = json_decode(stripslashes(str_replace('\\', $separator, $composerJson)), true); //workaround for stripslashes @@ -29,6 +28,10 @@ public function resolvePluginNamespace(string $composerJson) $namespace = str_replace($separator, '\\', key($path)); $namespace = str_replace('\\\\', '\\', $namespace); + if (! is_string($namespace)) { + continue; + } + $this->pluginBaseNamespace = rtrim($namespace, '\\'); $this->pluginName = str_replace('\\', '', $this->pluginBaseNamespace); $this->pluginSrcPath = getcwd() . DIRECTORY_SEPARATOR . rtrim(current($path), '/'); @@ -41,7 +44,7 @@ public function resolvePluginNamespace(string $composerJson) public function getFullNamespace(?string $additional = null): string { - if (!$additional) { + if (! $additional) { return $this->getPluginBaseNamespace(); } @@ -53,13 +56,12 @@ public function getFullNamespace(?string $additional = null): string public function isNamespace(string $path): bool { - return true; + return true; } - public function getWorkingDir(?string $additional = null): string { - if (!$additional) { + if (! $additional) { return $this->getPluginSrcPath(); } diff --git a/src/Resources/skeleton/Admin/Component/main.js b/src/Resources/skeleton/Admin/Component/main.js deleted file mode 100644 index 501cb16..0000000 --- a/src/Resources/skeleton/Admin/Component/main.js +++ /dev/null @@ -1,9 +0,0 @@ -{{mainJsContent | raw}} -{%- if componentName is defined %} -{% set path = '/module/' ~ moduleName|u.snake|slug ~ '/components/' ~ componentName|u.snake|slug %} -{%- if path not in mainJsContent %} -import './module/{{moduleName|u.snake|slug}}/components/{{componentName|u.snake|slug}}'; -{% endif -%} -{% endif -%} - - diff --git a/src/Resources/skeleton/Admin/ComponentOverride/main.js b/src/Resources/skeleton/Admin/ComponentOverride/main.js deleted file mode 100644 index 0c8d30f..0000000 --- a/src/Resources/skeleton/Admin/ComponentOverride/main.js +++ /dev/null @@ -1,9 +0,0 @@ -{{mainJsContent | raw}} -{%- if componentName is defined %} -{% set path = '/module/' ~ componentName|u.snake|slug%} -{%- if path not in mainJsContent %} -import './module/{{componentName|u.snake|slug}}-override'; -{% endif -%} -{% endif -%} - - diff --git a/src/Resources/skeleton/Admin/Module/main.js b/src/Resources/skeleton/Admin/Module/main.js deleted file mode 100644 index 686ff66..0000000 --- a/src/Resources/skeleton/Admin/Module/main.js +++ /dev/null @@ -1,9 +0,0 @@ -{{mainJsContent | raw}} -{%- if prefixedModuleName is defined %} -{% set path = '/module/' ~ prefixedModuleName|u.snake|slug %} -{%- if path not in mainJsContent %} -import './module/{{prefixedModuleName|u.snake|slug}}'; -{% endif -%} -{% endif -%} - - diff --git a/src/Resources/skeleton/CliCommand/{{commandName|u.camel.title}}.php b/src/Resources/skeleton/CliCommand/{{commandName|u.camel.title}}.php new file mode 100644 index 0000000..263240a --- /dev/null +++ b/src/Resources/skeleton/CliCommand/{{commandName|u.camel.title}}.php @@ -0,0 +1,27 @@ +setName('{{cliCommandName}}'); + $this->setDescription('Custom Command.'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + return Command::SUCCESS; + } + +} diff --git a/src/Resources/skeleton/Cms/Element/main.js b/src/Resources/skeleton/Cms/Element/main.js deleted file mode 100644 index 9918fc0..0000000 --- a/src/Resources/skeleton/Cms/Element/main.js +++ /dev/null @@ -1,15 +0,0 @@ -{{mainJsContent | raw}} -{%- if elementName is defined %} -{% set elementPath = '/module/sw-cms/elements/' ~ elementName|u.snake|slug %} -{%- if elementPath not in mainJsContent %} -import './module/sw-cms/elements/{{elementName|u.snake|slug}}'; -{% endif -%} -{% endif -%} - -{%- if blockName is defined %} -{% set path = '/module/sw-cms/blocks/' ~ blockCategory|u.snake|slug ~ '/' ~ blockName|u.snake|slug %} -{%- if path not in mainJsContent %} -import './module/sw-cms/blocks/{{blockCategory|u.snake|slug}}/{{blockName|u.snake|slug}}'; -{% endif -%} -{% endif -%} - diff --git a/src/Resources/skeleton/Config/Routes/routes.xml b/src/Resources/skeleton/Config/Routes/routes.xml new file mode 100644 index 0000000..0b0630a --- /dev/null +++ b/src/Resources/skeleton/Config/Routes/routes.xml @@ -0,0 +1,7 @@ + + + + diff --git a/src/Resources/skeleton/Controller/{{controllerName}}.php b/src/Resources/skeleton/Controller/{{controllerName}}.php new file mode 100644 index 0000000..f6e2640 --- /dev/null +++ b/src/Resources/skeleton/Controller/{{controllerName}}.php @@ -0,0 +1,27 @@ +add( + // new fields here + ); + } + + public function getDefinitionClass(): string + { + return ''; //@todo add definition class you want to extend + } +} diff --git a/src/Resources/skeleton/ScheduledTask/{{taskName|u.camel.title}}.php b/src/Resources/skeleton/ScheduledTask/{{taskName|u.camel.title}}.php new file mode 100644 index 0000000..34394b1 --- /dev/null +++ b/src/Resources/skeleton/ScheduledTask/{{taskName|u.camel.title}}.php @@ -0,0 +1,23 @@ +mkdir(__DIR__ . '/../../' . $this->testDirectory); + } + $maker = new EntityMaker(new MigrationMaker(), new HydratorMaker(), new Many2ManyMaker(), new TranslationMaker()); $namespaceResolver = $this->getNamespaceResolver(); $input = $this->getInputInterface(); - $maker->make($namespaceResolver, $input, ['timestamp' => 1667133679]); + $input->setInteractive(false); + $maker->make($namespaceResolver, $input, [ + 'timestamp' => '1667133679', + ]); $testDirectory = __DIR__ . '/../../' . $this->testDirectory; $paths = [ @@ -40,14 +50,15 @@ public function test_command_creates_new_entity() ]; foreach ($paths as $path) { - $this->assertFileExists($testDirectory . $path); + $dirPath = $testDirectory . $path; + $this->assertFileExists($dirPath, sprintf('The directory %s does not exist', $dirPath)); } - } - private function getNamespaceResolver(): NamespaceResolverInterface { + private function getNamespaceResolver(): NamespaceResolverInterface + { $resolver = new PluginNamespaceResolver(); - $resolver->resolvePluginNamespace('{"name":"pure/new-plugin","type":"shopware-platform-plugin","require":{},"autoload":{"psr-4":{"Pure\\NewPlugin\\":"' . $this->testDirectory .'"}},"extra":{}}'); + $resolver->resolvePluginNamespace('{"name":"pure/new-plugin","type":"shopware-platform-plugin","require":{},"autoload":{"psr-4":{"Pure\\NewPlugin\\":"' . $this->testDirectory . '"}},"extra":{}}'); return $resolver; } @@ -57,20 +68,27 @@ protected function getInputInterface(): InputInterface $input = $this->createMock(InputInterface::class); $input->method('getOption')->will( $this->returnCallback(function ($arg) { - return match ($arg) { - 'translation', 'force', 'migration' => true, - 'prefix' => 'pure', - default => null, - }; + switch ($arg) { + case 'translation': + case 'force': + case 'migration': + return true; + case 'prefix': + return 'pure'; + default: + return null; + } }) ); $input->method('getArgument')->will( $this->returnCallback(function ($arg) { - return match ($arg) { - 'name' => 'FantasyName', - default => null, - }; + switch ($arg) { + case 'name': + return 'FantasyName'; + default: + return null; + } }) ); diff --git a/tests/Plugin/PluginGeneratorTest.php b/tests/Plugin/PluginGeneratorTest.php index 6dc76e4..82e086d 100644 --- a/tests/Plugin/PluginGeneratorTest.php +++ b/tests/Plugin/PluginGeneratorTest.php @@ -3,7 +3,7 @@ namespace Pureware\PurewareCli\Tests\Plugin; use PHPUnit\Framework\TestCase; -use Pureware\PurewareCli\Command\New\NewPluginCommand; +use Pureware\PurewareCli\Command\Generators\NewPluginCommand; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; @@ -21,23 +21,23 @@ public function test_command_creates_new_plugin() $this->assertDirectoryDoesNotExist($fullPath, 'Plugin still exist'); - $application = new Application(); + $application->setAutoExit(true); $application->add(new NewPluginCommand()); $command = $application->find('new:plugin'); $command = new CommandTester($command); - $execute = $command->execute( + $command->execute( [ 'pluginName' => $testPluginName, '--workingDir' => $executeDirectory, '--git' => true, - '--quiet' => true + '--quiet' => true, + '--no-interaction' => true, ] ); $this->assertDirectoryExists($fullPath, 'Plugin dir does not exists'); $this->assertDirectoryExists($fullPath . DIRECTORY_SEPARATOR . '.git', 'Git dir does not exists'); - } public function test_command_creates_new_plugin_with_shopware_version() @@ -52,23 +52,23 @@ public function test_command_creates_new_plugin_with_shopware_version() $this->assertDirectoryDoesNotExist($fullPath, 'Plugin still exist'); - $application = new Application(); + $application->setAutoExit(true); $application->add(new NewPluginCommand()); $command = $application->find('new:plugin'); $command = new CommandTester($command); - $execute = $command->execute( + $command->execute( [ 'pluginName' => $testPluginName, '--workingDir' => $executeDirectory, '--git' => true, '--quiet' => true, - '--shopwareVersion' => '6.4.15.1' + '--shopwareVersion' => '6.4.15.1', + '--no-interaction' => true, ] ); $this->assertDirectoryExists($fullPath, 'Plugin dir does not exists'); $this->assertDirectoryExists($fullPath . DIRECTORY_SEPARATOR . '.git', 'Git dir does not exists'); - } } diff --git a/tests/Plugin/PluginNamespaceResolverTest.php b/tests/Plugin/PluginNamespaceResolverTest.php index 9cf5d96..cd90d45 100644 --- a/tests/Plugin/PluginNamespaceResolverTest.php +++ b/tests/Plugin/PluginNamespaceResolverTest.php @@ -7,8 +7,10 @@ class PluginNamespaceResolverTest extends \PHPUnit\Framework\TestCase { - - protected NamespaceResolverInterface $resolver; + /** + * @var \Pureware\PurewareCli\Resolver\NamespaceResolverInterface + */ + protected $resolver; public function setUp(): void { @@ -26,7 +28,7 @@ public function test_plugin_base_namespace() $pluginWorkingDir = getcwd() . DIRECTORY_SEPARATOR . 'src'; $this->assertEquals($pluginBaseNamespace, $this->resolver->getFullNamespace()); $this->assertEquals($pluginBaseNamespace . '\\Aggregate\\Translations', $this->resolver->getFullNamespace('Aggregate\Translations')); - $this->assertEquals($pluginWorkingDir, $this->resolver->getWorkingDir()); + $this->assertEquals($pluginWorkingDir, $this->resolver->getWorkingDir()); } public function test_plugin_namespace_for_different_composer_types()