From bae79d68ab2092518b6359eab02833317e2abb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Gonzalo=20Artur=20de=20la=20Villarmois?= Date: Sun, 29 Mar 2026 17:49:51 +1300 Subject: [PATCH] * Fix CI/CD php version * Add Pint * Format code --- .github/workflows/release.yml | 27 +++++++++++++++++-- .github/workflows/tests.yml | 25 ++++++++++++++++- www/app/Enums/NintendoFileExtension.php | 2 +- www/app/Helpers/FileSize.php | 5 ++-- .../Http/Controllers/DBI/IndexController.php | 25 ++++++++--------- .../Controllers/Tinfoil/IndexController.php | 4 +-- .../Http/Middleware/EnsureIsTinfoilClient.php | 7 ++--- www/bootstrap/providers.php | 4 ++- www/composer.json | 4 +-- www/composer.lock | 27 ++++++++++--------- www/config/auth.php | 4 ++- www/config/database.php | 5 ++-- www/routes/api.php | 6 +++-- www/routes/web.php | 18 ++++++------- .../Feature/DBI/DirectoryListingTest.php | 4 +-- .../Feature/Tinfoil/IndexControllerTest.php | 2 +- www/tests/Pest.php | 4 ++- 17 files changed, 114 insertions(+), 59 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a555e88..8634e3e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' extensions: mbstring coverage: none @@ -34,10 +34,33 @@ jobs: working-directory: www run: php artisan test + lint: + name: Check code style (Pint) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: mbstring + coverage: none + + - name: Install Composer dependencies + working-directory: www + run: composer install --no-interaction --prefer-dist --optimize-autoloader + + - name: Run Pint + working-directory: www + run: ./vendor/bin/pint --test + docker: name: Build and push Docker image runs-on: ubuntu-latest - needs: test + needs: [test, lint] steps: - name: Checkout diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 58fe852..1dd15a0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' extensions: mbstring coverage: none @@ -33,3 +33,26 @@ jobs: - name: Run tests working-directory: www run: php artisan test + + lint: + name: Check code style (Pint) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: mbstring + coverage: none + + - name: Install Composer dependencies + working-directory: www + run: composer install --no-interaction --prefer-dist --optimize-autoloader + + - name: Run Pint + working-directory: www + run: ./vendor/bin/pint --test diff --git a/www/app/Enums/NintendoFileExtension.php b/www/app/Enums/NintendoFileExtension.php index e65b339..b35581a 100644 --- a/www/app/Enums/NintendoFileExtension.php +++ b/www/app/Enums/NintendoFileExtension.php @@ -18,7 +18,7 @@ enum NintendoFileExtension: string */ public static function values(): array { - return array_map(fn($case) => $case->value, self::cases()); + return array_map(fn ($case) => $case->value, self::cases()); } /** diff --git a/www/app/Helpers/FileSize.php b/www/app/Helpers/FileSize.php index e82e27e..7135188 100644 --- a/www/app/Helpers/FileSize.php +++ b/www/app/Helpers/FileSize.php @@ -5,6 +5,7 @@ namespace App\Helpers; class FileSize { private const UNITS = ['', 'K', 'M', 'G', 'T']; + private const THRESHOLD = 1024; /** @@ -18,10 +19,10 @@ class FileSize $unitIndex = (int) floor(log($bytes, self::THRESHOLD)); $unitIndex = min($unitIndex, count(self::UNITS) - 1); - + $size = $bytes / pow(self::THRESHOLD, $unitIndex); $decimals = $unitIndex === 0 ? 0 : 2; - return number_format($size, $decimals, '.', '') . self::UNITS[$unitIndex]; + return number_format($size, $decimals, '.', '').self::UNITS[$unitIndex]; } } diff --git a/www/app/Http/Controllers/DBI/IndexController.php b/www/app/Http/Controllers/DBI/IndexController.php index cd08653..d33b444 100644 --- a/www/app/Http/Controllers/DBI/IndexController.php +++ b/www/app/Http/Controllers/DBI/IndexController.php @@ -35,6 +35,7 @@ class IndexController extends Controller private function getRequestPath(Request $request): ?string { $path = $request->route('path'); + return $path ? rawurldecode($path) : null; } @@ -51,9 +52,9 @@ class IndexController extends Controller */ private function serveFile(string $path): Response|BinaryFileResponse { - $storagePath = self::GAMES_DIRECTORY . '/' . $path; + $storagePath = self::GAMES_DIRECTORY.'/'.$path; - if (!Storage::exists($storagePath)) { + if (! Storage::exists($storagePath)) { return response('File not found', 404); } @@ -68,19 +69,19 @@ class IndexController extends Controller */ private function serveDirectoryListing(?string $path, Request $request): Response { - $storagePath = $path - ? self::GAMES_DIRECTORY . '/' . $path + $storagePath = $path + ? self::GAMES_DIRECTORY.'/'.$path : self::GAMES_DIRECTORY; $directories = $this->getDirectories($storagePath); $files = $this->getFiles($storagePath); - + // Determine if this is a DBI client or regular browser $isDBI = str_starts_with($request->userAgent() ?? '', 'DBI/'); - + // Determine base URL for links based on request path $baseUrl = str_starts_with($request->path(), 'api/dbi') ? '/api/dbi/' : '/'; - + $html = $this->buildDirectoryListingHtml($directories, $files, $path ?? '', $baseUrl, $isDBI); return response($html)->header('Content-Type', 'text/html'); @@ -131,8 +132,8 @@ class IndexController extends Controller */ private function buildDirectoryListingHtml(Collection $directories, Collection $files, string $currentPath, string $baseUrl, bool $isDBI): string { - $displayPath = $currentPath - ? '/games/' . rawurldecode($currentPath) . '/' + $displayPath = $currentPath + ? '/games/'.rawurldecode($currentPath).'/' : '/games/'; return view('dbi.directory-listing', [ @@ -151,7 +152,7 @@ class IndexController extends Controller */ private function getParentDirectoryUrl(string $currentPath, string $baseUrl, bool $isDBI): ?string { - if (!$currentPath) { + if (! $currentPath) { return null; } @@ -167,8 +168,8 @@ class IndexController extends Controller return $baseUrl; } - return rtrim($baseUrl, '/') . '/' . collect(explode('/', $parentPath)) + return rtrim($baseUrl, '/').'/'.collect(explode('/', $parentPath)) ->map(fn ($segment) => rawurlencode($segment)) ->implode('/'); } -} \ No newline at end of file +} diff --git a/www/app/Http/Controllers/Tinfoil/IndexController.php b/www/app/Http/Controllers/Tinfoil/IndexController.php index 0ceea8e..9c3da1a 100644 --- a/www/app/Http/Controllers/Tinfoil/IndexController.php +++ b/www/app/Http/Controllers/Tinfoil/IndexController.php @@ -18,7 +18,7 @@ class IndexController extends Controller { return response()->json([ 'files' => $this->getInstallableFiles()->values(), - 'success' => config('app.name') + 'success' => config('app.name'), ]); } @@ -31,7 +31,7 @@ class IndexController extends Controller ->filter(fn ($path) => NintendoFileExtension::isSupported($path)) ->map(fn ($path) => [ 'url' => url($path), - 'size' => Storage::size($path) + 'size' => Storage::size($path), ]); } } diff --git a/www/app/Http/Middleware/EnsureIsTinfoilClient.php b/www/app/Http/Middleware/EnsureIsTinfoilClient.php index b0850f7..991a641 100644 --- a/www/app/Http/Middleware/EnsureIsTinfoilClient.php +++ b/www/app/Http/Middleware/EnsureIsTinfoilClient.php @@ -6,20 +6,17 @@ use Closure; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Log; class EnsureIsTinfoilClient { /** * Handle an incoming request. * - * @param Request $request - * @param Closure(Request): (Response|RedirectResponse) $next - * @return Response|RedirectResponse + * @param Closure(Request): (Response|RedirectResponse) $next */ public function handle(Request $request, Closure $next): Response|RedirectResponse { - if (!!$request->header('theme')) { + if ((bool) $request->header('theme')) { return redirect()->route('tinfoil'); } diff --git a/www/bootstrap/providers.php b/www/bootstrap/providers.php index 38b258d..fc94ae6 100644 --- a/www/bootstrap/providers.php +++ b/www/bootstrap/providers.php @@ -1,5 +1,7 @@ [ 'users' => [ 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), + 'model' => env('AUTH_MODEL', User::class), ], // 'users' => [ diff --git a/www/config/database.php b/www/config/database.php index c57fa63..93b15be 100644 --- a/www/config/database.php +++ b/www/config/database.php @@ -1,6 +1,7 @@ true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ - (PHP_VERSION_ID >= 80500 ? \Pdo\Mysql::ATTR_SSL_CA : \PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + (PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], @@ -79,7 +80,7 @@ return [ 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ - (PHP_VERSION_ID >= 80500 ? \Pdo\Mysql::ATTR_SSL_CA : \PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + (PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], diff --git a/www/routes/api.php b/www/routes/api.php index 3b0c1aa..1e1935e 100644 --- a/www/routes/api.php +++ b/www/routes/api.php @@ -1,5 +1,7 @@ name('tinfoil'); -Route::get('dbi/{path?}', \App\Http\Controllers\DBI\IndexController::class) +Route::get('dbi/{path?}', DBIIndexController::class) ->where('path', '.*') ->name('dbi'); diff --git a/www/routes/web.php b/www/routes/web.php index d048365..29336f9 100644 --- a/www/routes/web.php +++ b/www/routes/web.php @@ -6,37 +6,37 @@ use Illuminate\Support\Facades\Route; Route::view('/', 'welcome')->middleware([ EnsureIsDbiClient::class, - EnsureIsTinfoilClient::class + EnsureIsTinfoilClient::class, ]); Route::get('/docs/{page}', function ($page) { $allowedPages = ['TINFOIL', 'DBI']; - if (!in_array($page, $allowedPages)) { + if (! in_array($page, $allowedPages)) { abort(404); } - + $content = file_get_contents(base_path("docs/{$page}.md")); - + // Convert relative image paths to absolute paths for web viewing $content = str_replace( '](images/', '](/docs-images/', $content ); - + return view('docs', ['content' => $content, 'title' => $page]); })->name('docs'); Route::get('/docs-images/{path}', function ($path) { $imagePath = base_path("docs/images/{$path}"); - - if (!file_exists($imagePath)) { + + if (! file_exists($imagePath)) { abort(404); } - + return response()->file($imagePath); })->where('path', '.*')->name('docs.images'); -Route::get('/{path}', fn() => response('Not Found', 404)) +Route::get('/{path}', fn () => response('Not Found', 404)) ->where('path', '(?!api|docs-images).*') ->middleware(EnsureIsDbiClient::class); diff --git a/www/tests/Feature/DBI/DirectoryListingTest.php b/www/tests/Feature/DBI/DirectoryListingTest.php index a6dc07b..947bc0c 100644 --- a/www/tests/Feature/DBI/DirectoryListingTest.php +++ b/www/tests/Feature/DBI/DirectoryListingTest.php @@ -106,7 +106,7 @@ test('DBI user-agent receives relative links', function () { $response = $this->get('/api/dbi/', ['HTTP_USER_AGENT' => 'DBI/1.0']); // DBI clients need a relative href like "GameA/" not an absolute path - $response->assertSee('href="' . rawurlencode('GameA') . '/"', false); + $response->assertSee('href="'.rawurlencode('GameA').'/"', false); }); test('browser user-agent receives absolute links', function () { @@ -114,7 +114,7 @@ test('browser user-agent receives absolute links', function () { $response = $this->get('/api/dbi/'); - $response->assertSee('href="/api/dbi/' . rawurlencode('GameA') . '"', false); + $response->assertSee('href="/api/dbi/'.rawurlencode('GameA').'"', false); }); test('displays the current subdirectory path in the page title', function () { diff --git a/www/tests/Feature/Tinfoil/IndexControllerTest.php b/www/tests/Feature/Tinfoil/IndexControllerTest.php index d42dc4c..7668f9b 100644 --- a/www/tests/Feature/Tinfoil/IndexControllerTest.php +++ b/www/tests/Feature/Tinfoil/IndexControllerTest.php @@ -47,7 +47,7 @@ test('only includes files with supported Nintendo Switch extensions', function ( $files = collect($response->json('files')); expect($files)->toHaveCount(4); - expect($files->pluck('url')->every(fn ($url) => !str_ends_with($url, '.txt') && !str_ends_with($url, '.jpg')))->toBeTrue(); + expect($files->pluck('url')->every(fn ($url) => ! str_ends_with($url, '.txt') && ! str_ends_with($url, '.jpg')))->toBeTrue(); }); test('file url is an absolute URL', function () { diff --git a/www/tests/Pest.php b/www/tests/Pest.php index 60f04a4..3834758 100644 --- a/www/tests/Pest.php +++ b/www/tests/Pest.php @@ -1,5 +1,7 @@ extend(Tests\TestCase::class) +pest()->extend(TestCase::class) // ->use(Illuminate\Foundation\Testing\RefreshDatabase::class) ->in('Feature');