This forum is in READ-ONLY mode.
You can look around, but if you want to ask a new question, please use Stack Overflow.

Grep-RuntimeException in PatternFinder.php

Discuss installing Symfony 2 here

Grep-RuntimeException in PatternFinder.php

by peterschmied » Sun Jan 06, 2013 7:25 pm

Hi,

I developed my (quite simple, no use of any database) Symfony 2.1.6 project on Windows where it runs without any problems. Deploying it to my Unix server (Strato shared hosting) gives me a headache as I receive the following error message opening app_dev.php:

RuntimeException: Command "/usr/bin/grep --extended-regexp --directories=recurse --devices=skip --files-with-matches --with-filename --color=never --include=*.php '.*' '/htdocs/beta/src/[my company]/[my bundle]/Resources/translations' '/htdocs/beta/vendor/symfony/symfony/src/Symfony/Component/Form/Resources/translations' '/htdocs/beta/vendor/symfony/symfony/src/Symfony/Component/Validator/Resources/translations'" exited with non-successful status code "2".

Any idea what the issue could be or how I can find out? The log is empty. Cache and log directory are writeable.

Thank you!

Workaround (ugly): I encommented the "throw new exception" statement in PatternFinder.php line 156

Peter
peterschmied
Junior Member
 
Posts: 2
Joined: Sun Jan 06, 2013 7:15 pm

Re: Grep-RuntimeException in PatternFinder.php

by fabstei » Sun Feb 03, 2013 10:10 pm

Hi Peter,

make sure that all files have the correct owner set and the error should disappear.

Best,
Fabian
fabstei
Junior Member
 
Posts: 1
Joined: Sun Feb 03, 2013 10:05 pm

Re: Grep-RuntimeException in PatternFinder.php

by peterbs » Tue Jun 11, 2013 4:53 pm

I was having issues deploying this to my Unix server, I gave up in the end. I'll give your recommendation a go and see.
I keep having a dream about being pregnant and this solved the dream.
peterbs
Junior Member
 
Posts: 1
Joined: Tue Jun 11, 2013 4:50 pm

Re: Grep-RuntimeException in PatternFinder.php

by sociosqu » Sun Aug 04, 2013 9:46 pm

Hi Peter,
I had the same problem and just found that Strato uses SunOs, where the parameterlist of grep is different to the parameterlist for Linux.
You can modify the file 'vendor/jms/di-extra-bundle/JMS/DiExtraBundle/Finder/PatterFinder.php' to observe SunOs and the call grep with the SunOs parameters.
Or use a dirty hack and force 'METHOD_FINDER'.

Please note, the parameters in 'findUsingGrepSolaris(..) below is not as it should be. I was currently too lazy to look up the correct parameters, but it seems to work with this. ;)

Code: Select all
<?php

