Skip to content

Commit 34bc1d5

Browse files
authored
Feat: Migration commands improvements (#601)
* feat: migration improvements * boolean as string * descriptive * fixes
1 parent 502738b commit 34bc1d5

File tree

9 files changed

+183
-45
lines changed

9 files changed

+183
-45
lines changed

packages/Amqp/tests/Integration/AmqpChannelInitializationTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function test_initialize_multiple_channels_at_once(): void
159159

160160
// Initialize multiple channels at once
161161
$result = $runner->execute('ecotone:migration:channel:setup', [
162-
'channels' => [self::TEST_CHANNEL_NAME_2, self::TEST_CHANNEL_NAME_3],
162+
'channel' => [self::TEST_CHANNEL_NAME_2, self::TEST_CHANNEL_NAME_3],
163163
'initialize' => true,
164164
]);
165165

@@ -198,7 +198,7 @@ public function test_delete_multiple_channels_at_once(): void
198198

199199
// Delete multiple channels at once
200200
$result = $runner->execute('ecotone:migration:channel:delete', [
201-
'channels' => [self::TEST_CHANNEL_NAME_2, self::TEST_CHANNEL_NAME_3],
201+
'channel' => [self::TEST_CHANNEL_NAME_2, self::TEST_CHANNEL_NAME_3],
202202
'force' => true,
203203
]);
204204

@@ -230,7 +230,7 @@ public function test_stream_channel_initialization(): void
230230

231231
// Initialize stream channel
232232
$result = $runner->execute('ecotone:migration:channel:setup', [
233-
'channels' => [self::TEST_STREAM_CHANNEL_NAME],
233+
'channel' => [self::TEST_STREAM_CHANNEL_NAME],
234234
'initialize' => true,
235235
]);
236236

@@ -248,7 +248,7 @@ public function test_stream_channel_initialization(): void
248248

249249
// Delete stream channel
250250
$result = $runner->execute('ecotone:migration:channel:delete', [
251-
'channels' => [self::TEST_STREAM_CHANNEL_NAME],
251+
'channel' => [self::TEST_STREAM_CHANNEL_NAME],
252252
'force' => true,
253253
]);
254254

packages/Dbal/src/Database/DatabaseDeleteCommand.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,26 @@ public function __construct(
2222

2323
#[ConsoleCommand('ecotone:migration:database:delete')]
2424
public function delete(
25-
#[ConsoleParameterOption] array $features = [],
26-
#[ConsoleParameterOption] bool $force = false,
27-
#[ConsoleParameterOption] bool $onlyUsed = true,
25+
#[ConsoleParameterOption] array $feature = [],
26+
#[ConsoleParameterOption] bool|string $force = false,
27+
#[ConsoleParameterOption] bool|string $onlyUsed = true,
2828
): ?ConsoleCommandResultSet {
29+
// Normalize boolean parameters from CLI strings
30+
$force = $this->normalizeBoolean($force);
31+
$onlyUsed = $this->normalizeBoolean($onlyUsed);
32+
2933
// If specific feature names provided
30-
if (\count($features) > 0) {
34+
if (\count($feature) > 0) {
3135
$rows = [];
3236

33-
if (! $force) {
34-
foreach ($features as $featureName) {
37+
if (!$force) {
38+
foreach ($feature as $featureName) {
3539
$rows[] = [$featureName, 'Would be deleted (use --force to confirm)'];
3640
}
3741
return ConsoleCommandResultSet::create(['Feature', 'Warning'], $rows);
3842
}
3943

40-
foreach ($features as $featureName) {
44+
foreach ($feature as $featureName) {
4145
$this->databaseSetupManager->drop($featureName);
4246
$rows[] = [$featureName, 'Deleted'];
4347
}
@@ -54,7 +58,7 @@ public function delete(
5458
);
5559
}
5660

57-
if (! $force) {
61+
if (!$force) {
5862
return ConsoleCommandResultSet::create(
5963
['Feature', 'Warning'],
6064
array_map(fn (string $feature) => [$feature, 'Would be deleted (use --force to confirm)'], $featureNames)
@@ -67,4 +71,18 @@ public function delete(
6771
array_map(fn (string $feature) => [$feature, 'Deleted'], $featureNames)
6872
);
6973
}
74+
75+
/**
76+
* Normalize boolean parameter from CLI string to actual boolean.
77+
* Handles cases where CLI passes "false" as a string.
78+
*/
79+
private function normalizeBoolean(bool|string $value): bool
80+
{
81+
if (is_bool($value)) {
82+
return $value;
83+
}
84+
85+
// Handle string values from CLI
86+
return $value !== 'false' && $value !== '0' && $value !== '';
87+
}
7088
}

packages/Dbal/src/Database/DatabaseSetupCommand.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,30 @@ public function __construct(
2222

2323
#[ConsoleCommand('ecotone:migration:database:setup')]
2424
public function setup(
25-
#[ConsoleParameterOption] array $features = [],
26-
#[ConsoleParameterOption] bool $initialize = false,
27-
#[ConsoleParameterOption] bool $sql = false,
28-
#[ConsoleParameterOption] bool $onlyUsed = true,
25+
#[ConsoleParameterOption] array $feature = [],
26+
#[ConsoleParameterOption] bool|string $initialize = false,
27+
#[ConsoleParameterOption] bool|string $sql = false,
28+
#[ConsoleParameterOption] bool|string $onlyUsed = true,
2929
): ?ConsoleCommandResultSet {
30+
// Normalize boolean parameters from CLI strings
31+
$initialize = $this->normalizeBoolean($initialize);
32+
$sql = $this->normalizeBoolean($sql);
33+
$onlyUsed = $this->normalizeBoolean($onlyUsed);
34+
3035
// If specific feature names provided
31-
if (count($features) > 0) {
36+
if (count($feature) > 0) {
3237
$rows = [];
3338

3439
if ($sql) {
35-
$statements = $this->databaseSetupManager->getCreateSqlStatementsForFeatures($features);
40+
$statements = $this->databaseSetupManager->getCreateSqlStatementsForFeatures($feature);
3641
return ConsoleCommandResultSet::create(
3742
['SQL Statement'],
3843
[[implode("\n", $statements)]]
3944
);
4045
}
4146

4247
if ($initialize) {
43-
foreach ($features as $featureName) {
48+
foreach ($feature as $featureName) {
4449
$this->databaseSetupManager->initialize($featureName);
4550
$rows[] = [$featureName, 'Created'];
4651
}
@@ -49,7 +54,7 @@ public function setup(
4954

5055
$initStatus = $this->databaseSetupManager->getInitializationStatus();
5156
$usageStatus = $this->databaseSetupManager->getUsageStatus();
52-
foreach ($features as $featureName) {
57+
foreach ($feature as $featureName) {
5358
$isInitialized = $initStatus[$featureName] ?? false;
5459
$isUsed = $usageStatus[$featureName] ?? false;
5560
$rows[] = [$featureName, $isUsed ? 'Yes' : 'No', $isInitialized ? 'Yes' : 'No'];
@@ -97,4 +102,18 @@ public function setup(
97102
$rows
98103
);
99104
}
105+
106+
/**
107+
* Normalize boolean parameter from CLI string to actual boolean.
108+
* Handles cases where CLI passes "false" as a string.
109+
*/
110+
private function normalizeBoolean(bool|string $value): bool
111+
{
112+
if (\is_bool($value)) {
113+
return $value;
114+
}
115+
116+
// Handle string values from CLI
117+
return $value !== 'false' && $value !== '0' && $value !== '';
118+
}
100119
}

packages/Dbal/tests/Integration/DatabaseInitializationTest.php

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public function test_database_setup_with_specific_features(): void
164164

165165
// Initialize only specific feature
166166
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', [
167-
'features' => ['dead_letter'],
167+
'feature' => ['dead_letter'],
168168
'initialize' => true,
169169
]);
170170

@@ -179,13 +179,13 @@ public function test_database_setup_shows_status_for_specific_features(): void
179179

180180
// First initialize
181181
$this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', [
182-
'features' => ['dead_letter'],
182+
'feature' => ['dead_letter'],
183183
'initialize' => true,
184184
]);
185185

186186
// Check status for specific feature
187187
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', [
188-
'features' => ['dead_letter'],
188+
'feature' => ['dead_letter'],
189189
]);
190190

191191
self::assertEquals(['Feature', 'Used', 'Initialized'], $result->getColumnHeaders());
@@ -197,7 +197,7 @@ public function test_database_setup_returns_sql_for_specific_features(): void
197197
$ecotone = $this->bootstrapEcotone();
198198

199199
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', [
200-
'features' => ['dead_letter'],
200+
'feature' => ['dead_letter'],
201201
'sql' => true,
202202
]);
203203

@@ -218,7 +218,7 @@ public function test_database_delete_with_specific_features(): void
218218

219219
// Delete specific feature
220220
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:delete', [
221-
'features' => ['dead_letter'],
221+
'feature' => ['dead_letter'],
222222
'force' => true,
223223
]);
224224

@@ -237,7 +237,7 @@ public function test_database_delete_shows_warning_for_specific_features_without
237237

238238
// Try to delete without force
239239
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:delete', [
240-
'features' => ['dead_letter'],
240+
'feature' => ['dead_letter'],
241241
]);
242242

243243
self::assertEquals(['Feature', 'Warning'], $result->getColumnHeaders());
@@ -294,4 +294,43 @@ private function cleanUpTables(): void
294294
$connection->executeStatement('DROP TABLE ' . DbalDeadLetterHandler::DEFAULT_DEAD_LETTER_TABLE);
295295
}
296296
}
297+
298+
public function test_database_setup_respects_string_false_for_initialize(): void
299+
{
300+
$ecotone = $this->bootstrapEcotone();
301+
302+
// Pass "false" as a string for initialize parameter
303+
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', ['initialize' => 'false']);
304+
305+
// Should show status, not initialize
306+
self::assertEquals(['Feature', 'Used', 'Initialized'], $result->getColumnHeaders());
307+
self::assertFalse($this->tableExists(DbalDeadLetterHandler::DEFAULT_DEAD_LETTER_TABLE));
308+
}
309+
310+
public function test_database_setup_respects_string_false_for_sql(): void
311+
{
312+
$ecotone = $this->bootstrapEcotone();
313+
314+
// Pass "false" as a string for sql parameter
315+
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', ['sql' => 'false']);
316+
317+
// Should show status, not SQL
318+
self::assertEquals(['Feature', 'Used', 'Initialized'], $result->getColumnHeaders());
319+
}
320+
321+
public function test_database_delete_respects_string_false_for_force(): void
322+
{
323+
$ecotone = $this->bootstrapEcotone();
324+
325+
// First create tables
326+
$this->executeConsoleCommand($ecotone, 'ecotone:migration:database:setup', ['initialize' => true]);
327+
self::assertTrue($this->tableExists(DbalDeadLetterHandler::DEFAULT_DEAD_LETTER_TABLE));
328+
329+
// Pass "false" as a string for force parameter
330+
$result = $this->executeConsoleCommand($ecotone, 'ecotone:migration:database:delete', ['force' => 'false']);
331+
332+
// Should show warning, not delete
333+
self::assertEquals(['Feature', 'Warning'], $result->getColumnHeaders());
334+
self::assertTrue($this->tableExists(DbalDeadLetterHandler::DEFAULT_DEAD_LETTER_TABLE));
335+
}
297336
}

