Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laravel 12 #41

Merged
merged 6 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ jobs:
ref: ${{ github.head_ref }}

- name: Run PHP CS Fixer
uses: docker://oskarstark/php-cs-fixer-ga
with:
args: --config=.php_cs.dist.php --allow-risky=yes
uses: aglipanci/[email protected]

- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
Expand Down
23 changes: 7 additions & 16 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,24 @@ on:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest

strategy:
fail-fast: true
matrix:
# os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest]
php: [8.1, 8.2]
laravel: [10.*, 11.*]
php: [8.2, 8.3, 8.4]
laravel: [11.*, 12.*]
stability: [prefer-lowest, prefer-stable]
include:
- laravel: 10.*
testbench: 8.*
collision: ^6.0
- laravel: 11.*
testbench: ^9.0
collision: ^8.1
exclude:
- laravel: 11.*
php: 8.1
- laravel: 12.*
testbench: ^10.0

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }}

steps:
- name: Checkout code
Expand All @@ -51,7 +42,7 @@ jobs:

- name: Install dependencies
run: |
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nunomaduro/collision:${{ matrix.collision }}" "nesbot/carbon:^2.64.1" --no-interaction --no-update
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
composer update --${{ matrix.stability }} --prefer-dist --no-interaction

- name: Execute tests
Expand Down
9 changes: 4 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
}
],
"require": {
"php": "^8.1",
"php": "^8.2",
"spatie/laravel-package-tools": "^1.16",
"illuminate/contracts": "^10.0|^11.0"
"illuminate/contracts": "^11.0|^12.0"
},
"require-dev": {
"nunomaduro/collision": "^6.0|^8.1",
"orchestra/testbench": "^8.0|^9.0",
"phpunit/phpunit": "^10.5"
"orchestra/testbench": "^9.0|^10.0",
"phpunit/phpunit": "^10.5|^11.0"
},
"autoload": {
"psr-4": {
Expand Down
22 changes: 22 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\ValueObject\PhpVersion;

return RectorConfig::configure()
->withPaths([
__DIR__.'/src',
__DIR__.'/tests',
])
->withPreparedSets(
deadCode: true,
codeQuality: true,
typeDeclarations: true,
privatization: true,
earlyReturn: true,
)
->withAttributesSets()
->withPhpSets()
->withPhpVersion(PhpVersion::PHP_82);
4 changes: 2 additions & 2 deletions src/Actions/AppendTailwindTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

class AppendTailwindTag
{
public function __invoke(string $contents)
public function __invoke(string $contents): ?string
{
if (str_contains($contents, '{{ tailwindcss(')) {
return $contents;
}

return preg_replace(
'/(\s*)(<\/head>)/',
PHP_EOL."\\1 <!-- TailwindCSS Styles -->".
PHP_EOL.'\\1 <!-- TailwindCSS Styles -->'.
"\\1 <link rel=\"stylesheet\" href=\"{{ tailwindcss('css/app.css') }}\" />\\1\\2",
$contents,
);
Expand Down
18 changes: 13 additions & 5 deletions src/Commands/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BuildCommand extends Command

protected $description = 'Generates a new build of Tailwind CSS for your project.';

public function handle()
public function handle(): int
{
$binFile = config('tailwindcss.bin_path');

Expand All @@ -35,7 +35,7 @@ public function handle()
$sourcePath = $this->fixFilePathForOs(config('tailwindcss.build.source_file_path'));
$sourceRelativePath = str_replace(rtrim(resource_path(), DIRECTORY_SEPARATOR), '', $sourcePath);
$destinationPath = $this->fixFilePathForOs(config('tailwindcss.build.destination_path'));
$destinationFileAbsolutePath = $destinationPath . DIRECTORY_SEPARATOR . trim($sourceRelativePath, DIRECTORY_SEPARATOR);
$destinationFileAbsolutePath = $destinationPath.DIRECTORY_SEPARATOR.trim($sourceRelativePath, DIRECTORY_SEPARATOR);
$destinationFileRelativePath = str_replace(rtrim(public_path(), DIRECTORY_SEPARATOR), '', $destinationFileAbsolutePath);

File::ensureDirectoryExists(dirname($destinationFileAbsolutePath));
Expand All @@ -57,7 +57,7 @@ public function handle()
'-o', $destinationFileAbsolutePath,
$this->option('watch') ? '--watch=always' : null,
$this->shouldMinify() ? '-m' : null,
]), function ($type, $output) {
]), function ($type, $output): void {
$this->output->write($output);
});

Expand Down Expand Up @@ -106,11 +106,19 @@ private function fixOsFilePathToUriPath(string $path): string

private function shouldVersion(): bool
{
return $this->option('digest') || $this->option('prod');
if ($this->option('digest')) {
return true;
}

return (bool) $this->option('prod');
}

private function shouldMinify(): bool
{
return $this->option('minify') || $this->option('prod');
if ($this->option('minify')) {
return true;
}

return (bool) $this->option('prod');
}
}
8 changes: 5 additions & 3 deletions src/Commands/DownloadCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class DownloadCommand extends Command

