Skip to content

Commit 17d06f8

Browse files
committed
Fix Reviews
1 parent e985f98 commit 17d06f8

File tree

4 files changed

+114
-51
lines changed

4 files changed

+114
-51
lines changed

src/Commands/Command.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5050

5151
if ($invocation['status'] === 'success') {
5252
IO::spinClear();
53-
$output->writeln($invocation['output']);
53+
IO::writeln($invocation['output']);
5454
return 0;
5555
}
5656

src/Commands/Tinker.php

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@
22

33
namespace Bref\Cli\Commands;
44

5-
use Bref\Cli\Tinker\BrefTinkerShell;
6-
use Psy\Configuration;
7-
use Psy\Shell;
85
use Bref\Cli\Cli\IO;
96
use Bref\Cli\Cli\Styles;
10-
use Bref\Cli\BrefCloudClient;
7+
use Bref\Cli\Tinker\BrefTinkerShell;
8+
use Psy\Configuration;
119
use Symfony\Component\Console\Input\InputInterface;
12-
use Symfony\Component\Console\Input\StringInput;
1310
use Symfony\Component\Console\Output\OutputInterface;
1411

1512
class Tinker extends ApplicationCommand
@@ -28,22 +25,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int
2825
{
2926
IO::writeln([Styles::brefHeader(), '']);
3027

31-
[
32-
'appName' => $appName,
33-
'environmentName' => $environmentName,
34-
'team' => $team,
35-
] = $this->parseStandardOptions($input);
28+
$brefCloudConfig = $this->parseStandardOptions($input);
3629

37-
// Auto enable verbose to avoid verbose async listener in VerboseModeEnabler which will causes issue when executing multiple commands
30+
// Auto enable verbose to avoid verbose async listener in VerboseModeEnabler which will cause issue when executing multiple commands
3831
IO::enableVerbose();
32+
IO::writeln(sprintf(
33+
"Starting Interactive Shell Session for [%s] in the [%s] environment",
34+
Styles::green($brefCloudConfig['appName']),
35+
Styles::red($brefCloudConfig['environmentName']),
36+
));
3937

40-
$config = Configuration::fromInput($input);
41-
$shellOutput = $config->getOutput();
42-
$shellOutput->writeln(sprintf("Starting Interactive Shell Session for <string>[%s]</string> in the <string>[%s]</string> environment", Styles::green($appName), Styles::red($environmentName)));
38+
$shellConfig = Configuration::fromInput($input);
39+
$shellOutput = $shellConfig->getOutput();
4340

44-
$shell = new BrefTinkerShell($config, str_replace("tinker", "command", (string) $input));
41+
$shell = new BrefTinkerShell($shellConfig, $brefCloudConfig);
4542
$shell->setRawOutput($shellOutput);
4643

47-
return $shell->run();
44+
try {
45+
return $shell->run();
46+
} catch (\Throwable $e) {
47+
IO::writeln(Styles::red($e->getMessage()));
48+
return 1;
49+
}
4850
}
4951
}

src/Tinker/BrefTinkerLoopListener.php

Lines changed: 80 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,54 @@
22

33
namespace Bref\Cli\Tinker;
44

5-
use Bref\Cli\Commands\Command;
6-
use GuzzleHttp\Exception\ClientException;
5+
use Bref\Cli\BrefCloudClient;
6+
use Bref\Cli\Cli\IO;
7+
use Bref\Cli\Cli\Styles;
78
use Psy\Exception\BreakException;
89
use Psy\Exception\ThrowUpException;
910
use Psy\ExecutionClosure;
1011
use Psy\ExecutionLoop\AbstractListener;
1112
use Psy\Shell;
12-
use Symfony\Component\Console\Input\ArgvInput;
13-
use Symfony\Component\Console\Input\StringInput;
14-
use Symfony\Component\Console\Output\BufferedOutput;
13+
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
14+
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
15+
use function Amp\delay;
1516

