-
Notifications
You must be signed in to change notification settings - Fork 99
/
Copy pathTerminal.php
105 lines (86 loc) · 2.14 KB
/
Terminal.php
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
<?php
namespace Laravel\Prompts;
use RuntimeException;
use Symfony\Component\Console\Terminal as SymfonyTerminal;
class Terminal
{
/**
* The initial TTY mode.
*/
protected ?string $initialTtyMode;
/**
* The number of columns in the terminal.
*/
protected int $cols;
/**
* The number of lines in the terminal.
*/
protected int $lines;
/**
* Read a line from the terminal.
*/
public function read(): string
{
$input = fread(STDIN, 1024);
return $input !== false ? $input : '';
}
/**
* Set the TTY mode.
*/
public function setTty(string $mode): void
{
$this->initialTtyMode ??= $this->exec('stty -g');
$this->exec("stty $mode");
}
/**
* Restore the initial TTY mode.
*/
public function restoreTty(): void
{
if ($this->initialTtyMode) {
$this->exec("stty {$this->initialTtyMode}");
$this->initialTtyMode = null;
}
}
/**
* Get the number of columns in the terminal.
*/
public function cols(): int
{
return $this->cols ??= (new SymfonyTerminal())->getWidth();
}
/**
* Get the number of lines in the terminal.
*/
public function lines(): int
{
return $this->lines ??= (new SymfonyTerminal())->getHeight();
}
/**
* Exit the interactive session.
*/
public function exit(): void
{
exit(1);
}
/**
* Execute the given command and return the output.
*/
protected function exec(string $command): string
{
$process = proc_open($command, [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
], $pipes);
if (! $process) {
throw new RuntimeException('Failed to create process.');
}
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
$code = proc_close($process);
if ($code !== 0 || $stdout === false) {
throw new RuntimeException(trim($stderr ?: "Unknown error (code: $code)"), $code);
}
return $stdout;
}
}