/*
 * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace JMS\DiExtraBundle\Finder;

use JMS\DiExtraBundle\Exception\RuntimeException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\ExecutableFinder;

class PatternFinder
{
    const METHOD_GREP = 1;
    const METHOD_FINDSTR = 2;
    const METHOD_FINDER = 3;
   const METHOD_GREP_SOLARIS = 4;

    private static $method;
    private static $grepPath;

    private $pattern;
    private $filePattern;
    private $recursive = true;
    private $regexPattern = false;

    public function __construct($pattern, $filePattern = '*.php')
    {
        if (null === self::$method) {
            self::determineMethod();
        }

        $this->pattern = $pattern;
        $this->filePattern = $filePattern;
    }

    public function setRecursive($bool)
    {
        $this->recursive = (Boolean) $bool;
    }

    public function setRegexPattern($bool)
    {
        $this->regexPattern = (Boolean) $bool;
    }

    public function findFiles(array $dirs)
    {
        // check for grep availability
        if (self::METHOD_GREP === self::$method) {
            return $this->findUsingGrep($dirs);
        }
      
      if (self::METHOD_GREP_SOLARIS === self::$method) {
            return $this->findUsingGrepSolaris($dirs);
        }

        // use FINDSTR on Windows
        if (self::METHOD_FINDSTR === self::$method) {
            return $this->findUsingFindstr($dirs);
        }

        // this should really be avoided at all costs since it is damn slow
        return $this->findUsingFinder($dirs);
    }

    private function findUsingFindstr(array $dirs)
    {
        $cmd = 'FINDSTR /M /S /P';

        if (!$this->recursive) {
            $cmd .= ' /L';
        }

        $cmd .= ' /D:'.escapeshellarg(implode(';', $dirs));
        $cmd .= ' '.escapeshellarg($this->pattern);
        $cmd .= ' '.$this->filePattern;

        exec($cmd, $lines, $exitCode);

        if (1 === $exitCode) {
            return array();
        }

        if (0 !== $exitCode) {
            throw new RuntimeException(sprintf('Command "%s" exited with non-successful status code. "%d".', $cmd, $exitCode));
        }

        // Looks like FINDSTR has different versions with different output formats.
        //
        // Supported format #1:
        //     C:\matched\dir1:
        // Relative\Path\To\File1.php
        // Relative\Path\To\File2.php
        //     C:\matched\dir2:
        // Relative\Path\To\File3.php
        // Relative\Path\To\File4.php
        //
        // Supported format #2:
        // C:\matched\dir1\Relative\Path\To\File1.php
        // C:\matched\dir1\Relative\Path\To\File2.php
        // C:\matched\dir2\Relative\Path\To\File3.php
        // C:\matched\dir2\Relative\Path\To\File4.php

        $files = array();
        $currentDir = '';
        foreach ($lines as $line) {
            if (':' === substr($line, -1)) {
                $currentDir = trim($line, ' :/').'/';
                continue;
            }

            $files[] = $currentDir.$line;
        }

        return $files;
    }
   
   private function findUsingGrepSolaris(array $dirs)
    {
        $cmd = self::$grepPath;
      
        foreach ($dirs as $dir) {
            $cmd .= ' '.escapeshellarg($dir);
        }
      
        exec($cmd, $files, $exitCode);

        if (1 === $exitCode) {
            return array();
        }

        if (0 !== $exitCode) {
            throw new RuntimeException(sprintf('Command "%s" exited with non-successful status code "%d".', $cmd, $exitCode));
        }

        return $files;
    }

    private function findUsingGrep(array $dirs)
    {
        $cmd = self::$grepPath;

        if (!$this->regexPattern) {
            $cmd .= ' --fixed-strings';
        } else {
            $cmd .= ' --extended-regexp';
        }

        if ($this->recursive) {
            $cmd .= ' --directories=recurse';
        } else {
            $cmd .= ' --directories=skip';
        }

        $cmd .= ' --devices=skip --files-with-matches --with-filename --color=never --include='.$this->filePattern;
        $cmd .= ' '.escapeshellarg($this->pattern);
      
        foreach ($dirs as $dir) {
            $cmd .= ' '.escapeshellarg($dir);
        }
      
        exec($cmd, $files, $exitCode);

        if (1 === $exitCode) {
            return array();
        }

        if (0 !== $exitCode) {
            throw new RuntimeException(sprintf('Command "%s" exited with non-successful status code "%d".', $cmd, $exitCode));
        }

        return $files;
    }

    private function findUsingFinder(array $dirs)
    {
        $finder = new Finder();
        $pattern = $this->pattern;
        $regex = $this->regexPattern;
        $finder
            ->files()
            ->name($this->filePattern)
            ->in($dirs)
            ->ignoreVCS(true)
            ->filter(function($file) use ($pattern, $regex) {
                if (!$regex) {
                    return false !== strpos(file_get_contents($file->getPathName()), $pattern);
                }

                return 0 < preg_match('#'.$pattern.'#', file_get_contents($file->getPathName()));
            })
        ;

        if (!$this->recursive) {
            $finder->depth('<= 0');
        }

        return array_keys(iterator_to_array($finder));
    }

    private static function determineMethod()
    {
        $finder = new ExecutableFinder();
        $isWindows = 0 === stripos(PHP_OS, 'win');
      $isSolaris = 0 === stripos(PHP_OS, 'Sun');
        $execAvailable = function_exists('exec');

        if (!$isWindows && $execAvailable && self::$grepPath = $finder->find('grep')) {
         if (!$isSolaris) {
            self::$method = self::METHOD_GREP;
         } else {
            self::$method = self::METHOD_GREP_SOLARIS;
         }
        } else if ($isWindows && $execAvailable) {
            self::$method = self::METHOD_FINDSTR;
        } else {
            self::$method = self::METHOD_FINDER;
        }
    }
}

sociosqu
Junior Member
 
Posts: 8
Joined: Fri May 25, 2012 6:10 pm