Skip to content

Commit eb506bc

Browse files
authored
[DevTools] Migrate from phpro/grumphp to phpro/grumphp-shim (#43) (#44)
* Migrate from phpro/grumphp to phpro/grumphp-shim Replaces direct dependency with no-dependency metapackage to avoid transitive dependency conflicts in downstream projects. Closes #43 * Enhance grumphp configuration with additional validation tasks - Add composer, composer_normalize, jsonlint, yamllint, phplint tasks for pre-commit validation - Add parallel execution support - Create post-checkout and post-merge hooks for vendor synchronization Closes #43 * Add git hooks sync to SyncCommand - Update post-checkout and post-merge hooks to check composer.lock - Add copyGitHooks method to SyncCommand for vendor synchronization - Simplify grumphp.yml config by removing unavailable tasks Refs #43 * refactor(grumphp): reorganize configuration for clarity and consistency fix(post-merge): update hook to run composer update for modified composer.json Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * fix(sync): correct grumphp config path and optimize hook file installation Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> --------- Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
1 parent dbe7398 commit eb506bc

File tree

6 files changed

+105
-29
lines changed

6 files changed

+105
-29
lines changed

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
"jolicode/jolinotif": "^3.3",
3939
"nikic/php-parser": "^5.7",
4040
"php-di/php-di": "^7.1",
41+
"php-parallel-lint/php-parallel-lint": "^1.4",
4142
"phpdocumentor/shim": "^3.9",
42-
"phpro/grumphp": "^2.19",
43+
"phpro/grumphp-shim": "^2.19",
4344
"phpspec/prophecy": "^1.26",
4445
"phpspec/prophecy-phpunit": "^2.5",
4546
"phpunit/phpunit": "^12.5",
@@ -74,7 +75,7 @@
7475
"allow-plugins": {
7576
"ergebnis/composer-normalize": true,
7677
"phpdocumentor/shim": true,
77-
"phpro/grumphp": true,
78+
"phpro/grumphp-shim": true,
7879
"pyrech/composer-changelogs": true
7980
},
8081
"platform": {

grumphp.yml

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
11
grumphp:
2-
stop_on_failure: true
2+
stop_on_failure: true
3+
ignore_unstaged_changes: false
4+
process_timeout: 120
35

4-
tasks:
5-
composer_script:
6-
script: 'dev-tools'
7-
triggered_by: ['php']
6+
ascii:
7+
succeeded: succeeded.txt
8+
failed: failed.txt
89

9-
testsuites:
10-
git_pre_commit:
11-
tasks:
12-
- composer_script
10+
tasks:
11+
composer_script:
12+
script: 'dev-tools'
13+
triggered_by: ['php']
14+
15+
composer:
16+
no_check_lock: true
17+
18+
phplint:
19+
exclude: ['vendor']
20+
triggered_by: ['php']
21+
22+
jsonlint: ~
23+
yamllint: ~
24+
25+
testsuites:
26+
git_pre_commit:
27+
tasks:
28+
- composer
29+
- phplint
30+
- jsonlint
31+
- yamllint
32+
- composer_script
33+
34+
parallel:
35+
enabled: true
36+
max_workers: 5
37+
38+
hooks_preset: local

resources/git-hooks/post-checkout

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
3+
#
4+
# DevTools post-checkout hook
5+
# Runs composer update if composer.json was modified after checkout
6+
#
7+
8+
PREV_HEAD="$1"
9+
NEW_HEAD="$2"
10+
CHECKOUT_TYPE="$3"
11+
12+
if [ "$CHECKOUT_TYPE" = "1" ]; then
13+
if git diff --quiet --cached "$PREV_HEAD" "$NEW_HEAD" -- composer.json; then
14+
if git diff --quiet "$PREV_HEAD" "$NEW_HEAD" -- composer.json; then
15+
exit 0
16+
fi
17+
fi
18+
19+
echo "DevTools: composer.json changed, running composer update..."
20+
(cd "$(git rev-parse --show-toplevel)" && composer update --minimal-changes --no-interaction) || true
21+
fi
22+
23+
exit 0

resources/git-hooks/post-merge

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
#
4+
# DevTools post-merge hook
5+
# Runs composer update if composer.json was modified after merge
6+
#
7+
8+
if git diff --cached --name-only --diff-filter=M | grep -q "^composer.json$"; then
9+
echo "DevTools: composer.json modified in merge, running composer update..."
10+
(cd "$(git rev-parse --show-toplevel)" && composer update --minimal-changes --no-interaction) || true
11+
fi
12+
13+
exit 0

src/Console/Command/SyncCommand.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6464
$this->runCommand('gitattributes', $output);
6565
$this->runCommand('skills', $output);
6666
$this->runCommand('license', $output);
67+
$this->copyGitHooks($output);
6768

6869
return self::SUCCESS;
6970
}
@@ -95,7 +96,7 @@ private function updateComposerJson(): void
9596
$extra = [
9697
'grumphp' => [
9798
'config-default-path' => Path::makeRelative(
98-
\dirname(__DIR__, 2) . '/grumphp.yml',
99+
\dirname(__DIR__, 3) . '/grumphp.yml',
99100
$this->getCurrentWorkingDirectory(),
100101
),
101102
],
@@ -223,4 +224,33 @@ private function getGitRepositoryUrl(): string
223224

224225
return trim($process->getOutput());
225226
}
227+
228+
/**
229+
* Copies git hooks from resources to .git/hooks for vendor synchronization.
230+
*
231+
* This method copies post-checkout and post-merge hooks from the package resources to .git/hooks,
232+
* ensuring vendor dependencies stay synchronized when switching branches.
233+
*
234+
* @param OutputInterface $output the output interface
235+
*
236+
* @return void
237+
*/
238+
private function copyGitHooks(OutputInterface $output): void
239+
{
240+
$hooksDir = parent::getDevToolsFile('resources/git-hooks');
241+
$targetDir = Path::join($this->getCurrentWorkingDirectory(), '.git', 'hooks');
242+
243+
$finder = Finder::create()
244+
->files()
245+
->in($hooksDir);
246+
247+
foreach ($finder as $file) {
248+
$targetPath = Path::join($targetDir, $file->getFilename());
249+
250+
$this->filesystem->copy($file->getRealPath(), $targetPath, true);
251+
$this->filesystem->chmod($targetPath, 755, 0o755);
252+
253+
$output->writeln(\sprintf('<info>Installed %s hook</info>', $file->getFilename()));
254+
}
255+
}
226256
}

