Last active
October 14, 2025 08:18
-
-
Save mikestreety/3ab51877065ce35ccba755e63944deff to your computer and use it in GitHub Desktop.
Set up linting for TYPO3 extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
/** | |
* TYPO3 Extension Linting Setup Script | |
* | |
* This script sets up a TYPO3 extension for linting by: | |
* - Adding .gitignore file | |
* - Modifying composer.json with linting dependencies and scripts | |
*/ | |
// File content templates | |
$gitignoreContent = ".cache/\n.Build\ncomposer.lock\n"; | |
if ($argc < 2) { | |
echo "Usage: php setup-extension-linting.php <extension-folder-path>\n"; | |
exit(1); | |
} | |
$extensionPath = rtrim($argv[1], '/'); | |
// Validate extension folder exists | |
if (!is_dir($extensionPath)) { | |
echo "Error: Extension folder '$extensionPath' does not exist.\n"; | |
exit(1); | |
} | |
// Validate composer.json exists | |
$composerJsonPath = $extensionPath . '/composer.json'; | |
if (!file_exists($composerJsonPath)) { | |
echo "Error: composer.json not found in '$extensionPath'.\n"; | |
exit(1); | |
} | |
echo "Setting up TYPO3 extension linting for: $extensionPath\n"; | |
/** | |
* Create .gitignore file | |
*/ | |
function createGitIgnore($extensionPath) | |
{ | |
global $gitignoreContent; | |
$gitignorePath = $extensionPath . '/.gitignore'; | |
file_put_contents($gitignorePath, $gitignoreContent); | |
echo "✓ Created .gitignore\n"; | |
} | |
/** | |
* Modify composer.json with testing configuration | |
*/ | |
function modifyComposerJson($extensionPath, $composer) | |
{ | |
$composerJsonPath = $extensionPath . '/composer.json'; | |
// Add extra | |
if (!isset($composer['extra'])) { | |
$composer['extra'] = []; | |
} | |
if (!isset($composer['extra']['typo3/cms'])) { | |
$composer['extra']['typo3/cms'] = []; | |
} | |
$composer['extra']['typo3/cms']['web-dir'] = ".Build/public"; | |
// Add require-dev | |
if (!isset($composer['require-dev'])) { | |
$composer['require-dev'] = []; | |
} | |
$requireDev = [ | |
"ergebnis/composer-normalize" => "^2.48", | |
"lintkit/editorconfig-config" => "^1.0", | |
"lintkit/php-coding-standards-config" => "^2.0", | |
"php-parallel-lint/php-parallel-lint" => "^1.4", | |
]; | |
foreach ($requireDev as $package => $version) { | |
if (!isset($composer['require-dev'][$package])) { | |
$composer['require-dev'][$package] = $version; | |
} | |
} | |
// Add config | |
if (!isset($composer['config'])) { | |
$composer['config'] = []; | |
} | |
$composer['config']['lock'] = false; | |
$composer['config']['vendor-dir'] = ".Build/vendor"; | |
if (!isset($composer['config']['allow-plugins'])) { | |
$composer['config']['allow-plugins'] = []; | |
} | |
$composer['config']['allow-plugins']['typo3/cms-composer-installers'] = true; | |
$composer['config']['allow-plugins']['typo3/class-alias-loader'] = true; | |
// Add scripts | |
if (!isset($composer['scripts'])) { | |
$composer['scripts'] = []; | |
} | |
$scripts = [ | |
"clean" => "rm -rf .Build", | |
"composer-normalize:dry-run" => "@composer-normalize:fix --dry-run", | |
"composer-normalize:fix" => "@composer normalize --indent-size 4 --indent-style space", | |
"editorconfig:dry-run" => "ec --finder-config .Build/vendor/lintkit/editorconfig-config/ec-cli-config.php", | |
"editorconfig:fix" => "@editorconfig:dry-run --fix", | |
"lint" => [ | |
"@lint:php", | |
"@composer-normalize:fix", | |
"@yaml-lint", | |
"@editorconfig:fix", | |
], | |
"lint:php" => [ | |
"@parallel-lint", | |
"@php-cs-fixer:fix", | |
], | |
"parallel-lint" => "parallel-lint ./ --exclude ./.Build", | |
"php-cs-fixer:dry-run" => "@php-cs-fixer:fix --dry-run", | |
"php-cs-fixer:fix" => "php-cs-fixer fix --config .Build/vendor/lintkit/php-coding-standards-config/.php-cs-fixer.php -v --diff", | |
"yaml-lint" => "yaml-lint ./Configuration", | |
]; | |
foreach ($scripts as $name => $command) { | |
$composer['scripts'][$name] = $command; | |
} | |
// Write back to file | |
$newContent = json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); | |
file_put_contents($composerJsonPath, $newContent); | |
echo "✓ Modified composer.json\n"; | |
} | |
// Main execution | |
try { | |
// Load and parse composer.json first | |
$composerJsonPath = $extensionPath . '/composer.json'; | |
$content = file_get_contents($composerJsonPath); | |
$composer = json_decode($content, true); | |
if (json_last_error() !== JSON_ERROR_NONE) { | |
throw new Exception("Invalid JSON in composer.json: " . json_last_error_msg()); | |
} | |
createGitIgnore($extensionPath); | |
modifyComposerJson($extensionPath, $composer); | |
echo "\n✅ Extension linting setup completed successfully!\n"; | |
echo "\nNext steps:\n"; | |
echo "1. Run 'composer install' in the extension folder\n"; | |
echo "2. Run 'composer lint'\n"; | |
} catch (Exception $e) { | |
echo "Error: " . $e->getMessage() . "\n"; | |
exit(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment