-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathTypeScriptBuilder.php
More file actions
97 lines (83 loc) · 3.61 KB
/
TypeScriptBuilder.php
File metadata and controls
97 lines (83 loc) · 3.61 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
<?php
namespace Sensiolabs\TypeScriptBundle;
use Sensiolabs\TypeScriptBundle\Tools\TypeScriptBinary;
use Sensiolabs\TypeScriptBundle\Tools\TypeScriptBinaryFactory;
use Sensiolabs\TypeScriptBundle\Tools\WatcherBinary;
use Sensiolabs\TypeScriptBundle\Tools\WatcherBinaryFactory;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
class TypeScriptBuilder
{
private SymfonyStyle $output;
private ?TypeScriptBinary $buildBinary = null;
private ?WatcherBinary $watcherBinary = null;
/**
* @param list<string> $typeScriptFilesPaths
*/
public function __construct(
private readonly array $typeScriptFilesPaths,
private readonly string $compiledFilesPaths,
private readonly string $projectRootDir,
private readonly string $binaryDownloadDir,
private readonly ?string $buildBinaryPath,
private readonly ?string $configFile,
private readonly string $swcVersion,
) {
}
public function createAllBuildProcess(bool $watch = false): \Generator
{
foreach ($this->typeScriptFilesPaths as $typeScriptFilePath) {
yield $this->createBuildProcess($typeScriptFilePath, $watch);
}
}
private function createBuildProcess(string $path, bool $watch = false): Process
{
$args = ['--out-dir', $this->compiledFilesPaths];
$fs = new Filesystem();
$relativePath = rtrim($fs->makePathRelative($path, $this->projectRootDir), '/');
if (str_starts_with($relativePath, '..')) {
throw new \Exception(\sprintf('The TypeScript file "%s" is not in the project directory "%s".', $path, $this->projectRootDir));
}
if ($this->configFile && file_exists($this->configFile)) {
$args = array_merge($args, ['--config-file', trim($fs->makePathRelative($this->configFile, $this->projectRootDir), '/')]);
}
$buildProcess = $this->getBuildBinary()->createProcess(array_merge(['compile', $relativePath], $args));
$buildProcess->setWorkingDirectory($this->projectRootDir);
$this->output->note(\sprintf('Executing SWC compile on %s.', $relativePath));
if ($this->output->isVerbose()) {
$this->output->writeln([
' Command:',
' '.$buildProcess->getCommandLine(),
]);
}
$buildProcess->start();
if (false === $watch) {
return $buildProcess;
}
return $this->getWatcherBinary()->startWatch($relativePath, fn ($path, $operation) => $this->createBuildProcess($path), ['ts']);
}
public function setOutput(SymfonyStyle $output): void
{
$this->output = $output;
}
private function getBuildBinary(): TypeScriptBinary
{
if ($this->buildBinary) {
return $this->buildBinary;
}
$typescriptBinaryFactory = new TypeScriptBinaryFactory($this->binaryDownloadDir, $this->swcVersion);
$typescriptBinaryFactory->setOutput($this->output);
return $this->buildBinary = $this->buildBinaryPath ?
$typescriptBinaryFactory->getBinaryFromPath($this->buildBinaryPath) :
$typescriptBinaryFactory->getBinaryFromServerSpecs(\PHP_OS, php_uname('m'), file_exists('/etc/alpine-release') ? 'musl' : 'gnu');
}
private function getWatcherBinary(): WatcherBinary
{
if ($this->watcherBinary) {
return $this->watcherBinary;
}
$watcherBinaryFactory = new WatcherBinaryFactory();
return $this->watcherBinary = $watcherBinaryFactory->getBinaryFromServerSpecs(\PHP_OS);
}
}