Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0dda934

Browse filesBrowse files
author
Amrouche Hamza
committed
[Process] Allow writing portable "prepared" command lines
1 parent a522e04 commit 0dda934
Copy full SHA for 0dda934

File tree

2 files changed

+54
-1
lines changed
Filter options

2 files changed

+54
-1
lines changed

‎src/Symfony/Component/Process/Process.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Process/Process.php
+28-1Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,10 @@ public function start(callable $callback = null, array $env = array())
278278

279279
$options = array('suppress_errors' => true);
280280

281-
if ('\\' === DIRECTORY_SEPARATOR) {
281+
$windows = '\\' === DIRECTORY_SEPARATOR;
282+
$commandline = $this->replacePlaceholder($commandline, $windows, $env);
283+
284+
if ($windows) {
282285
$options['bypass_shell'] = true;
283286
$commandline = $this->prepareWindowsCommandLine($commandline, $envBackup);
284287
} elseif (!$this->useFileHandles && $this->isSigchildEnabled()) {
@@ -1562,4 +1565,28 @@ private function escapeArgument($argument)
15621565

15631566
return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
15641567
}
1568+
1569+
private function replacePlaceholder($commandLine, $windows, $env)
1570+
{
1571+
$toReplace = $windows ? array('!', '!') : array('$', '');
1572+
if (!preg_match_all('/\{([a-zA-Z0-9]+?)\}/', $commandLine, $matches)) {
1573+
return $commandLine;
1574+
}
1575+
1576+
$patterns = $replacements = array();
1577+
$isInEnv = false;
1578+
foreach ($matches as $match) {
1579+
$patterns[] = sprintf('/{%s}/', $match[0]);
1580+
$replacements[] = sprintf('%s%s%s', $toReplace[0], $match[0], $toReplace[1]);
1581+
if (isset($env[$match[0]])) {
1582+
$isInEnv = true;
1583+
}
1584+
}
1585+
1586+
if (!$isInEnv) {
1587+
throw new InvalidArgumentException(sprintf('There are no passed env for the command line "%s", replacement cannot be done.', $commandLine));
1588+
}
1589+
1590+
return preg_replace($patterns, $replacements, $commandLine);
1591+
}
15651592
}

‎src/Symfony/Component/Process/Tests/ProcessTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Process/Tests/ProcessTest.php
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,32 @@ public function provideEscapeArgument()
14701470
yield array('éÉèÈàÀöä');
14711471
}
14721472

1473+
public function testPreparedCommand()
1474+
{
1475+
$p = new Process('echo {abc}');
1476+
$p->run(null, array('abc' => 'ABC'));
1477+
1478+
$expected = <<<EOTXT
1479+
ABC\n
1480+
EOTXT;
1481+
$this->assertSame($expected, $p->getOutput());
1482+
}
1483+
1484+
/**
1485+
* @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
1486+
* @expectedExceptionMessage There are no passed env for the command line "echo {abc}", replacement cannot be done.
1487+
*/
1488+
public function testPreparedCommandWithoutProvidedParam()
1489+
{
1490+
$p = new Process('echo {abc}');
1491+
$p->run(null, array('bcd' => 'ABC'));
1492+
1493+
$expected = <<<EOTXT
1494+
ABC
1495+
EOTXT;
1496+
$this->assertSame($expected, $p->getOutput());
1497+
}
1498+
14731499
public function testEnvArgument()
14741500
{
14751501
$env = array('FOO' => 'Foo', 'BAR' => 'Bar');

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.