|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Sandro Keil (https://sandro-keil.de) |
|
4
|
|
|
* |
|
5
|
|
|
* @link http://github.com/sandrokeil/interop-config for the canonical source repository |
|
6
|
|
|
* @copyright Copyright (c) 2017-2017 Sandro Keil |
|
7
|
|
|
* @license http://github.com/sandrokeil/interop-config/blob/master/LICENSE.md New BSD License |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
declare(strict_types=1); |
|
11
|
|
|
|
|
12
|
|
|
namespace Interop\Config\Tool; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* Utilities for console tooling. |
|
16
|
|
|
* |
|
17
|
|
|
* Provides the following facilities: |
|
18
|
|
|
* |
|
19
|
|
|
* - Colorize strings using markup (e.g., `<info>message</info>`, |
|
20
|
|
|
* `<error>message</error>`) |
|
21
|
|
|
* - Write output to a specified stream, optionally with colorization. |
|
22
|
|
|
* - Write a line of output to a specified stream, optionally with |
|
23
|
|
|
* colorization, using the system EOL sequence.. |
|
24
|
|
|
* - Write an error message to STDERR. |
|
25
|
|
|
* - Reads a single line from the user |
|
26
|
|
|
* |
|
27
|
|
|
* Colorization will only occur when expected sequences are discovered and then, only if the console terminal allows it. |
|
28
|
|
|
* |
|
29
|
|
|
* Essentially, provides the bare minimum to allow you to provide messages to the current console. |
|
30
|
|
|
* |
|
31
|
|
|
* @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com) |
|
32
|
|
|
*/ |
|
33
|
|
|
class ConsoleHelper |
|
34
|
|
|
{ |
|
35
|
|
|
const COLOR_GREEN = "\033[32m"; |
|
36
|
|
|
const COLOR_YELLOW = "\033[33m"; |
|
37
|
|
|
const COLOR_RED = "\033[31m"; |
|
38
|
|
|
const COLOR_RESET = "\033[0m"; |
|
39
|
|
|
|
|
40
|
|
|
const HIGHLIGHT_INFO = 'info'; |
|
41
|
|
|
const HIGHLIGHT_VALUE = 'value'; |
|
42
|
|
|
const HIGHLIGHT_ERROR = 'error'; |
|
43
|
|
|
|
|
44
|
|
|
private $highlightMap = [ |
|
45
|
|
|
self::HIGHLIGHT_VALUE => self::COLOR_GREEN, |
|
46
|
|
|
self::HIGHLIGHT_INFO => self::COLOR_YELLOW, |
|
47
|
|
|
self::HIGHLIGHT_ERROR => self::COLOR_RED, |
|
48
|
|
|
]; |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* @var string Exists only for testing. |
|
52
|
|
|
*/ |
|
53
|
|
|
private $eol = PHP_EOL; |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* @var bool |
|
57
|
|
|
*/ |
|
58
|
|
|
private $supportsColor; |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* @var resource Exists only for testing. |
|
62
|
|
|
*/ |
|
63
|
|
|
private $errorStream = STDERR; |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Input stream |
|
67
|
|
|
* |
|
68
|
|
|
* @var resource |
|
69
|
|
|
*/ |
|
70
|
|
|
private $inputStream; |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* Output stream |
|
74
|
|
|
* |
|
75
|
|
|
* @var resource |
|
76
|
|
|
*/ |
|
77
|
|
|
private $outputStream; |
|
78
|
|
|
|
|
79
|
36 |
|
public function __construct($inputStream = STDIN, $outputStream = STDOUT, $errorStream = STDERR) |
|
80
|
|
|
{ |
|
81
|
36 |
|
$this->inputStream = $inputStream; |
|
82
|
36 |
|
$this->outputStream = $outputStream; |
|
83
|
36 |
|
$this->errorStream = $errorStream; |
|
84
|
36 |
|
$this->supportsColor = $this->detectColorCapabilities($outputStream); |
|
85
|
36 |
|
} |
|
86
|
|
|
|
|
87
|
16 |
|
public function readLine(string $name, string $text = 'Please enter a value for'): string |
|
88
|
|
|
{ |
|
89
|
16 |
|
fwrite($this->outputStream, $this->colorize(sprintf('%s <info>%s</info>: ', $text, $name))); |
|
90
|
16 |
|
return trim(fread($this->inputStream, 1024), "\n"); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
/** |
|
94
|
|
|
* Colorize a string for use with the terminal. |
|
95
|
|
|
* |
|
96
|
|
|
* Takes strings formatted as `<key>string</key>` and formats them per the |
|
97
|
|
|
* $highlightMap; if color support is disabled, simply removes the formatting |
|
98
|
|
|
* tags. |
|
99
|
|
|
* |
|
100
|
|
|
* @param string $string |
|
101
|
|
|
* @return string |
|
102
|
|
|
*/ |
|
103
|
31 |
|
public function colorize(string $string): string |
|
104
|
|
|
{ |
|
105
|
31 |
|
$reset = $this->supportsColor ? self::COLOR_RESET : ''; |
|
106
|
31 |
|
foreach ($this->highlightMap as $key => $color) { |
|
107
|
31 |
|
$pattern = sprintf('#<%s>(.*?)</%s>#s', $key, $key); |
|
108
|
31 |
|
$color = $this->supportsColor ? $color : ''; |
|
109
|
31 |
|
$string = preg_replace($pattern, $color . '$1' . $reset, $string); |
|
110
|
|
|
} |
|
111
|
31 |
|
return $string; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* @param string $string |
|
116
|
|
|
* @param bool $colorize Whether or not to colorize the string |
|
117
|
|
|
* @return void |
|
118
|
|
|
*/ |
|
119
|
6 |
|
public function write(string $string, bool $colorize = true): void |
|
120
|
|
|
{ |
|
121
|
6 |
|
if ($colorize) { |
|
122
|
6 |
|
$string = $this->colorize($string); |
|
123
|
|
|
} |
|
124
|
6 |
|
$string = $this->formatNewlines($string); |
|
125
|
|
|
|
|
126
|
6 |
|
fwrite($this->outputStream, $string); |
|
127
|
6 |
|
} |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* @param string $string |
|
131
|
|
|
* @param bool $colorize Whether or not to colorize the line |
|
132
|
|
|
* @return void |
|
133
|
|
|
*/ |
|
134
|
2 |
|
public function writeLine(string $string, bool $colorize = true): void |
|
135
|
|
|
{ |
|
136
|
2 |
|
$this->write($string . $this->eol, $colorize); |
|
137
|
2 |
|
} |
|
138
|
|
|
|
|
139
|
|
|
/** |
|
140
|
|
|
* @param string $string |
|
141
|
|
|
* @param bool $colorize Whether or not to colorize the line |
|
142
|
|
|
* @return void |
|
143
|
|
|
*/ |
|
144
|
14 |
|
public function writeErrorLine(string $string, bool $colorize = true): void |
|
145
|
|
|
{ |
|
146
|
14 |
|
$string .= $this->eol; |
|
147
|
|
|
|
|
148
|
14 |
|
if ($colorize) { |
|
149
|
14 |
|
$string = $this->colorize($string); |
|
150
|
|
|
} |
|
151
|
14 |
|
$string = $this->formatNewlines($string); |
|
152
|
|
|
|
|
153
|
14 |
|
fwrite($this->errorStream, $string); |
|
154
|
14 |
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* Emit an error message. |
|
158
|
|
|
* |
|
159
|
|
|
* Wraps the message in `<error></error>`, and passes it to `writeLine()`, |
|
160
|
|
|
* using STDERR as the resource; emits an additional empty line when done, |
|
161
|
|
|
* also to STDERR. |
|
162
|
|
|
* |
|
163
|
|
|
* @param string $message |
|
164
|
|
|
* @return void |
|
165
|
|
|
*/ |
|
166
|
14 |
|
public function writeErrorMessage(string $message): void |
|
167
|
|
|
{ |
|
168
|
14 |
|
$this->writeErrorLine(sprintf('<error>%s</error>', $message), true); |
|
169
|
14 |
|
$this->writeErrorLine('', false); |
|
170
|
14 |
|
} |
|
171
|
|
|
|
|
172
|
|
|
/** |
|
173
|
|
|
* @param resource $resource |
|
174
|
|
|
* @return bool |
|
175
|
|
|
*/ |
|
176
|
36 |
|
private function detectColorCapabilities($resource = STDOUT): bool |
|
177
|
|
|
{ |
|
178
|
36 |
|
if ('\\' === DIRECTORY_SEPARATOR) { |
|
179
|
|
|
// Windows |
|
180
|
|
|
return false !== getenv('ANSICON') |
|
181
|
|
|
|| 'ON' === getenv('ConEmuANSI') |
|
182
|
|
|
|| 'xterm' === getenv('TERM'); |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
try { |
|
186
|
36 |
|
return function_exists('posix_isatty') && posix_isatty($resource); |
|
187
|
36 |
|
} catch (\Throwable $e) { |
|
|
|
|
|
|
188
|
36 |
|
return false; |
|
189
|
|
|
} |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
/** |
|
193
|
|
|
* Ensure newlines are appropriate for the current terminal. |
|
194
|
|
|
* |
|
195
|
|
|
* @param string |
|
196
|
|
|
* @return string |
|
197
|
|
|
*/ |
|
198
|
20 |
|
private function formatNewlines(string $string): string |
|
199
|
|
|
{ |
|
200
|
20 |
|
$string = str_replace($this->eol, "\0PHP_EOL\0", $string); |
|
201
|
20 |
|
$string = preg_replace("/(\r\n|\n|\r)/", $this->eol, $string); |
|
202
|
20 |
|
return str_replace("\0PHP_EOL\0", $this->eol, $string); |
|
203
|
|
|
} |
|
204
|
|
|
} |
|
205
|
|
|
|
Scrutinizer analyzes your
composer.json/composer.lockfile if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.