1617
class BrefTinkerLoopListener extends AbstractListener
1718
{
18-
protected string $commandInput;
19+
/**
20+
* @var array{appName: string, environmentName: string, team: string}
21+
*/
22+
protected array $brefConfig;
23+
24+
/**
25+
* @var array{
26+
* id: int,
27+
* name: string,
28+
* region: string|null,
29+
* url: string|null,
30+
* outputs: array<string, string>,
31+
* app: array{id: int, name: string},
32+
* }
33+
*/
34+
protected array $environment;
35+
36+
protected BrefCloudClient $brefCloudClient;
1937

20-
public function __construct(string $commandInput)
38+
/**
39+
* @param array<string, string> $brefConfig
40+
* @throws ExceptionInterface
41+
* @throws HttpExceptionInterface
42+
*/
43+
public function __construct(array $brefConfig)
2144
{
22-
$this->commandInput = $commandInput;
45+
$this->brefConfig = $brefConfig;
46+
[
47+
'appName' => $appName,
48+
'environmentName' => $environmentName,
49+
'team' => $team,
50+
] = $brefConfig;
51+
$this->brefCloudClient = new BrefCloudClient;
52+
$this->environment = $this->brefCloudClient->findEnvironment($team, $appName, $environmentName);
2353
}
2454

2555
public static function isSupported(): bool
@@ -42,18 +72,9 @@ public function onExecute(Shell $shell, string $code)
4272
$context = $vars['_context'] ?? base64_encode(serialize(["_" => null]));
4373
// Evaluate the current code buffer
4474
try {
45-
$command = new Command();
46-
$args = join(" ", [
47-
'bref:tinker',
48-
'--execute=\"'.base64_encode($code).'\"',
49-
'--context=\"'.$context.'\"',
50-
]);
51-
$output = new BufferedOutput();
52-
$input = new ArgvInput(array_merge((new StringInput($this->commandInput))->getRawTokens(), [$args]));
53-
54-
$resultCode = $command->run($input, $output);
55-
$resultOutput = $output->fetch();
75+
[$resultCode, $resultOutput] = $this->evaluateCode($code, $context);
5676
if ($resultCode !== 0) {
77+
$shell->rawOutput->writeln($resultOutput);
5778
throw new BreakException("The remote tinker shell returned an error (code $resultCode).");
5879
}
5980

@@ -81,12 +102,47 @@ public function onExecute(Shell $shell, string $code)
81102
}
82103

83104
return ExecutionClosure::NOOP_INPUT;
84-
} catch (ClientException $_e) {
105+
} catch (\Throwable $_e) {
85106
throw new BreakException($_e->getMessage());
86-
} catch (BreakException $breakException) {
87-
throw $breakException;
88-
} catch (\Throwable $throwable) {
89-
throw new ThrowUpException($throwable);
107+
}
108+
}
109+
110+
/**
111+
* @return array{0: int, 1: string} [exitCode, output]
112+
* @throws ExceptionInterface
113+
* @throws HttpExceptionInterface
114+
*/
115+
protected function evaluateCode(string $code, string $context): array
116+
{
117+
$command = implode(" ", [
118+
'bref:tinker',
119+
'--execute=\"'.base64_encode($code).'\"',
120+
'--context=\"'.$context.'\"',
121+
]);
122+
$id = $this->brefCloudClient->startCommand($this->environment['id'], $command);
123+
124+
// Timeout after 2 minutes and 10 seconds
125+
$timeout = 130;
126+
$startTime = time();
127+
128+
while (true) {
129+
$invocation = $this->brefCloudClient->getCommand($id);
130+
131+
if ($invocation['status'] === 'success') {
132+
return [0, $invocation['output']];
133+
}
134+
135+
if ($invocation['status'] === 'failed') {
136+
return [1, $invocation['output']];
137+
}
138+
139+
if ((time() - $startTime) > $timeout) {
140+
IO::writeln(Styles::red('Timed out'));
141+
IO::writeln(Styles::gray('The execution timed out after 2 minutes, the command might still be running'));
142+
return [1, 'Timed out'];
143+
}
144+
145+
delay(0.5);
90146
}
91147
}
92148
}

src/Tinker/BrefTinkerShell.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,29 @@
33
namespace Bref\Cli\Tinker;
44

55
use Psy\Configuration;
6+
use Psy\ExecutionLoop\AbstractListener;
67
use Psy\Output\ShellOutput;
78
use Psy\Shell;
9+
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
10+
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
811

912
class BrefTinkerShell extends Shell
1013
{
14+
public ShellOutput $rawOutput;
15+
1116
/**
12-
* @var ShellOutput
17+
* @var array<string, string>
1318
*/
14-
public $rawOutput;
15-
16-
protected string $commandInput;
17-
18-
public function __construct(?Configuration $config = null, string $commandInput = '')
19+
protected array $brefCloudConfig;
20+
21+
public function __construct(?Configuration $config = null, array $brefCloudConfig = [])
1922
{
20-
$this->commandInput = $commandInput;
23+
$this->brefCloudConfig = $brefCloudConfig;
2124

2225
parent::__construct($config);
2326
}
2427

25-
public function setRawOutput($rawOutput)
28+
public function setRawOutput($rawOutput): self
2629
{
2730
$this->rawOutput = $rawOutput;
2831

@@ -32,13 +35,15 @@ public function setRawOutput($rawOutput)
3235
/**
3336
* Gets the default command loop listeners.
3437
*
35-
* @return array An array of Execution Loop Listener instances
38+
* @return array<AbstractListener> An array of Execution Loop Listener instances
39+
* @throws ExceptionInterface
40+
* @throws HttpExceptionInterface
3641
*/
3742
protected function getDefaultLoopListeners(): array
3843
{
3944
$listeners = parent::getDefaultLoopListeners();
4045

41-
$listeners[] = new BrefTinkerLoopListener($this->commandInput);
46+
$listeners[] = new BrefTinkerLoopListener($this->brefCloudConfig);
4247

4348
return $listeners;
4449
}

0 commit comments

Comments
 (0)