diff --git a/captainhook.json b/captainhook.json
index 233e387e..1057cb29 100644
--- a/captainhook.json
+++ b/captainhook.json
@@ -1,44 +1,53 @@
-{
- "pre-push": {
- "enabled": true,
- "actions": [
- {
- "action": "php vendor/bin/phpstan analyse --memory-limit 300M"
- }
- ]
- },
- "pre-commit": {
- "enabled": true,
- "actions": [
- {
- "action": "php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --diff {$STAGED_FILES|of-type:php} --sequential",
- "conditions": [
- {
- "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType",
- "args": ["php"]
- }
- ]
- }
- ]
- },
- "post-change": {
- "enabled": true,
- "actions": [
- {
- "action": "composer install",
- "options": [],
- "conditions": [
- {
- "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\Any",
- "args": [
- [
- "composer.json",
- "composer.lock"
- ]
- ]
- }
- ]
- }
- ]
- }
-}
+{
+ "pre-push": {
+ "enabled": true,
+ "actions": [
+ {
+ "action": "php vendor/bin/phpstan analyse --memory-limit 300M"
+ }
+ ]
+ },
+ "pre-commit": {
+ "enabled": true,
+ "actions": [
+ {
+ "action": "php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --diff {$STAGED_FILES|of-type:php} --sequential",
+ "conditions": [
+ {
+ "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType",
+ "args": ["php"]
+ }
+ ]
+ },
+ {
+ "action": "bin/spc dev:lint-config --check",
+ "conditions": [
+ {
+ "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\InDirectory",
+ "args": ["config"]
+ }
+ ]
+ }
+ ]
+ },
+ "post-change": {
+ "enabled": true,
+ "actions": [
+ {
+ "action": "composer install",
+ "options": [],
+ "conditions": [
+ {
+ "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\Any",
+ "args": [
+ [
+ "composer.json",
+ "composer.lock"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/composer.json b/composer.json
index fbdbc94b..c5470b54 100644
--- a/composer.json
+++ b/composer.json
@@ -50,6 +50,7 @@
"scripts": {
"analyse": "phpstan analyse --memory-limit 300M",
"cs-fix": "php-cs-fixer fix",
+ "lint-config": "bin/spc dev:lint-config",
"test": "vendor/bin/phpunit tests/ --no-coverage",
"build:phar": "vendor/bin/box compile"
},
diff --git a/src/StaticPHP/Command/Dev/LintConfigCommand.php b/src/StaticPHP/Command/Dev/LintConfigCommand.php
index 8149af14..d0e4cfa1 100644
--- a/src/StaticPHP/Command/Dev/LintConfigCommand.php
+++ b/src/StaticPHP/Command/Dev/LintConfigCommand.php
@@ -7,6 +7,7 @@ namespace StaticPHP\Command\Dev;
use StaticPHP\Command\BaseCommand;
use StaticPHP\Registry\Registry;
use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Yaml\Yaml;
#[AsCommand('dev:lint-config', 'Lint configuration file format', ['dev:sort-config'])]
@@ -14,15 +15,28 @@ class LintConfigCommand extends BaseCommand
{
public function handle(): int
{
+ $checkOnly = $this->input->getOption('check');
+ $hasChanges = false;
+
// get loaded configs
$loded_configs = Registry::getLoadedArtifactConfigs();
foreach ($loded_configs as $file) {
- $this->sortConfigFile($file, 'artifact');
+ if ($this->sortConfigFile($file, 'artifact', $checkOnly)) {
+ $hasChanges = true;
+ }
}
$loaded_pkg_configs = Registry::getLoadedPackageConfigs();
foreach ($loaded_pkg_configs as $file) {
- $this->sortConfigFile($file, 'package');
+ if ($this->sortConfigFile($file, 'package', $checkOnly)) {
+ $hasChanges = true;
+ }
}
+
+ if ($checkOnly && $hasChanges) {
+ $this->output->writeln('Some config files need sorting. Run "bin/spc dev:lint-config" to fix them.');
+ return static::FAILURE;
+ }
+
return static::SUCCESS;
}
@@ -88,22 +102,27 @@ class LintConfigCommand extends BaseCommand
return $a <=> $b;
}
- private function sortConfigFile(mixed $file, string $config_type): void
+ protected function configure(): void
+ {
+ $this->addOption('check', null, InputOption::VALUE_NONE, 'Check if config files need sorting without modifying them');
+ }
+
+ private function sortConfigFile(mixed $file, string $config_type, bool $checkOnly): bool
{
// read file content with different extensions
$content = file_get_contents($file);
if ($content === false) {
- $this->output->writeln("Failed to read artifact config file: {$file}");
- return;
+ $this->output->writeln("Failed to read config file: {$file}");
+ return false;
}
$data = match (pathinfo($file, PATHINFO_EXTENSION)) {
'json' => json_decode($content, true),
- 'yml', 'yaml' => Yaml::parse($content), // skip yaml files for now
+ 'yml', 'yaml' => Yaml::parse($content),
default => null,
};
if (!is_array($data)) {
- $this->output->writeln("Invalid JSON format in artifact config file: {$file}");
- return;
+ $this->output->writeln("Invalid format in config file: {$file}");
+ return false;
}
ksort($data);
foreach ($data as $artifact_name => &$config) {
@@ -115,7 +134,18 @@ class LintConfigCommand extends BaseCommand
'yml', 'yaml' => Yaml::dump($data, 4, 2),
default => null,
};
- file_put_contents($file, $new_content);
- $this->output->writeln("Sorted artifact config file: {$file}");
+
+ // Check if content has changed
+ if ($content !== $new_content) {
+ if ($checkOnly) {
+ $this->output->writeln("File needs sorting: {$file}");
+ return true;
+ }
+ file_put_contents($file, $new_content);
+ $this->output->writeln("Sorted config file: {$file}");
+ return true;
+ }
+
+ return false;
}
}