diff --git a/.editorconfig b/.editorconfig index 3faf149..5e5b915 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,6 @@ indent_style = tab indent_size = tab tab_width = 4 -[{*.json, *.yaml, *.yml, *.md}] +[*.{json,yaml,yml,md}] indent_style = space indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 30b5b7d..f343907 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,9 @@ -.github export-ignore -tests/ export-ignore +.docs export-ignore +.editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore -.travis.yml export-ignore +.github export-ignore +Makefile export-ignore phpstan.neon export-ignore -ecs.php export-ignore -*.php diff=php +ruleset.xml export-ignore +tests export-ignore diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 60c34b6..0000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,10 +0,0 @@ -version = 1 - -[merge] -automerge_label = "automerge" -blacklist_title_regex = "^WIP.*" -blacklist_labels = ["WIP"] -method = "rebase" -delete_branch_on_merge = true -notify_on_conflict = true -optimistic_updates = false diff --git a/.github/workflows/codesniffer.yml b/.github/workflows/codesniffer.yml new file mode 100644 index 0000000..a58ac4f --- /dev/null +++ b/.github/workflows/codesniffer.yml @@ -0,0 +1,18 @@ +name: "Codesniffer" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 8 * * 1" + +jobs: + codesniffer: + name: "Codesniffer" + uses: contributte/.github/.github/workflows/codesniffer.yml@master + with: + php: "8.2" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..fac01f8 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,18 @@ +name: "Coverage" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 9 * * 1" + +jobs: + coverage: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester-coverage-v2.yml@master + with: + php: "8.2" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index cd1df55..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: "build" - -on: - pull_request: - paths-ignore: - - ".docs/**" - push: - branches: - - "*" - schedule: - - cron: "0 8 * * 1" # At 08:00 on Monday - -jobs: - tests: - runs-on: ubuntu-latest - strategy: - matrix: - php: [ '8.2', '8.3', '8.4', '8.5' ] - latte: [ '', '--prefer-lowest' ] - exclude: - - php: '8.5' - latte: '--prefer-lowest' - fail-fast: false - steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl, iconv, json, mbstring, tokenizer - coverage: none - - run: composer install --no-interaction - - run: composer update latte/latte ${{ matrix.latte }} --no-interaction - - run: make tests - - coverage: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 - with: - php-version: '8.5' - extensions: curl, iconv, json, mbstring, tokenizer - coverage: pcov - - run: composer install --no-interaction - - run: make coverage-clover - - uses: codecov/codecov-action@v1 - - phpstan: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 - with: - php-version: '8.5' - coverage: none - - run: composer install --no-interaction - - run: make phpstan - - coding-standard: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 - with: - php-version: '8.5' - coverage: none - - run: composer install --no-interaction - - run: make cs diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..13ceb07 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,18 @@ +name: "Phpstan" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 10 * * 1" + +jobs: + phpstan: + name: "Phpstan" + uses: contributte/.github/.github/workflows/phpstan.yml@master + with: + php: "8.2" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..ef17693 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,43 @@ +name: "Nette Tester" + +on: + pull_request: + workflow_dispatch: + + push: + branches: ["*"] + + schedule: + - cron: "0 10 * * 1" + +jobs: + test85: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.5" + + test84: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.4" + + test83: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.3" + + test82: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.2" + + testlower: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.2" + composer: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable --prefer-lowest" diff --git a/.gitignore b/.gitignore index b76b6b0..f0b3670 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,14 @@ -tests/**/output/*.actual -tests/**/output/*.expected -vendor/ -composer.lock -coverage.* +# IDE +/.idea + +# Composer +/vendor +/composer.lock + +# Tests +/tests/tmp +/coverage.* +/tests/**/*.log +/tests/**/*.html +/tests/**/*.expected +/tests/**/*.actual diff --git a/Makefile b/Makefile index 1f076c3..bba41fc 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,34 @@ -.PHONY: install qa cs csf phpstan tests coverage-clover coverage-html - +.PHONY: install install: composer update +.PHONY: qa qa: phpstan cs +.PHONY: cs cs: - vendor/bin/ecs check src tests +ifdef GITHUB_ACTION + vendor/bin/phpcs --standard=ruleset.xml -q --report=checkstyle --extensions="php,phpt" src tests | cs2pr +else + vendor/bin/phpcs --standard=ruleset.xml --extensions="php,phpt" src tests +endif +.PHONY: csf csf: - vendor/bin/ecs check src tests --fix + vendor/bin/phpcbf --standard=ruleset.xml --extensions="php,phpt" src tests +.PHONY: phpstan phpstan: - vendor/bin/phpstan analyze -l 8 src + vendor/bin/phpstan analyze -c phpstan.neon +.PHONY: tests tests: vendor/bin/tester -C tests -coverage-clover: +.PHONY: coverage +coverage: +ifdef GITHUB_ACTION vendor/bin/tester -C --coverage coverage.xml --coverage-src src tests - -coverage-html: - vendor/bin/tester -C --coverage coverage.hzml --coverage-src src tests +else + vendor/bin/tester -C --coverage coverage.html --coverage-src src tests +endif diff --git a/composer.json b/composer.json index 57c236c..207470a 100644 --- a/composer.json +++ b/composer.json @@ -22,26 +22,32 @@ "require": { "php": ">=8.2", "ext-curl": "*", - "nette/di": "^3.0" + "nette/di": "^3.2.0" }, "require-dev": { - "latte/latte": "^2.4 || ^3.0", - "nette/application": "^3.0", - "nette/bootstrap": "^3.0", - "nette/tester": "^2.0", - "phpstan/phpstan": "^2.0", - "symplify/easy-coding-standard": "^12.0", - "tracy/tracy": "^2.4" + "contributte/phpstan": "^0.2.0", + "contributte/qa": "^0.4.0", + "contributte/tester": "^0.4.0", + "latte/latte": "^3.0.0", + "nette/application": "^3.2.0", + "nette/bootstrap": "^3.2.0", + "nette/neon": "^3.4.0", + "tracy/tracy": "^2.10.0" }, "suggest": { "tracy/tracy": "to enable asset debugging in the debug bar panel", - "latte/latte": "to enable Latte integration via {webpack} macro" + "latte/latte": "to enable Latte 3 integration via {webpack} tag" }, "autoload": { "psr-4": { "Contributte\\Webpack\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, "prefer-stable": true, "config": { "sort-packages": true, diff --git a/ecs.php b/ecs.php deleted file mode 100644 index 65d6118..0000000 --- a/ecs.php +++ /dev/null @@ -1,22 +0,0 @@ -fileExtensions(['php', 'phpt']); - $ecsConfig->skip(['temp/*']); - - $ecsConfig->sets([SetList::CLEAN_CODE, SetList::PSR_12]); - $ecsConfig->indentation(Option::INDENTATION_TAB); - - $ecsConfig->rule(SingleQuoteFixer::class); - $ecsConfig->rule(ClassAttributesSeparationFixer::class); - $ecsConfig->ruleWithConfiguration(PhpdocLineSpanFixer::class, ['property' => 'single']); -}; diff --git a/phpstan.neon b/phpstan.neon index c203aeb..807af32 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,20 @@ +includes: + - vendor/contributte/phpstan/phpstan.neon + parameters: - excludePaths: - - src/Latte/WebpackMacros.php # latte 2 compatibility + level: 8 + phpVersion: 80200 + + scanDirectories: + - src + + fileExtensions: + - php + + paths: + - src + + ignoreErrors: + - identifier: if.condNotBoolean + - identifier: booleanAnd.leftNotBoolean + - identifier: booleanNot.exprNotBoolean diff --git a/ruleset.xml b/ruleset.xml new file mode 100644 index 0000000..1f3d548 --- /dev/null +++ b/ruleset.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + tests/bootstrap.php + + + + + src/Manifest/Mapper/* + src/Latte/* + tests/* + + + src/Manifest/Mapper/* + src/Latte/* + tests/* + + + /tests/tmp + diff --git a/src/AssetLocator.php b/src/AssetLocator.php index b342992..46fd426 100644 --- a/src/AssetLocator.php +++ b/src/AssetLocator.php @@ -1,14 +1,18 @@ -locateInPath($this->publicPathProvider->getPublicPath(), $asset); + } + + public function locateInBuildDirectory(string $asset): string + { + return $this->locateInPath($this->directoryProvider->getBuildDirectory(), $asset); } private function locateInPath(string $path, string $asset): string { - if ($this->devServer->isAvailable() && \in_array($asset, $this->ignoredAssetNames, true)) { + if ($this->devServer->isAvailable() && in_array($asset, $this->ignoredAssetNames, true)) { return 'data:,'; } @@ -33,21 +48,12 @@ private function locateInPath(string $path, string $asset): string return $assetName; } - return \rtrim($path, '/') . '/' . \ltrim($assetName, '/'); - } - - public function locateInPublicPath(string $asset): string - { - return $this->locateInPath($this->publicPathProvider->getPublicPath(), $asset); - } - - public function locateInBuildDirectory(string $asset): string - { - return $this->locateInPath($this->directoryProvider->getBuildDirectory(), $asset); + return rtrim($path, '/') . '/' . ltrim($assetName, '/'); } private function isAbsoluteUrl(string $url): bool { - return \str_contains($url, '://') || \str_starts_with($url, '//'); + return str_contains($url, '://') || str_starts_with($url, '//'); } + } diff --git a/src/AssetNameResolver/AssetNameResolverInterface.php b/src/AssetNameResolver/AssetNameResolverInterface.php index 6061663..787ef12 100644 --- a/src/AssetNameResolver/AssetNameResolverInterface.php +++ b/src/AssetNameResolver/AssetNameResolverInterface.php @@ -1,10 +1,10 @@ - */ private array $resolvedAssets = []; public function __construct( private readonly AssetNameResolverInterface $inner, - ) { + ) + { } public function resolveAssetName(string $asset): string { $resolved = $this->inner->resolveAssetName($asset); $this->resolvedAssets[] = [$asset, $resolved]; + return $resolved; } @@ -28,4 +29,5 @@ public function getResolvedAssets(): array { return $this->resolvedAssets; } + } diff --git a/src/AssetNameResolver/IdentityAssetNameResolver.php b/src/AssetNameResolver/IdentityAssetNameResolver.php index 1a3eae4..881de74 100644 --- a/src/AssetNameResolver/IdentityAssetNameResolver.php +++ b/src/AssetNameResolver/IdentityAssetNameResolver.php @@ -1,13 +1,13 @@ -|null */ private ?array $manifestCache = null; public function __construct( private readonly string $manifestName, private readonly ManifestLoader $loader, - ) { + ) + { } public function resolveAssetName(string $asset): string @@ -29,7 +30,7 @@ public function resolveAssetName(string $asset): string } if (!isset($this->manifestCache[$asset])) { - throw new CannotResolveAssetNameException(\sprintf( + throw new CannotResolveAssetNameException(sprintf( "Asset '%s' was not found in the manifest file '%s'", $asset, $this->loader->getManifestPath($this->manifestName) @@ -38,4 +39,5 @@ public function resolveAssetName(string $asset): string return $this->manifestCache[$asset]; } + } diff --git a/src/AssetNameResolver/StaticAssetNameResolver.php b/src/AssetNameResolver/StaticAssetNameResolver.php index 83f203c..c4a579d 100644 --- a/src/AssetNameResolver/StaticAssetNameResolver.php +++ b/src/AssetNameResolver/StaticAssetNameResolver.php @@ -1,23 +1,25 @@ - $resolutions */ public function __construct( private readonly array $resolutions, - ) { + ) + { } public function resolveAssetName(string $asset): string { if (!isset($this->resolutions[$asset])) { - throw new CannotResolveAssetNameException(\sprintf( + throw new CannotResolveAssetNameException(sprintf( "Asset '%s' was not found in the resolutions array", $asset )); @@ -25,4 +27,5 @@ public function resolveAssetName(string $asset): string return $this->resolutions[$asset]; } + } diff --git a/src/BasePath/BasePathProvider.php b/src/BasePath/BasePathProvider.php index deccfe1..cdc439d 100644 --- a/src/BasePath/BasePathProvider.php +++ b/src/BasePath/BasePathProvider.php @@ -1,10 +1,10 @@ -httpRequest->getUrl()->getBasePath(); } + } diff --git a/src/BuildDirectoryProvider.php b/src/BuildDirectoryProvider.php index 81c4f1a..c9451ca 100644 --- a/src/BuildDirectoryProvider.php +++ b/src/BuildDirectoryProvider.php @@ -1,6 +1,4 @@ -devServer->getInternalUrl() : $this->directory; } + } diff --git a/src/DI/WebpackExtension.php b/src/DI/WebpackExtension.php index b394ed4..c8efc30 100644 --- a/src/DI/WebpackExtension.php +++ b/src/DI/WebpackExtension.php @@ -1,6 +1,4 @@ - $config */ final class WebpackExtension extends CompilerExtension { + private readonly bool $debugMode; private readonly bool $consoleMode; @@ -39,14 +41,14 @@ final class WebpackExtension extends CompilerExtension public function __construct(bool $debugMode, ?bool $consoleMode = null) { $this->debugMode = $debugMode; - $this->consoleMode = $consoleMode ?? \PHP_SAPI === 'cli'; + $this->consoleMode = $consoleMode ?? PHP_SAPI === 'cli'; } public function getConfigSchema(): Schema { return Expect::structure([ 'debugger' => Expect::bool($this->debugMode), - 'macros' => Expect::bool(\interface_exists(LatteFactory::class)), + 'macros' => Expect::bool(interface_exists(LatteFactory::class)), 'devServer' => Expect::structure([ 'enabled' => Expect::bool($this->debugMode), 'url' => Expect::string()->nullable()->dynamic(), @@ -64,7 +66,7 @@ public function getConfigSchema(): Schema ])->castTo('array'), 'manifest' => Expect::structure([ 'name' => Expect::string()->nullable(), - 'optimize' => Expect::bool(!$this->debugMode && (!$this->consoleMode || (bool) \getenv('CONTRIBUTTE_WEBPACK_OPTIMIZE_MANIFEST'))), + 'optimize' => Expect::bool(!$this->debugMode && (!$this->consoleMode || (bool) getenv('CONTRIBUTTE_WEBPACK_OPTIMIZE_MANIFEST'))), 'mapper' => Expect::anyOf(Expect::string(), Expect::type(Statement::class))->default(WebpackManifestPluginMapper::class), 'timeout' => Expect::anyOf(Expect::float(), Expect::int())->default(1), ])->castTo('array'), @@ -95,7 +97,7 @@ public function loadConfiguration(): void new Statement(CurlClient::class), ]); - $assetLocator = $builder->addDefinition($this->prefix('assetLocator'), new ServiceDefinition()) + $builder->addDefinition($this->prefix('assetLocator'), new ServiceDefinition()) ->setFactory(AssetLocator::class, [ 'ignoredAssetNames' => $this->config['devServer']['ignoredAssets'], ]); @@ -108,21 +110,14 @@ public function loadConfiguration(): void ->setFactory(AssetNameResolver\DebuggerAwareAssetNameResolver::class, [$assetResolver]); } - // latte macro + // latte extension if ($this->config['macros']) { try { $latteFactory = $builder->getDefinitionByType(LatteFactory::class); - \assert($latteFactory instanceof FactoryDefinition); + assert($latteFactory instanceof FactoryDefinition); $definition = $latteFactory->getResultDefinition(); - - // @phpstan-ignore-next-line latte 2 compatibility - if (\version_compare(Engine::VERSION, '3', '<')) { - $definition->addSetup('?->addProvider(?, ?)', ['@self', 'webpackAssetLocator', $assetLocator]); - $definition->addSetup('?->onCompile[] = function ($engine) { Contributte\Webpack\Latte\WebpackMacros::install($engine->getCompiler()); }', ['@self']); - } else { - $definition->addSetup('addExtension', [new Statement(\Contributte\Webpack\Latte\WebpackExtension::class)]); - } + $definition->addSetup('addExtension', [new Statement(\Contributte\Webpack\Latte\WebpackExtension::class)]); } catch (MissingServiceException $e) { // ignore } @@ -133,12 +128,12 @@ public function beforeCompile(): void { $builder = $this->getContainerBuilder(); - if ($this->config['debugger'] && \interface_exists(Tracy\IBarPanel::class)) { + if ($this->config['debugger'] && interface_exists(Tracy\IBarPanel::class)) { $definition = $builder->getDefinition($this->prefix('pathProvider')); - \assert($definition instanceof ServiceDefinition); + assert($definition instanceof ServiceDefinition); $definition->addSetup('@Tracy\Bar::addPanel', [ - new Statement(WebpackPanel::class) + new Statement(WebpackPanel::class), ]); } } @@ -164,7 +159,7 @@ private function setupAssetResolver(array $config): ServiceDefinition $assetResolver->setFactory(AssetNameResolver\ManifestAssetNameResolver::class, [ $config['manifest']['name'], - $loader + $loader, ]); } else { $devServerInstance = new DevServer(false, '', '', 0.0, new CurlClient()); @@ -188,4 +183,5 @@ private function setupAssetResolver(array $config): ServiceDefinition return $assetResolver; } + } diff --git a/src/Debugging/WebpackPanel.php b/src/Debugging/WebpackPanel.php index 40464ba..8b633fc 100644 --- a/src/Debugging/WebpackPanel.php +++ b/src/Debugging/WebpackPanel.php @@ -1,6 +1,4 @@ -devServer; + // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable $assets = $this->assetResolver->getResolvedAssets(); require __DIR__ . '/templates/WebpackPanel.tab.phtml'; - return (string) \ob_get_clean(); + + return (string) ob_get_clean(); } public function getPanel(): string { - \ob_start(function (): void { + ob_start(function (): void { }); + // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable $devServer = $this->devServer; + // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable $path = $this->pathProvider->getPublicPath(); + // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable $assets = $this->assetResolver->getResolvedAssets(); require __DIR__ . '/templates/WebpackPanel.panel.phtml'; - return (string) \ob_get_clean(); + + return (string) ob_get_clean(); } + } diff --git a/src/DevServer/DevServer.php b/src/DevServer/DevServer.php index 1393ebb..e13cdeb 100644 --- a/src/DevServer/DevServer.php +++ b/src/DevServer/DevServer.php @@ -1,6 +1,4 @@ -available ??= $this->httpClient->isAvailable($this->url, $this->timeout); } + } diff --git a/src/DevServer/Http/Client.php b/src/DevServer/Http/Client.php index 330d2f3..33233df 100644 --- a/src/DevServer/Http/Client.php +++ b/src/DevServer/Http/Client.php @@ -1,10 +1,10 @@ - 'GET', - \CURLOPT_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + curl_setopt_array($curl, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, // no output please - \CURLOPT_RETURNTRANSFER => false, - \CURLOPT_HEADER => false, - \CURLOPT_FILE => $output, + CURLOPT_RETURNTRANSFER => false, + CURLOPT_HEADER => false, + CURLOPT_FILE => $output, // setup timeout; this requires NOSIGNAL for values below 1s - \CURLOPT_TIMEOUT_MS => (int) $timeout * 1000, - \CURLOPT_NOSIGNAL => $timeout < 1 && \PHP_OS_FAMILY !== 'Windows', + CURLOPT_TIMEOUT_MS => (int) $timeout * 1000, + CURLOPT_NOSIGNAL => $timeout < 1 && PHP_OS_FAMILY !== 'Windows', // allow self-signed certificates - \CURLOPT_SSL_VERIFYHOST => 0, - \CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_SSL_VERIFYPEER => false, ]); - \curl_exec($curl); - $error = \curl_error($curl); + curl_exec($curl); + $error = curl_error($curl); return $error === ''; } + } diff --git a/src/DevServer/Http/MockClient.php b/src/DevServer/Http/MockClient.php index 1651984..3544b2f 100644 --- a/src/DevServer/Http/MockClient.php +++ b/src/DevServer/Http/MockClient.php @@ -1,6 +1,4 @@ -isAvailable; } + } diff --git a/src/Latte/WebpackExtension.php b/src/Latte/WebpackExtension.php index 568e36b..fd8cd5b 100644 --- a/src/Latte/WebpackExtension.php +++ b/src/Latte/WebpackExtension.php @@ -1,6 +1,4 @@ - $this->assetLocator, ]; } + } diff --git a/src/Latte/WebpackMacros.php b/src/Latte/WebpackMacros.php deleted file mode 100644 index 217bf81..0000000 --- a/src/Latte/WebpackMacros.php +++ /dev/null @@ -1,27 +0,0 @@ -addMacro('webpack', [$me, 'macroWebpackAsset']); - } - - public function macroWebpackAsset(MacroNode $node, PhpWriter $writer): string - { - return $writer->write('echo %escape(%modify($this->global->webpackAssetLocator->locateInPublicPath(%node.word)))'); - } -} diff --git a/src/Latte/WebpackNode.php b/src/Latte/WebpackNode.php index bd495e3..839a4ff 100644 --- a/src/Latte/WebpackNode.php +++ b/src/Latte/WebpackNode.php @@ -1,6 +1,4 @@ -expression = $tag->parser->parseUnquotedStringOrExpression(); $node->modifier = $tag->parser->parseModifier(); $node->modifier->escape = true; + return $node; } @@ -45,9 +45,11 @@ public function print(PrintContext $context): string /** * @return \Generator */ + // phpcs:ignore SlevomatCodingStandard.PHP.DisallowReference.DisallowedReturningReference public function &getIterator(): \Generator { yield $this->expression; yield $this->modifier; } + } diff --git a/src/Manifest/CannotLoadManifestException.php b/src/Manifest/CannotLoadManifestException.php index 1cb0600..d7fa83f 100644 --- a/src/Manifest/CannotLoadManifestException.php +++ b/src/Manifest/CannotLoadManifestException.php @@ -1,9 +1,8 @@ -getManifestPath($fileName); - if (\is_file($path)) { - $manifest = @\file_get_contents($path); // @ - errors handled by custom exception + if (is_file($path)) { + $manifest = @file_get_contents($path); // @ - errors handled by custom exception } else { - $ch = \curl_init($path); + $ch = curl_init($path); if ($ch === false) { $manifest = false; } else { - \curl_setopt_array($ch, [ - \CURLOPT_CUSTOMREQUEST => 'GET', - \CURLOPT_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + curl_setopt_array($ch, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, - \CURLOPT_RETURNTRANSFER => true, - \CURLOPT_FAILONERROR => true, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FAILONERROR => true, // setup timeout; this requires NOSIGNAL for values below 1s - \CURLOPT_TIMEOUT_MS => (int) $this->timeout * 1000, - \CURLOPT_NOSIGNAL => $this->timeout < 1 && \PHP_OS_FAMILY !== 'Windows', + CURLOPT_TIMEOUT_MS => (int) $this->timeout * 1000, + CURLOPT_NOSIGNAL => $this->timeout < 1 && PHP_OS_FAMILY !== 'Windows', // allow self-signed certificates - \CURLOPT_SSL_VERIFYHOST => 0, - \CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_SSL_VERIFYPEER => false, ]); /** @var string|false $manifest */ - $manifest = \curl_exec($ch); + $manifest = curl_exec($ch); if ($manifest === false) { - $errorMessage = \curl_error($ch); + $errorMessage = curl_error($ch); } } } if ($manifest === false) { - throw new CannotLoadManifestException(\sprintf( + throw new CannotLoadManifestException(sprintf( "Manifest file '%s' could not be loaded: %s", $path, - $errorMessage ?? \error_get_last()['message'] ?? 'unknown error', + $errorMessage ?? error_get_last()['message'] ?? 'unknown error', )); } - return $this->manifestMapper->map(\json_decode($manifest, flags: \JSON_THROW_ON_ERROR | \JSON_OBJECT_AS_ARRAY)); + return $this->manifestMapper->map(json_decode($manifest, flags: JSON_THROW_ON_ERROR | JSON_OBJECT_AS_ARRAY)); } public function getManifestPath(string $fileName): string { return $this->directoryProvider->getBuildDirectory() . '/' . $fileName; } + } diff --git a/src/Manifest/ManifestMapper.php b/src/Manifest/ManifestMapper.php index 92d5caf..59d1b81 100644 --- a/src/Manifest/ManifestMapper.php +++ b/src/Manifest/ManifestMapper.php @@ -1,19 +1,21 @@ - $manifest * @return array */ abstract public function map(array $manifest): array; + } diff --git a/src/Manifest/Mapper/AssetsWebpackPluginMapper.php b/src/Manifest/Mapper/AssetsWebpackPluginMapper.php index a2b3c35..c9d75d1 100644 --- a/src/Manifest/Mapper/AssetsWebpackPluginMapper.php +++ b/src/Manifest/Mapper/AssetsWebpackPluginMapper.php @@ -1,6 +1,4 @@ -devServer->isAvailable() ? $this->devServer->getUrl() - : \rtrim($this->basePathProvider->getBasePath(), '/') . '/' . \trim($this->path, '/'); + : rtrim($this->basePathProvider->getBasePath(), '/') . '/' . trim($this->path, '/'); } + } diff --git a/tests/AssetLocatorTest.phpt b/tests/AssetLocatorTest.phpt index 9a2512d..c15fbad 100644 --- a/tests/AssetLocatorTest.phpt +++ b/tests/AssetLocatorTest.phpt @@ -1,6 +1,4 @@ -locateInBuildDirectory('foo2.js')); Assert::same('//localhost/foo2.js', $assetLocator->locateInPublicPath('foo2.js')); } + } (new AssetLocatorTest())->run(); diff --git a/tests/AssetNameResolver/DebuggerAwareAssetNameResolverTest.phpt b/tests/AssetNameResolver/DebuggerAwareAssetNameResolverTest.phpt index 08e870e..2b11933 100644 --- a/tests/AssetNameResolver/DebuggerAwareAssetNameResolverTest.phpt +++ b/tests/AssetNameResolver/DebuggerAwareAssetNameResolverTest.phpt @@ -1,6 +1,4 @@ -getResolvedAssets()); } + } (new DebuggerAwareAssetNameResolverTest())->run(); diff --git a/tests/AssetNameResolver/IdentityAssetNameResolverTest.phpt b/tests/AssetNameResolver/IdentityAssetNameResolverTest.phpt index 4715542..f1a43ab 100644 --- a/tests/AssetNameResolver/IdentityAssetNameResolverTest.phpt +++ b/tests/AssetNameResolver/IdentityAssetNameResolverTest.phpt @@ -1,6 +1,4 @@ -resolveAssetName('asset.js')); } + } (new IdentityAssetNameResolverTest())->run(); diff --git a/tests/AssetNameResolver/ManifestAssetNameResolverTest.phpt b/tests/AssetNameResolver/ManifestAssetNameResolverTest.phpt index f90de14..1a06e84 100644 --- a/tests/AssetNameResolver/ManifestAssetNameResolverTest.phpt +++ b/tests/AssetNameResolver/ManifestAssetNameResolverTest.phpt @@ -1,6 +1,4 @@ -resolveAssetName('asset.js'); }, CannotResolveAssetNameException::class); } + } (new ManifestAssetNameResolverTest())->run(); diff --git a/tests/AssetNameResolver/StaticAssetNameResolverTest.phpt b/tests/AssetNameResolver/StaticAssetNameResolverTest.phpt index 15baac4..086ca4d 100644 --- a/tests/AssetNameResolver/StaticAssetNameResolverTest.phpt +++ b/tests/AssetNameResolver/StaticAssetNameResolverTest.phpt @@ -1,6 +1,4 @@ -resolveAssetName('unknownAsset.js'); }, CannotResolveAssetNameException::class); } + } (new StaticAssetNameResolverTest())->run(); diff --git a/tests/BuildDirectoryProviderTest.phpt b/tests/BuildDirectoryProviderTest.phpt index b1a7902..7856c60 100644 --- a/tests/BuildDirectoryProviderTest.phpt +++ b/tests/BuildDirectoryProviderTest.phpt @@ -1,6 +1,4 @@ -getBuildDirectory()); } + } (new BuildDirectoryProviderTest())->run(); diff --git a/tests/DI/WebpackExtensionTest.phpt b/tests/DI/WebpackExtensionTest.phpt index b0c3f10..a3d8d7a 100644 --- a/tests/DI/WebpackExtensionTest.phpt +++ b/tests/DI/WebpackExtensionTest.phpt @@ -1,6 +1,4 @@ -createContainer('basic'); Assert::type(DebuggerAwareAssetNameResolver::class, $container->getByType(AssetNameResolverInterface::class)); Assert::type(PublicPathProvider::class, $container->getByType(PublicPathProvider::class)); - Assert::type(DevServer::class, $devServer = $container->getByType(DevServer::class)); - /** @var DevServer $devServer */ + $devServer = $container->getByType(DevServer::class); + Assert::type(DevServer::class, $devServer); + Assert::true($devServer->isEnabled()); /** @var Bar $bar */ @@ -52,9 +53,10 @@ final class WebpackExtensionTest extends TestCase Assert::type(IdentityAssetNameResolver::class, $container->getByType(AssetNameResolverInterface::class)); Assert::type(PublicPathProvider::class, $container->getByType(PublicPathProvider::class)); - Assert::type(DevServer::class, $devServer = $container->getByType(DevServer::class)); + /** @var DevServer $devServer */ + $devServer = $container->getByType(DevServer::class); + Assert::type(DevServer::class, $devServer); - /** @var \Contributte\Webpack\DevServer\DevServer $devServer */ Assert::false($devServer->isEnabled()); /** @var Bar $bar */ @@ -91,7 +93,7 @@ final class WebpackExtensionTest extends TestCase public function testOptimizedManifest(): void { - \putenv('CONTRIBUTTE_WEBPACK_OPTIMIZE_MANIFEST=1'); + putenv('CONTRIBUTTE_WEBPACK_OPTIMIZE_MANIFEST=1'); $container = $this->createContainer('optimizedManifest'); $resolver = $container->getByType(AssetNameResolverInterface::class); @@ -147,6 +149,7 @@ final class WebpackExtensionTest extends TestCase return $configurator->createContainer(); } + } (new WebpackExtensionTest())->run(); diff --git a/tests/DevServerTest.phpt b/tests/DevServerTest.phpt index 91b4836..2e0dcbe 100644 --- a/tests/DevServerTest.phpt +++ b/tests/DevServerTest.phpt @@ -1,6 +1,4 @@ -isEnabled()); Assert::false($devServer->isAvailable()); } + } (new DevServerTest())->run(); diff --git a/tests/Latte/WebpackExtensionTest.phpt b/tests/Latte/WebpackExtensionTest.phpt index 2eff020..96f9e1b 100644 --- a/tests/Latte/WebpackExtensionTest.phpt +++ b/tests/Latte/WebpackExtensionTest.phpt @@ -1,6 +1,4 @@ -setLoader(new StringLoader()); Assert::same('/dist/asset.js', $latte->renderToString('{webpack asset.js}')); } + } (new WebpackExtensionTest())->run(); diff --git a/tests/Latte/WebpackMacrosTest.phpt b/tests/Latte/WebpackMacrosTest.phpt deleted file mode 100644 index 5365b39..0000000 --- a/tests/Latte/WebpackMacrosTest.phpt +++ /dev/null @@ -1,51 +0,0 @@ -')) { - Environment::skip('Requires Latte 2.'); - } - - $assetLocator = new AssetLocator( - createBuildDirectoryProvider('/home/user'), - createPublicPathProvider('/dist'), - createAssetNameResolver(['asset.js' => 'asset.js']), - createDisabledDevServer(), - [], - ); - - $latte = new Engine(); - $latte->addProvider('webpackAssetLocator', $assetLocator); - $latte->onCompile[] = function (Engine $engine): void { - WebpackMacros::install($engine->getCompiler()); - }; - - $latte->setLoader(new StringLoader()); - Assert::same('/dist/asset.js', $latte->renderToString('{webpack asset.js}')); - } -} - -(new WebpackMacrosTest())->run(); diff --git a/tests/Manifest/ManifestLoaderTest.phpt b/tests/Manifest/ManifestLoaderTest.phpt index 689651a..f469c07 100644 --- a/tests/Manifest/ManifestLoaderTest.phpt +++ b/tests/Manifest/ManifestLoaderTest.phpt @@ -1,6 +1,4 @@ - 'resolved.asset.js'], $manifest); + return ['asset.js' => 'mapped.asset.js']; } + }; $manifestLoader = new ManifestLoader($buildDirProvider, $manifestMapper, 1); @@ -39,6 +41,7 @@ final class ManifestLoaderTest extends TestCase $manifestLoader->loadManifest('unknown.js'); }, CannotLoadManifestException::class); } + } (new ManifestLoaderTest())->run(); diff --git a/tests/Manifest/Mapper/AssetsWebpackPluginMapperTest.phpt b/tests/Manifest/Mapper/AssetsWebpackPluginMapperTest.phpt index 83a5f34..fd43b4f 100644 --- a/tests/Manifest/Mapper/AssetsWebpackPluginMapperTest.phpt +++ b/tests/Manifest/Mapper/AssetsWebpackPluginMapperTest.phpt @@ -1,6 +1,4 @@ - 'resolved.asset.js', ], $result); } + } (new AssetsWebpackPluginMapperTest())->run(); diff --git a/tests/Manifest/Mapper/WebpackManifestPluginMapperTest.phpt b/tests/Manifest/Mapper/WebpackManifestPluginMapperTest.phpt index ecffde3..87cbfa4 100644 --- a/tests/Manifest/Mapper/WebpackManifestPluginMapperTest.phpt +++ b/tests/Manifest/Mapper/WebpackManifestPluginMapperTest.phpt @@ -1,6 +1,4 @@ - 'resolved.asset.js', ], $result); } + } (new WebpackManifestPluginMapperTest())->run(); diff --git a/tests/PublicPathProviderTest.phpt b/tests/PublicPathProviderTest.phpt index 5535818..eeaba1e 100644 --- a/tests/PublicPathProviderTest.phpt +++ b/tests/PublicPathProviderTest.phpt @@ -1,6 +1,4 @@ -getPublicPath()); } + } (new PublicPathProviderTest())->run(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 96dcf5e..6a84380 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,7 +1,8 @@ -basePath; } + }; } @@ -62,7 +65,8 @@ function createEnabledDevServer(bool $isAvailable): DevServer */ function createAssetNameResolver(array $mapping): AssetNameResolverInterface { - return new class($mapping) implements AssetNameResolverInterface { + return new class ($mapping) implements AssetNameResolverInterface { + /** @var array */ private array $mapping; @@ -76,12 +80,13 @@ public function __construct(array $mapping) public function resolveAssetName(string $asset): string { - if (!\array_key_exists($asset, $this->mapping)) { + if (!array_key_exists($asset, $this->mapping)) { throw new CannotResolveAssetNameException(); } return $this->mapping[$asset]; } + }; }