1
1
<?php
2
2
3
- namespace Sensiolabs \TypeScriptBundle ;
3
+ namespace Sensiolabs \TypeScriptBundle \ Tools ;
4
4
5
+ use Symfony \Component \Console \Output \OutputInterface ;
5
6
use Symfony \Component \Console \Style \SymfonyStyle ;
6
7
use Symfony \Component \HttpClient \HttpClient ;
7
- use Symfony \Component \Process \Process ;
8
8
use Symfony \Contracts \HttpClient \HttpClientInterface ;
9
9
10
- class TypeScriptBinary
10
+ class TypescriptBinaryFactory
11
11
{
12
12
private const VERSION = 'v1.3.92 ' ;
13
13
private const SWC_RELEASE_URL_PATTERN = 'https://github.com/swc-project/swc/releases/download/%s/%s ' ;
14
14
15
15
public function __construct (
16
16
private readonly string $ binaryDownloadDir ,
17
- private readonly ?string $ binaryPath ,
18
- private ?SymfonyStyle $ output = null ,
19
17
private ?HttpClientInterface $ httpClient = null ,
20
- private ?string $ binaryName = null ,
18
+ private ?OutputInterface $ output = null ,
21
19
) {
22
20
$ this ->httpClient = $ httpClient ?? HttpClient::create ();
23
21
}
24
22
25
- /**
26
- * @param array<string> $args
27
- */
28
- public function createProcess (array $ args ): Process
23
+ public function getBinaryFromPath ($ pathToExecutable ): TypeScriptBinary
29
24
{
30
- if (null === $ this ->binaryPath ) {
31
- $ binary = $ this ->getDefaultBinaryPath ();
32
- if (!is_file ($ binary )) {
33
- $ this ->downloadBinary ();
34
- }
35
- } else {
36
- $ binary = $ this ->binaryPath ;
37
- }
38
-
39
- array_unshift ($ args , $ binary );
40
-
41
- return new Process ($ args );
25
+ return new TypeScriptBinary ($ pathToExecutable );
42
26
}
43
27
44
- public function downloadBinary ( ): void
28
+ public function getBinaryFromServerSpecs ( $ os , $ machine , $ kernel ): TypeScriptBinary
45
29
{
46
- $ targetPath = $ this ->getDefaultBinaryPath ();
47
- if (file_exists ($ targetPath )) {
48
- return ;
49
- }
50
-
51
- if (!is_dir ($ this ->binaryDownloadDir )) {
52
- mkdir ($ this ->binaryDownloadDir , 0777 , true );
30
+ $ binaryName = self ::getBinaryNameFromServerSpecs ($ os , $ machine , $ kernel );
31
+ if (!file_exists ($ this ->binaryDownloadDir .'/ ' .$ binaryName )) {
32
+ $ this ->downloadAndExtract ($ binaryName );
53
33
}
54
34
55
- $ url = sprintf (self ::SWC_RELEASE_URL_PATTERN , self ::VERSION , $ this ->getBinaryName ());
56
- $ this ->output ?->note(sprintf ('Downloading TypeScript binary to %s... ' , $ targetPath ));
57
-
58
- $ response = $ this ->httpClient ->request ('GET ' , $ url , [
59
- 'on_progress ' => function (int $ dlNow , int $ dlSize , array $ info ) use (&$ progressBar ): void {
60
- if (0 === $ dlSize ) {
61
- return ;
62
- }
63
-
64
- if (!$ progressBar ) {
65
- $ progressBar = $ this ->output ?->createProgressBar($ dlSize );
66
- }
35
+ return $ this ->getBinaryFromPath ($ this ->binaryDownloadDir .'/ ' .$ binaryName );
36
+ }
67
37
68
- $ progressBar ?->setProgress($ dlNow );
69
- },
70
- ]);
71
- $ fileHandler = fopen ($ targetPath , 'w ' );
72
- foreach ($ this ->httpClient ->stream ($ response ) as $ chunk ) {
73
- fwrite ($ fileHandler , $ chunk ->getContent ());
74
- }
38
+ public function setOutput (?SymfonyStyle $ output ): self
39
+ {
40
+ $ this ->output = $ output ;
75
41
76
- fclose ($ fileHandler );
77
- chmod ($ targetPath , 7770 );
78
- $ progressBar ?->finish();
79
- $ this ->output ?->writeln('' );
42
+ return $ this ;
80
43
}
81
44
82
- private function getBinaryName ( ): string
45
+ public function setHttpClient ( HttpClientInterface $ client ): self
83
46
{
84
- if (null !== $ this ->binaryName ) {
85
- return $ this ->binaryName ;
86
- }
87
- $ os = strtolower (\PHP_OS );
88
- $ machine = strtolower (php_uname ('m ' ));
47
+ $ this ->httpClient = $ client ;
89
48
49
+ return $ this ;
50
+ }
51
+
52
+ public static function getBinaryNameFromServerSpecs (
53
+ $ os ,
54
+ $ machine ,
55
+ $ kernel ,
56
+ ) {
57
+ list ($ os , $ machine , $ kernel ) = [strtolower ($ os ), strtolower ($ machine ), strtolower ($ kernel )];
90
58
if (str_contains ($ os , 'darwin ' )) {
91
59
if ('arm64 ' === $ machine ) {
92
- return $ this -> binaryName = 'swc-darwin-arm64 ' ;
60
+ return 'swc-darwin-arm64 ' ;
93
61
}
94
62
95
63
if ('x86_64 ' === $ machine ) {
96
- return $ this -> binaryName = 'swc-darwin-x64 ' ;
64
+ return 'swc-darwin-x64 ' ;
97
65
}
98
66
99
67
throw new \Exception (sprintf ('No matching machine found for Darwin platform (Machine: %s). ' , $ machine ));
100
68
}
101
69
102
70
if (str_contains ($ os , 'linux ' )) {
103
- $ kernel = strtolower (php_uname ('r ' ));
104
71
$ kernelVersion = str_contains ($ kernel , 'musl ' ) ? 'musl ' : 'gnu ' ;
105
72
if ('arm64 ' === $ machine || 'aarch64 ' === $ machine ) {
106
- return $ this -> binaryName = 'swc-linux-arm64- ' .$ kernelVersion ;
73
+ return 'swc-linux-arm64- ' .$ kernelVersion ;
107
74
}
108
75
if ('x86_64 ' === $ machine ) {
109
- return $ this -> binaryName = 'swc-linux-x64- ' .$ kernelVersion ;
76
+ return 'swc-linux-x64- ' .$ kernelVersion ;
110
77
}
111
78
112
79
throw new \Exception (sprintf ('No matching machine found for Linux platform (Machine: %s). ' , $ machine ));
113
80
}
114
81
115
82
if (str_contains ($ os , 'win ' )) {
116
83
if ('x86_64 ' === $ machine ) {
117
- return $ this -> binaryName = 'swc-win32-x64-msvc ' ;
84
+ return 'swc-win32-x64-msvc ' ;
118
85
}
119
86
if ('amd64 ' === $ machine ) {
120
- return $ this -> binaryName = 'swc-win32-arm64-msvc ' ;
87
+ return 'swc-win32-arm64-msvc ' ;
121
88
}
122
89
if ('i586 ' === $ machine ) {
123
- return $ this -> binaryName = 'swc-win32-ia32-msvc ' ;
90
+ return 'swc-win32-ia32-msvc ' ;
124
91
}
125
92
126
93
throw new \Exception (sprintf ('No matching machine found for Windows platform (Machine: %s). ' , $ machine ));
@@ -129,8 +96,45 @@ private function getBinaryName(): string
129
96
throw new \Exception (sprintf ('Unknown platform or architecture (OS: %s, Machine: %s). ' , $ os , $ machine ));
130
97
}
131
98
132
- private function getDefaultBinaryPath ( ): string
99
+ private function downloadAndExtract ( $ binaryName ): void
133
100
{
134
- return $ this ->binaryDownloadDir .'/ ' .$ this ->getBinaryName ();
101
+ if (!is_dir ($ this ->binaryDownloadDir )) {
102
+ mkdir ($ this ->binaryDownloadDir , 0777 , true );
103
+ }
104
+ $ targetPath = $ this ->binaryDownloadDir .'/ ' .$ binaryName ;
105
+ if (file_exists ($ targetPath )) {
106
+ return ;
107
+ }
108
+ $ url = sprintf (self ::SWC_RELEASE_URL_PATTERN , self ::VERSION , $ binaryName );
109
+
110
+ if ($ this ->output ?->isVerbose()) {
111
+ $ this ->output ?->note(sprintf ('Downloading SWC binary from "%s" to "%s"... ' , $ url , $ targetPath ));
112
+ } else {
113
+ $ this ->output ?->note('Downloading SWC binary ... ' );
114
+ }
115
+
116
+ $ response = $ this ->httpClient ->request ('GET ' , $ url , [
117
+ 'on_progress ' => function (int $ dlNow , int $ dlSize , array $ info ) use (&$ progressBar ): void {
118
+ if (0 === $ dlSize ) {
119
+ return ;
120
+ }
121
+
122
+ if (!$ progressBar ) {
123
+ $ progressBar = $ this ->output ?->createProgressBar($ dlSize );
124
+ }
125
+
126
+ $ progressBar ?->setProgress($ dlNow );
127
+ },
128
+ ]);
129
+ $ fileHandler = fopen ($ targetPath , 'w ' );
130
+ foreach ($ this ->httpClient ->stream ($ response ) as $ chunk ) {
131
+ fwrite ($ fileHandler , $ chunk ->getContent ());
132
+ }
133
+
134
+ fclose ($ fileHandler );
135
+ $ progressBar ?->finish();
136
+ $ this ->output ?->writeln('' );
137
+
138
+ chmod ($ this ->binaryDownloadDir .'/ ' .$ binaryName , 7770 );
135
139
}
136
140
}
0 commit comments