Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Console] Allow to return all tokens after the command name #54347

Merged
merged 1 commit into from Mar 21, 2024

Conversation

lyrixx
Copy link
Member

@lyrixx lyrixx commented Mar 20, 2024

Q A
Branch? 7.1
Bug fix? no
New feature? yes
Deprecations? no
Issues
License MIT

follows #54238

Now, we can make it works at the command level (previous PR was at the application level)

#!/usr/bin/env php
<?php

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Process\Process;

require __DIR__ . '/vendor/autoload.php';

$command = new Command('ls');
$command->ignoreValidationErrors();
$command->setCode(function ($input) {
    $p = new Process(['ls', ...$input->getRawTokens(true)]);
    $p->setTty(true);
    $p->mustRun();
});
$app = new Application();
$app->add($command);
$app->run();

image

@derrabus derrabus changed the title [Console] Allow to returns all tokens after the command name [Console] Allow to return all tokens after the command name Mar 20, 2024
@stof
Copy link
Member

stof commented Mar 20, 2024

should we also implement this in ArrayInput (and deprecate not implementing in child classes of Input to have it in all Input implementations in 8.0) ?

@lyrixx
Copy link
Member Author

lyrixx commented Mar 21, 2024

should we also implement this in ArrayInput (and deprecate not implementing in child classes of Input to have it in all Input implementations in 8.0) ?

I though about this, and It's not necessary IMHO. since you construct the array yourself, before calling new ArrayInput, you already have the array by definition.

More over, I don't really this any use case for that.

Anyway, I started to implements it:

diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php
index d27ff411ee..5f4439faf1 100644
--- a/src/Symfony/Component/Console/Input/ArrayInput.php
+++ b/src/Symfony/Component/Console/Input/ArrayInput.php
@@ -87,6 +87,35 @@ class ArrayInput extends Input
         return $default;
     }
 
+    /**
+     * Returns un-parsed and not validated tokens.
+     *
+     * @param bool $strip Whether to return the raw parameters (false) or the values after the command name (true)
+     *
+     * @return list<string>
+     */
+    public function getRawTokens(bool $strip = false): array
+    {
+        if (!$strip) {
+            return $this->parameters;
+        }
+
+        $parameters = [];
+        $keep = false;
+        foreach ($this->parameters as $name => $value) {
+            if (!$keep && $value === $this->getFirstArgument()) {
+                $keep = true;
+
+                continue;
+            }
+            if ($keep) {
+                $parameters[$name] = $value;
+            }
+        }
+
+        return $parameters;
+    }
+
     /**
      * Returns a stringified representation of the args passed to the command.
      */
diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
index d6fe32bb3a..f965e3c58e 100644
--- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
+++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
@@ -170,4 +170,28 @@ class ArrayInputTest extends TestCase
         $input = new ArrayInput(['array_arg' => ['val_1', 'val_2']]);
         $this->assertSame('val_1 val_2', (string) $input);
     }
+
+
+    public function testGetRawTokensFalse()
+    {
+        $input = new ArrayInput(['cli.php', '--foo', 'bar']);
+        $this->assertSame(['cli.php', '--foo', 'bar'], $input->getRawTokens());
+    }
+
+    /**
+     * @dataProvider provideGetRawTokensTrueTests
+     */
+    public function testGetRawTokensTrue(array $argv, array $expected)
+    {
+        $input = new ArrayInput($argv);
+        $this->assertSame($expected, $input->getRawTokens(true));
+    }
+
+    public static function provideGetRawTokensTrueTests(): iterable
+    {
+        yield [['command' => 'foo:bar'], []];
+        yield [['command' => 'foo:bar', '--no-ansi' => true], ['--no-ansi' => true]];
+        yield [['command' => 'foo:bar', 'name' => 'john'], ['name' => 'john']];
+        yield [['--no-ansi' => true, 'command' => 'foo:bar', 'name' => 'john'], ['name' => 'john']];
+    }
 }

But when I see the tests, especially the very last one, I really think it does not make sens to add it to the array input, and by extension to input

@fabpot
Copy link
Member

fabpot commented Mar 21, 2024

Thank you @lyrixx.

@fabpot fabpot merged commit a51e675 into symfony:7.1 Mar 21, 2024
5 of 10 checks passed
@lyrixx lyrixx deleted the console-raw-tokens branch March 21, 2024 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants