Skip to content

Commit dafcbd6

Browse files
author
Pete Bishop
committed
Implement Debug Command
1 parent 0102a92 commit dafcbd6

File tree

2 files changed

+178
-1
lines changed

2 files changed

+178
-1
lines changed

src/Commands/DebugCommand.php

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
3+
namespace Native\Laravel\Commands;
4+
5+
use Composer\InstalledVersions;
6+
use Illuminate\Console\Command;
7+
use Illuminate\Contracts\Console\PromptsForMissingInput;
8+
use Illuminate\Support\Collection;
9+
use Illuminate\Support\Facades\File;
10+
use Illuminate\Support\Facades\Process;
11+
use function Laravel\Prompts\error;
12+
use function Laravel\Prompts\intro;
13+
use function Laravel\Prompts\info;
14+
use function Laravel\Prompts\note;
15+
use function Laravel\Prompts\outro;
16+
use function Laravel\Prompts\select;
17+
18+
class DebugCommand extends Command implements PromptsForMissingInput
19+
{
20+
protected $signature = 'native:debug {output}';
21+
protected $description = 'Generate debug information required for opening an issue.';
22+
23+
private Collection $debugInfo;
24+
25+
public function handle(): void
26+
{
27+
$this->debugInfo = collect();
28+
intro('Generating Debug Information...');
29+
30+
$this->processEnvironment()
31+
->processNativePHP()
32+
->processErrorLog();
33+
34+
switch ($this->argument('output')) {
35+
case 'File':
36+
$this->outputToFile();
37+
break;
38+
case 'Console':
39+
$this->outputToConsole();
40+
break;
41+
default:
42+
error('Invalid output option specified.');
43+
}
44+
45+
outro('Debug Information Generated.');
46+
}
47+
48+
private function processEnvironment(): static
49+
{
50+
info('Generating Environment Data...');
51+
$environment = [
52+
'PHP' => [
53+
'Version' => phpversion(),
54+
'Path' => PHP_BINARY,
55+
],
56+
'Laravel' => [
57+
'Version' => app()->version(),
58+
'ConfigCached' => file_exists($this->laravel->getCachedConfigPath()),
59+
'DebugEnabled' => $this->laravel->hasDebugModeEnabled()
60+
],
61+
'Node' => [
62+
'Version' => trim(Process::run('node -v')->output()),
63+
'Path' => trim(Process::run('which node')->output()),
64+
'NPM' => trim(Process::run('npm -v')->output()),
65+
],
66+
'OperatingSystem' => PHP_OS,
67+
];
68+
69+
$this->debugInfo->put('Environment', $environment);
70+
71+
return $this;
72+
}
73+
74+
private function processNativePHP(): static
75+
{
76+
info('Processing NativePHP Data...');
77+
// Get composer versions
78+
$versions = collect([
79+
'nativephp/electron' => null,
80+
'nativephp/laravel' => null,
81+
'nativephp/php-bin' => null,
82+
])->mapWithKeys(function ($version, $key) {
83+
try {
84+
$version = InstalledVersions::getVersion($key);
85+
} catch (\OutOfBoundsException) {
86+
$version = 'Not Installed';
87+
}
88+
89+
return [$key => $version];
90+
});
91+
92+
$isNotarisationConfigured = env('NATIVEPHP_APPLE_ID')
93+
&& env('NATIVEPHP_APPLE_ID_PASS')
94+
&& env('NATIVEPHP_APPLE_TEAM_ID');
95+
96+
$this->debugInfo->put(
97+
'NativePHP',
98+
[
99+
'Versions' => $versions,
100+
'Configuration' => [
101+
'Provider' => config('nativephp.provider'),
102+
'BuildHooks' => [
103+
'Pre' => config('nativephp.prebuild'),
104+
'Post' => config('nativephp.postbuild'),
105+
],
106+
'NotarizationEnabled' => $isNotarisationConfigured,
107+
'CustomPHPBinary' => env('NATIVEPHP_PHP_BINARY_PATH') ?: false,
108+
],
109+
]
110+
);
111+
112+
return $this;
113+
}
114+
115+
private function processErrorLog(): void
116+
{
117+
info('Processing Error Log Data...');
118+
$errorLog = file_exists($logPath = storage_path('logs/laravel.log'))
119+
? file_get_contents($logPath)
120+
: 'No logs found.';
121+
122+
// Process each line as a single array element
123+
$errorLog = explode(PHP_EOL, $errorLog);
124+
$errorCount = 0;
125+
$errors = [];
126+
127+
$currentLine = '';
128+
foreach ($errorLog as $line) {
129+
if ($errorCount === 5) {
130+
break;
131+
}
132+
133+
// Check if string starts with date format Y-m-d H:i:s in square brackets
134+
if (preg_match('/^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]/', $line)) {
135+
if (!empty($currentLine)) {
136+
$errors[] = $currentLine;
137+
$currentLine = '';
138+
$errorCount++;
139+
}
140+
}
141+
142+
$currentLine .= $line . PHP_EOL;
143+
}
144+
145+
if (!empty($currentLine)) {
146+
$errors[] = $currentLine;
147+
}
148+
149+
$this->debugInfo->put('ErrorLog', $errors);
150+
}
151+
152+
protected function promptForMissingArgumentsUsing(): array
153+
{
154+
return [
155+
'output' => fn () => select(
156+
'Where would you like to output the debug information?',
157+
['File', 'Console'],
158+
'File'
159+
)
160+
];
161+
}
162+
163+
private function outputToFile(): void
164+
{
165+
File::put(base_path('nativephp_debug.json'), json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
166+
note('Debug information saved to ' . base_path('nativephp_debug.json'));
167+
}
168+
169+
private function outputToConsole(): void
170+
{
171+
$this->output->writeln(
172+
print_r($this->debugInfo->toArray(), true)
173+
);
174+
}
175+
}

src/NativeServiceProvider.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Facades\Artisan;
99
use Illuminate\Support\Facades\DB;
1010
use Native\Laravel\ChildProcess as ChildProcessImplementation;
11+
use Native\Laravel\Commands\DebugCommand;
1112
use Native\Laravel\Commands\FreshCommand;
1213
use Native\Laravel\Commands\LoadPHPConfigurationCommand;
1314
use Native\Laravel\Commands\LoadStartupConfigurationCommand;
@@ -35,8 +36,9 @@ public function configurePackage(Package $package): void
3536
$package
3637
->name('nativephp')
3738
->hasCommands([
38-
MigrateCommand::class,
39+
DebugCommand::class,
3940
FreshCommand::class,
41+
MigrateCommand::class,
4042
SeedDatabaseCommand::class,
4143
])
4244
->hasConfigFile()

0 commit comments

Comments
 (0)