packages/Ecotone/src/Messaging/Channel/Manager/ChannelDeleteCommand.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,24 @@ public function __construct(
2424

2525
#[ConsoleCommand('ecotone:migration:channel:delete')]
2626
public function delete(
27-
#[ConsoleParameterOption] array $channels = [],
28-
#[ConsoleParameterOption] bool $force = false,
27+
#[ConsoleParameterOption] array $channel = [],
28+
#[ConsoleParameterOption] bool|string $force = false,
2929
): ?ConsoleCommandResultSet {
30+
// Normalize boolean parameters from CLI strings
31+
$force = $this->normalizeBoolean($force);
32+
3033
// If specific channel names provided
31-
if (count($channels) > 0) {
34+
if (\count($channel) > 0) {
3235
$rows = [];
3336

34-
if (! $force) {
35-
foreach ($channels as $channelName) {
37+
if (!$force) {
38+
foreach ($channel as $channelName) {
3639
$rows[] = [$channelName, 'Would be deleted (use --force to confirm)'];
3740
}
3841
return ConsoleCommandResultSet::create(['Channel', 'Warning'], $rows);
3942
}
4043

41-
foreach ($channels as $channelName) {
44+
foreach ($channel as $channelName) {
4245
$this->channelSetupManager->delete($channelName);
4346
$rows[] = [$channelName, 'Deleted'];
4447
}
@@ -55,7 +58,7 @@ public function delete(
5558
);
5659
}
5760

58-
if (! $force) {
61+
if (!$force) {
5962
return ConsoleCommandResultSet::create(
6063
['Channel', 'Warning'],
6164
array_map(fn (string $channel) => [$channel, 'Would be deleted (use --force to confirm)'], $channelNames)
@@ -68,4 +71,18 @@ public function delete(
6871
array_map(fn (string $channel) => [$channel, 'Deleted'], $channelNames)
6972
);
7073
}
74+
75+
/**
76+
* Normalize boolean parameter from CLI string to actual boolean.
77+
* Handles cases where CLI passes "false" as a string.
78+
*/
79+
private function normalizeBoolean(bool|string $value): bool
80+
{
81+
if (\is_bool($value)) {
82+
return $value;
83+
}
84+
85+
// Handle string values from CLI
86+
return $value !== 'false' && $value !== '0' && $value !== '';
87+
}
7188
}

packages/Ecotone/src/Messaging/Channel/Manager/ChannelSetupCommand.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,26 @@ public function __construct(
2222

2323
#[ConsoleCommand('ecotone:migration:channel:setup')]
2424
public function setup(
25-
#[ConsoleParameterOption] array $channels = [],
26-
#[ConsoleParameterOption] bool $initialize = false,
25+
#[ConsoleParameterOption] array $channel = [],
26+
#[ConsoleParameterOption] bool|string $initialize = false,
2727
): ?ConsoleCommandResultSet {
28+
// Normalize boolean parameters from CLI strings
29+
$initialize = $this->normalizeBoolean($initialize);
30+
2831
// If specific channel names provided
29-
if (count($channels) > 0) {
32+
if (count($channel) > 0) {
3033
$rows = [];
3134

3235
if ($initialize) {
33-
foreach ($channels as $channelName) {
36+
foreach ($channel as $channelName) {
3437
$this->channelSetupManager->initialize($channelName);
3538
$rows[] = [$channelName, 'Initialized'];
3639
}
3740
return ConsoleCommandResultSet::create(['Channel', 'Status'], $rows);
3841
}
3942

4043
$status = $this->channelSetupManager->getInitializationStatus();
41-
foreach ($channels as $channelName) {
44+
foreach ($channel as $channelName) {
4245
$channelStatus = $status[$channelName] ?? false;
4346
$rows[] = [$channelName, $this->formatStatus($channelStatus)];
4447
}
@@ -74,6 +77,20 @@ public function setup(
7477
return ConsoleCommandResultSet::create(['Channel', 'Initialized'], $rows);
7578
}
7679

80+
/**
81+
* Normalize boolean parameter from CLI string to actual boolean.
82+
* Handles cases where CLI passes "false" as a string.
83+
*/
84+
private function normalizeBoolean(bool|string $value): bool
85+
{
86+
if (\is_bool($value)) {
87+
return $value;
88+
}
89+
90+
// Handle string values from CLI
91+
return $value !== 'false' && $value !== '0' && $value !== '';
92+
}
93+
7794
/**
7895
* Format the initialization status for display
7996
*/

packages/Ecotone/src/Messaging/Channel/Manager/ChannelSetupManager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function delete(string $channelName): void
107107

108108
/**
109109
* Returns initialization status for each channel
110-
* @return array<string, bool|string> Map of channel name to initialization status (bool for managed, 'Not managed by migration' for non-managed)
110+
* @return array<string, bool|string> Map of channel name to initialization status (bool for managed, 'Not managed by channel migration' for non-managed)
111111
*/
112112
public function getInitializationStatus(): array
113113
{
@@ -119,7 +119,7 @@ public function getInitializationStatus(): array
119119

120120
foreach ($this->allPollableChannelNames as $channelName) {
121121
if (! isset($status[$channelName])) {
122-
$status[$channelName] = 'Not managed by migration';
122+
$status[$channelName] = 'Not managed by channel migration';
123123
}
124124
}
125125

0 commit comments

Comments
 (0)