-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRunCommand.php
More file actions
134 lines (111 loc) · 3.63 KB
/
Copy pathRunCommand.php
File metadata and controls
134 lines (111 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
declare(strict_types=1);
namespace Watcher;
use Depend\DependencyFinder;
use DOMDocument;
use Exception;
use LogicException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
use Watcher\FileSystem\PHPUnitConfigFinder;
use Watcher\PHPUnit\Configuration;
use Watcher\PHPUnit\SavingConfiguration;
use Watcher\PHPUnit\XMLConfig;
use function array_filter;
use function array_map;
use function array_unique;
use function copy;
use function getcwd;
use function usleep;
final class RunCommand extends Command
{
/** @var OutputInterface */
private $output;
/** @var DependencyFinder */
private $dependencyFinder;
/** @var Watcher */
private $watcher;
/** @var Configuration */
private $configFile;
/** @var string */
private $configLocation;
protected function configure() : void
{
$this->setName('watch')
->setDescription('Start watching the files')
->addOption(
'src',
's',
InputOption::VALUE_OPTIONAL,
'Source folder to watch',
'./src'
)
->addOption(
'test',
't',
InputOption::VALUE_OPTIONAL,
'Test folder to watch',
'./tests'
);
}
/**
* @throws Exception
*/
public function execute(InputInterface $input, OutputInterface $output) : int
{
$this->output = $output;
$src = convertInputToPath($input->getOption('src'));
$test = convertInputToPath($input->getOption('test'));
$this->dependencyFinder = new DependencyFinder([$src, $test]);
$this->dependencyFinder->build();
$this->watcher = new Watcher([$src, $test]);
$cwd = getcwd();
if ($cwd === false) {
throw new LogicException('Unable to determine current directory, exiting');
}
$this->configLocation = $cwd . '/phpunit.tmp.xml.dist';
$originalConfig = (new PHPUnitConfigFinder())->find();
copy($originalConfig, $this->configLocation);
$dom = new DOMDocument();
$dom->load($originalConfig);
$this->configFile = new SavingConfiguration(new XMLConfig($dom), $this->configLocation);
$this->configFile->removeExistingTestSuite();
$this->loop();
return 1;
}
private function loop() : void
{
while (true) {
if (! $this->watcher->hasChangedFiles()) {
usleep(1000000);
continue;
}
$changedFiles = array_filter(
array_map('realpath', $this->watcher->getChangedFilesSinceLastCommit())
);
$this->doLoop($changedFiles);
usleep(1000000);
}
}
/**
* @param array<string> $changedFiles
*/
private function doLoop(array $changedFiles) : void
{
$this->dependencyFinder->reBuild($changedFiles);
$changedAndRelatedFiles = array_unique(
$this->dependencyFinder->getAllFilesDependingOn($changedFiles)
);
$this->configFile->addTestSuiteWithFilteredTestFiles($changedAndRelatedFiles);
$p = new Process([
'vendor/bin/phpunit',
'--configuration=' . $this->configLocation,
]);
$p->run();
$this->output->write($p->getOutput());
$this->configFile->removeExistingTestSuite();
}
}