bug #34848 [Process] change the syntax of portable command lines (nicolas-grekas)
This PR was merged into the 4.4 branch.
Discussion
----------
[Process] change the syntax of portable command lines
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix #34838
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/12772
An alternative to #34845
Right now, portable command lines use `"$FOO"` for placeholders.
But because we validate that a corresponding variable exists before running the command, this fails with `Command line is missing a value for key "$FOO"` when `FOO` is not defined.
This PR proposes to use `"${:FOO}"` instead. The difference with the previous syntax is that this cannot collide with existing shell scripts as it is invalid for them.
When this is merged, we'll have to update https://symfony.com/blog/new-in-symfony-4-1-prepared-commands too.
Commits
-------
3c7b775b3e
[Process] change the syntax of portable prepared command lines
This commit is contained in:
commit
2e7032420f
@ -1643,12 +1643,12 @@ class Process implements \IteratorAggregate
|
||||
|
||||
private function replacePlaceholders(string $commandline, array $env)
|
||||
{
|
||||
return preg_replace_callback('/"\$([_a-zA-Z]++[_a-zA-Z0-9]*+)"/', function ($matches) use ($commandline, $env) {
|
||||
return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) {
|
||||
if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) {
|
||||
throw new InvalidArgumentException(sprintf('Command line is missing a value for key %s: %s.', $matches[0], $commandline));
|
||||
throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": %s.', $matches[1], $commandline));
|
||||
}
|
||||
|
||||
return '\\' === \DIRECTORY_SEPARATOR ? $this->escapeArgument($env[$matches[1]]) : $matches[0];
|
||||
return $this->escapeArgument($env[$matches[1]]);
|
||||
}, $commandline);
|
||||
}
|
||||
|
||||
|
@ -1463,7 +1463,7 @@ EOTXT;
|
||||
|
||||
public function testPreparedCommand()
|
||||
{
|
||||
$p = Process::fromShellCommandline('echo "$abc"DEF');
|
||||
$p = Process::fromShellCommandline('echo "${:abc}"DEF');
|
||||
$p->run(null, ['abc' => 'ABC']);
|
||||
|
||||
$this->assertSame('ABCDEF', rtrim($p->getOutput()));
|
||||
@ -1471,7 +1471,7 @@ EOTXT;
|
||||
|
||||
public function testPreparedCommandMulti()
|
||||
{
|
||||
$p = Process::fromShellCommandline('echo "$abc""$def"');
|
||||
$p = Process::fromShellCommandline('echo "${:abc}""${:def}"');
|
||||
$p->run(null, ['abc' => 'ABC', 'def' => 'DEF']);
|
||||
|
||||
$this->assertSame('ABCDEF', rtrim($p->getOutput()));
|
||||
@ -1479,7 +1479,7 @@ EOTXT;
|
||||
|
||||
public function testPreparedCommandWithQuoteInIt()
|
||||
{
|
||||
$p = Process::fromShellCommandline('php -r "$code" "$def"');
|
||||
$p = Process::fromShellCommandline('php -r "${:code}" "${:def}"');
|
||||
$p->run(null, ['code' => 'echo $argv[1];', 'def' => '"DEF"']);
|
||||
|
||||
$this->assertSame('"DEF"', rtrim($p->getOutput()));
|
||||
@ -1488,16 +1488,16 @@ EOTXT;
|
||||
public function testPreparedCommandWithMissingValue()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Process\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Command line is missing a value for key "$abc": echo "$abc".');
|
||||
$p = Process::fromShellCommandline('echo "$abc"');
|
||||
$this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}".');
|
||||
$p = Process::fromShellCommandline('echo "${:abc}"');
|
||||
$p->run(null, ['bcd' => 'BCD']);
|
||||
}
|
||||
|
||||
public function testPreparedCommandWithNoValues()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Process\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Command line is missing a value for key "$abc": echo "$abc".');
|
||||
$p = Process::fromShellCommandline('echo "$abc"');
|
||||
$this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}".');
|
||||
$p = Process::fromShellCommandline('echo "${:abc}"');
|
||||
$p->run(null, []);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user