protected $description = 'Downloads the Tailwind CSS binary for the version specified in your config/tailwindcss.php.';

public function handle()
public function handle(): int
{
$os = php_uname('s');
$cpu = php_uname('m');
Expand Down Expand Up @@ -57,8 +57,10 @@ public function handle()
return self::FAILURE;
}

File::ensureDirectoryExists(dirname($targetPath));
File::exists($targetPath) && File::delete($targetPath);
File::ensureDirectoryExists(dirname((string) $targetPath));
if (File::exists($targetPath)) {
File::delete($targetPath);
}
File::put($targetPath, $contents);
File::chmod($targetPath, 0755);

Expand Down
65 changes: 25 additions & 40 deletions src/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,43 @@ class InstallCommand extends Command

protected $description = 'Installs the Tailwind CSS scaffolding for new Laravel applications.';

public function handle()
public function handle(): int
{
$this->ensureTailwindConfigExists();
$this->ensureTailwindCliBinaryExists();
$this->appendTailwindStylesToLayouts();
$this->installMiddleware('\Tonysm\TailwindCss\Http\Middleware\AddLinkHeaderForPreloadedAssets::class');
$this->addIngoreLines();
$this->runFirstBuild();
$this->removeUnusedFiles();

$this->newLine();

$this->components->info('TailwindCSS Laravel was installed successfully.');
$this->components->info('Tailwind CSS Laravel was installed successfully.');

return self::SUCCESS;
}

protected function phpBinary()
protected function phpBinary(): string
{
return (new PhpExecutableFinder())->find(false) ?: 'php';
return (new PhpExecutableFinder)->find(false) ?: 'php';
}

private function ensureTailwindConfigExists()
private function ensureTailwindConfigExists(): void
{
$this->copyStubToApp(
stub: __DIR__ . '/../../stubs/postcss.config.js',
stub: __DIR__.'/../../stubs/postcss.config.js',
to: base_path('postcss.config.js'),
);

if (! File::exists($appCssFilePath = resource_path('css/app.css')) || empty(trim(File::get($appCssFilePath))) || $this->mainCssIsDefault($appCssFilePath)) {
if (! File::exists($appCssFilePath = resource_path('css/app.css')) || in_array(trim(File::get($appCssFilePath)), ['', '0'], true) || $this->mainCssIsDefault($appCssFilePath)) {
$this->copyStubToApp(
stub: __DIR__ . '/../../stubs/resources/css/app.css',
stub: __DIR__.'/../../stubs/resources/css/app.css',
to: $appCssFilePath,
);
}
}

private function ensureTailwindCliBinaryExists()
private function ensureTailwindCliBinaryExists(): void
{
if (! File::exists(config('tailwindcss.bin_path')) || $this->option('download')) {
Process::forever()->tty(SymfonyProcess::isTtySupported())->run([
Expand All @@ -66,7 +65,7 @@ private function ensureTailwindCliBinaryExists()
'tailwindcss:download',
'--cli-version',
$this->option('cli-version') ?: config('tailwindcss.version'),
], function ($_type, $output) {
], function ($_type, $output): void {
$this->output->write($output);
});
}
Expand All @@ -81,12 +80,9 @@ private function copyStubToApp(string $stub, string $to): void
/**
* Install the middleware to a group in the application Http Kernel.
*
* @param string $after
* @param string $name
* @param string $group
* @return void
*/
private function installMiddlewareAfter($after, $name, $group = 'web')
private function installMiddlewareAfter(string $after, string $name, $group = 'web'): void
{
$httpKernel = file_get_contents(app_path('Http/Kernel.php'));

Expand All @@ -98,8 +94,8 @@ private function installMiddlewareAfter($after, $name, $group = 'web')
}

$modifiedMiddlewareGroup = str_replace(
$after . ',',
$after . ',' . PHP_EOL . ' ' . $name . ',',
$after.',',
$after.','.PHP_EOL.' '.$name.',',
$middlewareGroup,
);

Expand All @@ -110,12 +106,12 @@ private function installMiddlewareAfter($after, $name, $group = 'web')
));
}

