<?php // this file sucks, screws up the header if incomplete // successfully corrects filenames though // fix this if you ever feel like it, or don't date_default_timezone_set('utc'); function git_changes(): array { $files = []; $dir = getcwd(); try { chdir(__DIR__ . '/..'); $output = explode("\n", trim(shell_exec('git status --short --porcelain=v1 --untracked-files=all --no-column'))); foreach($output as $line) { $line = trim($line); $file = realpath(explode(' ', $line)[1]); $files[] = $file; } } finally { chdir($dir); } return $files; } function collect_files(string $directory): array { $files = []; $dir = glob(realpath($directory) . DIRECTORY_SEPARATOR . '*'); foreach($dir as $file) { if(is_dir($file)) { $files = array_merge($files, collect_files($file)); continue; } $files[] = $file; } return $files; } echo 'Indexing changed files according to git...' . PHP_EOL; $changed = git_changes(); echo 'Collecting files...' . PHP_EOL; $sources = collect_files(__DIR__ . '/../src'); $tests = collect_files(__DIR__ . '/../tests'); $files = array_merge($sources, $tests); $topDir = dirname(__DIR__) . DIRECTORY_SEPARATOR; $now = date('Y-m-d'); foreach($files as $file) { echo 'Scanning ' . str_replace($topDir, '', $file) . '...' . PHP_EOL; try { $handle = fopen($file, 'rb'); $checkPHP = trim(fgets($handle)) === '<?php'; if(!$checkPHP) { echo 'File is not PHP.' . PHP_EOL; continue; } $headerLines = []; $expectLine = '// ' . basename($file); $nameLine = trim(fgets($handle)); if($nameLine !== $expectLine) { echo ' File name is missing or invalid, queuing update...' . PHP_EOL; $headerLines['name'] = $expectLine; } $createdPrefix = '// Created: '; $createdLine = trim(fgets($handle)); if(strpos($createdLine, $createdPrefix) !== 0) { echo ' Creation date is missing, queuing update...' . PHP_EOL; $headerLines['created'] = $createdPrefix . $now; } $updatedPrefix = '// Updated: '; $updatedLine = trim(fgets($handle)); $updatedDate = substr($updatedLine, strlen($updatedPrefix)); if(strpos($updatedLine, $updatedPrefix) !== 0 || (in_array($file, $changed) && $updatedDate !== $now)) { echo ' Updated date is inaccurate, queuing update...' . PHP_EOL; $headerLines['updated'] = $updatedPrefix . $now; } $blankLine = trim(fgets($handle)); if(!empty($blankLine)) { echo ' Trailing newline missing, queuing update...' . PHP_EOL; $headerLines['blank'] = ''; } if(!empty($headerLines)) { fclose($handle); try { $tmpName = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'ndx-uh-' . bin2hex(random_bytes(8)) . '.tmp'; copy($file, $tmpName); $read = fopen($tmpName, 'rb'); $handle = fopen($file, 'wb'); fwrite($handle, fgets($read)); $insertAfter = []; if(empty($headerLines['name'])) fwrite($handle, fgets($read)); else { $line = fgets($read); if(strpos($line, '// ') !== 0) $insertAfter[] = $line; fwrite($handle, $headerLines['name'] . "\n"); } if(empty($headerLines['created'])) fwrite($handle, fgets($read)); else { $line = fgets($read); if(strpos($line, '// Created: ') !== 0) $insertAfter[] = $line; fwrite($handle, $headerLines['created'] . "\n"); } if(empty($headerLines['updated'])) fwrite($handle, fgets($read)); else { $line = fgets($read); if(strpos($line, '// Updated: ') !== 0) $insertAfter[] = $line; fwrite($handle, $headerLines['updated'] . "\n"); } if(!isset($headerLines['blank'])) fwrite($handle, fgets($read)); else { $line = fgets($read); if(!empty($line)) { $insertAfter[] = $line; fwrite($handle, "\n"); } } foreach($insertAfter as $line) fwrite($handle, $line); while(($line = fgets($read)) !== false) fwrite($handle, $line); } finally { if(is_resource($read)) fclose($read); if(is_file($tmpName)) unlink($tmpName); } } } finally { fclose($handle); } }