Skip to content

Commit 7ee525b

Browse files
spaceemotionfreekmurze
authored andcommitted
Fix windows compatibility (#98)
* Fix infinite loop on windows when searching config On Windows the root directory includes the drive letter instead of simply being "DIRECTORY_SEPARATOR". This caused an infinite loop. * Don't use an interactive process on windows This lets us still watch the folder for changes and execute PHPUnit, we just don't get the benefits of the "runtime settings". * Hide the manual when running on windows * Fix OS compatibility PhpunitWatcherTest * Add note for windows users to README * Introduce OS utility to avoid code duplication * Fix typo in Watcher class
1 parent ebd3383 commit 7ee525b

File tree

6 files changed

+56
-6
lines changed

6 files changed

+56
-6
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Want to pass some arguments to PHPUnit? No problem, just tack them on:
6767
phpunit-watcher watch --filter=it_can_run_a_single_test
6868
```
6969

70+
#### A note for Windows users
71+
Currently, TTY is not being supported, so any interaction has been disabled. While watching for changes works,
72+
any arguments for PHPUnit have to be provided when initially calling `phpunit-watcher`.
73+
7074
## Customization
7175

7276
Certain aspects of the behaviour of the tool can be modified. The file for options may be named `.phpunit-watcher.yml`, `phpunit-watcher.yml` or `phpunit-watcher.yml.dist`. The tool will look for a file in that order.

src/OS.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Spatie\PhpUnitWatcher;
4+
5+
class OS
6+
{
7+
/**
8+
* Indicates if the process is being executed in a windows machine.
9+
*
10+
* @return bool
11+
*/
12+
public static function isOnWindows()
13+
{
14+
return DIRECTORY_SEPARATOR !== '/';
15+
}
16+
}

src/Screens/Phpunit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ protected function writeHeader()
9494
protected function runTests()
9595
{
9696
$result = (new Process(array_merge([$this->phpunitBinaryPath], explode(' ', $this->phpunitArguments))))
97-
->setTty(true)
97+
->setTty(Process::isTtySupported())
9898
->run(function ($type, $line) {
9999
echo $line;
100100
});

src/Watcher.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Clue\React\Stdio\Stdio;
66
use React\EventLoop\Factory;
7+
use React\Stream\ThroughStream;
78
use Symfony\Component\Finder\Finder;
89
use Spatie\PhpUnitWatcher\Screens\Phpunit;
910
use Yosymfony\ResourceWatcher\ResourceWatcher;
@@ -29,7 +30,7 @@ public function __construct(Finder $finder, array $options)
2930

3031
$this->loop = Factory::create();
3132

32-
$this->terminal = new Terminal(new Stdio($this->loop));
33+
$this->terminal = new Terminal($this->buildStdio());
3334

3435
$this->options = $options;
3536
}
@@ -56,4 +57,22 @@ public function startWatching()
5657

5758
$this->loop->run();
5859
}
60+
61+
protected function buildStdio()
62+
{
63+
$output = null;
64+
65+
if (OS::isOnWindows()) {
66+
// Interaction on windows is currently not supported
67+
fclose(STDIN);
68+
69+
// Simple fix for windows compatibility since we don't write a lot of data at once
70+
// https://github.com/clue/reactphp-stdio/issues/83#issuecomment-546678609
71+
$output = new ThroughStream(static function ($data) {
72+
echo $data;
73+
});
74+
}
75+
76+
return new Stdio($this->loop, null, $output);
77+
}
5978
}

src/WatcherCommand.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ protected function determineOptions(InputInterface $input): array
4040
$options['phpunit']['arguments'] = $commandLineArguments;
4141
}
4242

43+
if (OS::isOnWindows()) {
44+
$options['hideManual'] = true;
45+
}
46+
4347
return $options;
4448
}
4549

@@ -74,17 +78,23 @@ protected function getConfigFileLocation()
7478

7579
while (is_dir($configDirectory)) {
7680
foreach ($configNames as $configName) {
77-
$configFullPath = "{$configDirectory}/{$configName}";
81+
$configFullPath = $configDirectory.DIRECTORY_SEPARATOR.$configName;
7882

7983
if (file_exists($configFullPath)) {
8084
return $configFullPath;
8185
}
8286
}
8387

84-
if ($configDirectory === DIRECTORY_SEPARATOR) {
88+
$parentDirectory = dirname($configDirectory);
89+
90+
// We do a direct comparison here since there's a difference between
91+
// the root directories on windows / *nix systems which does not
92+
// let us compare it against the DIRECTORY_SEPARATOR directly
93+
if ($parentDirectory === $configDirectory) {
8594
return;
8695
}
87-
$configDirectory = dirname($configDirectory);
96+
97+
$configDirectory = $parentDirectory;
8898
}
8999
}
90100

tests/PhpunitWatcherTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\PhpUnitWatcher\Test;
44

5+
use Spatie\PhpUnitWatcher\OS;
56
use PHPUnit\Framework\TestCase;
67
use Symfony\Component\Process\Process;
78

@@ -10,7 +11,7 @@ class PhpunitWatcherTest extends TestCase
1011
/** @test */
1112
public function the_watcher_can_be_executed()
1213
{
13-
$process = new Process('./phpunit-watcher');
14+
$process = new Process(OS::isOnWindows() ? ['php', 'phpunit-watcher'] : ['./phpunit-watcher']);
1415

1516
$process->run();
1617

0 commit comments

Comments
 (0)