|
4 | 4 |
|
5 | 5 | namespace Tempest\Console\Commands; |
6 | 6 |
|
| 7 | +use Stringable; |
| 8 | +use Tempest\Console\Console; |
7 | 9 | use Tempest\Console\ConsoleArgument; |
8 | 10 | use Tempest\Console\ConsoleCommand; |
9 | 11 | use Tempest\Console\ExitCode; |
10 | | -use Tempest\Console\HasConsole; |
11 | 12 | use Tempest\Container\Container; |
| 13 | +use Tempest\Core\AppConfig; |
| 14 | +use Tempest\Core\Insight; |
| 15 | +use Tempest\Core\InsightsProvider; |
| 16 | +use Tempest\Support\Arr; |
| 17 | +use Tempest\Support\Json; |
| 18 | +use Tempest\Support\Str; |
12 | 19 |
|
13 | 20 | final readonly class AboutCommand |
14 | 21 | { |
15 | | - use HasConsole; |
| 22 | + public function __construct( |
| 23 | + private readonly Console $console, |
| 24 | + private readonly Container $container, |
| 25 | + private readonly AppConfig $appConfig, |
| 26 | + ) {} |
16 | 27 |
|
17 | | - private Container $container; |
18 | | - private SystemInfoProvider $infoProvider; |
19 | | - |
20 | | - public function __construct(Container $container) |
21 | | - { |
22 | | - $this->container = $container; |
23 | | - $this->infoProvider = $container->get(SystemInfoProvider::class); |
24 | | - } |
25 | | - |
26 | | - #[ConsoleCommand( |
27 | | - name: 'about', |
28 | | - description: 'View a summary of information about your Tempest project', |
29 | | - aliases: ['a'], |
30 | | - )] |
| 28 | + #[ConsoleCommand(name: 'about', description: 'Shows insights about the application', aliases: ['insights'])] |
31 | 29 | public function __invoke( |
32 | | - #[ConsoleArgument(description: 'Format to json', aliases: ['-j', '--json'])] |
| 30 | + #[ConsoleArgument(description: 'Formats the outpuyt to JSON', aliases: ['--json'])] |
33 | 31 | ?bool $json = null, |
34 | 32 | ): ExitCode { |
35 | | - // Collect all information into a structured array |
36 | | - $data = $this->infoProvider->gatherInformation(); |
37 | | - |
38 | | - // Check if user chose JSON option |
39 | 33 | if ($json) { |
40 | | - // Convert array keys to snake_case |
41 | | - $snakeCaseData = $this->arrayKeysToSnakeCase($data); |
42 | | - // Encode the data as JSON |
43 | | - $jsonOutput = json_encode($snakeCaseData, JSON_PRETTY_PRINT); |
44 | | - // Check if json_encode failed |
45 | | - if ($jsonOutput === false) { |
46 | | - $this->console->error('Failed to encode JSON: ' . json_last_error_msg()); |
47 | | - return ExitCode::ERROR; |
48 | | - } |
49 | | - $this->console->writeln($jsonOutput); |
| 34 | + $this->writeInsightsAsJson(); |
50 | 35 | } else { |
51 | | - // Otherwise, display the data in the standard formatted way |
52 | | - $this->displayNormalOutput($data); |
| 36 | + $this->writeFormattedInsights(); |
53 | 37 | } |
54 | 38 |
|
55 | 39 | return ExitCode::SUCCESS; |
56 | 40 | } |
57 | 41 |
|
58 | | - /** |
59 | | - * Displays the gathered information in the standard console format. |
60 | | - * |
61 | | - * @param array $data The structured information to display |
62 | | - */ |
63 | | - private function displayNormalOutput(array $data): void |
| 42 | + private function writeFormattedInsights(): void |
64 | 43 | { |
65 | | - // Display Environment section |
66 | | - $this->displaySection('Environment', $data['environment']); |
| 44 | + foreach ($this->appConfig->insightsProviders as $class) { |
| 45 | + /** @var InsightsProvider $provider */ |
| 46 | + $provider = $this->container->get($class); |
67 | 47 |
|
68 | | - // Display Database section |
69 | | - $this->displaySection('Database', $data['database']); |
| 48 | + $this->console->header($provider->name); |
70 | 49 |
|
71 | | - // Display Cache section with styled statuses |
72 | | - $this->console->header('Cache'); |
73 | | - foreach ($data['cache'] as $key => $value) { |
74 | | - $this->displayCacheStatus($key, $value); |
| 50 | + foreach ($provider->getInsights() as $key => $value) { |
| 51 | + $this->console->keyValue($key, $this->formatInsight($value)); |
| 52 | + } |
75 | 53 | } |
76 | | - |
77 | | - // Display TailwindCSS section |
78 | | - $this->displaySection('TailwindCSS', $data['tailwindcss']); |
79 | 54 | } |
80 | 55 |
|
81 | | - /** |
82 | | - * Displays a standard section with a header and key-value pairs. |
83 | | - * |
84 | | - * @param string $sectionName The name of the section to display |
85 | | - * @param array $sectionData The data for the section |
86 | | - */ |
87 | | - private function displaySection(string $sectionName, array $sectionData): void |
| 56 | + private function writeInsightsAsJson(): void |
88 | 57 | { |
89 | | - $this->console->header($sectionName); |
90 | | - foreach ($sectionData as $key => $value) { |
91 | | - $this->console->keyValue($key, $value); |
| 58 | + $json = []; |
| 59 | + |
| 60 | + foreach ($this->appConfig->insightsProviders as $class) { |
| 61 | + /** @var InsightsProvider $provider */ |
| 62 | + $provider = $this->container->get($class); |
| 63 | + |
| 64 | + $json[Str\to_snake_case($provider->name)] = Arr\map_with_keys( |
| 65 | + array: $provider->getInsights(), |
| 66 | + map: fn (mixed $value, string $key) => yield Str\to_snake_case($key) => $this->rawInsight($value), |
| 67 | + ); |
92 | 68 | } |
93 | | - } |
94 | 69 |
|
95 | | - /** |
96 | | - * Displays the status of a cache in an appropriate style. |
97 | | - * |
98 | | - * @param string $label The name of the cache to be displayed. |
99 | | - * @param string $envVar The corresponding environment variable. |
100 | | - */ |
101 | | - private function displayCacheStatus(string $label, bool|string|int $value): void |
102 | | - { |
103 | | - $isEnabled = $this->infoProvider->isCacheEnabled($value); |
104 | | - $status = $isEnabled ? "<style='bold fg-green'>ENABLED</style>" : "<style='bold fg-red'>DISABLED</style>"; |
105 | | - $this->console->keyValue($label, $status); |
| 70 | + $this->console->writeRaw(Json\encode($json)); |
106 | 71 | } |
107 | 72 |
|
108 | | - /** |
109 | | - * Transform a string in snake case format |
110 | | - * |
111 | | - * @param string $string |
112 | | - * @return string |
113 | | - */ |
114 | | - private function toSnakeCase(string $string): string |
| 73 | + private function formatInsight(Stringable|Insight|string $value): string |
115 | 74 | { |
116 | | - // Replace spaces by underscores |
117 | | - $string = str_replace(' ', '_', $string); |
118 | | - // Convert all characters in lowercase |
119 | | - $string = strtolower($string); |
120 | | - return $string; |
| 75 | + if ($value instanceof Insight) { |
| 76 | + return $value->formattedValue; |
| 77 | + } |
| 78 | + |
| 79 | + return (string) $value; |
121 | 80 | } |
122 | 81 |
|
123 | | - /** |
124 | | - * Convert keys of an array in snake case |
125 | | - * |
126 | | - * @param array $array |
127 | | - * @return array |
128 | | - */ |
129 | | - private function arrayKeysToSnakeCase(array $array): array |
| 82 | + private function rawInsight(Stringable|Insight|string $value): string |
130 | 83 | { |
131 | | - $result = []; |
132 | | - foreach ($array as $key => $value) { |
133 | | - // Convert key in snake_case |
134 | | - $newKey = $this->toSnakeCase($key); |
135 | | - if (is_array($value)) { |
136 | | - // If value is an array, apply recusivity |
137 | | - $result[$newKey] = $this->arrayKeysToSnakeCase($value); |
138 | | - } else { |
139 | | - // Else keep the value as is |
140 | | - $result[$newKey] = $value; |
141 | | - } |
| 84 | + if ($value instanceof Insight) { |
| 85 | + return $value->value; |
142 | 86 | } |
143 | | - return $result; |
| 87 | + |
| 88 | + return Str\strip_tags((string) $value); |
144 | 89 | } |
145 | 90 | } |
0 commit comments