Merge branch '2.3' into 2.7

* 2.3:
  [travis] Remove PHP 7 from allowed failures
  [Finder] Optimize the hot-path
  Update Process.php

Conflicts:
	composer.json
	src/Symfony/Bridge/Doctrine/composer.json
	src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
This commit is contained in:
Nicolas Grekas 2015-09-19 21:59:23 +02:00
commit 1ba6cfee48
6 changed files with 57 additions and 22 deletions

View File

@ -16,10 +16,7 @@ matrix:
- php: 5.6
env: deps=high
- php: 7
- php: 5.6
env: deps=low
allow_failures:
- php: 7
fast_finish: true
services: mongodb

View File

@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.3.9",
"doctrine/common": "~2.3",
"doctrine/common": "~2.4",
"twig/twig": "~1.20|~2.0",
"psr/log": "~1.0"
},
@ -70,8 +70,8 @@
"require-dev": {
"symfony/phpunit-bridge": "self.version",
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": "~2.2",
"doctrine/orm": "~2.2,>=2.2.3",
"doctrine/dbal": "~2.4",
"doctrine/orm": "~2.4,>=2.4.5",
"doctrine/doctrine-bundle": "~1.2",
"monolog/monolog": "~1.11",
"ircmaxell/password-compat": "~1.0",

View File

@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.3.9",
"doctrine/common": "~2.3"
"doctrine/common": "~2.4"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7",
@ -31,8 +31,8 @@
"symfony/validator": "~2.5,>=2.5.5",
"symfony/translation": "~2.0,>=2.0.5",
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": "~2.2",
"doctrine/orm": "~2.2,>=2.2.3"
"doctrine/dbal": "~2.4",
"doctrine/orm": "~2.4,>=2.4.5"
},
"suggest": {
"symfony/form": "",

View File

@ -18,8 +18,10 @@ namespace Symfony\Component\Finder\Iterator;
*/
class ExcludeDirectoryFilterIterator extends FilterIterator implements \RecursiveIterator
{
private $iterator;
private $isRecursive;
private $patterns = array();
private $excludedDirs = array();
private $excludedPattern;
/**
* Constructor.
@ -29,9 +31,18 @@ class ExcludeDirectoryFilterIterator extends FilterIterator implements \Recursiv
*/
public function __construct(\Iterator $iterator, array $directories)
{
$this->iterator = $iterator;
$this->isRecursive = $iterator instanceof \RecursiveIterator;
$patterns = array();
foreach ($directories as $directory) {
$this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
if (!$this->isRecursive || false !== strpos($directory, '/')) {
$patterns[] = preg_quote($directory, '#');
} else {
$this->excludedDirs[$directory] = true;
}
}
if ($patterns) {
$this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#';
}
parent::__construct($iterator);
@ -44,12 +55,15 @@ class ExcludeDirectoryFilterIterator extends FilterIterator implements \Recursiv
*/
public function accept()
{
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
$path = str_replace('\\', '/', $path);
foreach ($this->patterns as $pattern) {
if (preg_match($pattern, $path)) {
return false;
}
if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
return false;
}
if ($this->excludedPattern) {
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
$path = str_replace('\\', '/', $path);
return !preg_match($this->excludedPattern, $path);
}
return true;
@ -57,13 +71,14 @@ class ExcludeDirectoryFilterIterator extends FilterIterator implements \Recursiv
public function hasChildren()
{
return $this->isRecursive && $this->getInnerIterator()->hasChildren();
return $this->isRecursive && $this->iterator->hasChildren();
}
public function getChildren()
{
$children = new self($this->getInnerIterator()->getChildren(), array());
$children->patterns = $this->patterns;
$children = new self($this->iterator->getChildren(), array());
$children->excludedDirs = $this->excludedDirs;
$children->excludedPattern = $this->excludedPattern;
return $children;
}

View File

@ -31,6 +31,11 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
*/
private $rewindable;
// these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
private $rootPath;
private $subPath;
private $directorySeparator = '/';
/**
* Constructor.
*
@ -48,6 +53,10 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
parent::__construct($path, $flags);
$this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
$this->rootPath = (string) $path;
if ('/' !== DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
$this->directorySeparator = DIRECTORY_SEPARATOR;
}
}
/**
@ -57,7 +66,17 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
*/
public function current()
{
return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname());
// the logic here avoids redoing the same work in all iterations
if (null === $subPathname = $this->subPath) {
$subPathname = $this->subPath = (string) $this->getSubPath();
}
if ('' !== $subPathname) {
$subPathname .= $this->directorySeparator;
}
$subPathname .= $this->getFilename();
return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
}
/**
@ -73,6 +92,10 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
if ($children instanceof self) {
// parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
$children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
// performance optimization to avoid redoing the same work in all children
$children->rewindable = &$this->rewindable;
$children->rootPath = $this->rootPath;
}
return $children;

View File

@ -275,7 +275,7 @@ class Process
$commandline = $this->commandline;
if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
$commandline = 'cmd /V:ON /E:ON /C "('.$commandline.')';
$commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
foreach ($this->processPipes->getFiles() as $offset => $filename) {
$commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename);
}