Skip to content

Commit 51a8e4a

Browse files
committed
feature: pass optional config values to migrate
closes #237
1 parent 7926b22 commit 51a8e4a

2 files changed

Lines changed: 233 additions & 18 deletions

File tree

src/Cli/ExecuteCommand.php

Lines changed: 135 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use Gt\Cli\Argument\ArgumentValueList;
55
use Gt\Cli\Command\Command;
6-
use Gt\Cli\Parameter\NamedParameter;
76
use Gt\Cli\Parameter\Parameter;
87
use Gt\Config\ConfigFactory;
98
use Gt\Database\Connection\Settings;
@@ -18,8 +17,8 @@ public function run(?ArgumentValueList $arguments = null):void {
1817
$defaultPath = $this->getDefaultPath($repoBasePath);
1918
$config = $this->getConfig($repoBasePath, $defaultPath);
2019

21-
$settings = $this->buildSettingsFromConfig($config, $repoBasePath);
22-
[$migrationPath, $migrationTable] = $this->getMigrationLocation($config, $repoBasePath);
20+
$settings = $this->buildSettingsFromConfig($config, $repoBasePath, $arguments);
21+
[$migrationPath, $migrationTable] = $this->getMigrationLocation($config, $repoBasePath, $arguments);
2322

2423
$migrator = new Migrator($settings, $migrationPath, $migrationTable);
2524
$migrator->setOutput(
@@ -47,18 +46,61 @@ private function isForced(?ArgumentValueList $arguments):bool {
4746
}
4847

4948
/** Build Settings from config for the current repository. */
50-
private function buildSettingsFromConfig(\Gt\Config\Config $config, string $repoBasePath): Settings {
49+
protected function buildSettingsFromConfig(
50+
\Gt\Config\Config $config,
51+
string $repoBasePath,
52+
?ArgumentValueList $arguments = null
53+
): Settings {
54+
$queryPath = $this->getOverrideOrConfigValue(
55+
$config,
56+
$arguments,
57+
"base-directory",
58+
"database.query_path",
59+
"query"
60+
);
5161
return new Settings(
52-
implode(DIRECTORY_SEPARATOR, [
53-
$repoBasePath,
54-
$config->get("database.query_path")
55-
]),
56-
$config->get("database.driver") ?? 'mysql',
57-
$config->get("database.schema"),
58-
$config->get("database.host") ?? "localhost",
59-
(int)($config->get("database.port") ?? "3306"),
60-
$config->get("database.username"),
61-
$config->get("database.password")
62+
$this->resolvePath($repoBasePath, $queryPath),
63+
$this->getOverrideOrConfigValue(
64+
$config,
65+
$arguments,
66+
"driver",
67+
"database.driver",
68+
"mysql"
69+
),
70+
$this->getOverrideOrConfigValue(
71+
$config,
72+
$arguments,
73+
"database",
74+
"database.schema"
75+
),
76+
$this->getOverrideOrConfigValue(
77+
$config,
78+
$arguments,
79+
"host",
80+
"database.host",
81+
"localhost"
82+
),
83+
(int)$this->getOverrideOrConfigValue(
84+
$config,
85+
$arguments,
86+
"port",
87+
"database.port",
88+
"3306"
89+
),
90+
$this->getOverrideOrConfigValue(
91+
$config,
92+
$arguments,
93+
"username",
94+
"database.username",
95+
""
96+
),
97+
$this->getOverrideOrConfigValue(
98+
$config,
99+
$arguments,
100+
"password",
101+
"database.password",
102+
""
103+
)
62104
);
63105
}
64106

@@ -67,10 +109,20 @@ private function buildSettingsFromConfig(\Gt\Config\Config $config, string $repo
67109
*
68110
* @return list<string>
69111
*/
70-
private function getMigrationLocation(\Gt\Config\Config $config, string $repoBasePath): array {
112+
protected function getMigrationLocation(
113+
\Gt\Config\Config $config,
114+
string $repoBasePath,
115+
?ArgumentValueList $arguments = null
116+
): array {
117+
$queryPath = $this->getOverrideOrConfigValue(
118+
$config,
119+
$arguments,
120+
"base-directory",
121+
"database.query_path",
122+
"query"
123+
);
71124
$migrationPath = implode(DIRECTORY_SEPARATOR, [
72-
$repoBasePath,
73-
$config->get("database.query_path") ?? "query",
125+
$this->resolvePath($repoBasePath, $queryPath),
74126
$config->get("database.migration_path") ?? "_migration",
75127
]);
76128
$migrationTable = $config->get("database.migration_table") ?? "_migration";
@@ -141,7 +193,6 @@ public function getRequiredNamedParameterList():array {
141193
}
142194

143195
public function getOptionalNamedParameterList():array {
144-
// TODO: It would be an improvement to allow passing database settings here rather than always require a config.ini
145196
return [];
146197
}
147198

@@ -151,6 +202,48 @@ public function getRequiredParameterList():array {
151202

152203
public function getOptionalParameterList():array {
153204
return [
205+
new Parameter(
206+
true,
207+
"base-directory",
208+
null,
209+
"Override database.query_path for this command"
210+
),
211+
new Parameter(
212+
true,
213+
"driver",
214+
null,
215+
"Override database.driver for this command"
216+
),
217+
new Parameter(
218+
true,
219+
"database",
220+
null,
221+
"Override database.schema for this command"
222+
),
223+
new Parameter(
224+
true,
225+
"host",
226+
null,
227+
"Override database.host for this command"
228+
),
229+
new Parameter(
230+
true,
231+
"port",
232+
null,
233+
"Override database.port for this command"
234+
),
235+
new Parameter(
236+
true,
237+
"username",
238+
null,
239+
"Override database.username for this command"
240+
),
241+
new Parameter(
242+
true,
243+
"password",
244+
null,
245+
"Override database.password for this command"
246+
),
154247
new Parameter(
155248
false,
156249
"force",
@@ -201,4 +294,28 @@ protected function getConfig(bool|string $repoBasePath, ?string $defaultPath):\G
201294
}
202295
return $config;
203296
}
297+
298+
protected function getOverrideOrConfigValue(
299+
\Gt\Config\Config $config,
300+
?ArgumentValueList $arguments,
301+
string $argumentKey,
302+
string $configKey,
303+
?string $default = null
304+
): ?string {
305+
if($arguments?->contains($argumentKey)) {
306+
return $arguments->get($argumentKey)->get() ?? $default;
307+
}
308+
309+
return $config->get($configKey) ?? $default;
310+
}
311+
protected function resolvePath(string $repoBasePath, string $path):string {
312+
if(str_starts_with($path, DIRECTORY_SEPARATOR)) {
313+
return $path;
314+
}
315+
316+
return implode(DIRECTORY_SEPARATOR, [
317+
$repoBasePath,
318+
$path,
319+
]);
320+
}
204321
}

test/phpunit/Cli/ExecuteCommandTest.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33

44
use Gt\Cli\Argument\ArgumentValueList;
55
use Gt\Cli\Stream;
6+
use Gt\Config\Config;
7+
use Gt\Config\ConfigSection;
68
use Gt\Database\Cli\ExecuteCommand;
79
use Gt\Database\Connection\Settings;
810
use Gt\Database\Database;
911
use Gt\Database\Test\Helper\Helper;
12+
use Gt\Cli\Parameter\Parameter;
1013
use PHPUnit\Framework\TestCase;
1114
use SplFileObject;
1215

@@ -189,4 +192,99 @@ public function testExecuteWithResetWithNumber():void {
189192
chdir($cwdBackup);
190193
}
191194
}
195+
196+
public function testOptionalParameterListContainsCliOverrides():void {
197+
$command = new ExecuteCommand();
198+
$parameterNames = array_map(
199+
fn(Parameter $parameter) => $parameter->getLongOption(),
200+
$command->getOptionalParameterList()
201+
);
202+
203+
self::assertContains("base-directory", $parameterNames);
204+
self::assertContains("driver", $parameterNames);
205+
self::assertContains("database", $parameterNames);
206+
self::assertContains("host", $parameterNames);
207+
self::assertContains("port", $parameterNames);
208+
self::assertContains("username", $parameterNames);
209+
self::assertContains("password", $parameterNames);
210+
self::assertContains("force", $parameterNames);
211+
self::assertContains("reset", $parameterNames);
212+
}
213+
214+
public function testCliArgumentsOverrideConfigValuesWhenBuildingSettings():void {
215+
$repoBasePath = "/tmp/project-root";
216+
$config = new Config(
217+
new ConfigSection("database", [
218+
"query_path" => "query",
219+
"driver" => "mysql",
220+
"schema" => "config-db",
221+
"host" => "config-host",
222+
"port" => "3306",
223+
"username" => "config-user",
224+
"password" => "config-pass",
225+
"migration_path" => "_migration",
226+
"migration_table" => "_migration",
227+
])
228+
);
229+
$args = new ArgumentValueList();
230+
$args->set("base-directory", "custom-query");
231+
$args->set("driver", "sqlite");
232+
$args->set("database", "/tmp/override.db");
233+
$args->set("host", "override-host");
234+
$args->set("port", "1234");
235+
$args->set("username", "override-user");
236+
$args->set("password", "override-pass");
237+
238+
$command = $this->createCommandProbe();
239+
$settings = $command->buildSettingsForTest($config, $repoBasePath, $args);
240+
241+
self::assertSame("/tmp/project-root/custom-query", $settings->getBaseDirectory());
242+
self::assertSame("sqlite", $settings->getDriver());
243+
self::assertSame("/tmp/override.db", $settings->getSchema());
244+
self::assertSame("override-host", $settings->getHost());
245+
self::assertSame(1234, $settings->getPort());
246+
self::assertSame("override-user", $settings->getUsername());
247+
self::assertSame("override-pass", $settings->getPassword());
248+
}
249+
250+
public function testBaseDirectoryOverrideIsUsedForMigrationLocation():void {
251+
$repoBasePath = "/tmp/project-root";
252+
$config = new Config(
253+
new ConfigSection("database", [
254+
"query_path" => "query",
255+
"migration_path" => "_migration",
256+
"migration_table" => "migration_log",
257+
])
258+
);
259+
$args = new ArgumentValueList();
260+
$args->set("base-directory", "alt-query");
261+
262+
$command = $this->createCommandProbe();
263+
[$migrationPath, $migrationTable] = $command->getMigrationLocationForTest($config, $repoBasePath, $args);
264+
265+
self::assertSame("/tmp/project-root/alt-query/_migration", $migrationPath);
266+
self::assertSame("migration_log", $migrationTable);
267+
}
268+
269+
private function createCommandProbe():ExecuteCommand {
270+
return new class extends ExecuteCommand {
271+
public function buildSettingsForTest(
272+
Config $config,
273+
string $repoBasePath,
274+
?ArgumentValueList $arguments = null
275+
): Settings {
276+
return $this->buildSettingsFromConfig($config, $repoBasePath, $arguments);
277+
}
278+
279+
/** @return list<string> */
280+
public function getMigrationLocationForTest(
281+
Config $config,
282+
string $repoBasePath,
283+
?ArgumentValueList $arguments = null
284+
): array {
285+
return $this->getMigrationLocation($config, $repoBasePath, $arguments);
286+
}
287+
};
288+
}
289+
192290
}

0 commit comments

Comments
 (0)