Skip to content

Commit 2d0421a

Browse files
committed
feat: improve terminal compatibility and error handling for interactive prompts 🎨
1 parent e92f859 commit 2d0421a

1 file changed

Lines changed: 73 additions & 17 deletions

File tree

src/Console/Command/Theme/BuildCommand.php

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,47 +62,43 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
6262
$themes = $this->themeList->getAllThemes();
6363
$options = array_map(fn($theme) => $theme->getCode(), $themes);
6464

65-
// Ensure proper terminal settings for Laravel Prompts
66-
if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
67-
// Fallback for non-TTY environments
65+
// Check if we're in an interactive terminal environment
66+
if (!$this->isInteractiveTerminal($output)) {
67+
// Fallback for non-interactive environments
6868
$this->displayAvailableThemes($this->io);
6969
return Command::SUCCESS;
7070
}
7171

72-
// Improve terminal compatibility
73-
putenv('COLUMNS=80');
74-
putenv('LINES=30');
75-
putenv('TERM=xterm-256color');
76-
77-
// Force output buffer flush before prompts
78-
if (ob_get_level()) {
79-
ob_end_flush();
80-
}
81-
82-
$this->io->newLine();
83-
$this->io->text("Available themes: " . implode(', ', $options));
84-
$this->io->newLine();
72+
// Set environment variables for Laravel Prompts
73+
$this->setPromptEnvironment();
8574

8675
$themeCodesPrompt = new MultiSelectPrompt(
8776
label: 'Select themes to build',
8877
options: $options,
89-
hint: 'Use arrow keys to navigate, Space to select/deselect, Enter to confirm',
78+
default: [], // No default selection
79+
hint: 'Arrow keys to navigate, Space to toggle, Enter to confirm (scroll with arrows if needed)',
9080
required: false,
9181
);
9282

9383
try {
9484
$themeCodes = $themeCodesPrompt->prompt();
9585
\Laravel\Prompts\Prompt::terminal()->restoreTty();
9686

87+
// Reset environment
88+
$this->resetPromptEnvironment();
89+
9790
// If no themes selected, show available themes
9891
if (empty($themeCodes)) {
9992
$this->io->info('No themes selected.');
10093
return Command::SUCCESS;
10194
}
10295
} catch (\Exception $e) {
96+
// Reset environment on exception
97+
$this->resetPromptEnvironment();
10398
// Fallback if prompt fails
10499
$this->io->error('Interactive mode failed: ' . $e->getMessage());
105100
$this->displayAvailableThemes($this->io);
101+
$this->io->newLine();
106102
return Command::SUCCESS;
107103
}
108104
}
@@ -275,4 +271,64 @@ private function displayBuildSummary(SymfonyStyle $io, array $successList, float
275271

276272
$io->newLine();
277273
}
274+
275+
/**
276+
* Check if the current environment supports interactive terminal input
277+
*
278+
* @param OutputInterface $output
279+
* @return bool
280+
*/
281+
private function isInteractiveTerminal(OutputInterface $output): bool
282+
{
283+
// Check if output is decorated (supports ANSI codes)
284+
if (!$output->isDecorated()) {
285+
return false;
286+
}
287+
288+
// Check if STDIN is available and readable
289+
if (!defined('STDIN') || !is_resource(STDIN)) {
290+
return false;
291+
}
292+
293+
// Check for common non-interactive environments
294+
$nonInteractiveEnvs = [
295+
'CI' => true,
296+
'GITHUB_ACTIONS' => true,
297+
'GITLAB_CI' => true,
298+
'JENKINS_URL' => true,
299+
'TEAMCITY_VERSION' => true,
300+
];
301+
302+
foreach ($nonInteractiveEnvs as $env => $value) {
303+
if (getenv($env) !== false) {
304+
return false;
305+
}
306+
}
307+
308+
// Additional check: try to detect if running in a proper TTY
309+
// This is a safer alternative to posix_isatty()
310+
$sttyOutput = shell_exec('stty -g 2>/dev/null');
311+
return !empty($sttyOutput);
312+
}
313+
314+
/**
315+
* Set environment for Laravel Prompts to work properly in Docker/DDEV
316+
*/
317+
private function setPromptEnvironment(): void
318+
{
319+
// Set terminal environment variables using putenv() - needed for Laravel Prompts
320+
putenv('COLUMNS=100');
321+
putenv('LINES=40');
322+
putenv('TERM=xterm-256color');
323+
}
324+
325+
/**
326+
* Reset terminal environment after prompts
327+
*/
328+
private function resetPromptEnvironment(): void
329+
{
330+
// Reset environment variables to original state
331+
putenv('COLUMNS');
332+
putenv('LINES');
333+
}
278334
}

0 commit comments

Comments
 (0)