#!/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_license_headers.php * BRIEF: Validates SPDX license headers in source files (advisory) */ declare(strict_types=1); require_once __DIR__ . '/../../vendor/autoload.php'; use MokoEnterprise\CliFramework; /** * Checks that tracked PHP, JS, CSS and Shell files contain an SPDX license identifier. * * This is an advisory check — always exits 0 regardless of findings. */ class CheckLicenseHeaders extends CliFramework { /** * Configure available arguments. */ protected function configure(): void { $this->setDescription('Validates SPDX license headers in source files (advisory)'); $this->addArgument('--path', 'Repository path to check', '.'); } /** * Run the license-header check (advisory — always exits 0). * * @return int Exit code: always 0. */ protected function run(): int { $path = $this->getArgument('--path'); $patterns = ['*.php', '*.js', '*.css', '*.sh']; $quoted = implode(' ', array_map('escapeshellarg', $patterns)); $output = shell_exec('git -C ' . escapeshellarg($path) . " ls-files {$quoted} 2>/dev/null") ?? ''; $files = array_filter(explode("\n", $output)); $missing = 0; $i = 0; $total = count($files); $this->section('Scanning license headers'); foreach ($files as $file) { $fullPath = $path . '/' . $file; if (!is_file($fullPath)) { continue; } if ($total >= 3) { $this->progress(++$i, $total, basename((string) $file)); } $handle = fopen($fullPath, 'r'); if ($handle === false) { continue; } $header = ''; for ($j = 0; $j < 20 && !feof($handle); $j++) { $header .= (string) fgets($handle); } fclose($handle); if (!str_contains($header, 'SPDX-License-Identifier:')) { $this->warning("Missing SPDX license identifier: {$file}"); $missing++; } } if ($total >= 3) { $this->progress($total, $total, 'done', true); } if ($missing === 0) { $this->status(true, 'All source files have license headers'); } else { $this->status(false, 'Some files missing license headers (advisory)', "{$missing} file(s)"); } $this->printSummary(max(0, $total - $missing), $missing, $this->elapsed()); return 0; } } $script = new CheckLicenseHeaders('check_license_headers', 'Validates SPDX license headers in source files'); exit($script->execute());