Passed
Push — master ( 3684ce...bd7ad1 )
by Caen
03:24 queued 12s
created

Command::safeHandle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Console\Concerns;
6
7
use function config;
8
use Exception;
9
use Hyde\Hyde;
10
use LaravelZero\Framework\Commands\Command as BaseCommand;
11
use function sprintf;
12
13
/**
14
 * @see \Hyde\Framework\Testing\Feature\CommandTest
15
 */
16
abstract class Command extends BaseCommand
17
{
18
    public const USER_EXIT = 130;
19
20
    /**
21
     * The base handle method that can be overridden by child classes.
22
     *
23
     * Alternatively, implement the safeHandle method in your child class
24
     * to utilize the automatic exception handling provided by this method.
25
     *
26
     * @return int The exit code.
27
     */
28
    public function handle(): int
29
    {
30
        try {
31
            return $this->safeHandle();
32
        } catch (Exception $exception) {
33
            return $this->handleException($exception);
34
        }
35
    }
36
37
    /**
38
     * This method can be overridden by child classes to provide automatic exception handling.
39
     *
40
     * Existing code can be converted simply by renaming the handle() method to safeHandle().
41
     *
42
     * @return int The exit code.
43
     */
44
    protected function safeHandle(): int
45
    {
46
        return Command::SUCCESS;
47
    }
48
49
    /**
50
     * Handle an exception that occurred during command execution.
51
     *
52
     * @return int The exit code
53
     */
54
    public function handleException(Exception $exception): int
55
    {
56
        // When testing it might be more useful to see the full stack trace, so we have an option to actually throw the exception.
57
        if (config('app.throw_on_console_exception', false)) {
58
            throw $exception;
59
        }
60
61
        // If the exception was thrown from the same file as a command, then we don't need to show which file it was thrown from.
62
        $location = str_ends_with($exception->getFile(), 'Command.php') ? '' : sprintf(' at %s:%s',
63
            $exception->getFile(), $exception->getLine()
64
        );
65
        $this->error("Error: {$exception->getMessage()}".$location);
66
67
        return Command::FAILURE;
68
    }
69
70
    /**
71
     * Create a filepath that can be opened in the browser from a terminal.
72
     */
73
    public static function createClickableFilepath(string $filepath): string
74
    {
75
        return 'file://'.str_replace('\\', '/', realpath($filepath) ?: Hyde::path($filepath));
76
    }
77
78
    /**
79
     * Write a nicely formatted and consistent message to the console. Using InfoComment for a lack of a better term.
80
     *
81
     * Text in [brackets] will automatically be wrapped in <comment> tags.
82
     */
83
    public function infoComment(string $string): void
84
    {
85
        $replacements = [
86
            '[' => '</info>[<comment>',
87
            ']' => '</comment>]<info>',
88
        ];
89
90
        $string = str_replace(array_keys($replacements), array_values($replacements), $string);
91
92
        $this->line("<info>$string</info>");
93
    }
94
95
    /** @experimental This method may change (or be removed) before the 1.0.0 release */
96
    public function gray(string $string): void
97
    {
98
        $this->line($this->inlineGray($string));
99
    }
100
101
    /** @experimental This method may change (or be removed) before the 1.0.0 release */
102
    public function inlineGray(string $string): string
103
    {
104
        return "<fg=gray>$string</>";
105
    }
106
107
    public function indentedLine(int $indent, string $string): void
108
    {
109
        $this->line(str_repeat(' ', $indent).$string);
110
    }
111
}
112