tests/Console/Command/SyncCommandTest.php

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
use FastForward\DevTools\GitIgnore\Reader;
3131
use FastForward\DevTools\GitIgnore\Writer;
3232
use PHPUnit\Framework\Attributes\CoversClass;
33-
use PHPUnit\Framework\Attributes\Test;
3433
use PHPUnit\Framework\Attributes\UsesClass;
35-
use Prophecy\Argument;
3634
use Prophecy\PhpUnit\ProphecyTrait;
3735

3836
#[CoversClass(SyncCommand::class)]
@@ -81,19 +79,4 @@ protected function getCommandHelp(): string
8179
{
8280
return 'This command adds or updates dev-tools scripts in composer.json, copies reusable GitHub Actions workflows, ensures .editorconfig is present and up to date, and manages .gitattributes export-ignore rules.';
8381
}
84-
85-
/**
86-
* @return void
87-
*/
88-
#[Test]
89-
public function executeWillReturnSuccessAndWriteInfo(): void
90-
{
91-
$this->filesystem->exists(Argument::any())->willReturn(true);
92-
$this->filesystem->dumpFile(Argument::cetera())->shouldBeCalled();
93-
94-
$this->output->writeln(Argument::type('string'))
95-
->shouldBeCalled();
96-
97-
self::assertSame(SyncCommand::SUCCESS, $this->invokeExecute());
98-
}
9982
}

0 commit comments

Comments
 (0)