text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: File.php 588 2010-05-25 15:11:56Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Package
 */
require_once PHPRACK_PATH . '/Package.php';

/**
 * @see phpRack_Adapters_File
 */
require_once PHPRACK_PATH . '/Adapters/File.php';

/**
 * File informations and content
 *
 * @package Tests
 */
class phpRack_Package_Disc_File extends phpRack_Package
{
    /**
     * Buffer used is tail function to read blocks from file end
     */
    const READ_BUFFER_SIZE = 1024;

    /**
     * Default number of lines to show
     */
    const LINES_TO_SHOW = 25;

    /**
     * Maximum number of bytes we can render, if more we will skip the rest
     *
     * @var int
     */
    protected $_maxBytesToRender = 50000;

    /**
     * Set another limit for max bytes to render
     *
     * @param int Number of bytes that is allowed for rendering
     * @return $this
     */
    public function setMaxBytesToRender($maxBytesToRender)
    {
        $this->_maxBytesToRender = $maxBytesToRender;
        return $this;
    }

    /**
     * Show the content of the file
     *
     * @param string File name to display
     * @return $this
     */
    public function cat($fileName)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        // Check that file exists
        if (!$this->_isFileExists($fileName)) {
            return $this;
        }

        // too long/big files should not be returned
        if (filesize($fileName) > $this->_maxBytesToRender) {
            $this->_log(
                sprintf(
                    "File '%s' is too big (%d bytes), we can't render its content in full",
                    $fileName,
                    filesize($fileName)
                )
            );
            return $this->tail($fileName);
        }

