Skip to content

Commit 3eb176a

Browse files
PatrickBrainMaestro
authored andcommitted
Add support for Windows (#8)
* Add .idea folder to ignore list For developers who use JetBrains IntellJIDEA. * Add missing empty line at end of file. * Add test-git-dir to ignore list. * Fix tests to run on windows too. * Use findstr on windows. * Add SHEBANG to hook files on windows. * Test that the shebang has been added. * Use native PHP functions in tests.
1 parent d166689 commit 3eb176a

File tree

7 files changed

+84
-13
lines changed

7 files changed

+84
-13
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
/vendor/
2+
/.idea/
3+
/test-git-dir/

src/Commands/AddCommand.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
4747
if (file_exists($filename)) {
4848
$output->writeln("<comment>{$hook} already exists</comment>");
4949
} else {
50+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
51+
// On windows we need to add a SHEBANG
52+
// See: https://github.com/BrainMaestro/composer-git-hooks/issues/7
53+
$script = '#!/bin/bash' . PHP_EOL . $script;
54+
}
55+
5056
file_put_contents($filename, $script);
5157
chmod($filename, 0755);
5258
$output->writeln("Added <info>{$hook}</info> hook");
@@ -82,9 +88,11 @@ private function addLockFile($hooks, $output)
8288

8389
private function ignoreLockFile($output)
8490
{
85-
passthru('grep -q ' . Hook::LOCK_FILE . ' .gitignore', $return);
86-
if ($return !== 0) {
87-
passthru('echo ' . Hook::LOCK_FILE . ' >> .gitignore');
91+
$contents = file_get_contents('.gitignore');
92+
$return = strpos($contents, Hook::LOCK_FILE);
93+
94+
if ($return === false) {
95+
file_put_contents('.gitignore', Hook::LOCK_FILE . PHP_EOL, FILE_APPEND);
8896
$output->writeln('<comment>Added ' . Hook::LOCK_FILE . ' to .gitignore</comment>');
8997
}
9098
}

tests/AddCommandTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ public function it_adds_hooks_that_do_not_already_exist()
3232
}
3333
}
3434

35+
/**
36+
* @test
37+
*/
38+
public function it_adds_shebang_to_hooks_on_windows()
39+
{
40+
if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')
41+
$this->markTestSkipped('This test is only relevant on windows. You\'re running Linux.');
42+
43+
$this->commandTester->execute([]);
44+
45+
foreach (array_keys(self::$hooks) as $hook) {
46+
$this->assertContains("Added {$hook} hook", $this->commandTester->getDisplay());
47+
48+
$content = file_get_contents(".git/hooks/" . $hook);
49+
$this->assertNotFalse(strpos($content, "#!/bin/bash"));
50+
$this->assertEquals(strpos($content, "#!/bin/bash"), 0);
51+
}
52+
}
53+
3554
/**
3655
* @test
3756
*/

tests/ListCommandTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ public function it_lists_hooks_that_exist()
3737
public function it_uses_a_different_git_path_if_specified()
3838
{
3939
$gitDir = 'test-git-dir';
40-
passthru("mkdir -p {$gitDir}/hooks");
40+
41+
mkdir("{$gitDir}/hooks", 0777, true);
42+
4143
self::createHooks($gitDir);
4244

4345
$this->commandTester->execute(['--git-dir' => $gitDir]);
@@ -46,6 +48,6 @@ public function it_uses_a_different_git_path_if_specified()
4648
$this->assertContains($hook, $this->commandTester->getDisplay());
4749
}
4850

49-
passthru("rm -rf {$gitDir}");
51+
$this->recursive_rmdir($gitDir);
5052
}
5153
}

tests/PrepareHookTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public static function tearDownAfterClass()
2323

