1: <?php declare(strict_types=1);
2:
3: namespace Salient\Contract\Console;
4:
5: use Psr\Log\LoggerInterface;
6: use Salient\Contract\Console\ConsoleFormatterInterface as FormatterInterface;
7: use Salient\Contract\Core\Instantiable;
8: use Salient\Contract\HasMessageLevel;
9: use Salient\Contract\HasMessageLevels;
10: use Throwable;
11:
12: interface ConsoleInterface extends
13: Instantiable,
14: HasMessageLevel,
15: HasMessageLevels,
16: HasMessageType,
17: HasMessageTypes
18: {
19: /**
20: * Register STDOUT and STDERR to receive console output if running on the
21: * command line
22: *
23: * - Errors and warnings are written to `STDERR`
24: * - Informational messages are written to `STDOUT`
25: * - Debug messages are ignored unless environment variable `DEBUG` is set
26: *
27: * @return $this
28: */
29: public function registerStdioTargets();
30:
31: /**
32: * Register STDERR to receive console output if running on the command line
33: *
34: * - Errors, warnings and informational messages are written to `STDERR`
35: * - Debug messages are ignored unless environment variable `DEBUG` is set
36: *
37: * @return $this
38: */
39: public function registerStderrTarget();
40:
41: /**
42: * Register a target to receive console output
43: *
44: * @param array<ConsoleInterface::LEVEL_*> $levels
45: * @return $this
46: */
47: public function registerTarget(
48: ConsoleTargetInterface $target,
49: array $levels = ConsoleInterface::LEVELS_ALL
50: );
51:
52: /**
53: * Deregister and close a registered target
54: *
55: * If `$target` is a registered target, it is deregistered and closed via
56: * {@see ConsoleTargetInterface::close()}, otherwise calling this method has
57: * no effect.
58: *
59: * @return $this
60: */
61: public function deregisterTarget(ConsoleTargetInterface $target);
62:
63: /**
64: * Get a list of registered targets, optionally filtered by level and type
65: *
66: * @param ConsoleInterface::LEVEL_*|null $level
67: * @param int-mask-of<ConsoleTargetTypeFlag::*> $flags
68: * @return ConsoleTargetInterface[]
69: */
70: public function getTargets(?int $level = null, int $flags = 0): array;
71:
72: /**
73: * Set or unset the prefix applied to each line of output by any registered
74: * targets that implement ConsoleTargetPrefixInterface
75: *
76: * @param int-mask-of<ConsoleTargetTypeFlag::*> $flags
77: * @return $this
78: */
79: public function setTargetPrefix(?string $prefix, int $flags = 0);
80:
81: /**
82: * Get the width of a registered target in columns
83: *
84: * Returns {@see ConsoleTargetInterface::getWidth()} from whichever is found
85: * first:
86: *
87: * - the first TTY target registered with the given level
88: * - the first `STDOUT` or `STDERR` target registered with the given level
89: * - the first target registered with the given level
90: * - the target returned by {@see getStderrTarget()} if backed by a TTY
91: * - the target returned by {@see getStdoutTarget()}
92: *
93: * @param ConsoleInterface::LEVEL_* $level
94: */
95: public function getWidth(int $level = ConsoleInterface::LEVEL_INFO): ?int;
96:
97: /**
98: * Get an output formatter for a registered target
99: *
100: * Returns {@see ConsoleTargetInterface::getFormatter()} from the same
101: * target as {@see ConsoleInterface::getWidth()}.
102: *
103: * @param ConsoleInterface::LEVEL_* $level
104: */
105: public function getFormatter(int $level = ConsoleInterface::LEVEL_INFO): FormatterInterface;
106:
107: /**
108: * Get a PSR-3 logger
109: */
110: public function getLogger(): LoggerInterface;
111:
112: /**
113: * Get a target for STDOUT, creating an unregistered one if necessary
114: */
115: public function getStdoutTarget(): ConsoleTargetStreamInterface;
116:
117: /**
118: * Get a target for STDERR, creating an unregistered one if necessary
119: */
120: public function getStderrTarget(): ConsoleTargetStreamInterface;
121:
122: /**
123: * Get the number of error messages recorded so far
124: */
125: public function getErrorCount(): int;
126:
127: /**
128: * Get the number of warning messages recorded so far
129: */
130: public function getWarningCount(): int;
131:
132: /**
133: * Escape a string so it can be safely used in a console message
134: */
135: public function escape(string $string): string;
136:
137: /**
138: * Print "! $msg1 $msg2" with level ERROR
139: *
140: * @return $this
141: */
142: public function error(
143: string $msg1,
144: ?string $msg2 = null,
145: ?Throwable $ex = null,
146: bool $count = true
147: );
148:
149: /**
150: * Print "! $msg1 $msg2" with level ERROR once per run
151: *
152: * @return $this
153: */
154: public function errorOnce(
155: string $msg1,
156: ?string $msg2 = null,
157: ?Throwable $ex = null,
158: bool $count = true
159: );
160:
161: /**
162: * Print "^ $msg1 $msg2" with level WARNING
163: *
164: * @return $this
165: */
166: public function warn(
167: string $msg1,
168: ?string $msg2 = null,
169: ?Throwable $ex = null,
170: bool $count = true
171: );
172:
173: /**
174: * Print "^ $msg1 $msg2" with level WARNING once per run
175: *
176: * @return $this
177: */
178: public function warnOnce(
179: string $msg1,
180: ?string $msg2 = null,
181: ?Throwable $ex = null,
182: bool $count = true
183: );
184:
185: /**
186: * Print "➤ $msg1 $msg2" with level NOTICE
187: *
188: * @return $this
189: */
190: public function info(string $msg1, ?string $msg2 = null);
191:
192: /**
193: * Print "➤ $msg1 $msg2" with level NOTICE once per run
194: *
195: * @return $this
196: */
197: public function infoOnce(string $msg1, ?string $msg2 = null);
198:
199: /**
200: * Print "- $msg1 $msg2" with level INFO
201: *
202: * @return $this
203: */
204: public function log(string $msg1, ?string $msg2 = null);
205:
206: /**
207: * Print "- $msg1 $msg2" with level INFO once per run
208: *
209: * @return $this
210: */
211: public function logOnce(string $msg1, ?string $msg2 = null);
212:
213: /**
214: * Print ": <caller> $msg1 $msg2" with level DEBUG
215: *
216: * @param int $depth To print your caller's name instead of your own, set
217: * `$depth` to 1.
218: * @return $this
219: */
220: public function debug(
221: string $msg1,
222: ?string $msg2 = null,
223: ?Throwable $ex = null,
224: int $depth = 0
225: );
226:
227: /**
228: * Print ": <caller> $msg1 $msg2" with level DEBUG once per run
229: *
230: * @param int $depth To print your caller's name instead of your own, set
231: * `$depth` to 1.
232: * @return $this
233: */
234: public function debugOnce(
235: string $msg1,
236: ?string $msg2 = null,
237: ?Throwable $ex = null,
238: int $depth = 0
239: );
240:
241: /**
242: * Print "⠿ $msg1 $msg2" with level INFO to TTY targets without moving to
243: * the next line
244: *
245: * This method can be called repeatedly to display progress updates without
246: * disrupting other console messages or bloating output logs.
247: *
248: * @return $this
249: */
250: public function logProgress(string $msg1, ?string $msg2 = null);
251:
252: /**
253: * Print a "clear to end of line" control sequence with level INFO to TTY
254: * targets with a logProgress() message
255: *
256: * @return $this
257: */
258: public function clearProgress();
259:
260: /**
261: * Print "$msg1 $msg2" with prefix and formatting optionally based on $level
262: *
263: * @param ConsoleInterface::LEVEL_* $level
264: * @param ConsoleInterface::TYPE_* $type
265: * @return $this
266: */
267: public function message(
268: string $msg1,
269: ?string $msg2 = null,
270: int $level = ConsoleInterface::LEVEL_INFO,
271: int $type = ConsoleInterface::TYPE_UNDECORATED,
272: ?Throwable $ex = null,
273: bool $count = true
274: );
275:
276: /**
277: * Print "$msg1 $msg2" with prefix and formatting optionally based on $level
278: * once per run
279: *
280: * @param ConsoleInterface::LEVEL_* $level
281: * @param ConsoleInterface::TYPE_* $type
282: * @return $this
283: */
284: public function messageOnce(
285: string $msg1,
286: ?string $msg2 = null,
287: int $level = ConsoleInterface::LEVEL_INFO,
288: int $type = ConsoleInterface::TYPE_UNDECORATED,
289: ?Throwable $ex = null,
290: bool $count = true
291: );
292:
293: /**
294: * Record a message with level $level without printing anything
295: *
296: * @param ConsoleInterface::LEVEL_* $level
297: * @return $this
298: */
299: public function count(int $level);
300:
301: /**
302: * Increase the indentation level of messages and print "» $msg1 $msg2" with
303: * level NOTICE
304: *
305: * If `$endMsg1` is not `null`, `"« $endMsg1 $endMsg2"` is printed with
306: * level NOTICE when {@see groupEnd()} is called to close the group.
307: *
308: * @return $this
309: */
310: public function group(
311: string $msg1,
312: ?string $msg2 = null,
313: ?string $endMsg1 = null,
314: ?string $endMsg2 = null
315: );
316:
317: /**
318: * Close the nested message group most recently opened with group()
319: *
320: * @return $this
321: */
322: public function groupEnd();
323:
324: /**
325: * Print an exception's name and message with a given level, optionally
326: * followed by its stack trace with a different level
327: *
328: * @param ConsoleInterface::LEVEL_* $level
329: * @param ConsoleInterface::LEVEL_*|null $traceLevel If `null`, the
330: * exception's stack trace is not printed.
331: * @return $this
332: */
333: public function exception(
334: Throwable $exception,
335: int $level = ConsoleInterface::LEVEL_ERROR,
336: ?int $traceLevel = ConsoleInterface::LEVEL_DEBUG
337: );
338:
339: /**
340: * Print a "command finished" message with a summary of errors, warnings and
341: * resource usage
342: *
343: * @return $this
344: */
345: public function summary(
346: string $finishedText = 'Command finished',
347: string $successText = 'without errors',
348: bool $withResourceUsage = false,
349: bool $withoutErrorCount = false,
350: bool $withStandardMessageType = false
351: );
352:
353: /**
354: * Print "$msg" to registered targets
355: *
356: * @param ConsoleInterface::LEVEL_* $level
357: * @param ConsoleInterface::TYPE_* $type
358: * @return $this
359: */
360: public function print(
361: string $msg,
362: int $level = ConsoleInterface::LEVEL_INFO,
363: int $type = ConsoleInterface::TYPE_UNFORMATTED
364: );
365:
366: /**
367: * Print "$msg" to registered STDOUT or STDERR targets
368: *
369: * @param ConsoleInterface::LEVEL_* $level
370: * @param ConsoleInterface::TYPE_* $type
371: * @return $this
372: */
373: public function printOut(
374: string $msg,
375: int $level = ConsoleInterface::LEVEL_INFO,
376: int $type = ConsoleInterface::TYPE_UNFORMATTED
377: );
378:
379: /**
380: * Print "$msg" to registered TTY targets
381: *
382: * @param ConsoleInterface::LEVEL_* $level
383: * @param ConsoleInterface::TYPE_* $type
384: * @return $this
385: */
386: public function printTty(
387: string $msg,
388: int $level = ConsoleInterface::LEVEL_INFO,
389: int $type = ConsoleInterface::TYPE_UNFORMATTED
390: );
391:
392: /**
393: * Print "$msg" to STDOUT even if no STDOUT target is registered
394: *
395: * @param ConsoleInterface::LEVEL_* $level
396: * @param ConsoleInterface::TYPE_* $type
397: * @return $this
398: */
399: public function printStdout(
400: string $msg,
401: int $level = ConsoleInterface::LEVEL_INFO,
402: int $type = ConsoleInterface::TYPE_UNFORMATTED
403: );
404:
405: /**
406: * Print "$msg" to STDERR even if no STDERR target is registered
407: *
408: * @param ConsoleInterface::LEVEL_* $level
409: * @param ConsoleInterface::TYPE_* $type
410: * @return $this
411: */
412: public function printStderr(
413: string $msg,
414: int $level = ConsoleInterface::LEVEL_INFO,
415: int $type = ConsoleInterface::TYPE_UNFORMATTED
416: );
417: }
418: