Skip to content

Commit d1d4927

Browse files
committed
Issue #113: open dbeaver app up and focus on it
1 parent 57e7175 commit d1d4927

9 files changed

Lines changed: 70 additions & 30 deletions

File tree

src/Command/Behat.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use App\Exceptions\ExecFailed;
66
use App\Service\Docker;
7-
use App\Service\Main;
7+
use App\Service\Moodle;
88
use App\Service\Plugins;
99
use App\StaticVars;
1010
use App\Traits\ExecTrait;
@@ -20,6 +20,7 @@ final class Behat extends AbstractCommand {
2020
// Service dependencies.
2121
protected Plugins $pluginsService;
2222
protected Docker $dockerService;
23+
protected Moodle $moodleService;
2324

2425
// Constants.
2526
const COMMAND_NAME = 'behat';
@@ -113,7 +114,8 @@ public function execute(Options $options): void {
113114

114115
$this->cli->notice('Initializing behat');
115116
$moodleContainer = $this->mainService->getDockerMoodleContainerName($instanceName);
116-
$cmd = 'docker exec -it '.$moodleContainer.' php /var/www/html/moodle/admin/tool/behat/cli/init.php --axe';
117+
$publicFolder = $this->moodleService->shouldUsePublicFolder($recipe) ? 'public' . DIRECTORY_SEPARATOR: '';
118+
$cmd = 'docker exec -it '.$moodleContainer.' php /var/www/html/moodle/'.$publicFolder.'admin/tool/behat/cli/init.php --axe';
117119
$this->execStream($cmd, 'Failed to initialize behat');
118120
// !NOTE AWFUL, AWFUL BUG FIX!
119121
// Have to do it twice because execStream only returns last line which can end up being performance information as opposed

src/Command/Database.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Database\Mysql;
77
use App\Database\Postgres;
88
use App\Database\Mariadb;
9+
use App\Helpers\OS;
910
use App\Model\Recipe;
1011
use App\Model\RegistryInstance;
1112
use App\StaticVars;
@@ -50,7 +51,7 @@ function() {
5051

5152
private function openDatabaseClient(?string $client): void {
5253
$cmd = match ($client) {
53-
'dbeaver' => $this->database->dbeaverConnectionString(),
54+
'dbeaver' => $this->database->dbeaverConnectCommand(),
5455
'pgadmin' => $this->getPgAdminCommand(),
5556
'mysql workbench' => $this->getMysqlWorkbenchCommand(),
5657
'psql (cli)', 'psql' => $this->getPsqlCommand(),
@@ -59,7 +60,17 @@ private function openDatabaseClient(?string $client): void {
5960
};
6061

6162
if (is_string($cmd)) {
62-
$this->exec($cmd);
63+
// GUI applications need detached execution for proper focus
64+
if (in_array($client, ['dbeaver', 'pgadmin', 'mysql workbench'])) {
65+
$this->execDetached($cmd);
66+
67+
if (OS::isMac() && $client === 'dbeaver') {
68+
$applescript = 'tell application "DBeaver" to activate';
69+
$this->execDetached('sleep 1 && osascript -e ' . escapeshellarg($applescript));
70+
}
71+
} else {
72+
$this->exec($cmd);
73+
}
6374
} else if (is_array($cmd)) {
6475
$this->execInteractive($cmd[0], $cmd[1]);
6576
}

src/Command/PHPUnit.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Command;
44

55
use App\Service\Main;
6+
use App\Service\Moodle;
67
use App\Service\Plugins;
78
use App\StaticVars;
89
use App\Traits\ExecTrait;
@@ -15,6 +16,9 @@ final class PHPUnit extends AbstractCommand {
1516
use SingletonTrait;
1617
use ExecTrait;
1718

19+
// Service dependencies.
20+
protected Moodle $moodleService;
21+
1822
const COMMAND_NAME = 'phpunit';
1923

2024
public static function instance(): PHPUnit {
@@ -37,7 +41,8 @@ public function execute(Options $options): void {
3741

3842
$this->cli->notice('Initializing PHPUnit');
3943

40-
$cmd = 'docker exec -it '.$moodleContainer.' php /var/www/html/moodle/admin/tool/phpunit/cli/init.php';
44+
$publicFolder = $this->moodleService->shouldUsePublicFolder($recipe) ? 'public' . DIRECTORY_SEPARATOR: '';
45+
$cmd = 'docker exec -it '.$moodleContainer.' php /var/www/html/moodle/'.$publicFolder.'admin/tool/phpunit/cli/init.php';
4146
$this->execStream($cmd, 'Failed to initialize phpunit');
4247
$runCode = 'bash -c "cd /var/www/html/moodle && vendor/bin/phpunit';
4348

src/Database/AbstractDatabase.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
use App\MChefCLI;
77
use App\Model\Recipe;
88
use App\Helpers\OS;
9+
use App\Traits\ExecTrait;
910

1011
abstract class AbstractDatabase implements DatabaseInterface {
12+
use ExecTrait;
13+
1114
public function __construct(protected Recipe $recipe, protected MChefCLI $cli) {
1215
}
1316

@@ -19,10 +22,35 @@ public function dropAllTables(): void {
1922
throw new NotImplementedException(__METHOD__);
2023
}
2124

22-
public function dbeaverConnectionString(): string {
25+
protected function dbeaverConnectBaseCommand(): string {
2326
throw new NotImplementedException(__METHOD__);
2427
}
2528

29+
public function dbeaverConnectCommand(): string {
30+
if (empty($this->recipe->dbHostPort)) {
31+
throw new \Error('The recipe must have dbHostPort specified in order to generate a connection string');
32+
}
33+
34+
$baseConnStr = $this->dbeaverConnectBaseCommand();
35+
36+
// Execute command to create connection first.
37+
// NOTE - this didn't work with just one command, hence - to create you need open -na and to open you need open -a.
38+
if (OS::isWindows()) {
39+
$dbeaverBaseCmd = 'start dbeaverc.exe';
40+
41+
} else if (OS::isMac()) {
42+
$dbeaverBaseCmd = 'open -na "DBeaver" --args';
43+
} else if (OS::isLinux()) {
44+
$dbeaverBaseCmd = 'xdg-open dbeaverc';
45+
} else {
46+
throw new \RuntimeException('Unsupported OS for DBeaver connection');
47+
}
48+
49+
$cmd = $dbeaverBaseCmd . ' -con ' . escapeshellarg($baseConnStr . '|connect=true|name=' . $this->getDbName());
50+
51+
return $cmd;
52+
}
53+
2654
public function buildDBQueryDockerCommand(string $query, bool $isCheck = false): string {
2755
throw new NotImplementedException(__METHOD__);
2856
}

src/Database/DatabaseInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function dropAllTables(): void;
1414
* Return a dbeaver connection string.
1515
* @return string
1616
*/
17-
public function dbeaverConnectionString(): string;
17+
public function dbeaverConnectCommand(): string;
1818

1919
/**
2020
* Build a docker command (docker exec ...) to run a database query.

src/Database/Mysql.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,14 @@ public function dropAllTables(): void {
4545
}
4646
}
4747

48-
public function dbeaverConnectionString(): string {
49-
if (empty($this->recipe->dbHostPort)) {
50-
throw new \Error('The recipe must have dbHostPort specified in order to generate a connection string');
51-
}
52-
$dbeavercmd = OS::isWindows() ? 'dbeaver.exe' : 'open -na "DBeaver" --args';
53-
$conString = sprintf(
48+
protected function dbeaverConnectBaseCommand(): string {
49+
return sprintf(
5450
'driver=mysql|host=localhost|port=%s|database=%s|user=%s|password=%s',
5551
$this->recipe->dbHostPort,
5652
$this->getDbName(),
5753
$this->recipe->dbUser,
5854
$this->recipe->dbPassword
5955
);
60-
61-
// Escape the *whole thing once*
62-
$cmd = $dbeavercmd . ' -con ' . escapeshellarg($conString);
63-
return $cmd;
6456
}
6557

6658
/**

src/Database/Postgres.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use App\Service\Main;
99

1010
class Postgres extends AbstractDatabase implements DatabaseInterface {
11+
1112
public function dropAllTables(): void {
1213
$mainService = Main::instance($this->cli);
1314
$dbContainer = $mainService->getDockerDatabaseContainerName();
@@ -57,22 +58,14 @@ public function dropAllTables(): void {
5758
}
5859
}
5960

60-
public function dbeaverConnectionString(): string {
61-
if (empty($this->recipe->dbHostPort)) {
62-
throw new \Error('The recipe must have dbHostPort specified in order to generate a connection string');
63-
}
64-
$dbeavercmd = OS::isWindows() ? 'dbeaver.exe' : 'open -na "DBeaver" --args';
65-
$conString = sprintf(
61+
protected function dbeaverConnectBaseCommand(): string {
62+
return sprintf(
6663
'driver=postgresql|host=localhost|port=%s|database=%s|user=%s|password=%s',
6764
$this->recipe->dbHostPort,
6865
$this->getDbName(),
6966
$this->recipe->dbUser,
7067
$this->recipe->dbPassword
7168
);
72-
73-
// Escape the *whole thing once*
74-
$cmd = $dbeavercmd . ' -con ' . escapeshellarg($conString);
75-
return $cmd;
7669
}
7770

7871
/**

src/Tests/DatabaseConnectionStringsTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function testMysqlConnectionStringMethods(): void {
2424
$mysql = new Mysql($recipe, StaticVars::$cli);
2525

2626
// Test DBeaver connection string
27-
$dbeaverCmd = $mysql->dbeaverConnectionString();
27+
$dbeaverCmd = $mysql->dbeaverConnectCommand();
2828
$this->assertStringContainsString('driver=mysql', $dbeaverCmd);
2929
$this->assertStringContainsString('port=3306', $dbeaverCmd);
3030
$this->assertStringContainsString('testuser', $dbeaverCmd);
@@ -78,7 +78,7 @@ public function testPostgresConnectionStringMethods(): void {
7878
$postgres = new Postgres($recipe, StaticVars::$cli);
7979

8080
// Test DBeaver connection string
81-
$dbeaverCmd = $postgres->dbeaverConnectionString();
81+
$dbeaverCmd = $postgres->dbeaverConnectCommand();
8282
$this->assertStringContainsString('driver=postgresql', $dbeaverCmd);
8383
$this->assertStringContainsString('port=5432', $dbeaverCmd);
8484
$this->assertStringContainsString('testuser', $dbeaverCmd);
@@ -135,6 +135,6 @@ public function testMissingDbHostPortThrowsError(): void {
135135

136136
$this->expectException(\Error::class);
137137
$this->expectExceptionMessage('The recipe must have dbHostPort specified');
138-
$mysql->dbeaverConnectionString();
138+
$mysql->dbeaverConnectCommand();
139139
}
140140
}

src/Traits/ExecTrait.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ protected function execStream(string $cmd, ?string $errorMsg = null): string {
5858
return $output;
5959
}
6060

61+
protected function execDetached(string $cmd): void {
62+
if ($this->verbose && !empty($this->cli)) {
63+
$this->cli->info($cmd);
64+
}
65+
// Execute command in background to detach from PHP process
66+
// This allows GUI applications to get proper focus
67+
exec($cmd . ' &');
68+
}
69+
6170
protected function execPassthru(string $cmd, ?string $errorMsg = null): void {
6271
if ($this->verbose && !empty($this->cli)) {
6372
$this->cli->info($cmd);

0 commit comments

Comments
 (0)