11<?php namespace xp \lambda ;
22
33use io \Path ;
4- use lang \CommandLine ;
4+ use lang \{ CommandLine , Process } ;
55
66trait Docker {
77 private $ command = null ;
88
99 /**
10- * Resolves a list of commands. Copy of `lang.Process::resolve()` from
11- * XP 10.14 in order to be compatible with older XP versions .
10+ * Resolves a list of commands. Raises an exception if none of the passed
11+ * commands is found .
1212 *
13- * @see https://github.com/xp-framework/core/pull/279
1413 * @param string[] $commands
1514 * @return string
1615 * @throws lang.IllegalStateException
1716 */
1817 private function resolve ($ commands ) {
19- clearstatcache ();
20-
21- // PATHEXT is in form ".{EXT}[;.{EXT}[;...]]"
22- $ extensions = array_merge (['' ], explode (PATH_SEPARATOR , getenv ('PATHEXT ' )));
23- $ paths = $ paths = explode (PATH_SEPARATOR , getenv ('PATH ' ));
18+ $ c = CommandLine::forName (PHP_OS );
2419 foreach ($ commands as $ command ) {
25-
26- // If the command is in fully qualified form and refers to a file
27- // that does not exist (e.g. "C:\DoesNotExist.exe", "\DoesNotExist.com"
28- // or /usr/bin/doesnotexist), do not attempt to search for it.
29- if ((DIRECTORY_SEPARATOR === $ command [0 ]) || ((strncasecmp (PHP_OS , 'Win ' , 3 ) === 0 ) &&
30- strlen ($ command ) > 1 && (': ' === $ command [1 ] || '/ ' === $ command [0 ])
31- )) {
32- foreach ($ extensions as $ ext ) {
33- $ q = $ command .$ ext ;
34- if (file_exists ($ q ) && !is_dir ($ q )) return realpath ($ q );
35- }
36- continue ;
37- }
38-
39- // Check the PATH environment setting for possible locations of the
40- // executable if its name is not a fully qualified path name.
41- foreach ($ paths as $ path ) {
42- foreach ($ extensions as $ ext ) {
43- $ q = $ path .DIRECTORY_SEPARATOR .$ command .$ ext ;
44- if (file_exists ($ q ) && !is_dir ($ q )) return realpath ($ q );
45- }
20+ foreach ($ c ->resolve ($ command ) as $ resolved ) {
21+ return $ resolved ;
4622 }
4723 }
4824
@@ -51,15 +27,27 @@ private function resolve($commands) {
5127
5228 /** Returns docker runtime */
5329 private function command () {
54- return $ this ->command ?? $ this ->command = CommandLine::forName (PHP_OS )->compose ($ this ->resolve (['docker ' , 'podman ' ]));
30+ return $ this ->command ?? $ this ->command = $ this ->resolve (['docker ' , 'podman ' ]);
31+ }
32+
33+ /** Runs docker with arguments */
34+ private function passthru ($ arguments ) {
35+ return (new Process ($ this ->command (), $ arguments , null , null , [STDIN , STDOUT , STDERR ]))->close ();
5536 }
5637
5738 /** Returns a given docker image, building it if necessary */
5839 private function image (string $ name , string $ version , array $ dependencies = [], bool $ rebuild = false ): array {
5940 $ image = "lambda-xp- {$ name }: {$ version }" ;
6041 $ images = [$ name => $ image ];
6142
62- $ rebuild ? $ out = [] : exec ("{$ this ->command ()} image ls -q {$ image }" , $ out , $ result );
43+ if ($ rebuild ) {
44+ $ out = null ;
45+ } else {
46+ $ p = new Process ($ this ->command (), ['image ' , 'ls ' , '-q ' , $ image ], null , null , [0 => STDIN , 2 => STDERR ]);
47+ $ out = $ p ->out ->readLine ();
48+ $ p ->close ();
49+ }
50+
6351 if (empty ($ out )) {
6452
6553 // Support 3-digit `6.1.0` as well as 4-digit `6.1.0.1234` formats
@@ -71,8 +59,14 @@ private function image(string $name, string $version, array $dependencies= [], b
7159 }
7260
7361 // Build this
74- $ file = new Path (__DIR__ , 'Dockerfile. ' .$ name );
75- passthru ("{$ this ->command ()} build -t {$ image } --build-arg php_version= {$ version } --build-arg xp_version= {$ runners } -f {$ file } . " , $ result );
62+ $ result = $ this ->passthru ([
63+ 'build ' ,
64+ '-t ' , $ image ,
65+ '--build-arg ' , "php_version= {$ version }" ,
66+ '--build-arg ' , "xp_version= {$ runners }" ,
67+ '-f ' , new Path (__DIR__ , 'Dockerfile. ' .$ name ),
68+ '. '
69+ ]);
7670 0 === $ result || $ images [$ name ]= null ;
7771 }
7872
0 commit comments