        $content = file_get_contents($fileName);
        if ($content === false) {
            $this->_failure("Failed file_get_contents('{$fileName}')");
            return $this;
        }
        $this->_log($content);
        return $this;
    }

    /**
     * Show last x lines from the file
     *
     * @param string File name
     * @param string How many lines to display?
     * @return $this
     */
    public function tail($fileName, $linesCount = self::LINES_TO_SHOW)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        // Check that file exists
        if (!$this->_isFileExists($fileName)) {
            return $this;
        }

        // Open file and move pointer to end of file
        $fp = fopen($fileName, 'rb');
        fseek($fp, 0, SEEK_END);

        // Read offset of end of file
        $offset = ftell($fp);

        // set ajax option with file end offset for usage in next Ajax request
        $this->_result->getTest()->setAjaxOptions(
            array(
                'data' => array('fileLastOffset' => $offset)
            )
        );

        $content = '';

        do {
            // Move file pointer for new read
            $offset = max(0, $offset - self::READ_BUFFER_SIZE);
            fseek($fp, $offset, SEEK_SET);

            $readBuffer = fread($fp, self::READ_BUFFER_SIZE);
            $linesCountInReadBuffer = substr_count($readBuffer, "\n");

            // If we have enought lines extract from last readed fragment only required lines
            if ($linesCountInReadBuffer >= $linesCount) {
                $readBuffer = implode("\n", array_slice(explode("\n", $readBuffer), -$linesCount));
            }

            // Update how many lines still need to be readed
            $linesCount -= $linesCountInReadBuffer;

            // Attach last readed lines at beggining of earlier readed fragments
            $content = $readBuffer . $content;

            if (strlen($content) > $this->_maxBytesToRender) {
                $this->_log(
                    sprintf(
                        "Content is too long already (%d bytes), we won't render any more",
                        strlen($content)
                    )
                );
                break;
            }
        } while ($offset > 0 && $linesCount > 0);

        $this->_log($content);
        return $this;
    }

    /**
     * Show last x lines from the file, and refresh it imediatelly
     *
     * @param string File name
     * @param string How many lines to display?
     * @param string How many seconds each line should be visible
     * @return $this
     * @see phpRack_Runner::run()
     */
    public function tailf($fileName, $linesCount = self::LINES_TO_SHOW, $secVisible = 5)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();
        $test = $this->_result->getTest();

        $test->setAjaxOptions(
            array(
                'reload' => 0.5, //500ms I think is okey for delay between requests, can be lower
                'secVisible' => $secVisible,
                'linesCount' => $linesCount,
                'attachOutput' => true
            )
        );
        $options = $test->getAjaxOptions();

        clearstatcache();
        // get current file size
        $fileSize = @filesize($fileName);
        if ($fileSize === false) {
            $this->_failure("Failed to filesize('{$fileName}')");
            return $this;
        }

        // if it is first request or file was truncated, send all x last lines
        if (!isset($options['fileLastOffset']) || $fileSize < $options['fileLastOffset']) {
            $this->tail($fileName, $linesCount);
            return $this;
        }

        $fp = @fopen($fileName, 'rb');
        if (!$fp) {
            $this->_failure("Failed to fopen('{$fileName}')");
            return $this;
        }
        // get only new content since last time
        $content = @stream_get_contents($fp, -1, $options['fileLastOffset']);
        if ($content === false) {
            $this->_failure("Failed to stream_get_contents({$fp}/'{$fileName}', -1, {$options['fileLastOffset']})");
            return $this;
        }

        // save current offset
        $offset = @ftell($fp);
        if ($offset === false) {
            $this->_failure("Failed to ftell({$fp}/'{$fileName}')");
            return $this;
        }
        if (@fclose($fp) === false) {
            $this->_failure("Failed to fclose({$fp}/'{$fileName}')");
            return $this;
        }

        $this->_log($content);

        // set ajax option with new file end offset for usage in next Ajax request
        $test->setAjaxOptions(
            array(
                'data' => array('fileLastOffset' => $offset),
            )
        );
        return $this;
    }

    /**
     * Show first x lines from the file
     *
     * @param string File name
     * @param string How many lines to display?
     * @return $this
     */
    public function head($fileName, $linesCount = self::LINES_TO_SHOW)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        // Check that file exists
        if (!$this->_isFileExists($fileName)) {
            return $this;
        }

        $content = '';
        $readedLinesCount = 0;
        $fp = @fopen($fileName, 'rb');
        if ($fp === false) {
            $this->_failure("Failed to fopen('{$fileName}')");
            return $this;
        }

        // Read line by line until we have required count or we reach EOF
        while ($readedLinesCount < $linesCount && !feof($fp)) {
            $content .= @fgets($fp);
            $readedLinesCount++;
            if (strlen($content) > $this->_maxBytesToRender) {
                $this->_log(
                    sprintf(
                        "Content is too long already (%d bytes), we won't render any more",
                        strlen($content)
                    )
                );
                break;
            }
        }

        if (@fclose($fp) === false) {
            $this->_failure("Failed to fclose('{$fileName}')");
            return $this;
        }

        $this->_log($content);
        return $this;
    }

    /**
     * Checks whether a file exists
     *
     * @param string File name to check
     * @return $this
     */
    public function exists($fileName)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        clearstatcache();
        if (file_exists($fileName)) {
            $this->_success("File '{$fileName}' exists");
        } else {
            $this->_failure("File '{$fileName}' does not exist");
        }
        return $this;
    }

    /**
     * Checks whether a file is readable
     *
     * @param string File name to check
     * @return $this
     */
    public function isReadable($fileName)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        clearstatcache();
        if (is_readable($fileName)) {
            $this->_success("File '{$fileName}' is readable");
        } else {
            $this->_failure("File '{$fileName}' is not readable");
        }
        return $this;
    }

    /**
     * Check whether a file is writable
     *
     * @param string File name to check
     * @return $this
     */
    public function isWritable($fileName)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        clearstatcache();
        if (is_writable($fileName)) {
            $this->_success("File '{$fileName}' is writable");
        } else {
            $this->_failure("File '{$fileName}' is not writable");
        }
        return $this;
    }

    /**
     * Check whether the filename is a directory
     *
     * @param string File name to check
     * @return $this
     */
    public function isDir($fileName)
    {
        $fileName = phpRack_Adapters_File::factory($fileName)->getFileName();

        clearstatcache();
        if (is_dir($fileName)) {
            $this->_success("File '{$fileName}' is a directory");
        } else {
            $this->_failure("File '{$fileName}' is not a directory");
        }
        return $this;
    }

    /**
     * Check that file exists
     *
     * @param string File name to check
     * @return boolean True if file exists
     */
    protected function _isFileExists($fileName)
    {
        if (!file_exists($fileName)) {
            $this->_failure("File '{$fileName}' is not found");
            return false;
        }

        $this->_log(
            sprintf(
                "File '%s' (%d bytes, modified on %s):",
                realpath($fileName),
                filesize($fileName),
                $this->_modifiedOn(filemtime($fileName))
            )
        );
        return true;
    }

    /**
     * Show when this file was modified
     *
     * @param integer Time/date when this file was modifed, result of filemtime()
     * @return string
     * @see _isFileExists()
     */
    protected function _modifiedOn($time)
    {
        $mins = round((time() - $time)/60, 1);
        if ($mins < 1) {
            $age = round($mins * 60) . 'sec';
        } elseif ($mins < 60) {
            $age = $mins . 'min';
        } elseif ($mins < 24 * 60) {
            $age = round($mins/60) . 'hrs';
        } else {
            $age = round($mins/(60*24)) . 'days';
        }

        return date('d-M-y H:i:s', $time) . ', ' . $age . ' ago';
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: FreeSpace.php 624 2010-07-22 06:09:55Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Package
 */
require_once PHPRACK_PATH . '/Package.php';

/**
 * Free space on HDD
 *
 * @package Tests
 */
class phpRack_Package_Disc_FreeSpace extends phpRack_Package
{

    /**
     * We have at least this amount of space on the current disc?
     *
     * @param integer Mega-bytes to check
     * @return $this
     */
    public function atLeast($mb)
    {
        $free = disk_free_space(dirname(__FILE__)) / (1024 * 1024);
        if ($free >= $mb) {
            $this->_success(sprintf("We have %0.2fMb free space, {$mb}Mb required", $free));
        } else {
            $this->_failure(sprintf("We have just %0.2fMb free space, while {$mb}Mb required", $free));
        }

        return $this;
    }

}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Auth.php 623 2010-07-19 12:23:28Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Runner
 */
require_once PHPRACK_PATH . '/Runner.php';

/**
 * Runner authentication adapter
 *
 * @package Tests
 */
class phpRack_Runner_Auth
{

    /**
     * COOKIE name
     *
     * @see isAuthenticated()
     */
    const COOKIE_NAME = 'phpRack_auth';

    /**
     * COOKIE lifetime in seconds
     *
     * We set to 30 days, which equals to 30 * 24 * 60 * 60 = 2592000
     *
     * @see isAuthenticated()
     */
    const COOKIE_LIFETIME = 2592000;

    /**
     * Form param names
     *
     * @see isAuthenticated()
     * @see login.phtml
     */
    const POST_LOGIN = 'login';
    const POST_PWD = 'password';

    /**
     * Param names for authenticating using GET
     *
     * @see isAuthenticated()
     */
    const GET_LOGIN = 'login';
    const GET_PWD = 'password';

    /**
     * Auth result, if authentication was already performed
     *
     * @var phpRack_Runner_Auth_Result
     * @see authenticate()
     */
    protected $_authResult = null;

    /**
     * Tests runner
     *
     * @var phpRack_Runner
     * @see __construct()
     * @see isAuthenticated()
     */
    protected $_runner = null;

    /**
     * Authentication options
     *
     * @var array
     */
    protected $_options = null;

    public function __construct(phpRack_Runner $runner, $options)
    {
        $this->_runner = $runner;
        $this->_options = $options;
    }

    /**
     * Authenticate the user before running any tests
     *
     * @param string Login of the user
     * @param string Secret password of the user
     * @param boolean Defines whether second argument is password or it's hash
     * @return phpRack_Runner_Auth_Result
     * @see bootstrap.php
     */
    public function authenticate($login, $password, $isHash = false)
    {
        // if it's already authenticated, just return it
        if (!is_null($this->_authResult)) {
            return $this->_authResult;
        }

        // make sure that we're working with HASH
        $hash = ($isHash) ? $password : md5($password);

        switch (true) {
            // plain authentication by login/password
            // this option is set by default to NULL, here we validate that
            // it was changed to ARRAY
            case is_array($this->_options['auth']):
                $method = 'plain';
                break;

            // list of login/password provided in file
            // this option is set by default to NULL, here we just validate
            // that it contains a name of file
            case is_string($this->_options['htpasswd']):
                $method = 'file';
                break;

            // list of login/password provided in associative array
            // key is username and value is password
            case is_array($this->_options['htpasswd']):
                $method = 'array';
                break;

            // authenticated TRUE, if no authentication required
            default:
                return $this->_validated(true);
        }

        $className = 'phpRack_Adapters_Auth_' . ucfirst($method);
        eval("require_once PHPRACK_PATH . '/Adapters/Auth/' . ucfirst(\$method) . '.php';");
        $adapter = new $className();
        $adapter->setOptions($this->_options)
            ->setRequest(
                array(
                    'login'    => $login,
                    'password' => $password,
                    'hash'     => $hash,
                )
            );
        return $adapter->authenticate();
    }

    /**
     * Try HTTP POST authentication method
     *
     * Login/password are provided in HTTP request, through POST params.
     * we should save them in COOKIE in order to avoid further login requests.
     *
     * @throws Exception if some required request parameter is missed
     * @return array with retrieved login and hash
     */
    private function _tryHttpPost()
    {
        if (!array_key_exists(self::POST_LOGIN, $_POST)
            || !array_key_exists(self::POST_PWD, $_POST)
        ) {
            return array();
        }
        $login = $_POST[self::POST_LOGIN];
        $hash = md5($_POST[self::POST_PWD]);
        setcookie(
            self::COOKIE_NAME, // name of HTTP cookie
            $login . ':' . $hash, // hashed form of login and pwd
            time() + self::COOKIE_LIFETIME // cookie expiration date
        );
        return array (
            'login' => $login,
            'hash'  => $hash
        );
    }

    /**
     * Try HTTP GET authentication method
     *
     * Login/password are provided as GET params as it's only one-time Phing
     * bridge, we don't store them anywhere
     *
     * @throws Exception if some required request parameter is missed
     * @return array with retrieved login and hash
     */
    private function _tryHttpGet()
    {
        if (!array_key_exists(self::GET_LOGIN, $_GET)
            || !array_key_exists(self::GET_PWD, $_GET)
        ) {
            return array();
        }
        return array (
            'login' => $_GET[self::GET_LOGIN],
            'hash'  => md5($_GET[self::GET_PWD])
        );
    }

    /**
     * Try HTTP Cookie authentication method
     *
     * Login/password are provided as GET params as it's only one-time Phing
     * bridge, we don't store them anywhere
     *
     * @return array with retrieved login and hash
     */
    private function _tryHttpCookie()
    {
        // global variables, in case they are not declared as global yet
        global $_COOKIE;

        if (!array_key_exists(self::COOKIE_NAME, $_COOKIE)) {
            return array();
        }

        // we already have authentication information in COOKIE, we just
        // need to parse it and validate
        $data = explode(':', $_COOKIE[self::COOKIE_NAME]);
        return array (
            'login' => $data[0],
            'hash'  => $data[1]
        );
    }

    /**
     * Try HTTP Plan authentication method
     *
     * We expect authentication information to be sent via headers for example
     * by Phing
     *
     * @return array with retrieved login and hash
     */
    private function _tryPlainAuth()
    {
        if (!array_key_exists('PHP_AUTH_USER', $_SERVER)
            || !array_key_exists('PHP_AUTH_PW', $_SERVER)
        ) {
            return array();
        }
        return array (
            'login' => $_SERVER['PHP_AUTH_USER'],
            'hash'  => md5($_SERVER['PHP_AUTH_PW'])
        );
    }

    /**
     * Checks whether user is authenticated before running any tests
     *
     * @return boolean
     * @see bootstrap.php
     */
    public function isAuthenticated()
    {
        if (!is_null($this->_authResult)) {
            return $this->_authResult->isValid();
        }

        // this is CLI environment, not web -- we don't require any
        // authentication
        if ($this->_runner->isCliEnvironment()) {
            return $this->_validated(true)->isValid();
        }

        // there are a number of possible authentication scenarios
        switch (true) {
            case ($result = $this->_tryHttpPost()):
                break;

            case ($result = $this->_tryHttpGet()):
                break;

            case ($result = $this->_tryHttpCookie()):
                break;

            case ($result = $this->_tryPlainAuth());
                break;

            default:
                // no authinfo, chances are that site is not protected
                $result = array('login' => false, 'hash'=> false);
        }
        $this->_authResult = $this->authenticate($result['login'], $result['hash'], true);
        return $this->_authResult->isValid();
    }

    /**
     * Get current auth result, if it exists
     *
     * @return phpRack_Runner_Auth_Result
     * @see boostrap.php
     * @throws Exception If the result is not set yet
     */
    public function getAuthResult()
    {
        if (!isset($this->_authResult)) {
            throw new Exception("AuthResult is not set yet, use authenticate() before");
        }
        return $this->_authResult;
    }

    /**
     * Save and return an AuthResult
     *
     * @param boolean Success/failure of the validation
     * @param string Optional error message
     * @return phpRack_Runner_Auth_Result
     * @see authenticate()
     */
    protected function _validated($result, $message = null)
    {
        /**
         * @see phpRack_Runner_Auth_Result
         */
        require_once PHPRACK_PATH . '/Runner/Auth/Result.php';
        return $this->_authResult = new phpRack_Runner_Auth_Result($result, $message);
    }

}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Logger.php 623 2010-07-19 12:23:28Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * Runner logger
 *
 * @package Tests
 * @see phpRack_Runner::run()
 */
class phpRack_Runner_Logger
{
    /**
     * Cuts log according to the limit provided
     *
     * @param string Log to cut
     * @param integer Limit in Kb
     * @see run()
     * @return string
     */
    public static function cutLog($log, $limit)
    {
        $len = 0;
        if (function_exists('mb_strlen')) {
            $len += mb_strlen($log, 'UTF-8');
        } elseif (function_exists('iconv_strlen')) {
            $len += iconv_strlen($log, 'UTF-8');
        } else {
            // bad variant
            $len += strlen($log) / 2;
        }

        $max = $limit * 1024; // in kb
        if ($len > $max) {
            $cutSize = $max / 2;
            $func = '';
            if (function_exists('iconv_substr')) {
                $func = 'iconv_substr';
            } elseif (function_exists('mb_substr')) {
                $func = 'mb_substr';
            }
            if ($func) {
                $head = call_user_func($func, $log, 0, $cutSize, 'UTF-8');
                $tail = call_user_func(
                    $func, $log, -1 * $cutSize, $cutSize, 'UTF-8'
                );
            } else {
                // bad variant
                $head = substr($log, 0, $cutSize / 2);
                $tail = substr($log, -1 * $cutSize / 2);
            }
            return $head . "\n\n... content skipped (" . ($len - $max) . " bytes) ...\n\n" . $tail;
        }
        return $log;
    }

    /**
     * Checks for string encoding, and if encoding is not utf-8, encodes to utf-8
     *
     * @param string String to convert into UTF-8
     * @return string Proper UTF-8 formatted string
     * @see run()
     * @see #60 I think that this method shall be extensively tested. Now I have problems
     *      with content that is not in English.
     */
    public static function utf8Encode($str)
    {
        return utf8_encode($str);
        // $isUtf = false;
        // if (function_exists('mb_check_encoding')) {
        //     $isUtf = mb_check_encoding($str, 'UTF-8');
        // }
        // if (function_exists('iconv')) {
        //     $isUtf = (@iconv('UTF-8', 'UTF-16', $str) !== false);
        // }
        // return (!$isUtf) ? utf8_encode($str) : $str;
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Result.php 623 2010-07-19 12:23:28Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * Result of authentication before running tests
 *
 * @package Tests
 * @see phpRack_Runner_Auth::_validated()
 */
class phpRack_Runner_Auth_Result
{

    /**
     * Stores auth result
     *
     * @var boolean
     * @see isValid()
     */
    protected $_valid;

    /**
     * Optional error message
     *
     * @var string
     * @see isValid()
     */
    protected $_message;

    /**
     * Constructor
     *
     * @param boolean Whether the auth is valid or not
     * @param string Optional error message
     * @return void
     */
    public function __construct($valid, $message = null)
    {
        $this->_valid = $valid;
        $this->_message = $message;
    }

    /**
     * Result is VALID?
     *
     * @return boolean
     */
    public function isValid()
    {
        return $this->_valid;
    }

    /**
     * Error message, if exists
     *
     * @return string
     */
    public function getMessage()
    {
        return $this->_message;
    }

}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\ConsoleOutput;

/**
 * A Shell wraps an Application to add shell capabilities to it.
 *
 * This class only works with a PHP compiled with readline support
 * (either --with-readline or --with-libedit)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Shell
{
    private $application;
    private $history;
    private $output;

    /**
     * Constructor.
     *
     * If there is no readline support for the current PHP executable
     * a \RuntimeException exception is thrown.
     *
     * @param Application $application An application instance
     *
     * @throws \RuntimeException When Readline extension is not enabled
     */
    public function __construct(Application $application)
    {
        if (!function_exists('readline')) {
            throw new \RuntimeException('Unable to start the shell as the Readline extension is not enabled.');
        }

        $this->application = $application;
        $this->history = getenv('HOME').'/.history_'.$application->getName();
        $this->output = new ConsoleOutput();
    }

    /**
     * Runs the shell.
     */
    public function run()
    {
        $this->application->setAutoExit(false);
        $this->application->setCatchExceptions(true);

        readline_read_history($this->history);
        readline_completion_function(array($this, 'autocompleter'));

        $this->output->writeln($this->getHeader());
        while (true) {
            $command = readline($this->application->getName().' > ');

            if (false === $command) {
                $this->output->writeln("\n");

                break;
            }

            readline_add_history($command);
            readline_write_history($this->history);

            if (0 !== $ret = $this->application->run(new StringInput($command), $this->output)) {
                $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
            }
        }
    }

    /**
     * Tries to return autocompletion for the current entered text.
     *
     * @param string  $text     The last segment of the entered text
     * @param integer $position The current position
     */
    private function autocompleter($text, $position)
    {
        $info = readline_info();
        $text = substr($info['line_buffer'], 0, $info['end']);

        if ($info['point'] !== $info['end']) {
            return true;
        }

        // task name?
        if (false === strpos($text, ' ') || !$text) {
            return array_keys($this->application->all());
        }

        // options and arguments?
        try {
            $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
        } catch (\Exception $e) {
            return true;
        }

        $list = array('--help');
        foreach ($command->getDefinition()->getOptions() as $option) {
            $list[] = '--'.$option->getName();
        }

        return $list;
    }

    /**
     * Returns the shell header.
     *
     * @return string The header string
     */
    protected function getHeader()
    {
        return <<<EOF

Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).

At the prompt, type <comment>help</comment> for some help,
or <comment>list</comment> to get a list available commands.

To exit the shell, type <comment>^D</comment>.

EOF;
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\DialogHelper;

/**
 * An Application is the container for a collection of commands.
 *
 * It is the main entry point of a Console application.
 *
 * This class is optimized for a standard CLI environment.
 *
 * Usage:
 *
 *     $app = new Application('myapp', '1.0 (stable)');
 *     $app->add(new SimpleCommand());
 *     $app->run();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class Application
{
    private $commands;
    private $wantHelps = false;
    private $runningCommand;
    private $name;
    private $version;
    private $catchExceptions;
    private $autoExit;
    private $definition;
    private $helperSet;

    /**
     * Constructor.
     *
     * @param string  $name    The name of the application
     * @param string  $version The version of the application
     *
     * @api
     */
    public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
    {
        $this->name = $name;
        $this->version = $version;
        $this->catchExceptions = true;
        $this->autoExit = true;
        $this->commands = array();
        $this->helperSet = new HelperSet(array(
            new FormatterHelper(),
            new DialogHelper(),
        ));

        $this->add(new HelpCommand());
        $this->add(new ListCommand());

        $this->definition = new InputDefinition(array(
            new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),

            new InputOption('--help',           '-h', InputOption::VALUE_NONE, 'Display this help message.'),
            new InputOption('--quiet',          '-q', InputOption::VALUE_NONE, 'Do not output any message.'),
            new InputOption('--verbose',        '-v', InputOption::VALUE_NONE, 'Increase verbosity of messages.'),
            new InputOption('--version',        '-V', InputOption::VALUE_NONE, 'Display this program version.'),
            new InputOption('--ansi',           '',   InputOption::VALUE_NONE, 'Force ANSI output.'),
            new InputOption('--no-ansi',        '',   InputOption::VALUE_NONE, 'Disable ANSI output.'),
            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'),
        ));
    }

    /**
     * Runs the current application.
     *
     * @param InputInterface  $input  An Input instance
     * @param OutputInterface $output An Output instance
     *
     * @return integer 0 if everything went fine, or an error code
     *
     * @throws \Exception When doRun returns Exception
     *
     * @api
     */
    public function run(InputInterface $input = null, OutputInterface $output = null)
    {
        if (null === $input) {
            $input = new ArgvInput();
        }

        if (null === $output) {
            $output = new ConsoleOutput();
        }

        try {
            $statusCode = $this->doRun($input, $output);
        } catch (\Exception $e) {
            if (!$this->catchExceptions) {
                throw $e;
            }

            $this->renderException($e, $output);
            $statusCode = $e->getCode();

            $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1;
        }

        if ($this->autoExit) {
            if ($statusCode > 255) {
                $statusCode = 255;
            }
            // @codeCoverageIgnoreStart
            exit($statusCode);
            // @codeCoverageIgnoreEnd
        }

        return $statusCode;
    }

    /**
     * Runs the current application.
     *
     * @param InputInterface  $input  An Input instance
     * @param OutputInterface $output An Output instance
     *
     * @return integer 0 if everything went fine, or an error code
     */
    public function doRun(InputInterface $input, OutputInterface $output)
    {
        $name = $this->getCommandName($input);

        if (true === $input->hasParameterOption(array('--ansi'))) {
            $output->setDecorated(true);
        } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
            $output->setDecorated(false);
        }

        if (true === $input->hasParameterOption(array('--help', '-h'))) {
            if (!$name) {
                $name = 'help';
                $input = new ArrayInput(array('command' => 'help'));
            } else {
                $this->wantHelps = true;
            }
        }

        if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
            $input->setInteractive(false);
        }

        if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
            $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
        } elseif (true === $input->hasParameterOption(array('--verbose', '-v'))) {
            $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
        }

        if (true === $input->hasParameterOption(array('--version', '-V'))) {
            $output->writeln($this->getLongVersion());

            return 0;
        }

        if (!$name) {
            $name = 'list';
            $input = new ArrayInput(array('command' => 'list'));
        }

        // the command name MUST be the first element of the input
        $command = $this->find($name);

        $this->runningCommand = $command;
        $statusCode = $command->run($input, $output);
        $this->runningCommand = null;

        return is_numeric($statusCode) ? $statusCode : 0;
    }

    /**
     * Set a helper set to be used with the command.
     *
     * @param HelperSet $helperSet The helper set
     *
     * @api
     */
    public function setHelperSet(HelperSet $helperSet)
    {
        $this->helperSet = $helperSet;
    }

    /**
     * Get the helper set associated with the command.
     *
     * @return HelperSet The HelperSet instance associated with this command
     *
     * @api
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }

    /**
     * Gets the InputDefinition related to this Application.
     *
     * @return InputDefinition The InputDefinition instance
     */
    public function getDefinition()
    {
        return $this->definition;
    }

    /**
     * Gets the help message.
     *
     * @return string A help message.
     */
    public function getHelp()
    {
        $messages = array(
            $this->getLongVersion(),
            '',
            '<comment>Usage:</comment>',
            sprintf("  [options] command [arguments]\n"),
            '<comment>Options:</comment>',
        );

        foreach ($this->getDefinition()->getOptions() as $option) {
            $messages[] = sprintf('  %-29s %s %s',
                '<info>--'.$option->getName().'</info>',
                $option->getShortcut() ? '<info>-'.$option->getShortcut().'</info>' : '  ',
                $option->getDescription()
            );
        }

        return implode("\n", $messages);
    }

    /**
     * Sets whether to catch exceptions or not during commands execution.
     *
     * @param Boolean $boolean Whether to catch exceptions or not during commands execution
     *
     * @api
     */
    public function setCatchExceptions($boolean)
    {
        $this->catchExceptions = (Boolean) $boolean;
    }

    /**
     * Sets whether to automatically exit after a command execution or not.
     *
     * @param Boolean $boolean Whether to automatically exit after a command execution or not
     *
     * @api
     */
    public function setAutoExit($boolean)
    {
        $this->autoExit = (Boolean) $boolean;
    }

    /**
     * Gets the name of the application.
     *
     * @return string The application name
     *
     * @api
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Sets the application name.
     *
     * @param string $name The application name
     *
     * @api
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * Gets the application version.
     *
     * @return string The application version
     *
     * @api
     */
    public function getVersion()
    {
        return $this->version;
    }

    /**
     * Sets the application version.
     *
     * @param string $version The application version
     *
     * @api
     */
    public function setVersion($version)
    {
        $this->version = $version;
    }

    /**
     * Returns the long version of the application.
     *
     * @return string The long application version
     *
     * @api
     */
    public function getLongVersion()
    {
        if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
            return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
        }

        return '<info>Console Tool</info>';
    }

    /**
     * Registers a new command.
     *
     * @param string $name The command name
     *
     * @return Command The newly created command
     *
     * @api
     */
    public function register($name)
    {
        return $this->add(new Command($name));
    }

    /**
     * Adds an array of command objects.
     *
     * @param Command[] $commands An array of commands
     *
     * @api
     */
    public function addCommands(array $commands)
    {
        foreach ($commands as $command) {
            $this->add($command);
        }
    }

    /**
     * Adds a command object.
     *
     * If a command with the same name already exists, it will be overridden.
     *
     * @param Command $command A Command object
     *
     * @return Command The registered command
     *
     * @api
     */
    public function add(Command $command)
    {
        $command->setApplication($this);

        $this->commands[$command->getName()] = $command;

        foreach ($command->getAliases() as $alias) {
            $this->commands[$alias] = $command;
        }

        return $command;
    }

    /**
     * Returns a registered command by name or alias.
     *
     * @param string $name The command name or alias
     *
     * @return Command A Command object
     *
     * @throws \InvalidArgumentException When command name given does not exist
     *
     * @api
     */
    public function get($name)
    {
        if (!isset($this->commands[$name])) {
            throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
        }

        $command = $this->commands[$name];

        if ($this->wantHelps) {
            $this->wantHelps = false;

            $helpCommand = $this->get('help');
            $helpCommand->setCommand($command);

            return $helpCommand;
        }

        return $command;
    }

    /**
     * Returns true if the command exists, false otherwise.
     *
     * @param string $name The command name or alias
     *
     * @return Boolean true if the command exists, false otherwise
     *
     * @api
     */
    public function has($name)
    {
        return isset($this->commands[$name]);
    }

    /**
     * Returns an array of all unique namespaces used by currently registered commands.
     *
     * It does not returns the global namespace which always exists.
     *
     * @return array An array of namespaces
     */
    public function getNamespaces()
    {
        $namespaces = array();
        foreach ($this->commands as $command) {
            $namespaces[] = $this->extractNamespace($command->getName());

            foreach ($command->getAliases() as $alias) {
                $namespaces[] = $this->extractNamespace($alias);
            }
        }

        return array_values(array_unique(array_filter($namespaces)));
    }

    /**
     * Finds a registered namespace by a name or an abbreviation.
     *
     * @param string $namespace A namespace or abbreviation to search for
     *
     * @return string A registered namespace
     *
     * @throws \InvalidArgumentException When namespace is incorrect or ambiguous
     */
    public function findNamespace($namespace)
    {
        $allNamespaces = array();
        foreach ($this->getNamespaces() as $n) {
            $allNamespaces[$n] = explode(':', $n);
        }

        $found = array();
        foreach (explode(':', $namespace) as $i => $part) {
            $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces)))));

            if (!isset($abbrevs[$part])) {
                throw new \InvalidArgumentException(sprintf('There are no commands defined in the "%s" namespace.', $namespace));
            }

            if (count($abbrevs[$part]) > 1) {
                throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$namespace])));
            }

            $found[] = $abbrevs[$part][0];
        }

        return implode(':', $found);
    }

    /**
     * Finds a command by name or alias.
     *
     * Contrary to get, this command tries to find the best
     * match if you give it an abbreviation of a name or alias.
     *
     * @param  string $name A command name or a command alias
     *
     * @return Command A Command instance
     *
     * @throws \InvalidArgumentException When command name is incorrect or ambiguous
     *
     * @api
     */
    public function find($name)
    {
        // namespace
        $namespace = '';
        $searchName = $name;
        if (false !== $pos = strrpos($name, ':')) {
            $namespace = $this->findNamespace(substr($name, 0, $pos));
            $searchName = $namespace.substr($name, $pos);
        }

        // name
        $commands = array();
        foreach ($this->commands as $command) {
            if ($this->extractNamespace($command->getName()) == $namespace) {
                $commands[] = $command->getName();
            }
        }

        $abbrevs = static::getAbbreviations(array_unique($commands));
        if (isset($abbrevs[$searchName]) && 1 == count($abbrevs[$searchName])) {
            return $this->get($abbrevs[$searchName][0]);
        }

        if (isset($abbrevs[$searchName]) && count($abbrevs[$searchName]) > 1) {
            $suggestions = $this->getAbbreviationSuggestions($abbrevs[$searchName]);

            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
        }

        // aliases
        $aliases = array();
        foreach ($this->commands as $command) {
            foreach ($command->getAliases() as $alias) {
                if ($this->extractNamespace($alias) == $namespace) {
                    $aliases[] = $alias;
                }
            }
        }

        $abbrevs = static::getAbbreviations(array_unique($aliases));
        if (!isset($abbrevs[$searchName])) {
            throw new \InvalidArgumentException(sprintf('Command "%s" is not defined.', $name));
        }

        if (count($abbrevs[$searchName]) > 1) {
            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($abbrevs[$searchName])));
        }

        return $this->get($abbrevs[$searchName][0]);
    }

    /**
     * Gets the commands (registered in the given namespace if provided).
     *
     * The array keys are the full names and the values the command instances.
     *
     * @param  string  $namespace A namespace name
     *
     * @return array An array of Command instances
     *
     * @api
     */
    public function all($namespace = null)
    {
        if (null === $namespace) {
            return $this->commands;
        }

        $commands = array();
        foreach ($this->commands as $name => $command) {
            if ($namespace === $this->extractNamespace($name)) {
                $commands[$name] = $command;
            }
        }

        return $commands;
    }

    /**
     * Returns an array of possible abbreviations given a set of names.
     *
     * @param array $names An array of names
     *
     * @return array An array of abbreviations
     */
    static public function getAbbreviations($names)
    {
        $abbrevs = array();
        foreach ($names as $name) {
            for ($len = strlen($name) - 1; $len > 0; --$len) {
                $abbrev = substr($name, 0, $len);
                if (!isset($abbrevs[$abbrev])) {
                    $abbrevs[$abbrev] = array($name);
                } else {
                    $abbrevs[$abbrev][] = $name;
                }
            }
        }

        // Non-abbreviations always get entered, even if they aren't unique
        foreach ($names as $name) {
            $abbrevs[$name] = array($name);
        }

        return $abbrevs;
    }

    /**
     * Returns a text representation of the Application.
     *
     * @param string $namespace An optional namespace name
     *
     * @return string A string representing the Application
     */
    public function asText($namespace = null)
    {
        $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;

        $messages = array($this->getHelp(), '');
        if ($namespace) {
            $messages[] = sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $namespace);
        } else {
            $messages[] = '<comment>Available commands:</comment>';
        }

        $width = 0;
        foreach ($commands as $command) {
            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
        }
        $width += 2;

        // add commands by namespace
        foreach ($this->sortCommands($commands) as $space => $commands) {
            if (!$namespace && '_global' !== $space) {
                $messages[] = '<comment>'.$space.'</comment>';
            }

            foreach ($commands as $name => $command) {
                $messages[] = sprintf("  <info>%-${width}s</info> %s", $name, $command->getDescription());
            }
        }

        return implode("\n", $messages);
    }

    /**
     * Returns an XML representation of the Application.
     *
     * @param string  $namespace An optional namespace name
     * @param Boolean $asDom     Whether to return a DOM or an XML string
     *
     * @return string|DOMDocument An XML string representing the Application
     */
    public function asXml($namespace = null, $asDom = false)
    {
        $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;

        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = true;
        $dom->appendChild($xml = $dom->createElement('symfony'));

        $xml->appendChild($commandsXML = $dom->createElement('commands'));

        if ($namespace) {
            $commandsXML->setAttribute('namespace', $namespace);
        } else {
            $namespacesXML = $dom->createElement('namespaces');
            $xml->appendChild($namespacesXML);
        }

        // add commands by namespace
        foreach ($this->sortCommands($commands) as $space => $commands) {
            if (!$namespace) {
                $namespaceArrayXML = $dom->createElement('namespace');
                $namespacesXML->appendChild($namespaceArrayXML);
                $namespaceArrayXML->setAttribute('id', $space);
            }

            foreach ($commands as $name => $command) {
                if ($name !== $command->getName()) {
                    continue;
                }

                if (!$namespace) {
                    $commandXML = $dom->createElement('command');
                    $namespaceArrayXML->appendChild($commandXML);
                    $commandXML->appendChild($dom->createTextNode($name));
                }

                $node = $command->asXml(true)->getElementsByTagName('command')->item(0);
                $node = $dom->importNode($node, true);

                $commandsXML->appendChild($node);
            }
        }

        return $asDom ? $dom : $dom->saveXml();
    }

    /**
     * Renders a catched exception.
     *
     * @param Exception       $e      An exception instance
     * @param OutputInterface $output An OutputInterface instance
     */
    public function renderException($e, $output)
    {
        $strlen = function ($string)
        {
            return function_exists('mb_strlen') ? mb_strlen($string, mb_detect_encoding($string)) : strlen($string);
        };

        do {
            $title = sprintf('  [%s]  ', get_class($e));
            $len = $strlen($title);
            $lines = array();
            foreach (explode("\n", $e->getMessage()) as $line) {
                $lines[] = sprintf('  %s  ', $line);
                $len = max($strlen($line) + 4, $len);
            }

            $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', $len - $strlen($title)));

            foreach ($lines as $line) {
                $messages[] = $line.str_repeat(' ', $len - $strlen($line));
            }

            $messages[] = str_repeat(' ', $len);

            $output->writeln("\n");
            foreach ($messages as $message) {
                $output->writeln('<error>'.$message.'</error>');
            }
            $output->writeln("\n");

            if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) {
                $output->writeln('<comment>Exception trace:</comment>');

                // exception related properties
                $trace = $e->getTrace();
                array_unshift($trace, array(
                    'function' => '',
                    'file'     => $e->getFile() != null ? $e->getFile() : 'n/a',
                    'line'     => $e->getLine() != null ? $e->getLine() : 'n/a',
                    'args'     => array(),
                ));

                for ($i = 0, $count = count($trace); $i < $count; $i++) {
                    $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
                    $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
                    $function = $trace[$i]['function'];
                    $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
                    $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';

                    $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
                }

                $output->writeln("\n");
            }
        } while ($e = $e->getPrevious());

        if (null !== $this->runningCommand) {
            $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
            $output->writeln("\n");
        }
    }

    /**
     * Gets the name of the command based on input.
     *
     * @param InputInterface $input The input interface
     *
     * @return string The command name
     */
    protected function getCommandName(InputInterface $input)
    {
        return $input->getFirstArgument('command');
    }

    /**
     * Sorts commands in alphabetical order.
     *
     * @param array $commands An associative array of commands to sort
     *
     * @return array A sorted array of commands
     */
    private function sortCommands($commands)
    {
        $namespacedCommands = array();
        foreach ($commands as $name => $command) {
            $key = $this->extractNamespace($name, 1);
            if (!$key) {
                $key = '_global';
            }

            $namespacedCommands[$key][$name] = $command;
        }
        ksort($namespacedCommands);

        foreach ($namespacedCommands as &$commands) {
            ksort($commands);
        }

        return $namespacedCommands;
    }

    /**
     * Returns abbreviated suggestions in string format.
     *
     * @param array $abbrevs Abbreviated suggestions to convert
     *
     * @return string A formatted string of abbreviated suggestions
     */
    private function getAbbreviationSuggestions($abbrevs)
    {
        return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
    }

    private function extractNamespace($name, $limit = null)
    {
        $parts = explode(':', $name);
        array_pop($parts);

        return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter interface for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 *
 * @api
 */
interface OutputFormatterInterface
{
    /**
     * Sets the decorated flag.
     *
     * @param Boolean $decorated Whether to decorated the messages or not
     *
     * @api
     */
    function setDecorated($decorated);

    /**
     * Gets the decorated flag.
     *
     * @return Boolean true if the output will decorate messages, false otherwise
     *
     * @api
     */
    function isDecorated();

    /**
     * Sets a new style.
     *
     * @param string                        $name  The style name
     * @param OutputFormatterStyleInterface $style The style instance
     *
     * @api
     */
    function setStyle($name, OutputFormatterStyleInterface $style);

    /**
     * Checks if output formatter has style with specified name.
     *
     * @param   string  $name
     *
     * @return  Boolean
     *
     * @api
     */
    function hasStyle($name);

    /**
     * Gets style options from style with specified name.
     *
     * @param   string  $name
     *
     * @return  OutputFormatterStyleInterface
     *
     * @api
     */
    function getStyle($name);

    /**
     * Formats a message according to the given styles.
     *
     * @param  string $message The message to style
     *
     * @return string The styled message
     *
     * @api
     */
    function format($message);
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter style interface for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 *
 * @api
 */
interface OutputFormatterStyleInterface
{
    /**
     * Sets style foreground color.
     *
     * @param   string  $color  color name
     *
     * @api
     */
    function setForeground($color = null);

    /**
     * Sets style background color.
     *
     * @param   string  $color  color name
     *
     * @api
     */
    function setBackground($color = null);

    /**
     * Sets some specific style option.
     *
     * @param   string  $option     option name
     *
     * @api
     */
    function setOption($option);

    /**
     * Unsets some specific style option.
     *
     * @param   string  $option     option name
     */
    function unsetOption($option);

    /**
     * Set multiple style options at once.
     *
     * @param   array   $options
     */
    function setOptions(array $options);

    /**
     * Applies the style to a given text.
     *
     * @param string $text The text to style
     *
     * @return string
     */
    function apply($text);
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter style class for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 *
 * @api
 */
class OutputFormatterStyle implements OutputFormatterStyleInterface
{
    static private $availableForegroundColors = array(
        'black'     => 30,
        'red'       => 31,
        'green'     => 32,
        'yellow'    => 33,
        'blue'      => 34,
        'magenta'   => 35,
        'cyan'      => 36,
        'white'     => 37
    );
    static private $availableBackgroundColors = array(
        'black'     => 40,
        'red'       => 41,
        'green'     => 42,
        'yellow'    => 43,
        'blue'      => 44,
        'magenta'   => 45,
        'cyan'      => 46,
        'white'     => 47
    );
    static private $availableOptions = array(
        'bold'          => 1,
        'underscore'    => 4,
        'blink'         => 5,
        'reverse'       => 7,
        'conceal'       => 8
    );

    private $foreground;
    private $background;
    private $options = array();

    /**
     * Initializes output formatter style.
     *
     * @param   string  $foreground     style foreground color name
     * @param   string  $background     style background color name
     * @param   array   $options        style options
     *
     * @api
     */
    public function __construct($foreground = null, $background = null, array $options = array())
    {
        if (null !== $foreground) {
            $this->setForeground($foreground);
        }
        if (null !== $background) {
            $this->setBackground($background);
        }
        if (count($options)) {
            $this->setOptions($options);
        }
    }

    /**
     * Sets style foreground color.
     *
     * @param   string  $color  color name
     *
     * @api
     */
    public function setForeground($color = null)
    {
        if (null === $color) {
            $this->foreground = null;

            return;
        }

        if (!isset(static::$availableForegroundColors[$color])) {
            throw new \InvalidArgumentException(sprintf(
                'Invalid foreground color specified: "%s". Expected one of (%s)',
                $color,
                implode(', ', array_keys(static::$availableForegroundColors))
            ));
        }

        $this->foreground = static::$availableForegroundColors[$color];
    }

    /**
     * Sets style background color.
     *
     * @param   string  $color  color name
     *
     * @api
     */
    public function setBackground($color = null)
    {
        if (null === $color) {
            $this->background = null;

            return;
        }

        if (!isset(static::$availableBackgroundColors[$color])) {
            throw new \InvalidArgumentException(sprintf(
                'Invalid background color specified: "%s". Expected one of (%s)',
                $color,
                implode(', ', array_keys(static::$availableBackgroundColors))
            ));
        }

        $this->background = static::$availableBackgroundColors[$color];
    }

    /**
     * Sets some specific style option.
     *
     * @param   string  $option     option name
     *
     * @api
     */
    public function setOption($option)
    {
        if (!isset(static::$availableOptions[$option])) {
            throw new \InvalidArgumentException(sprintf(
                'Invalid option specified: "%s". Expected one of (%s)',
                $option,
                implode(', ', array_keys(static::$availableOptions))
            ));
        }

        if (false === array_search(static::$availableOptions[$option], $this->options)) {
            $this->options[] = static::$availableOptions[$option];
        }
    }

    /**
     * Unsets some specific style option.
     *
     * @param   string  $option     option name
     */
    public function unsetOption($option)
    {
        if (!isset(static::$availableOptions[$option])) {
            throw new \InvalidArgumentException(sprintf(
                'Invalid option specified: "%s". Expected one of (%s)',
                $option,
                implode(', ', array_keys(static::$availableOptions))
            ));
        }

        $pos = array_search(static::$availableOptions[$option], $this->options);
        if (false !== $pos) {
            unset($this->options[$pos]);
        }
    }

    /**
     * Set multiple style options at once.
     *
     * @param   array   $options
     */
    public function setOptions(array $options)
    {
        $this->options = array();

        foreach ($options as $option) {
            $this->setOption($option);
        }
    }

    /**
     * Applies the style to a given text.
     *
     * @param string $text The text to style
     *
     * @return string
     */
    public function apply($text)
    {
        $codes = array();

        if (null !== $this->foreground) {
            $codes[] = $this->foreground;
        }
        if (null !== $this->background) {
            $codes[] = $this->background;
        }
        if (count($this->options)) {
            $codes = array_merge($codes, $this->options);
        }

        return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text);
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Formatter;

/**
 * Formatter class for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 *
 * @api
 */
class OutputFormatter implements OutputFormatterInterface
{
    private $decorated;
    private $styles = array();

    /**
     * Initializes console output formatter.
     *
     * @param   Boolean $decorated  Whether this formatter should actually decorate strings
     * @param   array   $styles     Array of "name => FormatterStyle" instance
     *
     * @api
     */
    public function __construct($decorated = null, array $styles = array())
    {
        $this->decorated = (Boolean) $decorated;

        $this->setStyle('error',    new OutputFormatterStyle('white', 'red'));
        $this->setStyle('info',     new OutputFormatterStyle('green'));
        $this->setStyle('comment',  new OutputFormatterStyle('yellow'));
        $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));

        foreach ($styles as $name => $style) {
            $this->setStyle($name, $style);
        }
    }

    /**
     * Sets the decorated flag.
     *
     * @param Boolean $decorated Whether to decorated the messages or not
     *
     * @api
     */
    public function setDecorated($decorated)
    {
        $this->decorated = (Boolean) $decorated;
    }

    /**
     * Gets the decorated flag.
     *
     * @return Boolean true if the output will decorate messages, false otherwise
     *
     * @api
     */
    public function isDecorated()
    {
        return $this->decorated;
    }

    /**
     * Sets a new style.
     *
     * @param string                        $name  The style name
     * @param OutputFormatterStyleInterface $style The style instance
     *
     * @api
     */
    public function setStyle($name, OutputFormatterStyleInterface $style)
    {
        $this->styles[strtolower($name)] = $style;
    }

    /**
     * Checks if output formatter has style with specified name.
     *
     * @param   string  $name
     *
     * @return  Boolean
     *
     * @api
     */
    public function hasStyle($name)
    {
        return isset($this->styles[strtolower($name)]);
    }

    /**
     * Gets style options from style with specified name.
     *
     * @param   string  $name
     *
     * @return  OutputFormatterStyleInterface
     *
     * @api
     */
    public function getStyle($name)
    {
        if (!$this->hasStyle($name)) {
            throw new \InvalidArgumentException('Undefined style: ' . $name);
        }

        return $this->styles[strtolower($name)];
    }

    /**
     * Formats a message according to the given styles.
     *
     * @param  string $message The message to style
     *
     * @return string The styled message
     *
     * @api
     */
    public function format($message)
    {
        return preg_replace_callback('#<([a-z][a-z0-9_=;-]+)>(.*?)</\\1?>#i', array($this, 'replaceStyle'), $message);
    }

    /**
     * Replaces style of the output.
     *
     * @param array $match
     *
     * @return string The replaced style
     */
    private function replaceStyle($match)
    {
        if (!$this->isDecorated()) {
            return $match[2];
        }

        if (isset($this->styles[strtolower($match[1])])) {
            $style = $this->styles[strtolower($match[1])];
        } else {
            $style = $this->createStyleFromString($match[1]);

            if (false === $style) {
                return $match[0];
            }
        }

        return $style->apply($this->format($match[2]));
    }

    /**
     * Tries to create new style instance from string.
     *
     * @param   string  $string
     *
     * @return  Symfony\Component\Console\Format\FormatterStyle|Boolean false if string is not format string
     */
    private function createStyleFromString($string)
    {
        if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
            return false;
        }

        $style = new OutputFormatterStyle();
        foreach ($matches as $match) {
            array_shift($match);

            if ('fg' == $match[0]) {
                $style->setForeground($match[1]);
            } elseif ('bg' == $match[0]) {
                $style->setBackground($match[1]);
            } else {
                $style->setOption($match[1]);
            }
        }

        return $style;
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * The Formatter class provides helpers to format messages.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FormatterHelper extends Helper
{
    /**
     * Formats a message within a section.
     *
     * @param string  $section The section name
     * @param string  $message The message
     * @param string  $style   The style to apply to the section
     */
    public function formatSection($section, $message, $style = 'info')
    {
        return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
    }

    /**
     * Formats a message as a block of text.
     *
     * @param string|array $messages The message to write in the block
     * @param string       $style    The style to apply to the whole block
     * @param Boolean      $large    Whether to return a large block
     *
     * @return string The formatter message
     */
    public function formatBlock($messages, $style, $large = false)
    {
        $messages = (array) $messages;

        $len = 0;
        $lines = array();
        foreach ($messages as $message) {
            $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
            $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
        }

        $messages = $large ? array(str_repeat(' ', $len)) : array();
        foreach ($lines as $line) {
            $messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
        }
        if ($large) {
            $messages[] = str_repeat(' ', $len);
        }

        foreach ($messages as &$message) {
            $message = sprintf('<%s>%s</%s>', $style, $message, $style);
        }

        return implode("\n", $messages);
    }

    /**
     * Returns the length of a string, uses mb_strlen if it is available.
     *
     * @param string $string The string to check its length
     *
     * @return integer The length of the string
     */
    private function strlen($string)
    {
        return function_exists('mb_strlen') ? mb_strlen($string, mb_detect_encoding($string)) : strlen($string);
    }

    /**
     * Returns the helper's canonical name
     *
     * @return string The canonical name of the helper
     */
    public function getName()
    {
        return 'formatter';
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\OutputInterface;

/**
 * The Dialog class provides helpers to interact with the user.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DialogHelper extends Helper
{
    /**
     * Asks a question to the user.
     *
     * @param OutputInterface $output
     * @param string|array    $question The question to ask
     * @param string          $default  The default answer if none is given by the user
     *
     * @return string The user answer
     */
    public function ask(OutputInterface $output, $question, $default = null)
    {
        // @codeCoverageIgnoreStart
        $output->write($question);

        $ret = trim(fgets(STDIN));

        return $ret ? $ret : $default;
        // @codeCoverageIgnoreEnd
    }

    /**
     * Asks a confirmation to the user.
     *
     * The question will be asked until the user answer by nothing, yes, or no.
     *
     * @param OutputInterface $output
     * @param string|array    $question The question to ask
     * @param Boolean         $default  The default answer if the user enters nothing
     *
     * @return Boolean true if the user has confirmed, false otherwise
     */
    public function askConfirmation(OutputInterface $output, $question, $default = true)
    {
        // @codeCoverageIgnoreStart
        $answer = 'z';
        while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
            $answer = $this->ask($output, $question);
        }

        if (false === $default) {
            return $answer && 'y' == strtolower($answer[0]);
        }

        return !$answer || 'y' == strtolower($answer[0]);
        // @codeCoverageIgnoreEnd
    }

    /**
     * Asks for a value and validates the response.
     *
     * The validator receives the data to validate. It must return the
     * validated data when the data is valid and throw an exception
     * otherwise.
     *
     * @param OutputInterface $output
     * @param string|array    $question
     * @param callback        $validator A PHP callback
     * @param integer         $attempts Max number of times to ask before giving up (false by default, which means infinite)
     * @param string          $default  The default answer if none is given by the user
     *
     * @return mixed
     *
     * @throws \Exception When any of the validator returns an error
     */
    public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null)
    {
        // @codeCoverageIgnoreStart
        $error = null;
        while (false === $attempts || $attempts--) {
            if (null !== $error) {
                $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
            }

            $value = $this->ask($output, $question, $default);

            try {
                return call_user_func($validator, $value);
            } catch (\Exception $error) {
            }
        }

        throw $error;
        // @codeCoverageIgnoreEnd
    }

    /**
     * Returns the helper's canonical name
     */
    public function getName()
    {
        return 'dialog';
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Command\Command;

/**
 * HelperSet represents a set of helpers to be used with a command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class HelperSet
{
    private $helpers;
    private $command;

    /**
     * @param Helper[] $helpers An array of helper.
     */
    public function __construct(array $helpers = array())
    {
        $this->helpers = array();
        foreach ($helpers as $alias => $helper) {
            $this->set($helper, is_int($alias) ? null : $alias);
        }
    }

    /**
     * Sets a helper.
     *
     * @param HelperInterface $helper The helper instance
     * @param string          $alias  An alias
     */
    public function set(HelperInterface $helper, $alias = null)
    {
        $this->helpers[$helper->getName()] = $helper;
        if (null !== $alias) {
            $this->helpers[$alias] = $helper;
        }

        $helper->setHelperSet($this);
    }

    /**
     * Returns true if the helper if defined.
     *
     * @param string  $name The helper name
     *
     * @return Boolean true if the helper is defined, false otherwise
     */
    public function has($name)
    {
        return isset($this->helpers[$name]);
    }

    /**
     * Gets a helper value.
     *
     * @param string $name The helper name
     *
     * @return HelperInterface The helper instance
     *
     * @throws \InvalidArgumentException if the helper is not defined
     */
    public function get($name)
    {
        if (!$this->has($name)) {
            throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
        }

        return $this->helpers[$name];
    }

    /**
     * Sets the command associated with this helper set.
     *
     * @param Command $command A Command instance
     */
    public function setCommand(Command $command = null)
    {
        $this->command = $command;
    }

    /**
     * Gets the command associated with this helper set.
     *
     * @return Command A Command instance
     */
    public function getCommand()
    {
        return $this->command;
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * HelperInterface is the interface all helpers must implement.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
interface HelperInterface
{
    /**
     * Sets the helper set associated with this helper.
     *
     * @param HelperSet $helperSet A HelperSet instance
     *
     * @api
     */
    function setHelperSet(HelperSet $helperSet = null);

    /**
     * Gets the helper set associated with this helper.
     *
     * @return HelperSet A HelperSet instance
     *
     * @api
     */
    function getHelperSet();

    /**
     * Returns the canonical name of this helper.
     *
     * @return string The canonical name
     *
     * @api
     */
    function getName();
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Helper;

/**
 * Helper is the base class for all helper classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Helper implements HelperInterface
{
    protected $helperSet = null;

    /**
     * Sets the helper set associated with this helper.
     *
     * @param HelperSet $helperSet A HelperSet instance
     */
    public function setHelperSet(HelperSet $helperSet = null)
    {
        $this->helperSet = $helperSet;
    }

    /**
     * Gets the helper set associated with this helper.
     *
     * @return HelperSet A HelperSet instance
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;

/**
 * Base class for output classes.
 *
 * There is three level of verbosity:
 *
 *  * normal: no option passed (normal output - information)
 *  * verbose: -v (more output - debug)
 *  * quiet: -q (no output)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
abstract class Output implements OutputInterface
{
    private $verbosity;
    private $formatter;

    /**
     * Constructor.
     *
     * @param integer                  $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE)
     * @param Boolean                  $decorated Whether to decorate messages or not (null for auto-guessing)
     * @param OutputFormatterInterface $formatter Output formatter instance
     *
     * @api
     */
    public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
    {
        if (null === $formatter) {
            $formatter = new OutputFormatter();
        }

        $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
        $this->formatter = $formatter;
        $this->formatter->setDecorated((Boolean) $decorated);
    }

    /**
     * Sets output formatter.
     *
     * @param OutputFormatterInterface $formatter
     *
     * @api
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        $this->formatter = $formatter;
    }

    /**
     * Returns current output formatter instance.
     *
     * @return  OutputFormatterInterface
     *
     * @api
     */
    public function getFormatter()
    {
        return $this->formatter;
    }

    /**
     * Sets the decorated flag.
     *
     * @param Boolean $decorated Whether to decorated the messages or not
     *
     * @api
     */
    public function setDecorated($decorated)
    {
        $this->formatter->setDecorated((Boolean) $decorated);
    }

    /**
     * Gets the decorated flag.
     *
     * @return Boolean true if the output will decorate messages, false otherwise
     *
     * @api
     */
    public function isDecorated()
    {
        return $this->formatter->isDecorated();
    }

    /**
     * Sets the verbosity of the output.
     *
     * @param integer $level The level of verbosity
     *
     * @api
     */
    public function setVerbosity($level)
    {
        $this->verbosity = (int) $level;
    }

    /**
     * Gets the current verbosity of the output.
     *
     * @return integer The current level of verbosity
     *
     * @api
     */
    public function getVerbosity()
    {
        return $this->verbosity;
    }

    /**
     * Writes a message to the output and adds a newline at the end.
     *
     * @param string|array $messages The message as an array of lines of a single string
     * @param integer      $type     The type of output
     *
     * @api
     */
    public function writeln($messages, $type = 0)
    {
        $this->write($messages, true, $type);
    }

    /**
     * Writes a message to the output.
     *
     * @param string|array $messages The message as an array of lines of a single string
     * @param Boolean      $newline  Whether to add a newline or not
     * @param integer      $type     The type of output
     *
     * @throws \InvalidArgumentException When unknown output type is given
     *
     * @api
     */
    public function write($messages, $newline = false, $type = 0)
    {
        if (self::VERBOSITY_QUIET === $this->verbosity) {
            return;
        }

        $messages = (array) $messages;

        foreach ($messages as $message) {
            switch ($type) {
                case OutputInterface::OUTPUT_NORMAL:
                    $message = $this->formatter->format($message);
                    break;
                case OutputInterface::OUTPUT_RAW:
                    break;
                case OutputInterface::OUTPUT_PLAIN:
                    $message = strip_tags($this->formatter->format($message));
                    break;
                default:
                    throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));
            }

            $this->doWrite($message, $newline);
        }
    }

    /**
     * Writes a message to the output.
     *
     * @param string  $message A message to write to the output
     * @param Boolean $newline Whether to add a newline or not
     */
    abstract public function doWrite($message, $newline);
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatter;

/**
 * ConsoleOutput is the default class for all CLI output. It uses STDOUT.
 *
 * This class is a convenient wrapper around `StreamOutput`.
 *
 *     $output = new ConsoleOutput();
 *
 * This is equivalent to:
 *
 *     $output = new StreamOutput(fopen('php://stdout', 'w'));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class ConsoleOutput extends StreamOutput
{
    /**
     * Constructor.
     *
     * @param integer         $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
     *                                   self::VERBOSITY_VERBOSE)
     * @param Boolean         $decorated Whether to decorate messages or not (null for auto-guessing)
     * @param OutputFormatter $formatter Output formatter instance
     *
     * @api
     */
    public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatter $formatter = null)
    {
        parent::__construct(fopen('php://stdout', 'w'), $verbosity, $decorated, $formatter);
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatter;

/**
 * StreamOutput writes the output to a given stream.
 *
 * Usage:
 *
 * $output = new StreamOutput(fopen('php://stdout', 'w'));
 *
 * As `StreamOutput` can use any stream, you can also use a file:
 *
 * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class StreamOutput extends Output
{
    private $stream;

    /**
     * Constructor.
     *
     * @param mixed           $stream    A stream resource
     * @param integer         $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
     *                                   self::VERBOSITY_VERBOSE)
     * @param Boolean         $decorated Whether to decorate messages or not (null for auto-guessing)
     * @param OutputFormatter $formatter Output formatter instance
     *
     * @throws \InvalidArgumentException When first argument is not a real stream
     *
     * @api
     */
    public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatter $formatter = null)
    {
        if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
            throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
        }

        $this->stream = $stream;

        if (null === $decorated) {
            $decorated = $this->hasColorSupport($decorated);
        }

        parent::__construct($verbosity, $decorated, $formatter);
    }

    /**
     * Gets the stream attached to this StreamOutput instance.
     *
     * @return resource A stream resource
     */
    public function getStream()
    {
        return $this->stream;
    }

    /**
     * Writes a message to the output.
     *
     * @param string  $message A message to write to the output
     * @param Boolean $newline Whether to add a newline or not
     *
     * @throws \RuntimeException When unable to write output (should never happen)
     */
    public function doWrite($message, $newline)
    {
        if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
            // @codeCoverageIgnoreStart
            // should never happen
            throw new \RuntimeException('Unable to write output.');
            // @codeCoverageIgnoreEnd
        }

        fflush($this->stream);
    }

    /**
     * Returns true if the stream supports colorization.
     *
     * Colorization is disabled if not supported by the stream:
     *
     *  -  windows without ansicon
     *  -  non tty consoles
     *
     * @return Boolean true if the stream supports colorization, false otherwise
     */
    protected function hasColorSupport()
    {
        // @codeCoverageIgnoreStart
        if (DIRECTORY_SEPARATOR == '\\') {
            return false !== getenv('ANSICON');
        }

        return function_exists('posix_isatty') && @posix_isatty($this->stream);
        // @codeCoverageIgnoreEnd
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

/**
 * NullOutput suppresses all output.
 *
 *     $output = new NullOutput();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class NullOutput extends Output
{
    /**
     * Writes a message to the output.
     *
     * @param string $message A message to write to the output
     * @param Boolean $newline Whether to add a newline or not
     */
    public function doWrite($message, $newline)
    {
    }
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;

/**
 * OutputInterface is the interface implemented by all Output classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
interface OutputInterface
{
    const VERBOSITY_QUIET   = 0;
    const VERBOSITY_NORMAL  = 1;
    const VERBOSITY_VERBOSE = 2;

    const OUTPUT_NORMAL = 0;
    const OUTPUT_RAW = 1;
    const OUTPUT_PLAIN = 2;

    /**
     * Writes a message to the output.
     *
     * @param string|array $messages The message as an array of lines of a single string
     * @param Boolean      $newline  Whether to add a newline or not
     * @param integer      $type     The type of output
     *
     * @throws \InvalidArgumentException When unknown output type is given
     *
     * @api
     */
    function write($messages, $newline = false, $type = 0);

    /**
     * Writes a message to the output and adds a newline at the end.
     *
     * @param string|array $messages The message as an array of lines of a single string
     * @param integer      $type     The type of output
     *
     * @api
     */
    function writeln($messages, $type = 0);

    /**
     * Sets the verbosity of the output.
     *
     * @param integer $level The level of verbosity
     *
     * @api
     */
    function setVerbosity($level);

    /**
     * Gets the current verbosity of the output.
     *
     * @return integer The current level of verbosity
     */
    function getVerbosity();

    /**
     * Sets the decorated flag.
     *
     * @param Boolean $decorated Whether to decorated the messages or not
     *
     * @api
     */
    function setDecorated($decorated);

    /**
     * Gets the decorated flag.
     *
     * @return Boolean true if the output will decorate messages, false otherwise
     *
     * @api
     */
    function isDecorated();

    /**
     * Sets output formatter.
     *
     * @param OutputFormatterInterface $formatter
     *
     * @api
     */
    function setFormatter(OutputFormatterInterface $formatter);

    /**
     * Returns current output formatter instance.
     *
     * @return  OutputFormatterInterface
     *
     * @api
     */
    function getFormatter();
}


text:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Input;

/**
 * InputInterface is the interface implemented by all input classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface InputInterface
{
    /**
     * Returns the first argument from the raw parameters (not parsed).
     *
     * @return string The value of the first argument or null otherwise
     */
    function getFirstArgument();

    /**
     * Returns true if the raw parameters (not parsed) contains a value.
     *
     * This method is to be used to introspect the input parameters
     * before it has been validated. It must be used carefully.
     *
     * @param string|array $values The values to look for in the raw parameters (can be an array)
     *
     * @return Boolean true if the value is contained in the raw parameters
     */
    function hasParameterOption($values);

    /**
     * Returns the value of a raw option (not parsed).
     *
     * This method is to be used to introspect the input parameters
     * before it has been validated. It must be used carefully.
     *
     * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
     * @param mixed $default The default value to return if no result is found
     *
     * @return mixed The option value
     */
    function getParameterOption($values, $default = false);

    /**
     * Binds the current Input instance with the given arguments and options.
     *
     * @param InputDefinition $definition A InputDefinition instance
     */
    function bind(InputDefinition $definition);

    /**
     * Validate if arguments given are correct.
     *
     * Throws an exception when not enough arguments are given.
     *
     * @throws \RuntimeException
     */
    function validate();

    /**
     * Returns all the given arguments merged with the default values.
     *
     * @return array
     */
    function getArguments();

    /**
     * Get argument by name.
     *
     * @param string $name The name of the argument
     * @return mixed
     */
    function getArgument($name);

    /**
     * @return array
     */
    function getOptions();

    /**
     * Get an option by name.
     *
     * @param string $name The name of the option
     * @return mixed
     */
    function getOption($name);

    /**
     * Is this input means interactive?
     *
     * @return Boolean
     */
    function isInteractive();
}