private function appendTailwindStylesToLayouts()
private function appendTailwindStylesToLayouts(): void
{
$this->existingLayoutFiles()
->each(fn ($file) => File::put(
$file,
(new AppendTailwindTag())(File::get($file)),
(new AppendTailwindTag)(File::get($file)),
));
}

Expand All @@ -126,7 +122,7 @@ private function existingLayoutFiles()
->filter(fn ($file) => File::exists($file));
}

private function installMiddleware(string $middleware)
private function installMiddleware(string $middleware): void
{
if (file_exists(app_path('Http/Kernel.php'))) {
$this->installMiddlewareAfter('SubstituteBindings::class', $middleware);
Expand All @@ -135,7 +131,7 @@ private function installMiddleware(string $middleware)
}
}

private function installMiddlewareToBootstrap(string $middleware, string $group = 'web', string $modifier = 'append')
private function installMiddlewareToBootstrap(string $middleware, string $group = 'web', string $modifier = 'append'): void
{
$bootstrapApp = file_get_contents(base_path('bootstrap/app.php'));

Expand All @@ -146,19 +142,19 @@ private function installMiddlewareToBootstrap(string $middleware, string $group
$bootstrapApp = str_replace(
'->withMiddleware(function (Middleware $middleware) {',
'->withMiddleware(function (Middleware $middleware) {'
. PHP_EOL . " \$middleware->{$group}({$modifier}: ["
. PHP_EOL . " {$middleware},"
. PHP_EOL . ' ]);'
. PHP_EOL,
.PHP_EOL." \$middleware->{$group}({$modifier}: ["
.PHP_EOL." {$middleware},"
.PHP_EOL.' ]);'
.PHP_EOL,
$bootstrapApp,
);

file_put_contents(base_path('bootstrap/app.php'), $bootstrapApp);
}

private function addIngoreLines()
private function addIngoreLines(): void
{
$binary = basename(config('tailwindcss.bin_path'));
$binary = basename((string) config('tailwindcss.bin_path'));

if (str_contains(File::get(base_path('.gitignore')), $binary)) {
return;
Expand All @@ -173,28 +169,17 @@ private function addIngoreLines()
LINES);
}

private function runFirstBuild()
private function runFirstBuild(): void
{
Process::forever()->tty(SymfonyProcess::isTtySupported())->run([
$this->phpBinary(),
'artisan',
'tailwindcss:build',
], function ($_type, $output) {
], function ($_type, $output): void {
$this->output->write($output);
});
}

private function removeUnusedFiles()
{
$files = [
base_path('tailwind.config.js'),
];

foreach ($files as $file) {
File::exists($file) && File::delete($file);
}
}

private function mainCssIsDefault($appCssFilePath): bool
{
return trim(File::get($appCssFilePath)) === trim(<<<'CSS'
Expand Down
12 changes: 5 additions & 7 deletions src/Http/Middleware/AddLinkHeaderForPreloadedAssets.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@

class AddLinkHeaderForPreloadedAssets
{
public function __construct(private Manifest $manifest)
{
}
public function __construct(private readonly Manifest $manifest) {}

public function handle($request, $next)
{
return tap($next($request), function ($response) {
if (count($assets = $this->manifest->assetsForPreloading()) > 0) {
return tap($next($request), function ($response): void {
if (($assets = $this->manifest->assetsForPreloading()) !== []) {
$response->header('Link', trim(implode(', ', array_filter(array_merge(
[$response->headers->get('Link', null)],
collect($assets)->map(fn ($attributes, $asset) => implode('; ', array_merge(
collect($assets)->map(fn ($attributes, $asset): string => implode('; ', array_merge(
["<$asset>"],
collect(array_merge(['rel' => 'preload', 'as' => 'style'], $attributes))
->map(fn ($value, $key) => "{$key}={$value}")
->map(fn ($value, $key): string => "{$key}={$value}")
->all(),
)))->all(),
)))));
Expand Down
Loading
Loading