2424
public static function createHooks($gitDir = '.git')
2525
{
26+
if (!is_dir("{$gitDir}/hooks")) {
27+
mkdir("{$gitDir}/hooks", 0777, true);
28+
}
29+
2630
foreach (self::$hooks as $hook => $script) {
2731
file_put_contents("{$gitDir}/hooks/{$hook}", $script);
2832
}
@@ -43,4 +47,30 @@ private static function prepare()
4347
$ignoreContents = file_get_contents('.gitignore');
4448
file_put_contents('.gitignore', str_replace(Hook::LOCK_FILE . PHP_EOL, '', $ignoreContents));
4549
}
50+
51+
/**
52+
* Since PHP does not support the recursive deletion of
53+
* a directory and its entire contents we need a helper here.
54+
*
55+
* @see https://stackoverflow.com/a/3338133
56+
*
57+
* @param $dir string
58+
*/
59+
protected function recursive_rmdir($dir)
60+
{
61+
if (is_dir($dir)) {
62+
$objects = scandir($dir);
63+
64+
foreach ($objects as $object) {
65+
if ($object != "." && $object != "..") {
66+
if (is_dir($dir."/".$object))
67+
$this->recursive_rmdir($dir."/".$object);
68+
else
69+
unlink($dir."/".$object);
70+
}
71+
}
72+
73+
rmdir($dir);
74+
}
75+
}
4676
}

tests/RemoveCommandTest.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ public function it_removes_hooks_that_were_added()
3737
public function it_removes_removed_hooks_from_the_lock_file()
3838
{
3939
foreach (array_keys(self::$hooks) as $hook) {
40-
passthru("grep -q {$hook} " . Hook::LOCK_FILE, $return);
40+
$contents = file_get_contents('.gitignore');
41+
$return = strpos($contents, Hook::LOCK_FILE);
42+
4143
$this->assertEquals(0, $return);
4244

4345
$this->commandTester->execute(['hooks' => [$hook]]);
4446
$this->assertContains("Removed {$hook} hook", $this->commandTester->getDisplay());
4547

46-
passthru("grep -q {$hook} " . Hook::LOCK_FILE, $return);
47-
$this->assertEquals(1, $return);
48+
$contents = file_get_contents('.gitignore');
49+
$return = strpos($contents, Hook::LOCK_FILE);
50+
$this->assertFalse($return);
4851
}
4952
}
5053

@@ -66,7 +69,9 @@ public function it_does_not_remove_hooks_not_present_in_the_lock_file()
6669
{
6770
$hook = 'test-hook';
6871
$this->commandTester->execute(['hooks' => [$hook]]);
69-
$this->assertContains("Skipped {$hook} hook - not present in lock file", $this->commandTester->getDisplay());
72+
$this->assertContains(
73+
"Skipped {$hook} hook - not present in lock file", $this->commandTester->getDisplay()
74+
);
7075
}
7176

7277
/**
@@ -89,7 +94,9 @@ public function it_removes_hooks_not_present_in_the_lock_file_if_forced_to()
8994
public function it_uses_a_different_git_path_if_specified()
9095
{
9196
$gitDir = 'test-git-dir';
92-
passthru("mkdir -p {$gitDir}/hooks");
97+
98+
mkdir("{$gitDir}/hooks", 0777, true);
99+
93100
self::createHooks($gitDir);
94101
$this->assertFalse(self::isDirEmpty("{$gitDir}/hooks"));
95102

@@ -100,7 +107,8 @@ public function it_uses_a_different_git_path_if_specified()
100107
}
101108

102109
$this->assertTrue(self::isDirEmpty("{$gitDir}/hooks"));
103-
passthru("rm -rf {$gitDir}");
110+
111+
$this->recursive_rmdir($gitDir);
104112
}
105113

106114
public function tearDown()

tests/UpdateCommandTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ public function it_updates_hooks_that_already_exist()
5151
public function it_uses_a_different_git_path_if_specified()
5252
{
5353
$gitDir = 'test-git-dir';
54-
passthru("mkdir -p {$gitDir}/hooks");
54+
55+
mkdir("{$gitDir}/hooks", 0777, true);
56+
5557
$this->commandTester->execute(['--git-dir' => $gitDir]);
5658

5759
foreach (array_keys(self::$hooks) as $hook) {
5860
$this->assertTrue(file_exists("{$gitDir}/hooks/{$hook}"));
5961
}
6062

61-
passthru("rm -rf {$gitDir}");
63+
$this->recursive_rmdir($gitDir);
6264
}
6365

6466
/**

0 commit comments

Comments
 (0)