From 96d526e32bec3f1d2e7979afd68e2bb8e683b5b7 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 5 Apr 2026 20:24:59 +0530 Subject: [PATCH 1/4] feat: allow cli container injection --- src/CLI/CLI.php | 12 +++++++++--- tests/CLI/CLITest.php | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index ee2f5da..59a9639 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -83,10 +83,11 @@ class CLI * * @param Adapter|null $adapter * @param array $args + * @param Container|null $container * * @throws Exception */ - public function __construct(?Adapter $adapter = null, array $args = []) + public function __construct(?Adapter $adapter = null, array $args = [], ?Container $container = null) { if (\php_sapi_name() !== 'cli') { throw new Exception('CLI tasks can only work from the command line'); @@ -97,7 +98,7 @@ public function __construct(?Adapter $adapter = null, array $args = []) @\cli_set_process_title($this->command); $this->adapter = $adapter ?? new Generic(); - $this->container = new Container(); + $this->container = $container ?? new Container(); } /** @@ -213,6 +214,11 @@ public function setResource(string $name, callable $callback, array $dependencie $this->container->set($name, $callback, $dependencies); } + public function getContainer(): Container + { + return $this->container; + } + /** * task-name --foo=test * @@ -401,7 +407,7 @@ protected function validate(string $key, array $param, $value): void } } - public function setContainer($container): self + public function setContainer(Container $container): self { $this->container = $container; diff --git a/tests/CLI/CLITest.php b/tests/CLI/CLITest.php index a72d43c..a50b2cf 100755 --- a/tests/CLI/CLITest.php +++ b/tests/CLI/CLITest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Utopia\CLI\Adapters\Generic; use Utopia\CLI\CLI; +use Utopia\DI\Container; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; @@ -201,6 +202,30 @@ public function testInjection() $this->assertEquals('test-value-me@example.com', $result); } + public function testProvidedContainer() + { + ob_start(); + + $container = new Container(); + $container->set('test', fn () => 'test-value'); + + $cli = new CLI(new Generic(), ['test.php', 'build'], $container); + + $this->assertSame($container, $cli->getContainer()); + + $cli->task('build') + ->inject('test') + ->action(function ($test) { + echo $test; + }); + + $cli->run(); + + $result = ob_get_clean(); + + $this->assertEquals('test-value', $result); + } + public function testMatch() { $cli = new CLI(new Generic(), ['test.php', 'build2', '--email=me@example.com', '--list=item1', '--list=item2']); // Mock command request From 2cdfc739c3e278ed4bad0e390984e22b328b9d1b Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 5 Apr 2026 20:30:31 +0530 Subject: [PATCH 2/4] fix: preserve injected container on reset --- src/CLI/CLI.php | 10 +++++++--- tests/CLI/CLITest.php | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index 59a9639..0611d29 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -33,6 +33,8 @@ class CLI */ protected Container $container; + protected ?Container $parentContainer = null; + /** * Args * @@ -98,7 +100,8 @@ public function __construct(?Adapter $adapter = null, array $args = [], ?Contain @\cli_set_process_title($this->command); $this->adapter = $adapter ?? new Generic(); - $this->container = $container ?? new Container(); + $this->parentContainer = $container; + $this->container = new Container($container); } /** @@ -409,14 +412,15 @@ protected function validate(string $key, array $param, $value): void public function setContainer(Container $container): self { - $this->container = $container; + $this->parentContainer = $container; + $this->container = new Container($container); return $this; } public function reset(): void { - $this->container = new Container(); + $this->container = new Container($this->parentContainer); } private function camelCaseIt($key): string diff --git a/tests/CLI/CLITest.php b/tests/CLI/CLITest.php index a50b2cf..078536f 100755 --- a/tests/CLI/CLITest.php +++ b/tests/CLI/CLITest.php @@ -211,7 +211,8 @@ public function testProvidedContainer() $cli = new CLI(new Generic(), ['test.php', 'build'], $container); - $this->assertSame($container, $cli->getContainer()); + $this->assertNotSame($container, $cli->getContainer()); + $this->assertEquals('test-value', $cli->getResource('test')); $cli->task('build') ->inject('test') @@ -226,6 +227,25 @@ public function testProvidedContainer() $this->assertEquals('test-value', $result); } + public function testResetPreservesInjectedContainer() + { + $container = new Container(); + $container->set('base', fn () => 'base-value'); + + $cli = new CLI(new Generic(), ['test.php', 'build'], $container); + $cli->setResource('runtime', fn () => 'runtime-value'); + + $this->assertEquals('base-value', $cli->getResource('base')); + $this->assertEquals('runtime-value', $cli->getResource('runtime')); + + $cli->reset(); + + $this->assertEquals('base-value', $cli->getResource('base')); + + $this->expectException(\Exception::class); + $cli->getResource('runtime'); + } + public function testMatch() { $cli = new CLI(new Generic(), ['test.php', 'build2', '--email=me@example.com', '--list=item1', '--list=item2']); // Mock command request From 7a206f12cbe33019cad5a8c5c4aa0f6a26d2850c Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 5 Apr 2026 20:31:10 +0530 Subject: [PATCH 3/4] Revert "fix: preserve injected container on reset" This reverts commit 2cdfc739c3e278ed4bad0e390984e22b328b9d1b. --- src/CLI/CLI.php | 10 +++------- tests/CLI/CLITest.php | 22 +--------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index 0611d29..59a9639 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -33,8 +33,6 @@ class CLI */ protected Container $container; - protected ?Container $parentContainer = null; - /** * Args * @@ -100,8 +98,7 @@ public function __construct(?Adapter $adapter = null, array $args = [], ?Contain @\cli_set_process_title($this->command); $this->adapter = $adapter ?? new Generic(); - $this->parentContainer = $container; - $this->container = new Container($container); + $this->container = $container ?? new Container(); } /** @@ -412,15 +409,14 @@ protected function validate(string $key, array $param, $value): void public function setContainer(Container $container): self { - $this->parentContainer = $container; - $this->container = new Container($container); + $this->container = $container; return $this; } public function reset(): void { - $this->container = new Container($this->parentContainer); + $this->container = new Container(); } private function camelCaseIt($key): string diff --git a/tests/CLI/CLITest.php b/tests/CLI/CLITest.php index 078536f..a50b2cf 100755 --- a/tests/CLI/CLITest.php +++ b/tests/CLI/CLITest.php @@ -211,8 +211,7 @@ public function testProvidedContainer() $cli = new CLI(new Generic(), ['test.php', 'build'], $container); - $this->assertNotSame($container, $cli->getContainer()); - $this->assertEquals('test-value', $cli->getResource('test')); + $this->assertSame($container, $cli->getContainer()); $cli->task('build') ->inject('test') @@ -227,25 +226,6 @@ public function testProvidedContainer() $this->assertEquals('test-value', $result); } - public function testResetPreservesInjectedContainer() - { - $container = new Container(); - $container->set('base', fn () => 'base-value'); - - $cli = new CLI(new Generic(), ['test.php', 'build'], $container); - $cli->setResource('runtime', fn () => 'runtime-value'); - - $this->assertEquals('base-value', $cli->getResource('base')); - $this->assertEquals('runtime-value', $cli->getResource('runtime')); - - $cli->reset(); - - $this->assertEquals('base-value', $cli->getResource('base')); - - $this->expectException(\Exception::class); - $cli->getResource('runtime'); - } - public function testMatch() { $cli = new CLI(new Generic(), ['test.php', 'build2', '--email=me@example.com', '--list=item1', '--list=item2']); // Mock command request From dda9ec7469342509702b1cf4c304031a5aebfbaf Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 5 Apr 2026 20:32:02 +0530 Subject: [PATCH 4/4] Reapply "fix: preserve injected container on reset" This reverts commit 7a206f12cbe33019cad5a8c5c4aa0f6a26d2850c. --- src/CLI/CLI.php | 10 +++++++--- tests/CLI/CLITest.php | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index 59a9639..0611d29 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -33,6 +33,8 @@ class CLI */ protected Container $container; + protected ?Container $parentContainer = null; + /** * Args * @@ -98,7 +100,8 @@ public function __construct(?Adapter $adapter = null, array $args = [], ?Contain @\cli_set_process_title($this->command); $this->adapter = $adapter ?? new Generic(); - $this->container = $container ?? new Container(); + $this->parentContainer = $container; + $this->container = new Container($container); } /** @@ -409,14 +412,15 @@ protected function validate(string $key, array $param, $value): void public function setContainer(Container $container): self { - $this->container = $container; + $this->parentContainer = $container; + $this->container = new Container($container); return $this; } public function reset(): void { - $this->container = new Container(); + $this->container = new Container($this->parentContainer); } private function camelCaseIt($key): string diff --git a/tests/CLI/CLITest.php b/tests/CLI/CLITest.php index a50b2cf..078536f 100755 --- a/tests/CLI/CLITest.php +++ b/tests/CLI/CLITest.php @@ -211,7 +211,8 @@ public function testProvidedContainer() $cli = new CLI(new Generic(), ['test.php', 'build'], $container); - $this->assertSame($container, $cli->getContainer()); + $this->assertNotSame($container, $cli->getContainer()); + $this->assertEquals('test-value', $cli->getResource('test')); $cli->task('build') ->inject('test') @@ -226,6 +227,25 @@ public function testProvidedContainer() $this->assertEquals('test-value', $result); } + public function testResetPreservesInjectedContainer() + { + $container = new Container(); + $container->set('base', fn () => 'base-value'); + + $cli = new CLI(new Generic(), ['test.php', 'build'], $container); + $cli->setResource('runtime', fn () => 'runtime-value'); + + $this->assertEquals('base-value', $cli->getResource('base')); + $this->assertEquals('runtime-value', $cli->getResource('runtime')); + + $cli->reset(); + + $this->assertEquals('base-value', $cli->getResource('base')); + + $this->expectException(\Exception::class); + $cli->getResource('runtime'); + } + public function testMatch() { $cli = new CLI(new Generic(), ['test.php', 'build2', '--email=me@example.com', '--list=item1', '--list=item2']); // Mock command request