#!/usr/bin/env php * * This file is part of a Moko Consulting project. * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: MokoStandards.Scripts.Validate * INGROUP: MokoStandards * REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform * PATH: /validate/check_php_syntax.php * BRIEF: Validates PHP syntax for all tracked PHP files using php -l */ declare(strict_types=1); require_once __DIR__ . '/../../vendor/autoload.php'; use MokoEnterprise\CliFramework; /** * Runs `php -l` against all tracked *.php files and reports any syntax errors. */ class CheckPhpSyntax extends CliFramework { /** * Configure available arguments. */ protected function configure(): void { $this->setDescription('Validates PHP syntax for all tracked PHP files'); $this->addArgument('--path', 'Repository path to check', '.'); } /** * Check PHP syntax for all tracked PHP files. * * @return int Exit code: 0 if all files pass, 1 if any syntax errors found. */ protected function run(): int { $path = $this->getArgument('--path'); $output = shell_exec('git -C ' . escapeshellarg($path) . " ls-files '*.php' 2>/dev/null") ?? ''; $files = array_values(array_filter(explode("\n", $output))); $total = count($files); $passed = 0; $errors = 0; $this->section('Checking PHP syntax'); foreach ($files as $i => $file) { $this->progress($i + 1, $total, $file); $fullPath = $path . '/' . $file; if (!is_file($fullPath)) { continue; } $out = []; $code = 0; exec('php -l ' . escapeshellarg($fullPath) . ' 2>&1', $out, $code); if ($code !== 0) { $this->progress($i + 1, $total, '', true); $detail = implode(' ', array_slice($out, 0, 1)); $this->status(false, $file, $detail); $errors++; } else { $passed++; } } $this->progress($total, $total, '', true); $this->printSummary($passed, $errors, $this->elapsed()); return $errors === 0 ? 0 : 1; } } $script = new CheckPhpSyntax('check_php_syntax', 'Validates PHP syntax for all tracked PHP files'); exit($script->execute());