From 6c025dab7ff448cf807c602f63a36852dfd45c77 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 16 Jun 2026 13:00:03 -0700 Subject: [PATCH 1/5] chore: cleanup and standardize dev commands --- dev/src/Command/ComponentExecuteCommand.php | 12 ++++--- dev/src/Command/ComponentInfoCommand.php | 8 ++++- dev/src/Command/ComponentUpdateCommand.php | 11 +++--- .../Command/ComponentUpdateDepsCommand.php | 36 ++++++++++++++++--- .../ComponentUpdateReadmeSampleCommand.php | 17 +++++++-- 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/dev/src/Command/ComponentExecuteCommand.php b/dev/src/Command/ComponentExecuteCommand.php index 4d3dfa05f5a1..53ce0ec9cb17 100644 --- a/dev/src/Command/ComponentExecuteCommand.php +++ b/dev/src/Command/ComponentExecuteCommand.php @@ -59,7 +59,13 @@ protected function configure() EOF) ->addArgument('code', InputArgument::REQUIRED, 'Path to a file or PHP code to execute') - ->addOption('component', 'c', InputOption::VALUE_REQUIRED, 'If specified, display repo info for this component only', '') + ->addOption( + 'component', + 'c', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'If specified, execute code for this component only', + [] + ) ->addOption('token', 't', InputOption::VALUE_REQUIRED, 'Github token to use for authentication', '') ->addOption('packagist-token', 'p', InputOption::VALUE_REQUIRED, 'Packagist token for the webhook') ; @@ -72,9 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $github = new GitHub(new RunShell(), $http, $input->getOption('token'), $output); $packagist = new Packagist($http, self::PACKAGIST_USERNAME, $input->getOption('packagist-token') ?? ''); - $componentName = $input->getOption('component'); - $components = $componentName ? [new Component($componentName)] : Component::getComponents(); - + $components = Component::getComponents($input->getOption('component')); $code = $input->getArgument('code'); if (file_exists($code)) { $executeFn = require $code; diff --git a/dev/src/Command/ComponentInfoCommand.php b/dev/src/Command/ComponentInfoCommand.php index bede5bb45027..7fd88a889521 100644 --- a/dev/src/Command/ComponentInfoCommand.php +++ b/dev/src/Command/ComponentInfoCommand.php @@ -75,7 +75,13 @@ protected function configure() $this->setName('component:info') ->setAliases(['info']) ->setDescription('list info of a component or the whole library') - ->addOption('component', 'c', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'get info for a single component', []) + ->addOption( + 'component', + 'c', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'get info for a single component', + [] + ) ->addOption('csv', '', InputOption::VALUE_OPTIONAL, 'export findings to csv.', false) ->addOption('fields', 'f', InputOption::VALUE_REQUIRED, sprintf( 'Comma-separated list of fields. Prefix with "+" to add to default filters, or use "all" for all fields.' diff --git a/dev/src/Command/ComponentUpdateCommand.php b/dev/src/Command/ComponentUpdateCommand.php index 4f6406c6675a..7ae436a17027 100644 --- a/dev/src/Command/ComponentUpdateCommand.php +++ b/dev/src/Command/ComponentUpdateCommand.php @@ -59,10 +59,12 @@ protected function configure() { $this->setName('component:update') ->setDescription('Update one or all components using Owlbot') - ->addArgument( + ->addOption( 'component', - InputArgument::OPTIONAL, - 'The name of the component to update. If not provided, all components will be updated.' + 'c', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'Add to the readme of the specified component', + [] ) ->addOption( 'googleapis-gen-path', @@ -82,7 +84,6 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output): int { - $componentName = $input->getArgument('component'); $googleApisGenDir = realpath($input->getOption('googleapis-gen-path')); $unsafeTimeout = $input->getOption('timeout'); @@ -104,7 +105,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->checkDockerAvailable(); // Find components to update - $components = Component::getComponents($componentName ? [$componentName] : []); + $components = Component::getComponents($input->getArgument('component')); foreach ($components as $component) { $componentName = $component->getName(); $output->writeln("\nRunning Owlbot in $componentName"); diff --git a/dev/src/Command/ComponentUpdateDepsCommand.php b/dev/src/Command/ComponentUpdateDepsCommand.php index a30791885760..494126580547 100644 --- a/dev/src/Command/ComponentUpdateDepsCommand.php +++ b/dev/src/Command/ComponentUpdateDepsCommand.php @@ -39,11 +39,37 @@ protected function configure() ->setDescription('update a dependency across all components') ->addArgument('package', InputArgument::REQUIRED, 'Package name to update, e.g. "google/gax"') ->addArgument('version', InputArgument::OPTIONAL, 'Package version to update to, e.g. "1.4.0"', '') - ->addOption('component', 'c', InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'bumps deps for the specified component/file') - ->addOption('bump', '', InputOption::VALUE_NONE, 'Bump to latest version of the package') - ->addOption('add', '', InputOption::VALUE_OPTIONAL, 'Adds the dep if it doesn\'t exist (--add=dev for require-dev)', false) - ->addOption('no-dev', '', InputOption::VALUE_NONE, 'Only updates the dep if its in "require" (deps in "require-dev" are left alone)') - ->addOption('local', '', InputOption::VALUE_NONE, 'Add a link to the local component') + ->addOption( + 'component', + 'c', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'bumps deps for the specified component/file' + ) + ->addOption( + 'bump', + '', + InputOption::VALUE_NONE, + 'Bump to latest version of the package' + ) + ->addOption( + 'add', + '', + InputOption::VALUE_OPTIONAL, + 'Adds the dep if it doesn\'t exist (--add=dev for require-dev)', + false + ) + ->addOption( + 'no-dev', + '', + InputOption::VALUE_NONE, + 'Only updates the dep if its in "require" (deps in "require-dev" are left alone)' + ) + ->addOption( + 'local', + '', + InputOption::VALUE_NONE, + 'Add a link to the local component' + ) ; } diff --git a/dev/src/Command/ComponentUpdateReadmeSampleCommand.php b/dev/src/Command/ComponentUpdateReadmeSampleCommand.php index 0e783d7e7d89..0d2d93475535 100644 --- a/dev/src/Command/ComponentUpdateReadmeSampleCommand.php +++ b/dev/src/Command/ComponentUpdateReadmeSampleCommand.php @@ -45,8 +45,19 @@ protected function configure() { $this->setName('component:update:readme-sample') ->setDescription('Add a sample to a component') - ->addOption('component', 'c', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add to the readme of the specified component', []) - ->addOption('update', '', InputOption::VALUE_NONE, 'updates the sample in the readme if it exists'); + ->addOption( + 'component', + 'c', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'Add to the readme of the specified component', + [] + ) + ->addOption( + 'force', + '', + InputOption::VALUE_NONE, + 'updates the sample in the readme if it exists' + ); ; } @@ -76,7 +87,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $sample = "```php\n" . $sample . "\n```"; if (preg_match('/### Sample\n\n(```(.|\n)*```)/', $readme, $matches)) { $output->writeln('Sample already exists in ' . $component->getName() . ' README.md'); - if (!$input->getOption('update')) { + if (!$input->getOption('force')) { continue; } if ($matches[1] === $sample) { From 9330c2f9d8dd6f615038c880e6ab2442a19fbb3c Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 16 Jun 2026 13:35:45 -0700 Subject: [PATCH 2/5] Rename ComponentUpdateGencodeCommandTest to ComponentUpdateCommandTest --- ...pdateGencodeCommandTest.php => ComponentUpdateCommandTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dev/tests/Unit/Command/{ComponentUpdateGencodeCommandTest.php => ComponentUpdateCommandTest.php} (100%) diff --git a/dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php b/dev/tests/Unit/Command/ComponentUpdateCommandTest.php similarity index 100% rename from dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php rename to dev/tests/Unit/Command/ComponentUpdateCommandTest.php From c8fe0316937fbfe7839dbc90f3ecb90bc33d8439 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 16 Jun 2026 13:37:02 -0700 Subject: [PATCH 3/5] Fix unit tests --- dev/tests/Unit/Command/ComponentUpdateCommandTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/tests/Unit/Command/ComponentUpdateCommandTest.php b/dev/tests/Unit/Command/ComponentUpdateCommandTest.php index 1adc4bcb2174..e8613c5c5254 100644 --- a/dev/tests/Unit/Command/ComponentUpdateCommandTest.php +++ b/dev/tests/Unit/Command/ComponentUpdateCommandTest.php @@ -80,7 +80,7 @@ public function testUpdateFailsWithInvalidGoogleapisDir() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - 'component' => self::COMPONENT_NAME, + '--component' => self::COMPONENT_NAME, '--googleapis-gen-path' => $googleapisGenPath, ]); } @@ -100,7 +100,7 @@ public function testUpdateFailsWithNoDocker() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - 'component' => self::COMPONENT_NAME, + '--component' => self::COMPONENT_NAME, '--googleapis-gen-path' => self::$tmpDir, ]); } @@ -120,7 +120,7 @@ public function testUpdateFailsWithInvalidComponentName() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - 'component' => 'NonExistantComponent', + '--component' => 'NonExistantComponent', '--googleapis-gen-path' => self::$tmpDir, ]); } @@ -190,7 +190,7 @@ public function testUpdateComponentSucceeds() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - 'component' => self::COMPONENT_NAME, + '--component' => self::COMPONENT_NAME, '--googleapis-gen-path' => $googleapisGenPath, ]); @@ -213,7 +213,7 @@ public function testUpdateComponentErrorsWithNonNumericTimeout() 'Y' // Does this information look correct? [Y/n] ]); $commandTester->execute([ - 'component' => self::COMPONENT_NAME, + '--component' => self::COMPONENT_NAME, '--timeout' => 'not-a-number', ]); } From 45f52de834efdebd13a310557f7db59be791b8f4 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 16 Jun 2026 14:43:32 -0700 Subject: [PATCH 4/5] fix missed test --- dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php b/dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php index 1adc4bcb2174..a0c55f5b9791 100644 --- a/dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php +++ b/dev/tests/Unit/Command/ComponentUpdateGencodeCommandTest.php @@ -120,7 +120,7 @@ public function testUpdateFailsWithInvalidComponentName() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - 'component' => 'NonExistantComponent', + '--component' => 'NonExistantComponent', '--googleapis-gen-path' => self::$tmpDir, ]); } From 5e6ef806b021de0be0dd8ae6947f95500a79d154 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 17 Jun 2026 14:18:36 +0000 Subject: [PATCH 5/5] fix tests once and for all (I said ONCE AND FOR ALL) --- dev/src/Command/ComponentUpdateCommand.php | 2 +- dev/tests/Unit/Command/ComponentUpdateCommandTest.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/src/Command/ComponentUpdateCommand.php b/dev/src/Command/ComponentUpdateCommand.php index 7ae436a17027..c430014fa41c 100644 --- a/dev/src/Command/ComponentUpdateCommand.php +++ b/dev/src/Command/ComponentUpdateCommand.php @@ -105,7 +105,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->checkDockerAvailable(); // Find components to update - $components = Component::getComponents($input->getArgument('component')); + $components = Component::getComponents($input->getOption('component')); foreach ($components as $component) { $componentName = $component->getName(); $output->writeln("\nRunning Owlbot in $componentName"); diff --git a/dev/tests/Unit/Command/ComponentUpdateCommandTest.php b/dev/tests/Unit/Command/ComponentUpdateCommandTest.php index e8613c5c5254..5010dd81f55b 100644 --- a/dev/tests/Unit/Command/ComponentUpdateCommandTest.php +++ b/dev/tests/Unit/Command/ComponentUpdateCommandTest.php @@ -80,7 +80,7 @@ public function testUpdateFailsWithInvalidGoogleapisDir() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - '--component' => self::COMPONENT_NAME, + '--component' => [self::COMPONENT_NAME], '--googleapis-gen-path' => $googleapisGenPath, ]); } @@ -100,7 +100,7 @@ public function testUpdateFailsWithNoDocker() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - '--component' => self::COMPONENT_NAME, + '--component' => [self::COMPONENT_NAME], '--googleapis-gen-path' => self::$tmpDir, ]); } @@ -120,7 +120,7 @@ public function testUpdateFailsWithInvalidComponentName() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - '--component' => 'NonExistantComponent', + '--component' => ['NonExistantComponent'], '--googleapis-gen-path' => self::$tmpDir, ]); } @@ -190,7 +190,7 @@ public function testUpdateComponentSucceeds() $commandTester = new CommandTester($application->get('component:update')); $commandTester->execute([ - '--component' => self::COMPONENT_NAME, + '--component' => [self::COMPONENT_NAME], '--googleapis-gen-path' => $googleapisGenPath, ]); @@ -213,7 +213,7 @@ public function testUpdateComponentErrorsWithNonNumericTimeout() 'Y' // Does this information look correct? [Y/n] ]); $commandTester->execute([ - '--component' => self::COMPONENT_NAME, + '--component' => [self::COMPONENT_NAME], '--timeout' => 'not-a-number', ]); }