phing-2.16.0/LICENSE0000644000175000017500000001672713027032674012733 0ustar druiddruid GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. phing-2.16.0/TaskContainer.php0000644000175000017500000000272413027032674015174 0ustar druiddruid. */ /** * Abstract interface for objects which can contain tasks (targets) * Used to check if a class can contain tasks (via instanceof) * * @author Andreas Aderhold * @copyright 2001,2002 THYRELL. All rights reserved * * @package phing */ interface TaskContainer { /** * Adds a task to this task container. Must be implemented * by derived class * * @param Task $task The task to be added to the container. */ public function addTask(Task $task); } phing-2.16.0/tasks/ext/SassTask.php0000644000175000017500000007542713027032674016122 0ustar druiddruid. * * @category Tasks * @package phing.tasks.ext * @author Paul Stuart * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) */ /** * Pull in Task class. */ require_once 'phing/Task.php'; /** * Executes Sass for a particular fileset. * * If the sass executable is not available, but scssphp is, then use that instead. * * @category Tasks * @package phing.tasks.ext * @author Paul Stuart * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @version Release: $Id: eb75e99660cf6fe49f68fe568e00aca4a193e31a $ * @link SassTask.php */ class SassTask extends Task { /** * Style to generate to. * * @var string */ protected $style = 'nested'; /** * Stack trace on error. * * @var bool */ protected $trace = false; /** * Unix-style newlines? * * @var bool */ protected $unixnewlines = true; /** * Encoding * * @var string */ protected $encoding = 'utf-8'; /** * SASS import path. * * @var string */ protected $loadPath = ''; /** * Whether to just check syntax * * @var bool */ protected $check = false; /** * Whether to use the sass command line tool. * * @var bool */ protected $useSass = true; /** * Whether to use the scssphp compiler, if available. * * @var bool */ protected $useScssphp = true; /** * Input filename if only processing one file is required. * * @var string|null */ protected $file = null; /** * Output filename * * @var string|null */ protected $output = null; /** * Scssphp compiler * * @var object */ protected $scssCompiler = null; /** * Contains the path info of our file to allow us to parse. * * @var array */ protected $pathInfo = null; /** * The Sass executable. * * @var string */ protected $executable = 'sass'; /** * The ext type we are looking for when Verifyext is set to true. * * More than likely should be "scss" or "sass". * * @var string */ protected $extfilter = ''; /** * This flag means 'note errors to the output, but keep going' * * @var bool */ protected $failonerror = true; /** * The fileset we will be running Sass on. * * @var array */ protected $filesets = array(); /** * Additional flags to pass to sass. * * @var string */ protected $flags = ''; /** * Indicates if we want to keep the directory structure of the files. * * @var bool */ protected $keepsubdirectories = true; /** * When true we will remove the current file ext. * * @var bool */ protected $removeoldext = true; /** * The new ext our files will have. * * @var string */ protected $newext = 'css'; /** * The path to send our output files to. * * If not defined they will be created in the same directory the * input is from. * * @var string */ protected $outputpath = ''; /** * Set input file (For example style.scss) * * Synonym for @see setFile * * @param string $file Filename * * @return void */ public function setInput($file) { $this->setFile($file); } /** * Set name of output file. * * @param string $file Filename of [css] to output. * * @return void */ public function setOutput($file) { $this->output = $file; } /** * Sets the failonerror flag. Default: true * * @param string $failonerror Jenkins style boolean value * * @access public * @return void */ public function setFailonerror($failonerror) { $this->failonerror = StringHelper::booleanValue($failonerror); } /** * Sets the executable to use for sass. Default: sass * * The default assumes sass is in your path. If not you can provide the full * path to sass. * * @param string $executable Name/path of sass executable * * @access public * @return void */ public function setExecutable($executable) { $this->executable = $executable; } /** * Return name/path of sass executable. * * @return string */ public function getExecutable() { return $this->executable; } /** * Sets the extfilter. Default: * * This will filter the fileset to only process files that match * this extension. This could also be done with the fileset. * * @param string $extfilter Extension to filter for. * * @access public * @return void */ public function setExtfilter($extfilter) { $this->extfilter = trim($extfilter, ' .'); } /** * Return extfilter setting. * * @return string */ public function getExtfilter() { return $this->extfilter; } /** * Additional flags to pass to sass. * * Command will be: * sass {$flags} {$inputfile} {$outputfile} * * @param string $flags List of flags accepted by sass. * * @access public * @return void */ public function setFlags($flags) { $this->flags = trim($flags); } /** * Return flags to be used when running the sass executable. * * @return string */ public function getFlags() { return trim($this->flags); } /** * Sets the removeoldext flag. Default: true * * This will cause us to strip the existing extension off the output * file. * * @param string $removeoldext Jenkins style boolean value * * @access public * @return void */ public function setRemoveoldext($removeoldext) { $this->removeoldext = StringHelper::booleanValue($removeoldext); } /** * Return removeoldext value (true/false) * * @return bool */ public function getRemoveoldext() { return $this->removeoldext; } /** * Set default encoding * * @param string $encoding Default encoding to use. * * @return void */ public function setEncoding($encoding) { $encoding = trim($encoding); if ($encoding !== '') { $this->flags .= " --default-encoding $encoding"; } else { $this->flags = str_replace( ' --default-encoding ' . $this->encoding, '', $this->flags ); } $this->encoding = $encoding; } /** * Return the output encoding. * * @return string */ public function getEncoding() { return $this->encoding; } /** * Sets the newext value. Default: css * * This is the extension we will add on to the output file regardless * of if we remove the old one or not. * * @param string $newext New extension to use, e.g. css * * @access public * @return void */ public function setNewext($newext) { $this->newext = trim($newext, ' .'); } /** * Return extension added to output files. * * @return string */ public function getNewext() { return $this->newext; } /** * Sets the outputpath value. Default: * * This will force the output path to be something other than * the path of the fileset used. * * @param string $outputpath Path name * * @access public * @return void */ public function setOutputpath($outputpath) { $this->outputpath = rtrim(trim($outputpath), DIRECTORY_SEPARATOR); } /** * Return the outputpath value. * * @return string */ public function getOutputpath() { return $this->outputpath; } /** * Sets the keepsubdirectories value. Default: true * * When set to true we will keep the directory structure. So any input * files in subdirectories will have their output file in that same * sub-directory. If false, all output files will be put in the path * defined by outputpath or in the directory top directory of the fileset. * * @param bool $keepsubdirectories Jenkins style boolean * * @access public * @return void */ public function setKeepsubdirectories($keepsubdirectories) { $this->keepsubdirectories = StringHelper::booleanValue($keepsubdirectories); } /** * Return keepsubdirectories value. * * @return bool */ public function getKeepsubdirectories() { return $this->keepsubdirectories; } /** * Nested creator, creates a FileSet for this task * * @return FileSet The created fileset object */ public function createFileSet() { $num = array_push($this->filesets, new FileSet()); return $this->filesets[$num - 1]; } /** * Whether to just check syntax. * * @param string $value Jenkins style boolean value * * @return void */ public function setCheck($value) { $check = StringHelper::booleanValue($value); $this->check = $check; if ($check) { $this->flags .= ' --check '; } else { $this->flags = str_replace(' --check ', '', $this->flags); } } /** * Indicate if just a syntax check is required. * * @return boolean */ public function getCheck() { return $this->check; } /** * Set style to compact * * @param string $value Jenkins style boolean value * * @return void */ public function setCompact($value) { $compress = StringHelper::booleanValue($value); if ($compress) { $this->flags = str_replace(' --style ' . $this->style, '', $this->flags); $this->flags .= ' --style compact'; $this->style = 'compact'; } } /** * Indicate whether style is set to 'coompact'. * * @return bool * @see setCompact */ public function getCompact() { return $this->style === 'compact'; } /** * Set style to compressed * * @param string $value Jenkins style boolean value * * @return void */ public function setCompressed($value) { $compress = StringHelper::booleanValue($value); if ($compress) { $this->flags = str_replace(' --style ' . $this->style, '', $this->flags); $this->flags .= ' --style compressed'; $this->style = 'compressed'; } } /** * Indicate whether style is set to 'compressed'. * * @return bool * @see setCompressed */ public function getCompressed() { return $this->style === 'compressed'; } /** * Set style to crunched. Supported by scssphp only. * * @param string $value Jenkins style boolean value * * @return void */ public function setCrunched($value) { $compress = StringHelper::booleanValue($value); if ($compress) { $this->style = 'crunched'; } } /** * Indicate whether style is set to 'crunched'. * * @return bool * @see setCrunched */ public function getCrunched() { return $this->style === 'crunched'; } /** * Set style to expanded * * @param string $value Jenkins style boolean value * * @return void */ public function setExpand($value) { $expand = StringHelper::booleanValue($value); if ($expand) { $this->flags = str_replace(' --style ' . $this->style, '', $this->flags); $this->flags .= ' --style expanded'; $this->style = 'expanded'; } } /** * Indicate whether style is set to 'expanded'. * * @return bool * @see setExpand */ public function getExpand() { return $this->style === 'expanded'; } /** * Set style to nested * * @param string $value Jenkins style boolean value * * @return void */ public function setNested($value) { $nested = StringHelper::booleanValue($value); if ($nested) { $this->flags = str_replace(' --style ' . $this->style, '', $this->flags); $this->flags .= ' --style nested'; $this->style = 'nested'; } } /** * Indicate whether style is set to 'nested'. * * @return bool * @see setNested */ public function getNested() { return $this->style === 'nested'; } /** * Whether to force recompiled when --update is used. * * @param string $value Jenkins style boolean value * * @return void */ public function setForce($value) { $force = StringHelper::booleanValue($value); $this->force = $force; if ($force) { $this->flags .= ' --force '; } else { $this->flags = str_replace(' --force ', '', $this->flags); } } /** * Return force value. * * @return bool */ public function getForce() { return $this->force; } /** * Whether to cache parsed sass files. * * @param string $value Jenkins style boolean value * * @return void */ public function setNoCache($value) { $noCache = StringHelper::booleanValue($value); $this->noCache = $noCache; if ($noCache) { $this->flags .= ' --no-cache '; } else { $this->flags = str_replace(' --no-cache ', '', $this->flags); } } /** * Return noCache value. * * @return bool */ public function getNoCache() { return $this->noCache; } /** * Specify SASS import path * * @param string $path Import path. * * @return void */ public function setPath($path) { $this->flags .= "--load-path $path"; $this->loadPath = $path; } /** * Return the SASS import path. * * @return string */ public function getPath() { return $this->loadPath; } /** * Set output style. * * @param mixed $style Style. * * @return void */ public function setStyle($style) { $style = strtolower($style); switch($style) { case 'nested': case 'compact': case 'compressed': case 'expanded': case 'crunched': $this->flags = str_replace(" --style $this->style", '', $this->flags); $this->style = $style; $this->flags .= " --style $style"; break; default: $this->log("Style $style ignored", Project::MSG_INFO); } } /** * Return style used for generating output. * * @return string */ public function getStyle() { return $this->style; } /** * Set trace option. * * IE: Whether to output a stack trace on error. * * @param string $trace Jenkins style boolean value * * @return void */ public function setTrace($trace) { $this->trace = StringHelper::booleanValue($trace); if ($this->trace) { $this->flags .= ' --trace '; } else { $this->flags = str_replace(' --trace ', '', $this->flags); } } /** * Return trace option. * * @return bool */ public function getTrace() { return $this->trace; } /** * Whether to use unix-style newlines. * * @param string $newlines Jenkins style boolean value * * @return void */ public function setUnixnewlines($newlines) { $unixnewlines = StringHelper::booleanValue($newlines); $this->unixnewlines = $unixnewlines; if ($unixnewlines) { $this->flags .= ' --unix-newlines '; } else { $this->flags = str_replace(' --unix-newlines ', '', $this->flags); } } /** * Return unix-newlines setting * * @return bool */ public function getUnixnewlines() { return $this->unixnewlines; } /** * Whether to identify source-file and line number for generated CSS. * * @param string $lineNumbers Jenkins style boolean value * * @return void */ public function setLineNumbers($lineNumbers) { $lineNumbers = StringHelper::booleanValue($lineNumbers); $this->lineNumbers = $lineNumbers; if ($lineNumbers) { $this->flags .= ' --line-numbers '; } else { $this->flags = str_replace(' --line-numbers ', '', $this->flags); } } /** * Return line-numbers setting. * * @return bool */ public function getLineNumbers() { return $this->lineNumbers; } /** * Whether to use the 'sass' command line tool. * * @param string $value Jenkins style boolean value. * * @return void * @link http://sass-lang.com/install */ public function setUseSass($value) { $this->useSass = StringHelper::booleanValue($value); } /** * Whether to use the scssphp compiler. * * @param string $value Jenkins style boolean value. * * @return void * @link http://leafo.github.io/scssphp/ */ public function setUseScssphp($value) { $this->useScssphp = StringHelper::booleanValue($value); if (version_compare(PHP_VERSION, '5.2', '<=')) { $this->useScssphp = false; $this->log( "SCSSPHP is incompatible with this version of PHP", Project::MSG_INFO ); } } /** * Set single filename to compile from scss to css. * * @param string $file Single filename to compile. * * @return void */ public function setFile($file) { $this->file = $file; } /** * Init: pull in the PEAR System class * * @access public * @return void */ public function init() { @include_once 'System.php'; if (!class_exists('System')) { throw new BuildException("You must have installed PEAR in order to use SassTask."); } @include_once 'vendor/autoload.php'; if (version_compare(PHP_VERSION, '5.2', '<=')) { $this->useScssphp = false; $this->log( "SCSSPHP is incompatible with this version of PHP", Project::MSG_INFO ); } } /** * Our main execution of the task. * * @throws BuildException * @throws Exception * * @access public * @return void */ public function main() { if ($this->useSass) { if (strlen($this->executable) < 0) { throw new BuildException("'executable' must be defined."); } } if (empty($this->filesets) && $this->file === null) { throw new BuildException( "Missing either a nested fileset or attribute 'file'" ); } // If both are set to be used, prefer sass over scssphp. $lUseScssphp = false; if ($this->useSass && $this->useScssphp) { if (System::which($this->executable) === false) { if ($this->loadScssphp() === false) { $msg = sprintf( "%s not found. Install sass or leafo scssphp.", $this->executable ); if ($this->failonerror) { throw new BuildException($msg); } else { $this->log($msg, Project::MSG_ERR); return; } } else { $lUseScssphp = true; $this->scssCompiler = $this->initialiseScssphp(); } } } elseif (!$this->useSass && !$this->useScssphp) { $this->log( "Neither sass nor scssphp are to be used.", Project::MSG_ERR ); return; } elseif ($this->useSass) { if (System::which($this->executable) === false) { $msg = sprintf( "%s not found. Install sass.", $this->executable ); if ($this->failonerror) { throw new BuildException($msg); } else { $this->log($msg, Project::MSG_ERR); return; } } } elseif ($this->useScssphp) { if ($this->loadScssphp() === false) { $msg = sprintf( "Install leafo scssphp." ); if ($this->failonerror) { throw new BuildException($msg); } else { $this->log($msg, Project::MSG_ERR); return; } } else { $lUseScssphp = true; $this->scssCompiler = $this->initialiseScssphp(); } } if (count($this->filesets) > 0) { $this->processFilesets($lUseScssphp); } elseif ($this->file !== null) { $this->processFile($lUseScssphp); } } /** * Compile a specified file. * * If output file is not specified, but outputpath is, place output in * that directory. If neither is specified, place .css file in the * directory that the input file is in. * * @param boolean $useScssphp Whether to use the scssphp compiler. * * @return void */ public function processFile($useScssphp) { $this->log("Process file", Project::MSG_INFO); if (is_null($this->output)) { $specifiedOutputPath = (strlen($this->outputpath) > 0); if ($specifiedOutputPath === false) { $info = pathinfo($this->file); $path = $info['dirname']; $this->outputpath = $path; } else { $path = $this->outputpath; } $output = $path . DIRECTORY_SEPARATOR . $info['filename']; if (!$this->removeoldext) { $output .= '.' . $this->pathInfo['extension']; } if (strlen($this->newext) > 0) { $output .= '.' . $this->newext; } $this->output = $output; } else { $output = $this->output; } $this->compile($this->file, $output, $useScssphp); } /** * Process filesets - compiling/generating css files as required. * * @param boolean $useScssphp Whether to use the scssphp compiler. * * @return void */ public function processFilesets($useScssphp) { foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $files = $ds->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath(); // If output path isn't defined then set it to the path of our fileset. $specifiedOutputPath = (strlen($this->outputpath) > 0); if ($specifiedOutputPath === false) { $this->outputpath = $dir; } foreach ($files as $file) { $fullFilePath = $dir . DIRECTORY_SEPARATOR . $file; $this->pathInfo = pathinfo($file); $run = true; switch(strtolower($this->pathInfo['extension'])) { case 'scss': case 'sass': break; default: $this->log('Ignoring ' . $file, Project::MSG_DEBUG); $run = false; } if ($run && ($this->extfilter === '' || $this->extfilter === $this->pathInfo['extension']) ) { $outputFile = $this->buildOutputFilePath(); $this->compile($fullFilePath, $outputFile, $useScssphp); } } } } /** * Compile * * @param string $fullFilePath Fully qualified filename to compile. * @param string $outputFile Filename for generated css. * @param boolean $lUseScssphp Whether to use scssphp compiler. * * @return void */ public function compile($fullFilePath, $outputFile, $lUseScssphp) { $output = null; if (!$lUseScssphp) { try { $output = $this->executeCommand( $fullFilePath, $outputFile ); if ($this->failonerror && $output[0] !== 0) { throw new BuildException( "Result returned as not 0. Result: {$output[0]}", Project::MSG_INFO ); } } catch (Exception $e) { if ($this->failonerror) { throw $e; } else { $this->log( "Result: {$output[0]}", Project::MSG_INFO ); } } } else { $this->log( sprintf("Compiling '%s' via scssphp", $fullFilePath), Project::MSG_INFO ); $input = file_get_contents($fullFilePath); try { $out = $this->scssCompiler->compile($input, $fullFilePath); if ($out !== '') { $success = file_put_contents($outputFile, $out); if ($success) { $this->log( sprintf( "'%s' compiled and written to '%s'", $fullFilePath, $outputFile ), Project::MSG_VERBOSE ); } } else { $this->log('Compilation resulted in empty string'); } } catch (Exception $ex) { if ($this->failonerror) { throw new BuildException($ex->getMessage()); } else { $this->log($ex->getMessage(), Project::MSG_ERR); } } } } /** * Builds the full path to the output file based on our settings. * * @return string * * @access protected */ protected function buildOutputFilePath() { $outputFile = $this->outputpath.DIRECTORY_SEPARATOR; $subpath = trim($this->pathInfo['dirname'], ' .'); if ($this->keepsubdirectories === true && strlen($subpath) > 0) { $outputFile .= $subpath . DIRECTORY_SEPARATOR; } $outputFile .= $this->pathInfo['filename']; if (!$this->removeoldext) { $outputFile .= '.' . $this->pathInfo['extension']; } if (strlen($this->newext) > 0) { $outputFile .= '.' . $this->newext; } return $outputFile; } /** * Executes the command and returns return code and output. * * @param string $inputFile Input file * @param string $outputFile Output file * * @access protected * @throws BuildException * @return array array(return code, array with output) */ protected function executeCommand($inputFile, $outputFile) { // Prevent over-writing existing file. if ($inputFile == $outputFile) { throw new BuildException('Input file and output file are the same!'); } $output = array(); $return = null; $fullCommand = $this->executable; if (strlen($this->flags) > 0) { $fullCommand .= " {$this->flags}"; } $fullCommand .= " {$inputFile} {$outputFile}"; $this->log("Executing: {$fullCommand}", Project::MSG_INFO); exec($fullCommand, $output, $return); return array($return, $output); } /** * Pull in scssphp package, return true if successful. * * @return bool */ public function loadScssphp() { $success = @include_once "vendor/leafo/scssphp/scss.inc.php"; if ($success === false) { $success = @include_once "scssphp/scss.inc.php"; } return $success; } /** * Get ScssPhp Compiler. * * @return Leafo\ScssPhp\Compiler */ public function getNewCompiler() { // Instantiate the class in a way that is compatible with // PHP 5.2 up to 7.x. $compiler = '\\Leafo\\ScssPhp\\Compiler'; return new $compiler; } /** * Initialise and return an instance of the ScssPhp Compiler. * * @return Leafo\ScssPhp\Compiler */ public function initialiseScssphp() { $scss = $this->getNewCompiler(); if ($this->style) { $ucStyle = ucfirst(strtolower($this->style)); $scss->setFormatter('Leafo\\ScssPhp\\Formatter\\' . $ucStyle); } if ($this->encoding) { $scss->setEncoding($this->encoding); } if ($this->lineNumbers) { $scss->setLineNumberStyle(1); } if ($this->loadPath !== '') { $scss->setImportPaths(explode(PATH_SEPARATOR, $this->loadPath)); } return $scss; } } phing-2.16.0/tasks/ext/apigen/ApiGenTask.php0000644000175000017500000002560513027032674017610 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * ApiGen task (http://apigen.org). * * @package phing.tasks.ext.apigen * @author Martin Srank * @author Jaroslav Hanslík * @author Lukáš Homza * @since 2.4.10 */ class ApiGenTask extends Task { /** * Default ApiGen executable name. * * @var string */ private $executable = 'apigen'; /** * Default ApiGen action. * * @var string */ private $action = 'generate'; /** * Default ApiGen options. * * @var string */ private $options = array(); /** * Sets the ApiGen executable name. * * @param string $executable */ public function setExecutable($executable) { $this->executable = (string) $executable; } /** * Sets the ApiGen action to be executed. * * @param string $action */ public function setAction($action) { $this->action = (string) $action; } /** * Sets the config file name. * * @param string $config */ public function setConfig($config) { $this->options['config'] = (string) $config; } /** * Sets source files or directories. * * @param string $source */ public function setSource($source) { $this->options['source'] = explode(',', $source); } /** * Sets the destination directory. * * @param string $destination */ public function setDestination($destination) { $this->options['destination'] = (string) $destination; } /** * Sets list of allowed file extensions. * * @param string $extensions */ public function setExtensions($extensions) { $this->options['extensions'] = explode(',', $extensions); } /** * Sets masks (case sensitive) to exclude files or directories from processing. * * @param string $exclude */ public function setExclude($exclude) { $this->options['exclude'] = explode(',', $exclude); } /** * Sets masks to exclude elements from documentation generating. * * @param string $skipDocPath */ public function setSkipDocPath($skipDocPath) { $this->options['skip-doc-path'] = explode(',', $skipDocPath); } /** * Sets the character set of source files. * * @param string $charset */ public function setCharset($charset) { $this->options['charset'] = explode(',', $charset); } /** * Sets the main project name prefix. * * @param string $main */ public function setMain($main) { $this->options['main'] = (string) $main; } /** * Sets the title of generated documentation. * * @param string $title */ public function setTitle($title) { $this->options['title'] = (string) $title; } /** * Sets the documentation base URL. * * @param string $baseUrl */ public function setBaseUrl($baseUrl) { $this->options['base-url'] = (string) $baseUrl; } /** * Sets the Google Custom Search ID. * * @param string $googleCseId */ public function setGoogleCseId($googleCseId) { $this->options['google-cse-id'] = (string) $googleCseId; } /** * Sets the Google Custom Search label. * * @param string $googleCseLabel */ public function setGoogleCseLabel($googleCseLabel) { $this->options['google-cse-label'] = (string) $googleCseLabel; } /** * Sets the Google Analytics tracking code. * * @param string $googleAnalytics */ public function setGoogleAnalytics($googleAnalytics) { $this->options['google-analytics'] = (string) $googleAnalytics; } /** * Sets the template config file name. * * @param string $templateConfig */ public function setTemplateConfig($templateConfig) { $this->options['template-config'] = (string) $templateConfig; } /** * Sets the template config file name. * * @param string $templateTheme */ public function setTemplateTheme($templateTheme) { $this->options['template-theme'] = (string) $templateTheme; } /** * Sets how elements should be grouped in the menu. * * @param string $groups */ public function setGroups($groups) { $this->options['groups'] = (string) $groups; } /** * Sets the element access levels. * * Documentation only for methods and properties with the given access level will be generated. * * @param string $accessLevels */ public function setAccessLevels($accessLevels) { $this->options['access-levels'] = (string) $accessLevels; } /** * Sets the element access levels. * * Documentation only for methods and properties with the given access level will be generated. * * @param string $annotationGroups */ public function setAnnotationGroups($annotationGroups) { $this->options['annotation-groups'] = (string) $annotationGroups; } /** * Sets if documentation for elements marked as internal and internal documentation parts should be generated. * * @param boolean $internal */ public function setInternal($internal) { if((bool) $internal) { $this->options['internal'] = null; } } /** * Sets if documentation for PHP internal classes should be generated. * * @param boolean $php */ public function setPhp($php) { if((bool) $php) { $this->options['php'] = null; } } /** * Sets if tree view of classes, interfaces, traits and exceptions should be generated. * * @param boolean $tree */ public function setTree($tree) { if((bool) $tree) { $this->options['tree'] = null; } } /** * Sets if documentation for deprecated elements should be generated. * * @param boolean $deprecated */ public function setDeprecated($deprecated) { if((bool) $deprecated) { $this->options['deprecated'] = null; } } /** * Sets if documentation of tasks should be generated. * * @param boolean $todo */ public function setTodo($todo) { if((bool) $todo) { $this->options['todo'] = null; } } /** * Sets if highlighted source code files should be generated. * * @param boolean $noSourceCode */ public function setSourceCode($noSourceCode) { if(!((bool) $noSourceCode)) { $this->options['no-source-code'] = null; } } /** * Sets if highlighted source code files should not be generated. * * @deprecated * @param boolean $noSourceCode */ public function setNoSourceCode($noSourceCode) { $this->setSourceCode(!$noSourceCode); } /** * Sets if a link to download documentation as a ZIP archive should be generated. * * @param boolean $download */ public function setDownload($download) { if((bool) $download) { $this->options['download'] = null; } } /** * Enables/disables the debug mode. * * @param boolean $debug */ public function setDebug($debug) { if((bool) $debug) { $this->options['debug'] = null; } } /** * Runs ApiGen. * * @throws BuildException If something is wrong. * @see Task::main() */ public function main() { if ('apigen' !== $this->executable && !is_file($this->executable)) { throw new BuildException(sprintf('Executable %s not found', $this->executable), $this->getLocation()); } if (!empty($this->options['config'])) { // Config check if (!is_file($this->options['config'])) { throw new BuildException(sprintf( 'Config file %s doesn\'t exist', $this->options['config'] ), $this->getLocation()); } } else { // Source check if (empty($this->options['source'])) { throw new BuildException('Source is not set', $this->getLocation()); } // Destination check if (empty($this->options['destination'])) { throw new BuildException('Destination is not set', $this->getLocation()); } } // Source check if (!empty($this->options['source'])) { foreach ($this->options['source'] as $source) { if (!file_exists($source)) { throw new BuildException(sprintf('Source %s doesn\'t exist', $source), $this->getLocation()); } } } // Execute ApiGen exec(escapeshellcmd($this->executable) . ' ' . escapeshellcmd($this->action) . ' ' . $this->constructArguments(), $output, $return); $logType = 0 === $return ? Project::MSG_INFO : Project::MSG_ERR; foreach ($output as $line) { $this->log($line, $logType); } } /** * Generates command line arguments for the ApiGen executable. * * @return string */ protected function constructArguments() { $args = array(); foreach ($this->options as $option => $value) { if (is_bool($value)) { $args[] = '--' . $option . '=' . ($value ? 'yes' : 'no'); } elseif (is_array($value)) { foreach ($value as $v) { $args[] = '--' . $option . '=' . escapeshellarg($v); } } else { $args[] = '--' . $option . '=' . escapeshellarg($value); } } return implode(' ', $args); } } phing-2.16.0/tasks/ext/creole/CreoleTask.php0000644000175000017500000001511013027032674017652 0ustar druiddruid. */ require_once 'phing/Task.php'; include_once 'phing/types/Reference.php'; /** * Handles Creole configuration needed by SQL type tasks. * * @author Hans Lellelid (Phing) * @author Nick Chalko (Ant) * @author Jeff Martin (Ant) * @author Michael McCallum (Ant) * @author Tim Stephenson (Ant) * @version $Id: b020d667f8bb1d09d43607ffaa4ff6e33bd91dbd $ * @package phing.tasks.system */ abstract class CreoleTask extends Task { /** * Used for caching loaders / driver. This is to avoid * getting an OutOfMemoryError when calling this task * multiple times in a row. * * NOT IMPLEMENTED YET */ private static $loaderMap = array(); private $caching = true; /** * Autocommit flag. Default value is false */ private $autocommit = false; /** * [optional] Classpath to Creole driver to use. * @param string */ private $driver; /** * DB url. */ private $url; /** * User name. */ private $userId; /** * Password */ private $password; /** * RDBMS Product needed for this SQL. **/ private $rdbms; /** * Initialize CreoleTask. * This method includes any necessary Creole libraries and triggers * appropriate error if they cannot be found. This is not done in header * because we may want this class to be loaded w/o triggering an error. */ public function init() { include_once 'creole/Creole.php'; if (!class_exists('Creole')) { throw new Exception("Creole task depends on Creole classes being on include_path. (i.e. include of 'creole/Creole.php' failed.)"); } } /** * Caching loaders / driver. This is to avoid * getting an OutOfMemoryError when calling this task * multiple times in a row; default: true * @param bool $enable */ public function setCaching($enable) { $this->caching = $enable; } /** * Sets the database connection URL; required. * @param string $url */ public function setUrl($url) { $this->url = $url; } /** * Set the Creole driver to be used. * * @param string $driver driver class name */ public function setDriver($driver) { $this->driver = $driver; } /** * Sets the password; required. * @param string $password The password to set */ public function setPassword($password) { $this->password = $password; } /** * Auto commit flag for database connection; * optional, default false. * * @param bool $autocommit The autocommit to set */ public function setAutocommit($autocommit) { $this->autocommit = $autocommit; } /** * Sets the version string, execute task only if * rdbms version match; optional. * * @param string $version */ public function setVersion($version) { $this->version = $version; } /** * @return array */ protected function getLoaderMap() { return self::$loaderMap; } /** * Creates a new Connection as using the driver, url, userid and password specified. * The calling method is responsible for closing the connection. * * @return Connection the newly created connection. * * @throws BuildException if the UserId/Password/Url is not set or there is no suitable driver or the driver fails to load. */ protected function getConnection() { if ($this->url === null) { throw new BuildException("Url attribute must be set!", $this->location); } try { $this->log("Connecting to " . $this->getUrl(), Project::MSG_VERBOSE); $info = new Properties(); $dsn = Creole::parseDSN($this->url); if (!isset($dsn["username"]) && $this->userId === null) { throw new BuildException("Username must be in URL or userid attribute must be set.", $this->location); } if ($this->userId) { $dsn["username"] = $this->getUserId(); } if ($this->password) { $dsn["password"] = $this->getPassword(); } if ($this->driver) { Creole::registerDriver($dsn['phptype'], $this->driver); } $conn = Creole::getConnection($dsn); $conn->setAutoCommit($this->autocommit); return $conn; } catch (SQLException $e) { throw new BuildException($e->getMessage(), $this->location); } } /** * @param $value */ public function isCaching($value) { $this->caching = $value; } /** * Gets the autocommit. * @return Returns a boolean */ public function isAutocommit() { return $this->autocommit; } /** * Gets the url. * * @return string */ public function getUrl() { return $this->url; } /** * Gets the userId. * * @return string */ public function getUserId() { return $this->userId; } /** * Set the user name for the connection; required. * @param string $userId */ public function setUserid($userId) { $this->userId = $userId; } /** * Gets the password. * @return string */ public function getPassword() { return $this->password; } } phing-2.16.0/tasks/ext/creole/CreoleSQLExecTask.php0000644000175000017500000004512213027032674021045 0ustar druiddruid. */ require_once 'phing/tasks/ext/creole/CreoleTask.php'; include_once 'phing/system/io/StringReader.php'; /** * Executes a series of SQL statements on a database using Creole. * *

Statements can * either be read in from a text file using the src attribute or from * between the enclosing SQL tags.

* *

Multiple statements can be provided, separated by semicolons (or the * defined delimiter). Individual lines within the statements can be * commented using either --, // or REM at the start of the line.

* *

The autocommit attribute specifies whether auto-commit should be * turned on or off whilst executing the statements. If auto-commit is turned * on each statement will be executed and committed. If it is turned off the * statements will all be executed as one transaction.

* *

The onerror attribute specifies how to proceed when an error occurs * during the execution of one of the statements. * The possible values are: continue execution, only show the error; * stop execution and commit transaction; * and abort execution and transaction and fail task.

* * @author Hans Lellelid (Phing) * @author Jeff Martin (Ant) * @author Michael McCallum (Ant) * @author Tim Stephenson (Ant) * @package phing.tasks.ext.creole * @version $Id: b0540d6f531fdc2a5103a09c92a54318ebdf8c0b $ */ class CreoleSQLExecTask extends CreoleTask { private $goodSql = 0; private $totalSql = 0; const DELIM_ROW = "row"; const DELIM_NORMAL = "normal"; /** * Database connection */ private $conn = null; /** * files to load */ private $filesets = array(); /** * all filterchains objects assigned to this task */ private $filterChains = array(); /** * SQL statement */ private $statement = null; /** * SQL input file */ private $srcFile = null; /** * SQL input command */ private $sqlCommand = ""; /** * SQL transactions to perform */ private $transactions = array(); /** * SQL Statement delimiter */ private $delimiter = ";"; /** * The delimiter type indicating whether the delimiter will * only be recognized on a line by itself */ private $delimiterType = "normal"; // can't use constant just defined /** * Print SQL results. */ private $print = false; /** * Print header columns. */ private $showheaders = true; /** * Results Output file. */ private $output = null; /** * Action to perform if an error is found **/ private $onError = "abort"; /** * Encoding to use when reading SQL statements from a file */ private $encoding = null; /** * Append to an existing file or overwrite it? */ private $append = false; /** * Set the name of the SQL file to be run. * Required unless statements are enclosed in the build file * @param PhingFile $srcFile */ public function setSrc(PhingFile $srcFile) { $this->srcFile = $srcFile; } /** * Set an inline SQL command to execute. * NB: Properties are not expanded in this text. * @param $sql */ public function addText($sql) { $this->sqlCommand .= $sql; } /** * Adds a set of files (nested fileset attribute). * @param FileSet $set */ public function addFileset(FileSet $set) { $this->filesets[] = $set; } /** * Creates a filterchain * * @return object The created filterchain object */ public function createFilterChain() { $num = array_push($this->filterChains, new FilterChain($this->project)); return $this->filterChains[$num - 1]; } /** * Add a SQL transaction to execute */ public function createTransaction() { $t = new SQLExecTransaction($this); $this->transactions[] = $t; return $t; } /** * Set the file encoding to use on the SQL files read in * * @param the $encoding * @internal param the $encoding encoding to use on the files */ public function setEncoding($encoding) { $this->encoding = $encoding; } /** * Set the statement delimiter. * *

For example, set this to "go" and delimitertype to "ROW" for * Sybase ASE or MS SQL Server.

* * @param delimiter */ public function setDelimiter($delimiter) { $this->delimiter = $delimiter; } /** * Set the Delimiter type for this sql task. The delimiter type takes two * values - normal and row. Normal means that any occurrence of the delimiter * terminate the SQL command whereas with row, only a line containing just * the delimiter is recognized as the end of the command. * * @param string $delimiterType */ public function setDelimiterType($delimiterType) { $this->delimiterType = $delimiterType; } /** * Set the print flag. * * @param boolean $print */ public function setPrint($print) { $this->print = (boolean) $print; } /** * Print headers for result sets from the * statements; optional, default true. * @param boolean $showheaders */ public function setShowheaders($showheaders) { $this->showheaders = (boolean) $showheaders; } /** * Set the output file; * optional, defaults to the console. * @param PhingFile $output */ public function setOutput(PhingFile $output) { $this->output = $output; } /** * whether output should be appended to or overwrite * an existing file. Defaults to false. * @param $append */ public function setAppend($append) { $this->append = (boolean) $append; } /** * Action to perform when statement fails: continue, stop, or abort * optional; default "abort" * @param $action */ public function setOnerror($action) { $this->onError = $action; } /** * Load the sql file and then execute it * @throws BuildException */ public function main() { $savedTransaction = array(); for ($i = 0, $size = count($this->transactions); $i < $size; $i++) { $savedTransaction[] = clone $this->transactions[$i]; } $savedSqlCommand = $this->sqlCommand; $this->sqlCommand = trim($this->sqlCommand); try { if ($this->srcFile === null && $this->sqlCommand === "" && empty($this->filesets) ) { if (count($this->transactions) === 0) { throw new BuildException("Source file or fileset, " . "transactions or sql statement " . "must be set!", $this->location); } } if ($this->srcFile !== null && !$this->srcFile->exists()) { throw new BuildException("Source file does not exist!", $this->location); } // deal with the filesets for ($i = 0, $size = count($this->filesets); $i < $size; $i++) { $fs = $this->filesets[$i]; $ds = $fs->getDirectoryScanner($this->project); $srcDir = $fs->getDir($this->project); $srcFiles = $ds->getIncludedFiles(); // Make a transaction for each file for ($j = 0, $size = count($srcFiles); $j < $size; $j++) { $t = $this->createTransaction(); $t->setSrc(new PhingFile($srcDir, $srcFiles[$j])); } } // Make a transaction group for the outer command $t = $this->createTransaction(); if ($this->srcFile) { $t->setSrc($this->srcFile); } $t->addText($this->sqlCommand); $this->conn = $this->getConnection(); try { $this->statement = $this->conn->createStatement(); $out = null; try { if ($this->output !== null) { $this->log("Opening output file " . $this->output, Project::MSG_VERBOSE); $out = new BufferedWriter(new FileWriter($this->output->getAbsolutePath(), $this->append)); } // Process all transactions for ($i = 0, $size = count($this->transactions); $i < $size; $i++) { $this->transactions[$i]->runTransaction($out); if (!$this->isAutocommit()) { $this->log("Committing transaction", Project::MSG_VERBOSE); $this->conn->commit(); } } if ($out) { $out->close(); } } catch (Exception $e) { if ($out) { $out->close(); } throw $e; } } catch (IOException $e) { if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") { try { $this->conn->rollback(); } catch (SQLException $ex) { } } throw new BuildException($e->getMessage(), $this->location); } catch (SQLException $e) { if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") { try { $this->conn->rollback(); } catch (SQLException $ex) { } } throw new BuildException($e->getMessage(), $this->location); } $this->log( $this->goodSql . " of " . $this->totalSql . " SQL statements executed successfully" ); } catch (Exception $e) { $this->transactions = $savedTransaction; $this->sqlCommand = $savedSqlCommand; throw $e; } // finally { $this->transactions = $savedTransaction; $this->sqlCommand = $savedSqlCommand; } /** * read in lines and execute them * @param Reader $reader * @param null $out * @throws BuildException */ public function runStatements(Reader $reader, $out = null) { $sql = ""; $line = ""; $buffer = ''; if ((is_array($this->filterChains)) && (!empty($this->filterChains))) { $in = FileUtils::getChainedReader(new BufferedReader($reader), $this->filterChains, $this->getProject()); while (-1 !== ($read = $in->read())) { // -1 indicates EOF $buffer .= $read; } $lines = explode("\n", $buffer); } else { $in = new BufferedReader($reader); while (($line = $in->readLine()) !== null) { $lines[] = $line; } } try { foreach ($lines as $line) { $line = trim($line); $line = ProjectConfigurator::replaceProperties( $this->project, $line, $this->project->getProperties() ); if (StringHelper::startsWith("//", $line) || StringHelper::startsWith("--", $line) || StringHelper::startsWith("#", $line) ) { continue; } if (strlen($line) > 4 && strtoupper(substr($line, 0, 4)) == "REM " ) { continue; } $sql .= " " . $line; $sql = trim($sql); // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (strpos($line, "--") !== false) { $sql .= "\n"; } if ($this->delimiterType == self::DELIM_NORMAL && StringHelper::endsWith($this->delimiter, $sql) || $this->delimiterType == self::DELIM_ROW && $line == $this->delimiter ) { $this->log("SQL: " . $sql, Project::MSG_VERBOSE); $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter)), $out); $sql = ""; } } // Catch any statements not followed by ; if ($sql !== "") { $this->execSQL($sql, $out); } } catch (SQLException $e) { throw new BuildException("Error running statements", $e); } } /** * Exec the sql statement. * @param $sql * @param null $out * @throws BuildException */ protected function execSQL($sql, $out = null) { // Check and ignore empty statements if (trim($sql) == "") { return; } try { $this->totalSql++; if (!$this->statement->execute($sql)) { $this->log($this->statement->getUpdateCount() . " rows affected", Project::MSG_VERBOSE); } else { if ($this->print) { $this->printResults($out); } } $this->goodSql++; } catch (SQLException $e) { $this->log("Failed to execute: " . $sql, Project::MSG_ERR); if ($this->onError != "continue") { throw new BuildException("Failed to execute SQL", $e); } $this->log($e->getMessage(), Project::MSG_ERR); } } /** * print any results in the statement. * @param null $out */ protected function printResults($out = null) { $rs = null; do { $rs = $this->statement->getResultSet(); if ($rs !== null) { $this->log("Processing new result set.", Project::MSG_VERBOSE); $line = ""; $colsprinted = false; while ($rs->next()) { $fields = $rs->getRow(); if (!$colsprinted && $this->showheaders) { $first = true; foreach ($fields as $fieldName => $ignore) { if ($first) { $first = false; } else { $line .= ","; } $line .= $fieldName; } if ($out !== null) { $out->write($line); $out->newLine(); } else { print($line . PHP_EOL); } $line = ""; $colsprinted = true; } // if show headers $first = true; foreach ($fields as $columnValue) { if ($columnValue != null) { $columnValue = trim($columnValue); } if ($first) { $first = false; } else { $line .= ","; } $line .= $columnValue; } if ($out !== null) { $out->write($line); $out->newLine(); } else { print($line . PHP_EOL); } $line = ""; } // while rs->next() } } while ($this->statement->getMoreResults()); print(PHP_EOL); if ($out !== null) { $out->newLine(); } } } /** * "Inner" class that contains the definition of a new transaction element. * Transactions allow several files or blocks of statements * to be executed using the same JDBC connection and commit * operation in between. * * @package phing.tasks.ext.creole */ class SQLExecTransaction { private $tSrcFile = null; private $tSqlCommand = ""; private $parent; /** * @param $parent */ public function __construct($parent) { // Parent is required so that we can log things ... $this->parent = $parent; } /** * @param PhingFile $src */ public function setSrc(PhingFile $src) { $this->tSrcFile = $src; } /** * @param $sql */ public function addText($sql) { $this->tSqlCommand .= $sql; } /** * @param null $out */ public function runTransaction($out = null) { if (!empty($this->tSqlCommand)) { $this->parent->log("Executing commands", Project::MSG_INFO); $this->parent->runStatements(new StringReader($this->tSqlCommand), $out); } if ($this->tSrcFile !== null) { $this->parent->log( "Executing file: " . $this->tSrcFile->getAbsolutePath(), Project::MSG_INFO ); $reader = new FileReader($this->tSrcFile); $this->parent->runStatements($reader, $out); $reader->close(); } } } phing-2.16.0/tasks/ext/git/GitCommitTask.php0000644000175000017500000001014113027032674017646 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-commit * * @package phing.tasks.ext.git * @author Jonathan Creasy * @see VersionControl_Git * @since 2.4.3 */ class GitCommitTask extends GitBaseTask { /** * @var boolean */ private $allFiles = false; /** * @var string */ private $message; /** * @var FileSet[] */ private $filesets = array(); /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } if ($this->allFiles !== true && empty($this->filesets)) { throw new BuildException('"allFiles" cannot be false if no filesets are specified.'); } $options = array(); if ($this->allFiles === true) { $options['all'] = true; } $arguments = array(); if ($this->allFiles !== true) { foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $srcFiles = $ds->getIncludedFiles(); foreach ($srcFiles as $file) { $arguments[] = $file; } } } if (!empty($this->message)) { $options['message'] = $this->message; } else { $options['allow-empty-message'] = true; } try { $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('commit'); $command->setArguments($arguments); $command->setOptions($options); $command->execute(); } catch (Exception $e) { throw new BuildException('The remote end hung up unexpectedly', $e); } $this->logCommand($options, $arguments); } /** * @param array $options * @param array $arguments */ protected function logCommand(array $options, array $arguments) { $msg = 'git-commit: Executed git commit '; foreach ($options as $option => $value) { $msg .= ' --' . $option . '=' . $value; } foreach ($arguments as $argument) { $msg .= ' ' . $argument; } $this->log($msg, Project::MSG_INFO); } /** * @return bool */ public function getAllFiles() { return $this->allFiles; } /** * @param $flag */ public function setAllFiles($flag) { $this->allFiles = (bool) $flag; } /** * @return string */ public function getMessage() { return $this->message; } /** * @param $message */ public function setMessage($message) { $this->message = $message; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } } phing-2.16.0/tasks/ext/git/GitTagTask.php0000644000175000017500000002472213027032674017143 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-tag * * @author Evan Kaufman * @author Victor Farazdagi * @version $Id: d01c0f1426d0075ae04ff7c156452d08909e966a $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.5 */ class GitTagTask extends GitBaseTask { /** * Make unsigned, annotated tag object. See -a of git-tag * @var boolean */ private $annotate = false; /** * Make GPG-signed tag. See -s of git-tag * @var boolean */ private $sign = false; /** * Make GPG-signed tag, using given key. See -u of git-tag * @var string */ private $keySign; /** * Replace existing tag with given name. See -f of git-tag * @var boolean */ private $replace = false; /** * Delete existing tags with given names. See -d of git-tag * @var boolean */ private $delete = false; /** * Verify gpg signature of given tag names. See -v of git-tag * @var boolean */ private $verify = false; /** * List tags with names matching given pattern. See -l of git-tag * @var boolean */ private $list = false; /** * specifies how many lines from the annotation, if any, are printed * when using -l. See -n of git-tag * @var int */ private $num; /** * Only list tags containing specified commit. See --contains of git-tag * @var string */ private $contains; /** * Use given tag message. See -m of git-tag * @var string */ private $message; /** * Take tag message from given file. See -F of git-tag * @var string */ private $file; /** * argument to git-tag * @var string */ private $name; /** * argument to git-tag * @var string */ private $commit; /** * argument to git-tag * @var string */ private $object; /** * argument to git-tag * @var string */ private $pattern; /** * Property name to set with output value from git-tag * @var string */ private $outputProperty; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('tag'); $command ->setOption('a', $this->isAnnotate()) ->setOption('s', $this->isSign()) ->setOption('f', $this->isReplace()) ->setOption('d', $this->isDelete()) ->setOption('v', $this->isVerify()) ->setOption('l', $this->isList()); if (null !== $this->getKeySign()) { $command->setOption('u', $this->getKeySign()); } if (null !== $this->getMessage()) { $command->setOption('m', $this->getMessage()); } if (null !== $this->getFile()) { $command->setOption('F', $this->getFile()); } // Use 'name' arg, if relevant if (null != $this->getName() && false == $this->isList()) { $command->addArgument($this->getName()); } if (null !== $this->getKeySign() || $this->isAnnotate() || $this->isSign()) { // Require a tag message or file if (null === $this->getMessage() && null === $this->getFile()) { throw new BuildException('"message" or "file" required to make a tag'); } } // Use 'commit' or 'object' args, if relevant if (null !== $this->getCommit()) { $command->addArgument($this->getCommit()); } else { if (null !== $this->getObject()) { $command->addArgument($this->getObject()); } } // Customize list (-l) options if ($this->isList()) { if (null !== $this->getContains()) { $command->setOption('contains', $this->getContains()); } if (null !== $this->getPattern()) { $command->addArgument($this->getPattern()); } if (null != $this->getNum()) { $command->setOption('n', $this->getNum()); } } $this->log('git-tag command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { $this->log($e->getMessage(), Project::MSG_ERR); throw new BuildException('Task execution failed. ' . $e->getMessage()); } if (null !== $this->outputProperty) { $this->project->setProperty($this->outputProperty, $output); } $this->log( sprintf('git-tag: tags for "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-tag output: ' . trim($output), Project::MSG_INFO); } /** * @param $flag */ public function setAnnotate($flag) { $this->annotate = (bool) $flag; } /** * @return bool */ public function getAnnotate() { return $this->annotate; } /** * @return bool */ public function isAnnotate() { return $this->getAnnotate(); } /** * @param $flag */ public function setSign($flag) { $this->sign = (bool) $flag; } /** * @return bool */ public function getSign() { return $this->sign; } /** * @return bool */ public function isSign() { return $this->getSign(); } /** * @param $keyId */ public function setKeySign($keyId) { $this->keySign = $keyId; } /** * @return string */ public function getKeySign() { return $this->keySign; } /** * @param $flag */ public function setReplace($flag) { $this->replace = (bool) $flag; } /** * @return bool */ public function getReplace() { return $this->replace; } /** * @return bool */ public function isReplace() { return $this->getReplace(); } /** * @param $flag */ public function setForce($flag) { return $this->setReplace($flag); } /** * @param $flag */ public function setDelete($flag) { $this->delete = (bool) $flag; } /** * @return bool */ public function getDelete() { return $this->delete; } /** * @return bool */ public function isDelete() { return $this->getDelete(); } /** * @param $flag */ public function setVerify($flag) { $this->verify = (bool) $flag; } /** * @return bool */ public function getVerify() { return $this->verify; } /** * @return bool */ public function isVerify() { return $this->getVerify(); } /** * @param $flag */ public function setList($flag) { $this->list = (bool) $flag; } /** * @return bool */ public function getList() { return $this->list; } /** * @return bool */ public function isList() { return $this->getList(); } /** * @param $num */ public function setNum($num) { $this->num = (int) $num; } /** * @return int */ public function getNum() { return $this->num; } /** * @param $commit */ public function setContains($commit) { $this->contains = $commit; } /** * @return string */ public function getContains() { return $this->contains; } /** * @param $msg */ public function setMessage($msg) { $this->message = $msg; } /** * @return string */ public function getMessage() { return $this->message; } /** * @param $file */ public function setFile($file) { $this->file = $file; } /** * @return string */ public function getFile() { return $this->file; } /** * @param $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * @param $commit */ public function setCommit($commit) { $this->commit = $commit; } /** * @return string */ public function getCommit() { return $this->commit; } /** * @param $object */ public function setObject($object) { $this->object = $object; } /** * @return string */ public function getObject() { return $this->object; } /** * @param $pattern */ public function setPattern($pattern) { $this->pattern = $pattern; } /** * @return string */ public function getPattern() { return $this->pattern; } /** * @param $prop */ public function setOutputProperty($prop) { $this->outputProperty = $prop; } } phing-2.16.0/tasks/ext/git/GitFetchTask.php0000644000175000017500000001642213027032674017457 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-fetch * * @author Victor Farazdagi * @version $Id: 0de7b4504804e074f617010ef52604d1da1e76b7 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitFetchTask extends GitBaseTask { /** * --force, -f key to git-fetch * @var boolean */ private $force = false; /** * --quiet, -q key to git-fetch * @var boolean */ private $quiet = false; /** * Fetch all remotes * --all key to git-fetch * @var boolean */ private $allRemotes = false; /** * Keep downloaded pack * --keep key to git-fetch * @var boolean */ private $keepFiles = false; /** * After fetching, remove any remote tracking branches which no longer * exist on the remote. * --prune key to git fetch * @var boolean */ private $prune = false; /** * Disable/enable automatic tag following * --no-tags key to git-fetch * @var boolean */ private $noTags = false; /** * Fetch all tags (even not reachable from branch heads) * --tags key to git-fetch * @var boolean */ private $tags = false; /** * argument to git-fetch * @var string */ private $group; /** * argument to git-fetch * @var string */ private $source = 'origin'; /** * argument to git-fetch * @var string */ private $refspec; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('fetch'); $command ->setOption('tags', $this->isTags()) ->setOption('no-tags', $this->isNoTags()) ->setOption('prune', $this->isPrune()) ->setOption('keep', $this->isKeepFiles()) ->setOption('q', $this->isQuiet()) ->setOption('force', $this->isForce()); // set operation target if ($this->isAllRemotes()) { // --all $command->setOption('all', true); } elseif ($this->getGroup()) { // $command->addArgument($this->getGroup()); } elseif ($this->getSource()) { // [] $command->addArgument($this->getSource()); if ($this->getRefspec()) { $command->addArgument($this->getRefspec()); } } else { throw new BuildException('No remote repository specified'); } $this->log('git-fetch command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log( sprintf('git-fetch: branch "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-fetch output: ' . trim($output), Project::MSG_INFO); } /** * @param $flag */ public function setForce($flag) { $this->force = $flag; } /** * @return bool */ public function getForce() { return $this->force; } /** * @return bool */ public function isForce() { return $this->getForce(); } /** * @param $flag */ public function setQuiet($flag) { $this->quiet = $flag; } /** * @return bool */ public function getQuiet() { return $this->quiet; } /** * @return bool */ public function isQuiet() { return $this->getQuiet(); } /** * @param $flag */ public function setAll($flag) { $this->allRemotes = $flag; } /** * @return bool */ public function getAll() { return $this->allRemotes; } /** * @return bool */ public function isAllRemotes() { return $this->getAll(); } /** * @param $flag */ public function setKeep($flag) { $this->keepFiles = $flag; } /** * @return bool */ public function getKeep() { return $this->keepFiles; } /** * @return bool */ public function isKeepFiles() { return $this->getKeep(); } /** * @param $flag */ public function setPrune($flag) { $this->prune = $flag; } /** * @return bool */ public function getPrune() { return $this->prune; } /** * @return bool */ public function isPrune() { return $this->getPrune(); } /** * @param $flag */ public function setNoTags($flag) { $this->noTags = $flag; } /** * @return bool */ public function getNoTags() { return $this->noTags; } /** * @return bool */ public function isNoTags() { return $this->getNoTags(); } /** * @param $flag */ public function setTags($flag) { $this->tags = $flag; } /** * @return bool */ public function getTags() { return $this->tags; } /** * @return bool */ public function isTags() { return $this->getTags(); } /** * @param $source */ public function setSource($source) { $this->source = $source; } /** * @return string */ public function getSource() { return $this->source; } /** * @param $spec */ public function setRefspec($spec) { $this->refspec = $spec; } /** * @return string */ public function getRefspec() { return $this->refspec; } /** * @param $group */ public function setGroup($group) { $this->group = $group; } /** * @return string */ public function getGroup() { return $this->group; } } phing-2.16.0/tasks/ext/git/GitCheckoutTask.php0000644000175000017500000001521113027032674020166 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-checkout * * @author Victor Farazdagi * @version $Id: 0eb5ad0732bc3acd74df7f9256b37952ddce3212 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitCheckoutTask extends GitBaseTask { /** * Branch name * @var string */ private $branchname; /** * If not HEAD, specify starting point * @var string */ private $startPoint; /** * --force, -f key to git-checkout * @var boolean */ private $force = false; /** * --quiet, -q key to git-checkout * @var boolean */ private $quiet = false; /** * When creating a new branch, set up "upstream" configuration. * --track key to git-checkout * @var boolean */ private $track = false; /** * Do not set up "upstream" configuration * --no-track key to git-checkout * @var boolean */ private $noTrack = false; /** * -b, -B, -m options to git-checkout * Respective task options: * create, forceCreate, merge * @var array */ private $extraOptions = array( 'b' => false, 'B' => false, 'm' => false, ); /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } if (null === $this->getBranchname()) { throw new BuildException('"branchname" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('checkout'); $command ->setOption('no-track', $this->isNoTrack()) ->setOption('q', $this->isQuiet()) ->setOption('force', $this->isForce()) ->setOption('b', $this->isCreate()) ->setOption('B', $this->isForceCreate()) ->setOption('m', $this->isMerge()); if ($this->isNoTrack()) { $command->setOption('track', $this->isTrack()); } $command->addArgument($this->getBranchname()); if (null !== $this->getStartPoint()) { $command->addArgument($this->getStartPoint()); } $this->log('git-checkout command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log( sprintf('git-checkout: checkout "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-checkout output: ' . trim($output), Project::MSG_INFO); } /** * @param $branchname */ public function setBranchname($branchname) { $this->branchname = $branchname; } /** * @return string */ public function getBranchname() { return $this->branchname; } /** * @param $startPoint */ public function setStartPoint($startPoint) { $this->startPoint = $startPoint; } /** * @return string */ public function getStartPoint() { return $this->startPoint; } /** * @param $flag */ public function setForce($flag) { $this->force = $flag; } /** * @return bool */ public function getForce() { return $this->force; } /** * @return bool */ public function isForce() { return $this->getForce(); } /** * @param $flag */ public function setQuiet($flag) { $this->quiet = $flag; } /** * @return bool */ public function getQuiet() { return $this->quiet; } /** * @return bool */ public function isQuiet() { return $this->getQuiet(); } /** * @param $flag */ public function setTrack($flag) { $this->track = $flag; } /** * @return bool */ public function getTrack() { return $this->track; } /** * @return bool */ public function isTrack() { return $this->getTrack(); } /** * @param $flag */ public function setNoTrack($flag) { $this->noTrack = $flag; } /** * @return bool */ public function getNoTrack() { return $this->noTrack; } /** * @return bool */ public function isNoTrack() { return $this->getNoTrack(); } /** * @param $flag */ public function setCreate($flag) { $this->extraOptions['b'] = $flag; } public function getCreate() { return $this->extraOptions['b']; } public function isCreate() { return $this->getCreate(); } // -B flag is not found in all versions of git // --force is present everywhere /** * @param $flag */ public function setForceCreate($flag) { $this->setForce($flag); } public function getForceCreate() { return $this->extraOptions['B']; } public function isForceCreate() { return $this->getForceCreate(); } /** * @param $flag */ public function setMerge($flag) { $this->extraOptions['m'] = $flag; } public function getMerge() { return $this->extraOptions['m']; } public function isMerge() { return $this->getMerge(); } } phing-2.16.0/tasks/ext/git/GitGcTask.php0000644000175000017500000001015513027032674016754 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-gc * * @author Victor Farazdagi * @version $Id: 5201d8d2dfb0c6ffb371ee85b8aa4bfc731b00c4 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitGcTask extends GitBaseTask { /** * --aggressive key to git-gc * @var boolean */ private $isAggressive = false; /** * --auto key to git-gc * @var boolean */ private $isAuto = false; /** * --no-prune key to git-gc * @var boolean */ private $noPrune = false; /** * --prune=option of git-gc * @var string */ private $prune = '2.weeks.ago'; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('gc'); $command ->setOption('aggressive', $this->isAggressive()) ->setOption('auto', $this->isAuto()) ->setOption('no-prune', $this->isNoPrune()); if ($this->isNoPrune() == false) { $command->setOption('prune', $this->getPrune()); } // suppress output $command->setOption('q'); $this->log('git-gc command: ' . $command->createCommandString(), Project::MSG_INFO); try { $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed', $e); } $this->log( sprintf('git-gc: cleaning up "%s" repository', $this->getRepository()), Project::MSG_INFO ); } /** * @see getAggressive() */ public function isAggressive() { return $this->getAggressive(); } /** * @return bool */ public function getAggressive() { return $this->isAggressive; } /** * @param $flag */ public function setAggressive($flag) { $this->isAggressive = (bool) $flag; } /** * @see getAuto() */ public function isAuto() { return $this->getAuto(); } /** * @return bool */ public function getAuto() { return $this->isAuto; } /** * @param $flag */ public function setAuto($flag) { $this->isAuto = (bool) $flag; } /** * @see NoPrune() */ public function isNoPrune() { return $this->getNoPrune(); } /** * @return bool */ public function getNoPrune() { return $this->noPrune; } /** * @param $flag */ public function setNoPrune($flag) { $this->noPrune = (bool) $flag; } /** * @return string */ public function getPrune() { return $this->prune; } /** * @param $date */ public function setPrune($date) { $this->prune = $date; } } phing-2.16.0/tasks/ext/git/GitBranchTask.php0000644000175000017500000001701313027032674017620 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-branch * * @author Victor Farazdagi * @version $Id: 0a0ccdabd2fb96209a3f7c2b5069408502064e71 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitBranchTask extends GitBaseTask { /** * Branch name * @var string */ private $branchname; /** * New Branch name for git-branch -m | -M * @var string */ private $newbranch; /** * If not HEAD, specify starting point * @var string */ private $startPoint; /** * --set-upstream key to git-branch * @var boolean */ private $setUpstream = false; /** * --track key to git-branch * @var boolean */ private $track = false; /** * --no-track key to git-branch * @var boolean */ private $noTrack = false; /** * --force, -f key to git-branch * @var boolean */ private $force = false; /** * -d, -D, -m, -M options to git-branch * Respective task options: * delete, forceDelete, move, forceMove * @var array */ private $extraOptions = array( 'd' => false, 'D' => false, 'm' => false, 'M' => false, ); /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } if (null === $this->getBranchname()) { throw new BuildException('"branchname" is required parameter'); } // if we are moving branch, we need to know new name if ($this->isMove() || $this->isForceMove()) { if (null === $this->getNewbranch()) { throw new BuildException('"newbranch" is required parameter'); } } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('branch'); $command ->setOption('set-upstream', $this->isSetUpstream()) ->setOption('no-track', $this->isNoTrack()) ->setOption('force', $this->isForce()); if ($this->isNoTrack() == false) { $command->setOption('track', $this->getTrack()); } // check extra options (delete, move) foreach ($this->extraOptions as $option => $flag) { if ($flag) { $command->setOption($option, true); } } $command->addArgument($this->getBranchname()); if (null !== $this->getStartPoint()) { $command->addArgument($this->getStartPoint()); } if (null !== $this->getNewbranch()) { $command->addArgument($this->getNewbranch()); } $this->log('git-branch command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log( sprintf('git-branch: branch "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-branch output: ' . trim($output), Project::MSG_INFO); } /** * @param $flag */ public function setSetUpstream($flag) { $this->setUpstream = $flag; } /** * @return bool */ public function getSetUpstream() { return $this->setUpstream; } /** * @return bool */ public function isSetUpstream() { return $this->getSetUpstream(); } /** * @param $flag */ public function setTrack($flag) { $this->track = $flag; } /** * @return bool */ public function getTrack() { return $this->track; } /** * @return bool */ public function isTrack() { return $this->getTrack(); } /** * @param $flag */ public function setNoTrack($flag) { $this->noTrack = $flag; } /** * @return bool */ public function getNoTrack() { return $this->noTrack; } /** * @return bool */ public function isNoTrack() { return $this->getNoTrack(); } /** * @param $flag */ public function setForce($flag) { $this->force = $flag; } /** * @return bool */ public function getForce() { return $this->force; } /** * @return bool */ public function isForce() { return $this->getForce(); } /** * @param $branchname */ public function setBranchname($branchname) { $this->branchname = $branchname; } /** * @return string */ public function getBranchname() { return $this->branchname; } /** * @param $startPoint */ public function setStartPoint($startPoint) { $this->startPoint = $startPoint; } /** * @return string */ public function getStartPoint() { return $this->startPoint; } /** * @param $flag */ public function setDelete($flag) { $this->extraOptions['d'] = $flag; } public function getDelete() { return $this->extraOptions['d']; } public function isDelete() { return $this->getDelete(); } /** * @param $flag */ public function setForceDelete($flag) { $this->extraOptions['D'] = $flag; } public function getForceDelete() { return $this->extraOptions['D']; } /** * @param $flag */ public function setMove($flag) { $this->extraOptions['m'] = $flag; } public function getMove() { return $this->extraOptions['m']; } public function isMove() { return $this->getMove(); } /** * @param $flag */ public function setForceMove($flag) { $this->extraOptions['M'] = $flag; } public function getForceMove() { return $this->extraOptions['M']; } public function isForceMove() { return $this->getForceMove(); } /** * @param $name */ public function setNewBranch($name) { $this->newbranch = $name; } /** * @return string */ public function getNewBranch() { return $this->newbranch; } } phing-2.16.0/tasks/ext/git/GitMergeTask.php0000644000175000017500000001622713027032674017470 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-merge * * @author Victor Farazdagi * @version $Id: e5d20b926ab512d72bfc19ac2f1ccc80d09f036c $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 * @link http://www.kernel.org/pub/software/scm/git/docs/git-merge.html */ class GitMergeTask extends GitBaseTask { /** * of git-merge * @var string */ private $remote; /** * Commit message * @var string */ private $message; /** * Merge strategy. See -s of git-merge * Available strategies are: octopus ours recursive resolve subtree * @var string */ private $strategy; /** * -X or --strategy-option of git-merge * @var string */ private $strategyOption; /** * --commit key of git-merge * @var boolean */ private $commit = false; /** * --no-commit key of git-merge * @var boolean */ private $noCommit = false; /** * --ff --no-ff keys to git-merge * @var boolean */ private $fastForwardCommit = false; /** * --quiet, -q key to git-merge * @var boolean */ private $quiet = false; /** * Valid merge strategies * @var array */ private $validStrategies = array( 'octopus', 'ours', 'theirs', 'recursive', 'resolve', 'subtree' ); /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $remotes = trim($this->getRemote()); if (null === $remotes || '' === $remotes) { throw new BuildException('"remote" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('merge'); $command ->setOption('commit', $this->isCommit()) ->setOption('q', $this->isQuiet()); if ($this->getMessage()) { $command->setOption('message', $this->getMessage()); } if (!$this->isCommit()) { $command->setOption('no-commit', $this->isNoCommit()); } if ($this->isFastForwardCommit()) { $command->setOption('no-ff', true); } $strategy = $this->getStrategy(); if ($strategy) { // check if strategy is valid if (false === in_array($strategy, $this->validStrategies)) { throw new BuildException( "Could not find merge strategy '" . $strategy . "'\n" . "Available strategies are: " . implode(', ', $this->validStrategies)); } $command->setOption('strategy', $strategy); if ($this->getStrategyOption()) { $command->setOption( 'strategy-option', $this->getStrategyOption() ); } } $remotes = explode(' ', $this->getRemote()); foreach ($remotes as $remote) { $command->addArgument($remote); } $this->log('git-merge command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log( sprintf('git-merge: replaying "%s" commits', $this->getRemote()), Project::MSG_INFO ); $this->log('git-merge output: ' . trim($output), Project::MSG_INFO); } /** * @param $remote */ public function setRemote($remote) { $this->remote = $remote; } /** * @return string */ public function getRemote() { return $this->remote; } /** * @param $message */ public function setMessage($message) { $this->message = $message; } /** * @return string */ public function getMessage() { return $this->message; } /** * @param $strategy */ public function setStrategy($strategy) { $this->strategy = $strategy; } /** * @return string */ public function getStrategy() { return $this->strategy; } /** * @param $strategyOption */ public function setStrategyOption($strategyOption) { $this->strategyOption = $strategyOption; } /** * @return string */ public function getStrategyOption() { return $this->strategyOption; } /** * @param $flag */ public function setQuiet($flag) { $this->quiet = $flag; } /** * @return bool */ public function getQuiet() { return $this->quiet; } /** * @return bool */ public function isQuiet() { return $this->getQuiet(); } /** * @param $flag */ public function setCommit($flag) { $this->commit = (boolean) $flag; } /** * @return bool */ public function getCommit() { return $this->commit; } /** * @return bool */ public function isCommit() { return $this->getCommit(); } /** * @param $flag */ public function setNoCommit($flag) { $this->noCommit = (boolean) $flag; } /** * @return bool */ public function getNoCommit() { return $this->noCommit; } /** * @return bool */ public function isNoCommit() { return $this->getNoCommit(); } /** * @param $flag */ public function setFastForwardCommit($flag) { $this->fastForwardCommit = $flag; } /** * @return bool */ public function getFastForwardCommit() { return $this->fastForwardCommit; } /** * @return bool */ public function isFastForwardCommit() { return $this->getFastForwardCommit(); } } phing-2.16.0/tasks/ext/git/GitDescribeTask.php0000644000175000017500000001561513027032674020151 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-describe * * @package phing.tasks.ext.git * @author Siad Ardroumli * @see VersionControl_Git */ class GitDescribeTask extends GitBaseTask { /** * Use any ref found in .git/refs/. See --all of git-describe * @var boolean */ private $all = false; /** * Use any tag found in .git/refs/tags. See --tags of git-describe * @var boolean */ private $tags = false; /** * Find tag that contains the commit. See --contains of git-describe * @var boolean */ private $contains = false; /** * Use digit object name. See --abbrev of git-describe * @var integer */ private $abbrev; /** * Consider up to most recent tags. See --candidates of git-describe * @var integer */ private $candidates; /** * Always output the long format. See --long of git-describe * @var boolean */ private $long = false; /** * Only consider tags matching the given pattern. See --match of git-describe * @var string */ private $match; /** * Show uniquely abbreviated commit object as fallback. See --always of git-describe * @var boolean */ private $always = false; /** * argument to git-describe * @var string */ private $committish; /** * Property name to set with output value from git-describe * @var string */ private $outputProperty; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('describe'); $command ->setOption('all', $this->isAll()) ->setOption('tags', $this->isTags()) ->setOption('contains', $this->isContains()) ->setOption('long', $this->isLong()) ->setOption('always', $this->isAlways()); if (null !== $this->getAbbrev()) { $command->setOption('abbrev', $this->getAbbrev()); } if (null !== $this->getCandidates()) { $command->setOption('candidates', $this->getCandidates()); } if (null !== $this->getMatch()) { $command->setOption('match', $this->getMatch()); } if (null !== $this->getCommittish()) { $command->addArgument($this->getCommittish()); } try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed'); } if (null !== $this->outputProperty) { $this->project->setProperty($this->outputProperty, $output); } $this->log( sprintf('git-describe: recent tags for "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-describe output: ' . trim($output), Project::MSG_INFO); } /** * @param $flag */ public function setAll($flag) { $this->all = (bool) $flag; } /** * @return bool */ public function getAll() { return $this->all; } /** * @return bool */ public function isAll() { return $this->getAll(); } /** * @param $flag */ public function setTags($flag) { $this->tags = (bool) $flag; } /** * @return bool */ public function getTags() { return $this->tags; } /** * @return bool */ public function isTags() { return $this->getTags(); } /** * @param $flag */ public function setContains($flag) { $this->contains = (bool) $flag; } /** * @return bool */ public function getContains() { return $this->contains; } /** * @return bool */ public function isContains() { return $this->getContains(); } /** * @param $length */ public function setAbbrev($length) { $this->abbrev = (int) $length; } /** * @return int */ public function getAbbrev() { return $this->abbrev; } /** * @param $count */ public function setCandidates($count) { $this->candidates = (int) $count; } /** * @return int */ public function getCandidates() { return $this->candidates; } /** * @param $flag */ public function setLong($flag) { $this->long = (bool) $flag; } /** * @return bool */ public function getLong() { return $this->long; } /** * @return bool */ public function isLong() { return $this->getLong(); } /** * @param $pattern */ public function setMatch($pattern) { $this->match = $pattern; } /** * @return string */ public function getMatch() { return $this->match; } /** * @param $flag */ public function setAlways($flag) { $this->always = (bool) $flag; } /** * @return bool */ public function getAlways() { return $this->always; } /** * @return bool */ public function isAlways() { return $this->getAlways(); } /** * @param $object */ public function setCommittish($object) { $this->committish = $object; } /** * @return string */ public function getCommittish() { return $this->committish; } /** * @param string $prop */ public function setOutputProperty($prop) { $this->outputProperty = $prop; } } phing-2.16.0/tasks/ext/git/GitPushTask.php0000644000175000017500000001574713027032674017356 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-push * * @author Victor Farazdagi * @version $Id: 8406c9cfd560b995db09e9888334355641cd3975 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 * @link http://www.kernel.org/pub/software/scm/git/docs/git-push.html */ class GitPushTask extends GitBaseTask { /** * Instead of naming each ref to push, specifies that all refs * --all key to git-push * @var boolean */ private $allRemotes = false; /** * Mirror to remote repository * --mirror key to git-push * @var boolean */ private $mirror = false; /** * Same as prefixing repos with colon * --delete argument to git-push * @var string */ private $delete = false; /** * Push all refs under refs/tags * --tags key to git-fetch * @var boolean */ private $tags = false; /** * argument to git-push * @var string */ private $destination = 'origin'; /** * argument to git-push * @var string */ private $refspec; /** * --force, -f key to git-push * @var boolean */ private $force = false; /** * --quiet, -q key to git-push * @var boolean */ private $quiet = true; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('push'); $command ->setOption('tags', $this->isTags()) ->setOption('mirror', $this->isMirror()) ->setOption('delete', $this->isDelete()) ->setOption('q', $this->isQuiet()) ->setOption('force', $this->isForce()); // set operation target if ($this->isAllRemotes()) { // --all $command->setOption('all', true); $this->log('git-push: push to all refs', Project::MSG_INFO); } elseif ($this->isMirror()) { // [] $command->setOption('mirror', true); $this->log('git-push: mirror all refs', Project::MSG_INFO); } elseif ($this->getDestination()) { // [] $command->addArgument($this->getDestination()); if ($this->getRefspec()) { $command->addArgument($this->getRefspec()); } $this->log( sprintf( 'git-push: pushing to %s %s', $this->getDestination(), $this->getRefspec() ), Project::MSG_INFO ); } else { throw new BuildException('At least one destination must be provided'); } $this->log('git-push command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log('git-push: complete', Project::MSG_INFO); if ($this->isDelete()) { $this->log('git-push: branch delete requested', Project::MSG_INFO); } $this->log('git-push output: ' . trim($output), Project::MSG_INFO); } /** * @param $flag */ public function setAll($flag) { $this->allRemotes = $flag; } /** * @return bool */ public function getAll() { return $this->allRemotes; } /** * @return bool */ public function isAllRemotes() { return $this->getAll(); } /** * @param $flag */ public function setMirror($flag) { $this->mirror = (boolean) $flag; } /** * @return bool */ public function getMirror() { return $this->mirror; } /** * @return bool */ public function isMirror() { return $this->getMirror(); } /** * @param $flag */ public function setDelete($flag) { $this->delete = (boolean) $flag; } /** * @return string */ public function getDelete() { return $this->delete; } /** * @return string */ public function isDelete() { return $this->getDelete(); } /** * @param $flag */ public function setTags($flag) { $this->tags = $flag; } /** * @return bool */ public function getTags() { return $this->tags; } /** * @return bool */ public function isTags() { return $this->getTags(); } /** * @param $destination */ public function setDestination($destination) { $this->destination = $destination; } /** * @return string */ public function getDestination() { return $this->destination; } /** * @param $spec */ public function setRefspec($spec) { $this->refspec = $spec; } /** * @return string */ public function getRefspec() { return $this->refspec; } /** * @param $flag */ public function setForce($flag) { $this->force = $flag; } /** * @return bool */ public function getForce() { return $this->force; } /** * @return bool */ public function isForce() { return $this->getForce(); } /** * @param $flag */ public function setQuiet($flag) { $this->quiet = $flag; } /** * @return bool */ public function getQuiet() { return $this->quiet; } /** * @return bool */ public function isQuiet() { return $this->getQuiet(); } } phing-2.16.0/tasks/ext/git/GitBaseTask.php0000644000175000017500000000724013027032674017276 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/BuildException.php'; /** * Base class for Git tasks * * @author Victor Farazdagi * @version $Id: 85ccdb98750754b0376c5a367925b260788f4086 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ abstract class GitBaseTask extends Task { /** * Bath to git binary * @var string */ private $gitPath = '/usr/bin/git'; /** * @var VersionControl_Git */ private $gitClient = null; /** * Current repository directory * @var string */ private $repository; /** * Initialize Task. * Check and include necessary libraries. */ public function init() { @include_once 'VersionControl/Git.php'; if (false == class_exists('VersionControl_Git')) { throw new BuildException("The Git tasks depend on PEAR\'s " . "VersionControl_Git package.", $this->getLocation()); } } /** * Set repository directory * * @param string $repository Repo directory * @return GitBaseTask */ public function setRepository($repository) { $this->repository = $repository; return $this; } /** * Get repository directory * * @return string */ public function getRepository() { return $this->repository; } /** * Set path to git executable * * @param string $gitPath New path to git repository * @return GitBaseTask */ public function setGitPath($gitPath) { $this->gitPath = $gitPath; return $this; } /** * Get path to git executable * * @return string */ public function getGitPath() { return $this->gitPath; } /** * @param bool $reset * @param null $repository * @return null|VersionControl_Git * @throws BuildException */ protected function getGitClient($reset = false, $repository = null) { $this->gitClient = ($reset === true) ? null : $this->gitClient; $repository = (null === $repository) ? $this->getRepository() : $repository; if (null === $this->gitClient) { try { $this->gitClient = new VersionControl_Git($repository); } catch (VersionControl_Git_Exception $e) { // re-package throw new BuildException( 'You must specify readable directory as repository.', $e); } } $this->gitClient->setGitCommandPath($this->getGitPath()); return $this->gitClient; } } phing-2.16.0/tasks/ext/git/GitInitTask.php0000644000175000017500000000462013027032674017326 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/BuildException.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Repository initialization task * * @author Victor Farazdagi * @version $Id: 8e8b0c6caa7260a0bb563b71f8af4291067cbef0 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitInitTask extends GitBaseTask { /** * Whether --bare key should be set for git-init * @var string */ private $isBare = false; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(); $client->initRepository($this->isBare()); $msg = 'git-init: initializing ' . ($this->isBare() ? '(bare) ' : '') . '"' . $this->getRepository() . '" repository'; $this->log($msg, Project::MSG_INFO); } /** * Alias @see getBare() * * @return string */ public function isBare() { return $this->getBare(); } /** * @return string */ public function getBare() { return $this->isBare; } /** * @param $flag */ public function setBare($flag) { $this->isBare = (bool) $flag; } } phing-2.16.0/tasks/ext/git/GitCloneTask.php0000644000175000017500000001402213027032674017460 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper around git-clone * * @author Victor Farazdagi * @version $Id: 1ca04138e62374984bd4e04a46fccec605dff5a7 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitCloneTask extends GitBaseTask { /** * Whether --depth key should be set for git-clone * @var int */ private $depth = 0; /** * Whether --bare key should be set for git-clone * @var bool */ private $isBare = false; /** * Whether --single-branch key should be set for git-clone * @var bool */ private $singleBranch = false; /** * Branch to check out * * @var string */ private $branch = ""; /** * Path to target directory * @var string */ private $targetPath; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } if (null === $this->getTargetPath()) { throw new BuildException('"targetPath" is required parameter'); } $files = @scandir($this->getTargetPath()); if (isset($files) && is_array($files) && (count($files) > 2)) { throw new BuildException( sprintf( '"%s" target directory is not empty', $this->getTargetPath() ) ); } try { $this->doClone($this->getGitClient(false, getcwd())); } catch (Exception $e) { throw new BuildException('The remote end hung up unexpectedly', $e); } $msg = 'git-clone: cloning ' . ($this->isBare() ? '(bare) ' : '') . ($this->hasDepth() ? ' (depth="' . $this->getDepth() . '") ' : '') . '"' . $this->getRepository() . '" repository' . ' to "' . $this->getTargetPath() . '" directory'; $this->log($msg, Project::MSG_INFO); } /** * Create a new clone * * @param VersionControl_Git $client * * @throws VersionControl_Git_Exception */ protected function doClone(VersionControl_Git $client) { $command = $client->getCommand('clone') ->setOption('q') ->setOption('bare', $this->isBare()) ->setOption('single-branch', $this->isSingleBranch()) ->setOption('depth', $this->hasDepth() ? $this->getDepth() : false) ->setOption('branch', $this->hasBranch() ? $this->getBranch() : false) ->addArgument($this->getRepository()) ->addArgument($this->getTargetPath()); if (is_dir($this->getTargetPath()) && version_compare('1.6.1.4', $client->getGitVersion(), '>=')) { $isEmptyDir = true; $entries = scandir($this->getTargetPath()); foreach ($entries as $entry) { if ('.' !== $entry && '..' !== $entry) { $isEmptyDir = false; break; } } if ($isEmptyDir) { @rmdir($this->getTargetPath()); } } $command->execute(); } /** * @return int */ public function getDepth() { return $this->depth; } /** * @param int $depth */ public function setDepth($depth) { $this->depth = $depth; } /** * @return bool */ public function hasDepth() { return (bool) $this->depth; } /** * Get path to target direcotry repo * * @return string */ public function getTargetPath() { return $this->targetPath; } /** * Set path to source repo * * @param string $targetPath Path to repository used as source * @return void */ public function setTargetPath($targetPath) { $this->targetPath = $targetPath; } /** * Alias @see getBare() * * @return bool */ public function isBare() { return $this->getBare(); } /** * @return bool */ public function getBare() { return $this->isBare; } /** * @param $flag */ public function setBare($flag) { $this->isBare = (bool) $flag; } /** * @return boolean */ public function isSingleBranch() { return $this->singleBranch; } /** * @param boolean $singleBranch */ public function setSingleBranch($singleBranch) { $this->singleBranch = $singleBranch; } /** * @return string */ public function getBranch() { return $this->branch; } /** * @return bool */ public function hasBranch() { return !empty($this->branch); } /** * @param string $branch */ public function setBranch($branch) { $this->branch = $branch; } } phing-2.16.0/tasks/ext/git/GitPullTask.php0000644000175000017500000002345513027032674017346 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-pull * * @author Victor Farazdagi * @version $Id: 3ca88dd906a2b8b95edd6c11265984a9d57dbde5 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.3 */ class GitPullTask extends GitBaseTask { /** * argument to git-pull * @var string */ private $source = 'origin'; /** * argument to git-pull * @var string */ private $refspec; /** * --rebase key to git-pull * @var boolean */ private $rebase = false; /** * --no-rebase key to git-pull * Allow to override --rebase (if set to default true in configuration) * @var boolean */ private $noRebase = false; /** * Merge strategy. See -s of git-pull * @var string */ private $strategy; /** * -X or --strategy-option of git-pull * @var string */ private $strategyOption; /** * Fetch all remotes * --all key to git-pull * @var boolean */ private $allRemotes = false; /** * --append key to git-pull * @var boolean */ private $append = false; /** * Keep downloaded pack * --keep key to git-pull * @var boolean */ private $keepFiles = false; /** * Disable/enable automatic tag following * --no-tags key to git-pull * @var boolean */ private $noTags = false; /** * Fetch all tags (even not reachable from branch heads) * --tags key to git-pull * @var boolean */ private $tags = false; /** * --quiet, -q key to git-pull * @var boolean */ private $quiet = true; /** * --force, -f key to git-pull * @var boolean */ private $force = false; /** * Valid merge strategies * @var array */ private $validStrategies = array( 'octopus', 'ours', 'recursive', 'resolve', 'subtree' ); /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('pull'); $command ->setOption('rebase', $this->isRebase()); if (!$this->isRebase()) { $command->setOption('no-rebase', $this->isNoRebase()); } $strategy = $this->getStrategy(); if ($strategy) { // check if strategy is valid if (false === in_array($strategy, $this->validStrategies)) { throw new BuildException( "Could not find merge strategy '" . $strategy . "'\n" . "Available strategies are: " . implode(', ', $this->validStrategies)); } $command->setOption('strategy', $strategy); if ($this->getStrategyOption()) { $command->setOption( 'strategy-option', $this->getStrategyOption() ); } } // order of arguments is important $command ->setOption('tags', $this->isTags()) ->setOption('no-tags', $this->isNoTags()) ->setOption('keep', $this->isKeepFiles()) ->setOption('append', $this->isAppend()) ->setOption('q', $this->isQuiet()) ->setOption('force', $this->isForce()); // set operation target if ($this->isAllRemotes()) { // --all $command->setOption('all', true); $this->log('git-pull: fetching from all remotes', Project::MSG_INFO); } elseif ($this->getSource()) { // [] $command->addArgument($this->getSource()); if ($this->getRefspec()) { $command->addArgument($this->getRefspec()); } $this->log( sprintf( 'git-pull: pulling from %s %s', $this->getSource(), $this->getRefspec() ), Project::MSG_INFO ); } else { throw new BuildException('No source repository specified'); } $this->log('git-pull command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed.', $e); } $this->log('git-pull: complete', Project::MSG_INFO); $this->log('git-pull output: ' . trim($output), Project::MSG_INFO); } /** * @param $strategy */ public function setStrategy($strategy) { $this->strategy = $strategy; } /** * @return string */ public function getStrategy() { return $this->strategy; } /** * @param $strategyOption */ public function setStrategyOption($strategyOption) { $this->strategyOption = $strategyOption; } /** * @return string */ public function getStrategyOption() { return $this->strategyOption; } /** * @param $source */ public function setSource($source) { $this->source = $source; } /** * @return string */ public function getSource() { return $this->source; } /** * @param $spec */ public function setRefspec($spec) { $this->refspec = $spec; } /** * @return string */ public function getRefspec() { return $this->refspec; } /** * @param $flag */ public function setAll($flag) { $this->allRemotes = $flag; } /** * @return bool */ public function getAll() { return $this->allRemotes; } /** * @return bool */ public function isAllRemotes() { return $this->getAll(); } /** * @param $flag */ public function setAppend($flag) { $this->append = (boolean) $flag; } /** * @return bool */ public function getAppend() { return $this->append; } /** * @return bool */ public function isAppend() { return $this->getAppend(); } /** * @param $flag */ public function setKeep($flag) { $this->keepFiles = $flag; } /** * @return bool */ public function getKeep() { return $this->keepFiles; } /** * @return bool */ public function isKeepFiles() { return $this->getKeep(); } /** * @param $flag */ public function setNoTags($flag) { $this->noTags = $flag; } /** * @return bool */ public function getNoTags() { return $this->noTags; } /** * @return bool */ public function isNoTags() { return $this->getNoTags(); } /** * @param $flag */ public function setTags($flag) { $this->tags = $flag; } /** * @return bool */ public function getTags() { return $this->tags; } /** * @return bool */ public function isTags() { return $this->getTags(); } /** * @param $flag */ public function setQuiet($flag) { $this->quiet = $flag; } /** * @return bool */ public function getQuiet() { return $this->quiet; } /** * @return bool */ public function isQuiet() { return $this->getQuiet(); } /** * @param $flag */ public function setRebase($flag) { $this->rebase = (boolean) $flag; } /** * @return bool */ public function getRebase() { return $this->rebase; } /** * @return bool */ public function isRebase() { return $this->getRebase(); } /** * @param $flag */ public function setNoRebase($flag) { $this->noRebase = (boolean) $flag; } /** * @return bool */ public function getNoRebase() { return $this->noRebase; } /** * @return bool */ public function isNoRebase() { return $this->getNoRebase(); } /** * @param $flag */ public function setForce($flag) { $this->force = $flag; } /** * @return bool */ public function getForce() { return $this->force; } /** * @return bool */ public function isForce() { return $this->getForce(); } } phing-2.16.0/tasks/ext/git/GitLogTask.php0000644000175000017500000001626613027032674017155 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/git/GitBaseTask.php'; /** * Wrapper aroung git-log * * @author Evan Kaufman * @author Victor Farazdagi * @version $Id: 8b23ec7a8c95625a37c67d7cba50df578b95b2b6 $ * @package phing.tasks.ext.git * @see VersionControl_Git * @since 2.4.5 */ class GitLogTask extends GitBaseTask { /** * Generate a diffstat. See --stat of git-log * @var string|boolean */ private $stat = false; /** * Names + status of changed files. See --name-status of git-log * @var boolean */ private $nameStatus = false; /** * Number of commits to show. See -|-n|--max-count of git-log * @var integer */ private $maxCount; /** * Don't show commits with more than one parent. See --no-merges of git-log * @var boolean */ private $noMerges = false; /** * Commit format. See --format of git-log * @var string */ private $format = 'medium'; /** * Date format. See --date of git-log * @var string */ private $date; /** * argument to git-log * @var string */ private $since; /** * argument to git-log * @var string */ private $until; /** * arguments to git-log * Accepts one or more paths delimited by PATH_SEPARATOR * @var string */ private $paths; /** * Property name to set with output value from git-log * @var string */ private $outputProperty; /** * The main entry point for the task */ public function main() { if (null === $this->getRepository()) { throw new BuildException('"repository" is required parameter'); } $client = $this->getGitClient(false, $this->getRepository()); $command = $client->getCommand('log'); $command ->setOption('stat', $this->getStat()) ->setOption('name-status', $this->isNameStatus()) ->setOption('no-merges', $this->isNoMerges()) ->setOption('format', $this->getFormat()); if (null !== $this->getMaxCount()) { $command->setOption('max-count', $this->getMaxCount()); } if (null !== $this->getDate()) { $command->setOption('date', $this->getDate()); } if (null !== $this->getSince()) { $command->setOption('since', $this->getSince()); } if (null !== $this->getUntil()) { $command->setOption('until', $this->getUntil()); } $command->addDoubleDash(true); if (null !== $this->getPaths()) { $command->addDoubleDash(false); $paths = explode(PATH_SEPARATOR, $this->getPaths()); foreach ($paths as $path) { $command->addArgument($path); } } $this->log('git-log command: ' . $command->createCommandString(), Project::MSG_INFO); try { $output = $command->execute(); } catch (Exception $e) { throw new BuildException('Task execution failed', $e); } if (null !== $this->outputProperty) { $this->project->setProperty($this->outputProperty, $output); } $this->log( sprintf('git-log: commit log for "%s" repository', $this->getRepository()), Project::MSG_INFO ); $this->log('git-log output: ' . trim($output), Project::MSG_INFO); } /** * @param $stat */ public function setStat($stat) { $this->stat = $stat; } /** * @return bool|string */ public function getStat() { return $this->stat; } /** * @param $flag */ public function setNameStatus($flag) { $this->nameStatus = (boolean) $flag; } /** * @return bool */ public function getNameStatus() { return $this->nameStatus; } /** * @return bool */ public function isNameStatus() { return $this->getNameStatus(); } /** * @param $count */ public function setMaxCount($count) { $this->maxCount = (int) $count; } /** * @return int */ public function getMaxCount() { return $this->maxCount; } /** * @param $flag */ public function setNoMerges($flag) { $this->noMerges = (bool) $flag; } /** * @return bool */ public function getNoMerges() { return $this->noMerges; } /** * @return bool */ public function isNoMerges() { return $this->getNoMerges(); } /** * @param $format */ public function setFormat($format) { $this->format = $format; } /** * @return string */ public function getFormat() { return $this->format; } /** * @param $date */ public function setDate($date) { $this->date = $date; } /** * @return string */ public function getDate() { return $this->date; } /** * @param $since */ public function setSince($since) { $this->since = $since; } /** * @return string */ public function getSince() { return $this->since; } /** * @param $after */ public function setAfter($after) { $this->setSince($after); } /** * @param $until */ public function setUntil($until) { $this->until = $until; } /** * @return string */ public function getUntil() { return $this->until; } /** * @param $before */ public function setBefore($before) { $this->setUntil($before); } /** * @param $paths */ public function setPaths($paths) { $this->paths = $paths; } /** * @return string */ public function getPaths() { return $this->paths; } /** * @param $prop */ public function setOutputProperty($prop) { $this->outputProperty = $prop; } } phing-2.16.0/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php0000644000175000017500000000667513027032674023745 0ustar druiddruid. */ require_once 'PhpDocumentor/phpDocumentor/Errors.inc'; /** * Phing subclass of the ErrorTracker class provided with PhpDocumentor to work around limitations in PhpDocumentor API. * * This class is necessary because PhpDocumentor does directly output errors and * warnings occurred during testing for undocumented elements to stdout. * This class is injected globally to force PhpDocumentor to use phing's logging * mechanism. * * Obviously this is far from ideal, but there's also no solution given the inflexibility of the * PhpDocumentor design. * * @author Timo A. Hummel @author felicitus * @version $Id: 33771f28a2886e13a8d3c38864d6758311c3e18d $ * @package phing.tasks.ext.phpdoc */ class PhingPhpDocumentorErrorTracker extends ErrorTracker { /** * @var object Reference to the task we're called with */ private $task; /** * Outputs a warning. This is an almost 1:1 copy from PhpDocumentor, * we're just processing the warning text and send it to phing's logger. * * @param $num integer Number of parameters * @return nothing */ public function addWarning($num) { $a = array('', '', '', ''); if (func_num_args() > 1) { for ($i = 1; $i < func_num_args(); $i++) { $a[$i - 1] = func_get_arg($i); } } $message = sprintf($GLOBALS['phpDocumentor_warning_descrip'][$num], $a[0], $a[1], $a[2], $a[3]); $this->task->log($message, Project::MSG_WARN); } /** * Outputs an error. This is an almost 1:1 copy from PhpDocumentor, * we're just processing the error text and send it to phing's logger. * * @param $num integer Number of parameters * @return nothing */ public function addError($num) { $a = array('', '', '', ''); if (func_num_args() > 1) { for ($i = 1; $i < func_num_args(); $i++) { $a[$i - 1] = func_get_arg($i); } } $message = sprintf($GLOBALS['phpDocumentor_error_descrip'][$num], $a[0], $a[1], $a[2], $a[3]); $this->task->log($message, Project::MSG_ERR); } /** * Sets the task we're working with. This is necessary since we need to be * able to call the method "log". * * @param object $task The task we're working with * @return nothing */ public function setTask($task) { $this->task = $task; } } phing-2.16.0/tasks/ext/phpdoc/PhpDocumentor2Task.php0000644000175000017500000001111013027032674021312 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * PhpDocumentor2 Task (http://www.phpdoc.org) * Based on the DocBlox Task * * @author Michiel Rook * @version $Id: fff99666d63c88940f9b305c2822856fa00ab5ce $ * @since 2.4.10 * @package phing.tasks.ext.phpdoc */ class PhpDocumentor2Task extends Task { /** * List of filesets * @var FileSet[] */ private $filesets = array(); /** * Destination/target directory * @var PhingFile */ private $destDir = null; /** * name of the template to use * @var string */ private $template = "responsive-twig"; /** * Title of the project * @var string */ private $title = "API Documentation"; /** * Name of default package * @var string */ private $defaultPackageName = "Default"; /** * Path to the phpDocumentor .phar * @var string */ private $pharLocation = ''; /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets destination/target directory * @param PhingFile $destDir */ public function setDestDir(PhingFile $destDir) { $this->destDir = $destDir; } /** * Convenience setter (@see setDestDir) * @param PhingFile $output */ public function setOutput(PhingFile $output) { $this->destDir = $output; } /** * Sets the template to use * @param strings $template */ public function setTemplate($template) { $this->template = (string) $template; } /** * Sets the title of the project * @param strings $title */ public function setTitle($title) { $this->title = (string) $title; } /** * Sets the default package name * @param string $defaultPackageName */ public function setDefaultPackageName($defaultPackageName) { $this->defaultPackageName = (string) $defaultPackageName; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Forces phpDocumentor to be quiet * @deprecated * @param boolean $quiet */ public function setQuiet($quiet) { $this->project->log(__CLASS__ . ": the 'quiet' option has been deprecated", Project::MSG_WARN); } /** * Task entry point * @see Task::main() */ public function main() { if (empty($this->destDir)) { throw new BuildException("You must supply the 'destdir' attribute", $this->getLocation()); } if (empty($this->filesets)) { throw new BuildException("You have not specified any files to include ()", $this->getLocation()); } if (version_compare(PHP_VERSION, '5.3.0') < 0) { throw new BuildException("The phpdocumentor2 task requires PHP 5.3+"); } require_once 'phing/tasks/ext/phpdoc/PhpDocumentor2Wrapper.php'; $wrapper = new PhpDocumentor2Wrapper(); $wrapper->setProject($this->project); $wrapper->setFilesets($this->filesets); $wrapper->setDestDir($this->destDir); $wrapper->setTemplate($this->template); $wrapper->setTitle($this->title); $wrapper->setDefaultPackageName($this->defaultPackageName); $wrapper->setPharLocation($this->pharLocation); $wrapper->run(); } } phing-2.16.0/tasks/ext/phpdoc/PhpDocumentor2Wrapper.php0000644000175000017500000001751113027032674022043 0ustar druiddruid. */ /** * Wrapper around PhpDocumentor2 (so we retain * PHP 5.2 compatibility in the main task) * * @author Michiel Rook * @version $Id: 9f22f2863b649ddf3820399fd5738c58900b3a24 $ * @since 2.4.10 * @package phing.tasks.ext.phpdoc */ class PhpDocumentor2Wrapper { /** * Phing project instance * @var Project */ private $project = null; /** * List of filesets * @var FileSet[] */ private $filesets = array(); /** * Destination/target directory * @var PhingFile */ private $destDir = null; /** * name of the template to use * @var string */ private $template = "responsive-twig"; /** * Title of the project * @var string */ private $title = "API Documentation"; /** * Name of the default package * @var string */ private $defaultPackageName = "Default"; /** * Path to the phpDocumentor 2 source * @var string */ private $phpDocumentorPath = ""; /** * Path to the phpDocumentor .phar * @var string */ private $pharLocation = ''; /** * @var \phpDocumentor\Application */ private $app = null; /** * Sets project instance * * @param Project $project */ public function setProject($project) { $this->project = $project; } /** * Sets filesets array * * @param FileSet[] $filesets */ public function setFilesets($filesets) { $this->filesets = $filesets; } /** * Sets destination/target directory * @param PhingFile $destDir */ public function setDestDir(PhingFile $destDir) { $this->destDir = $destDir; } /** * Sets the template to use * @param string $template */ public function setTemplate($template) { $this->template = (string) $template; } /** * Sets the title of the project * @param string $title */ public function setTitle($title) { $this->title = (string) $title; } /** * Sets the default package name * @param string $defaultPackageName */ public function setDefaultPackageName($defaultPackageName) { $this->defaultPackageName = (string) $defaultPackageName; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Finds and initializes the phpDocumentor installation */ private function initializePhpDocumentor() { $phpDocumentorPath = ''; if (!empty($this->pharLocation)) { include_once 'phar://' . $this->pharLocation . '/vendor/autoload.php'; if (!class_exists('phpDocumentor\\Bootstrap')) { throw new BuildException( $this->pharLocation . ' does not look like a phpDocumentor 2 .phar' ); } } elseif (class_exists('Composer\\Autoload\\ClassLoader', false)) { if (!class_exists('phpDocumentor\\Bootstrap')) { throw new BuildException('You need to install phpDocumentor 2 or add your include path to your composer installation.'); } } else { $phpDocumentorPath = $this->findPhpDocumentorPath(); if (empty($phpDocumentorPath)) { throw new BuildException("Please make sure phpDocumentor 2 is installed and on the include_path."); } set_include_path($phpDocumentorPath . PATH_SEPARATOR . get_include_path()); require_once $phpDocumentorPath . '/phpDocumentor/Bootstrap.php'; } $this->app = \phpDocumentor\Bootstrap::createInstance()->initialize(); $this->phpDocumentorPath = $phpDocumentorPath; } /** * Build a list of files (from the fileset elements) * and call the phpDocumentor parser * * @return string */ private function parseFiles() { $parser = $this->app['parser']; $builder = $this->app['descriptor.builder']; $builder->createProjectDescriptor(); $projectDescriptor = $builder->getProjectDescriptor(); $projectDescriptor->setName($this->title); $paths = array(); // filesets foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $dir = $fs->getDir($this->project); $srcFiles = $ds->getIncludedFiles(); foreach ($srcFiles as $file) { $paths[] = $dir . FileSystem::getFileSystem()->getSeparator() . $file; } } $this->project->log("Will parse " . count($paths) . " file(s)", Project::MSG_VERBOSE); $files = new \phpDocumentor\Fileset\Collection(); $files->addFiles($paths); $mapper = new \phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper($this->app['descriptor.cache']); $mapper->garbageCollect($files); $mapper->populate($projectDescriptor); $parser->setPath($files->getProjectRoot()); $parser->setDefaultPackageName($this->defaultPackageName); $parser->parse($builder, $files); $mapper->save($projectDescriptor); return $mapper; } /** * Transforms the parsed files */ private function transformFiles() { $transformer = $this->app['transformer']; $compiler = $this->app['compiler']; $builder = $this->app['descriptor.builder']; $projectDescriptor = $builder->getProjectDescriptor(); $transformer->getTemplates()->load($this->template, $transformer); $transformer->setTarget($this->destDir->getAbsolutePath()); foreach ($compiler as $pass) { $pass->execute($projectDescriptor); } } /** * Runs phpDocumentor 2 */ public function run() { $this->initializePhpDocumentor(); $cache = $this->app['descriptor.cache']; $cache->getOptions()->setCacheDir($this->destDir->getAbsolutePath()); $this->parseFiles(); $this->project->log("Transforming...", Project::MSG_VERBOSE); $this->transformFiles(); } /** * Find the correct php documentor path * * @return null|string */ private function findPhpDocumentorPath() { $phpDocumentorPath = null; $directories = array('phpDocumentor', 'phpdocumentor'); foreach ($directories as $directory) { foreach (Phing::explodeIncludePath() as $path) { $testPhpDocumentorPath = $path . DIRECTORY_SEPARATOR . $directory . DIRECTORY_SEPARATOR . 'src'; if (file_exists($testPhpDocumentorPath)) { $phpDocumentorPath = $testPhpDocumentorPath; } } } return $phpDocumentorPath; } } phing-2.16.0/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php0000644000175000017500000002137113027032674022426 0ustar druiddruid. */ require_once 'PhpDocumentor/phpDocumentor/Setup.inc.php'; /** * Phing subclass of the phpDocumentor_setup class provided with PhpDocumentor to work around limitations in PhpDocumentor API. * * This class is necessary because phpDocumentor_setup does not expose a complete API for setting configuration options. Because * this class must directly modify some "private" GLOBAL(!) configuration variables, it is liable to break if the PhpDocumentor * internal implementation changes. Obviously this is far from ideal, but there's also no solution given the inflexibility of the * PhpDocumentor design. * * @author Hans Lellelid @author hans * @version $Id: 3c0527274eb0d0c2c6ed888ff23fe5b38367bb04 $ * @package phing.tasks.ext.phpdoc */ class PhingPhpDocumentorSetup extends phpDocumentor_setup { /** * Constructs a new PhingPhpDocumentorSetup. * * @param null $configdir * @param object $task The task we're working with, so we can pass it on to the ErrorTracker * @internal param string $configDir Directory in which to look for configuration files. */ public function __construct($configdir = null, $task) { global $_phpDocumentor_cvsphpfile_exts, $_phpDocumentor_setting, $_phpDocumentor_phpfile_exts; $this->setup = new Io(); $this->render = new phpDocumentor_IntermediateParser("Default Title"); $GLOBALS['_phpDocumentor_install_dir'] = $configdir; $this->parseIni(); // These redundant-looking lines seem to actually make a difference. // See: http://phing.info/trac/ticket/150 $_phpDocumentor_phpfile_exts = $GLOBALS['_phpDocumentor_phpfile_exts']; $_phpDocumentor_cvsphpfile_exts = $GLOBALS['_phpDocumentor_cvsphpfile_exts']; if (tokenizer_ext) { $this->parse = new phpDocumentorTParser(); } else { $this->parse = new Parser(); } $this->setMemoryLimit(); include_once 'phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php'; // Inject our own error tracker to PhpDocumentor $GLOBALS['phpDocumentor_errors'] = new PhingPhpDocumentorErrorTracker(); $GLOBALS['phpDocumentor_errors']->setTask($task); } /** * Set whether to generate sourcecode for each file parsed. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param bool $b */ public function setGenerateSourcecode($b) { global $_phpDocumentor_setting; $_phpDocumentor_setting['sourcecode'] = (boolean) $b; } /** * Set an array of README/INSTALL/CHANGELOG file paths. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param array $files Absolute paths to files. */ public function setRicFiles($files) { global $_phpDocumentor_RIC_files; $_phpDocumentor_RIC_files = $files; } /** * Set comma-separated list of tags to ignore. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $tags */ public function setIgnoreTags($tags) { global $_phpDocumentor_setting; $ignoretags = explode(',', $tags); $ignoretags = array_map('trim', $ignoretags); $tags = array(); foreach ($ignoretags as $tag) { if (!in_array( $tag, array('@global', '@access', '@package', '@ignore', '@name', '@param', '@return', '@staticvar', '@var') ) ) { $tags[] = $tag; } } $_phpDocumentor_setting['ignoretags'] = $tags; } /** * Set whether to parse dirs as PEAR repos. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param bool $b */ public function setPear($b) { global $_phpDocumentor_setting; $_phpDocumentor_setting['pear'] = (boolean) $b; } /** * Set fullpath to directory to look in for examples. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $dir */ public function setExamplesDir($dir) { global $_phpDocumentor_setting; $_phpDocumentor_setting['examplesdir'] = $dir; } /** * Sets the default package name. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $name */ public function setDefaultPackageName($name) { $GLOBALS['phpDocumentor_DefaultPackageName'] = trim($name); } /** * Sets the default category name. * * This method exists as a hack because there is no API exposed for this in PhpDocumentor. * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * * @param string $name */ public function setDefaultCategoryName($name) { $GLOBALS['phpDocumentor_DefaultCategoryName'] = trim($name); } /** * Enables quiet mode. * * This method exists as a hack because the API exposed for this method in PhpDocumentor * doesn't work correctly. * * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this * is subject to break if PhpDocumentor internals changes. * */ public function setQuietMode() { global $_phpDocumentor_setting; $_phpDocumentor_setting['quiet'] = true; parent::setQuietMode(); } /** * Control whether or not warnings will be shown for undocumented elements. * Useful for identifying classes and methods that haven't yet been * documented. * * @param bool $bEnable */ public function setUndocumentedelements($bEnable) { $this->render->setUndocumentedElementWarningsMode($bEnable); } /** * custom tags, will be recognized and put in tags[] instead of * unknowntags[] * * This method exists as a hack because the API exposed for this method in * PhpDocumentor doesn't work correctly. * * Note that because we are setting a "private" GLOBAL(!!) config var with * this value, this is subject to break if PhpDocumentor internals changes. * * @param string $sCustomtags */ public function setCustomtags($sCustomtags) { global $_phpDocumentor_setting; $_phpDocumentor_setting['customtags'] = $sCustomtags; } /** * Files to ignore * * @param string $sIgnore */ public function setIgnore($sIgnore) { global $_phpDocumentor_setting; $_phpDocumentor_setting['ignore'] = $sIgnore; } } phing-2.16.0/tasks/ext/phpdoc/PhpDocumentorTask.php0000644000175000017500000003243313027032674021243 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * Task to run PhpDocumentor. * * @author Hans Lellelid * @author Michiel Rook * @version $Id: 11e97cff8a9f2331750049c1c8fe4fb57f3cc962 $ * @package phing.tasks.ext.phpdoc */ class PhpDocumentorTask extends Task { /** * @var string Title for browser window / package index. */ protected $title; /** * @var PhingFile The target directory for output files. */ protected $destdir; /** * @var array FileSet[] Filesets for files to parse. */ protected $filesets = array(); /** * @var array FileSet[] Project documentation (README/INSTALL/CHANGELOG) files. */ protected $projDocFilesets = array(); /** * @var string Package output format. */ protected $output; /** * @var boolean Whether to generate sourcecode for each file parsed. */ protected $linksource = false; /** * @var boolean Whether to parse private members. */ protected $parsePrivate = false; /** * @var boolean Whether to use javadoc descriptions (more primitive). */ protected $javadocDesc = false; /** * @var PhingFile Base directory for locating template files. */ protected $templateBase; /** * @var boolean Wheter to suppress output. */ protected $quiet = false; /** * @var string Comma-separated list of packages to output. */ protected $packages; /** * @var string Comma-separated list of tags to ignore. */ protected $ignoreTags; /** * @var string Default package name. */ protected $defaultPackageName; /** * @var string Default category name. */ protected $defaultCategoryName; /** * @var PhingFile Directory in which to look for examples. */ protected $examplesDir; /** * @var PhingFile Directory in which to look for configuration files. */ protected $configDir; /** * @var boolean Whether to parse as a PEAR repository. */ protected $pear = false; /** * @var boolean Control whether or not warnings will be shown for * undocumented elements. Useful for identifying classes and * methods that haven't yet been documented. */ protected $undocumentedelements = false; /** * @var string custom tags, will be recognized and put in tags[] instead of * unknowntags[]. */ protected $customtags = ''; /** * @var string files to ignore */ protected $ignore = ''; /** * Set the title for the generated documentation * @param $title */ public function setTitle($title) { $this->title = $title; } /** * Set the destination directory for the generated documentation * @param PhingFile $destdir */ public function setDestdir(PhingFile $destdir) { $this->destdir = $destdir; } /** * Alias for {@link setDestdir()}. * @see setDestdir() * @param PhingFile $destdir */ public function setTarget(PhingFile $destdir) { $this->setDestdir($destdir); } /** * Set the output format (e.g. HTML:Smarty:PHP). * @param string $output */ public function setOutput($output) { $this->output = $output; } /** * Set whether to generate sourcecode for each file parsed * @param boolean */ public function setSourcecode($b) { $this->setLinksource($b); } /** * Set whether to generate sourcecode for each file parsed * @param boolean */ public function setLinksource($b) { $this->linksource = $b; } /** * Set whether to suppress output. * @param boolean $b */ public function setQuiet($b) { $this->quiet = $b; } /** * Should private members/classes be documented * @param boolean */ public function setParseprivate($parseprivate) { $this->parsePrivate = $parseprivate; } /** * Whether to use javadoc descriptions (more primitive). * @param boolean */ public function setJavadocdesc($javadoc) { $this->javadocDesc = $javadoc; } /** * Set (comma-separated) list of packages to output. * * @param string $packages */ public function setPackageoutput($packages) { $this->packages = $packages; } /** * Set (comma-separated) list of tags to ignore. * * @param string $tags */ public function setIgnoretags($tags) { $this->ignoreTags = $tags; } /** * Set a directory to search for examples in. * @param PhingFile $d */ public function setExamplesdir(PhingFile $d) { $this->examplesDir = $d; } /** * Set a directory to search for configuration files in. * @param PhingFile $d */ public function setConfigdir(PhingFile $d) { $this->configDir = $d; } /** * Sets the default package name. * @param string $name */ public function setDefaultpackagename($name) { $this->defaultPackageName = $name; } /** * Sets the default category name. * @param string $name */ public function setDefaultcategoryname($name) { $this->defaultCategoryName = $name; } /** * Set whether to parse as PEAR repository. * @param boolean $b */ public function setPear($b) { $this->pear = $b; } /** * Creates a FileSet. * @return FileSet */ public function createFileset() { $num = array_push($this->filesets, new FileSet()); return $this->filesets[$num - 1]; } /** * Creates a readme/install/changelog fileset. * @return FileSet */ public function createProjdocfileset() { $num = array_push($this->projDocFilesets, new FileSet()); return $this->projDocFilesets[$num - 1]; } /** * Control whether or not warnings will be shown for undocumented elements. * Useful for identifying classes and methods that haven't yet been * documented. * @param boolean $b */ public function setUndocumentedelements($b) { $this->undocumentedelements = $b; } /** * custom tags, will be recognized and put in tags[] instead of * unknowntags[]. * * @param string $sCustomtags */ public function setCustomtags($sCustomtags) { $this->customtags = $sCustomtags; } /** * Set base location of all templates for this parse. * * @param PhingFile $oTemplateBase * @internal param PhingFile $destdir */ public function setTemplateBase(PhingFile $oTemplateBase) { $this->templateBase = $oTemplateBase; } /** * Set files to ignore * @param string $sIgnore */ public function setIgnore($sIgnore) { $this->ignore = $sIgnore; } /** * Searches include_path for PhpDocumentor install and adjusts include_path appropriately. * @throws BuildException - if unable to find PhpDocumentor on include_path */ protected function findPhpDocumentorInstall() { $found = null; foreach (Phing::explodeIncludePath() as $path) { $testpath = $path . DIRECTORY_SEPARATOR . 'PhpDocumentor'; if (file_exists($testpath)) { $found = $testpath; break; } } if (!$found) { throw new BuildException("PhpDocumentor task depends on PhpDocumentor being installed and on include_path.", $this->getLocation( )); } // otherwise, adjust the include_path to path to include the PhpDocumentor directory ... set_include_path(get_include_path() . PATH_SEPARATOR . $found); include_once "phpDocumentor/Setup.inc.php"; if (!class_exists('phpDocumentor_setup')) { throw new BuildException("Error including PhpDocumentor setup class file."); } } /** * Main entrypoint of the task * Loads the necessary environment for running PhpDoc, then runs PhpDoc * * @throws BuildException - if the phpdoc classes can't be loaded. */ public function main() { $this->findPhpDocumentorInstall(); include_once 'phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php'; $this->validate(); $configdir = $this->configDir ? $this->configDir->getAbsolutePath() : null; $phpdoc = new PhingPhpDocumentorSetup($configdir, $this); $this->setPhpDocumentorOptions($phpdoc); //$phpdoc->readCommandLineSettings(); $phpdoc->setupConverters($this->output); $phpdoc->createDocs(); } /** * Validates that necessary minimum options have been set. * @throws BuildException if validation doesn't pass */ protected function validate() { if (!$this->destdir) { throw new BuildException("You must specify a destdir for phpdoc.", $this->getLocation()); } if (!$this->output) { throw new BuildException("You must specify an output format for phpdoc (e.g. HTML:frames:default).", $this->getLocation( )); } if (empty($this->filesets)) { throw new BuildException("You have not specified any files to include () for phpdoc.", $this->getLocation( )); } } /** * Sets the options on the passed-in phpdoc setup object. * @param PhingPhpDocumentorSetup $phpdoc */ protected function setPhpDocumentorOptions(PhingPhpDocumentorSetup $phpdoc) { // Title MUST be set first ... (because it re-initializes the internal state of the PhpDocu renderer) if ($this->title) { $phpdoc->setTitle($this->title); } if ($this->parsePrivate) { $phpdoc->setParsePrivate(); } if ($this->javadocDesc) { $phpdoc->setJavadocDesc(); } if ($this->quiet) { $phpdoc->setQuietMode(); } if ($this->destdir) { $phpdoc->setTargetDir($this->destdir->getAbsolutePath()); } if ($this->packages) { $phpdoc->setPackageOutput($this->packages); } if ($this->templateBase) { $phpdoc->setTemplateBase($this->templateBase->getAbsolutePath()); } if ($this->linksource) { $phpdoc->setGenerateSourcecode($this->linksource); } if ($this->examplesDir) { $phpdoc->setExamplesDir($this->examplesDir->getAbsolutePath()); } if ($this->ignoreTags) { $phpdoc->setIgnoreTags($this->ignoreTags); } if ($this->defaultPackageName) { $phpdoc->setDefaultPackageName($this->defaultPackageName); } if ($this->defaultCategoryName) { $phpdoc->setDefaultCategoryName($this->defaultCategoryName); } if ($this->pear) { $phpdoc->setPear($this->pear); } if ($this->ignore) { $phpdoc->setIgnore($this->ignore); } // append any files in filesets $filesToParse = array(); foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } //print_r(implode(",", $filesToParse)); $phpdoc->setFilesToParse(implode(",", $filesToParse)); // append any files in filesets $ricFiles = array(); foreach ($this->projDocFilesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $ricFiles[] = $f->getName(); } } $phpdoc->setRicFiles($ricFiles); if ($this->undocumentedelements) { $phpdoc->setUndocumentedelements($this->undocumentedelements); } if ($this->customtags) { $phpdoc->setCustomtags($this->customtags); } } } phing-2.16.0/tasks/ext/phpdoc/PhpDocumentorExternalTask.php0000644000175000017500000001671113027032674022747 0ustar druiddruid. */ require_once 'phing/tasks/ext/phpdoc/PhpDocumentorTask.php'; /** * Task to run phpDocumentor with an external process * * This classes uses the commandline phpdoc script to build documentation. * Use this task instead of the PhpDocumentorTask when you've a clash with the * Smarty libraries. * * @author Michiel Rook * @author Markus Fischer * @version $Id: b72762694ae5d5619ecebf9b66c08bd6ff868821 $ * @package phing.tasks.ext.phpdoc */ class PhpDocumentorExternalTask extends PhpDocumentorTask { /** * The path to the executable for phpDocumentor */ protected $programPath = 'phpdoc'; protected $sourcepath = null; /** * @var bool ignore symlinks to other files or directories */ protected $ignoresymlinks = false; /** * Sets the path to the phpDocumentor executable * @param $programPath */ public function setProgramPath($programPath) { $this->programPath = $programPath; } /** * Returns the path to the phpDocumentor executable */ public function getProgramPath() { return $this->programPath; } /** * Set the source path. A directory or a comma separate list of directories. * @param $sourcepath */ public function setSourcepath($sourcepath) { $this->sourcepath = $sourcepath; } /** * Ignore symlinks to other files or directories. * * @param bool $bSet */ public function setIgnoresymlinks($bSet) { $this->ignoresymlinks = $bSet; } /** * Main entrypoint of the task */ public function main() { $this->validate(); $arguments = join(' ', $this->constructArguments()); $this->log("Running phpDocumentor..."); exec($this->programPath . " " . $arguments, $output, $return); if ($return != 0) { throw new BuildException("Could not execute phpDocumentor: " . implode(' ', $output)); } foreach ($output as $line) { if (strpos($line, 'ERROR') !== false) { $this->log($line, Project::MSG_ERR); continue; } $this->log($line, Project::MSG_VERBOSE); } } /** * Constructs an argument string for phpDocumentor * @return array */ protected function constructArguments() { $aArgs = array(); if ($this->title) { $aArgs[] = '--title "' . $this->title . '"'; } if ($this->destdir) { $aArgs[] = '--target "' . $this->destdir->getAbsolutePath() . '"'; } if ($this->sourcepath) { $aArgs[] = '--directory "' . $this->sourcepath . '"'; } if ($this->output) { $aArgs[] = '--output ' . $this->output; } if ($this->linksource) { $aArgs[] = '--sourcecode on'; } if ($this->parseprivate) { $aArgs[] = '--parseprivate on'; } if ($this->ignore) { $aArgs[] = '--ignore ' . $this->ignore; } // append any files in filesets $filesToParse = array(); foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } if (count($filesToParse) > 0) { $aArgs[] = '--filename "' . join(',', $filesToParse) . '"'; } // append any files in filesets $ricFiles = array(); foreach ($this->projDocFilesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $ricFiles[] = $f->getAbsolutePath(); } } if (count($ricFiles) > 0) { $aArgs[] = '--readmeinstallchangelog "' . join(',', $ricFiles) . '"'; } if ($this->javadocDesc) { $aArgs[] = '--javadocdesc on'; } if ($this->quiet) { $aArgs[] = '--quiet on'; } if ($this->packages) { $aArgs[] = '--packageoutput "' . $this->packages . '"'; } if ($this->ignoreTags) { $aArgs[] = '--ignore-tags "' . $this->ignoreTags . '"'; } if ($this->defaultCategoryName) { $aArgs[] = '--defaultcategoryname "' . $this->defaultCategoryName . '"'; } if ($this->examplesDir) { $aArgs[] = '--examplesdir "' . $this->examplesDir->getAbsolutePath() . '"'; } if ($this->templateBase) { $aArgs[] = '--templatebase "' . $this->templateBase->getAbsolutePath() . '"'; } if ($this->pear) { $aArgs[] = '--pear on'; } if ($this->undocumentedelements) { $aArgs[] = '--undocumentedelements on'; } if ($this->customtags) { $aArgs[] = '--customtags "' . $this->customtags . '"'; } if ($this->ignoresymlinks) { $aArgs[] = '--ignoresymlinks on'; } return $aArgs; } /** * Override PhpDocumentorTask::init() because they're specific to the phpdoc * API which we don't use. */ public function init() { } /** * Validates that necessary minimum options have been set. Based on * PhpDocumentorTask::validate(). */ protected function validate() { if (!$this->destdir) { throw new BuildException("You must specify a destdir for phpdoc.", $this->getLocation()); } if (!$this->output) { throw new BuildException("You must specify an output format for " . "phpdoc (e.g. HTML:frames:default).", $this->getLocation()); } if (empty($this->filesets) && !$this->sourcepath) { throw new BuildException("You have not specified any files to " . "include ( or sourcepath attribute) for phpdoc.", $this->getLocation()); } if ($this->configdir) { $this->log( 'Ignoring unsupported configdir-Attribute', Project::MSG_VERBOSE ); } } } ; phing-2.16.0/tasks/ext/inifile/IniFileRemove.php0000644000175000017500000000304513027032674020465 0ustar druiddruid * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * Class for collecting details for removing keys or sections from an ini file * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ class IniFileRemove { /** * Property * * @var string */ protected $property = null; /** * Section * * @var string */ protected $section = null; /** * Set Section name * * @param string $section Name of section in ini file * * @return void */ public function setSection($section) { $this->section = $section; } /** * Set Property/Key name * * @param string $property ini key name * * @return void */ public function setProperty($property) { $this->property = $property; } /** * Get Property * * @return string */ public function getProperty() { return $this->property; } /** * Get Section * * @return string */ public function getSection() { return $this->section; } } phing-2.16.0/tasks/ext/inifile/IniFileTask.php0000644000175000017500000002222513027032674020133 0ustar druiddruid * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ require_once 'IniFileSet.php'; require_once 'IniFileRemove.php'; require_once 'IniFileConfig.php'; /** * InifileTask * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link InifileTask.php */ class InifileTask extends Task { /** * Source file * * @var string|null */ protected $source = null; /** * Dest file * * @var string|null */ protected $dest = null; /** * Whether to halt phing on error. * * @var bool */ protected $haltonerror = false; /** * Sets * * @var array */ protected $sets = array(); /** * Removals * * @var array */ protected $removals = array(); /** * IniFileConfig instance * * @var IniFileConfig */ protected $ini = null; /** * Taskname for logger * @var string */ protected $taskName = 'IniFile'; /** * Check file to be read from * * @param string $readFile Filename * * @return void */ public function checkReadFile($readFile) { if (is_null($readFile)) { return false; } if (!file_exists($readFile)) { $msg = "$readFile does not exist."; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } if (!is_readable($readFile)) { $msg = "$readFile is not readable."; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } $this->ini->read($readFile); $this->log("Read from $readFile"); return true; } /** * Check file to write to * * @param string $writeFile Filename * * @return void */ public function checkWriteFile($writeFile) { if (file_exists($writeFile) && !is_writable($writeFile)) { $msg = "$writeFile is not writable"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return false; } return true; } /** * The main entry point method. * * @return void */ public function main() { $this->ini = new IniFileConfig(); $readFile = null; $writeFile = null; if (!is_null($this->source) && is_null($this->dest)) { $readFile = $this->source; } elseif (!is_null($this->dest) && is_null($this->source)) { $readFile = $this->dest; } else { $readFile = $this->source; } if (!is_null($this->dest)) { $writeFile = $this->dest; } elseif (!is_null($this->source)) { $writeFile = $this->source; } else { $writeFile = $this->dest; } if ($readFile === null && $writeFile === null) { $msg = "Neither source nor dest is set"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); return; } if (!$this->checkReadFile($readFile)) { return; } if (!$this->checkWriteFile($writeFile)) { return; } $this->enumerateSets(); $this->enumerateRemoves(); try { $this->ini->write($writeFile); $this->log("Wrote to $writeFile"); } catch (Exception $ex) { $msg = $ex->getMessage(); if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); } } /** * Work through all Set commands. * * @return void */ public function enumerateSets() { foreach ($this->sets as $set) { $value = $set->getValue(); $key = $set->getProperty(); $section = $set->getSection(); $operation = $set->getOperation(); if ($value !== null) { try { $this->ini->set($section, $key, $value); $this->log( "[$section] $key set to $value", Project::MSG_DEBUG ); } catch (Exception $ex) { $this->log( "Error setting value for section '" . $section . "', key '" . $key ."'" ); $this->log($ex->getMessage(), Project::MSG_DEBUG); } } elseif ($operation !== null) { $v = $this->ini->get($section, $key); // value might be wrapped in quotes with a semicolon at the end if (!is_numeric($v)) { if (preg_match('/^"(\d*)";?$/', $v, $match)) { $v = $match[1]; } elseif (preg_match("/^'(\d*)';?$/", $v, $match)) { $v = $match[1]; } else { $this->log( "Value $v is not numeric. Skipping $operation operation." ); continue; } } if ($operation == '+') { ++$v; } elseif ($operation == '-') { --$v; } else { if (($operation != '-') && ($operation != '+')) { $msg = "Unrecognised operation $operation"; if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); } } try { $this->ini->set($section, $key, $v); $this->log( "[$section] $key set to $v", Project::MSG_DEBUG ); } catch (Exception $ex) { $this->log( "Error setting value for section '" . $section . "', key '" . $key ."'" ); $this->log($ex->getMessage(), Project::MSG_DEBUG); } } else { $this->log( "Set: value and operation are both not set", Project::MSG_ERR ); } } } /** * Work through all Remove commands. * * @return void */ public function enumerateRemoves() { foreach ($this->removals as $remove) { $key = $remove->getProperty(); $section = $remove->getSection(); if ($section == '') { $this->log( "Remove: section must be set", Project::MSG_ERR ); continue; } $this->ini->remove($section, $key); if (($section != '') && ($key != '')) { $this->log( "$key in section [$section] has been removed.", Project::MSG_DEBUG ); } elseif (($section != '') && ($key == '')) { $this->log("[$section] has been removed.", Project::MSG_DEBUG); } } } /** * Set Source property * * @param string $source Name of originating ini file to parse * * @return void */ public function setSource($source) { $this->source = $source; } /** * Set Dest property * * @param string $dest Destination filename to write ini contents to. * * @return void */ public function setDest($dest) { $this->dest = $dest; } /** * Set haltonerror attribute. * * @param string $halt 'yes', or '1' to halt. * * @return void */ public function setHaltonerror($halt) { $doHalt = false; if (strtolower($halt) == 'yes' || $halt == 1) { $doHalt = true; } $this->haltonerror = $doHalt; } /** * Create a Set method * * @return IniFileSet */ public function createSet() { $set = new IniFileSet(); $this->sets[] = $set; return $set; } /** * Create a Remove method * * @return IniFileRemove */ public function createRemove() { $remove = new IniFileRemove(); $this->removals[] = $remove; return $remove; } } phing-2.16.0/tasks/ext/inifile/IniFileSet.php0000644000175000017500000000447113027032674017767 0ustar druiddruid * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * InifileSet * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link InifileSet.php */ class IniFileSet { /** * Property * * @var string */ protected $property = null; /** * Section * * @var string */ protected $section = null; /** * Value * * @var mixed */ protected $value = null; /** * Operation * * @var mixed */ protected $operation = null; /** * Set Operation * * @param string $operation +/- * * @return void */ public function setOperation($operation) { $this->operation = $operation; } /** * Get Operation * * @return void */ public function getOperation() { return $this->operation; } /** * Set Section name * * @param string $section Name of section in ini file * * @return void */ public function setSection($section) { $this->section = trim($section); } /** * Set Property * * @param string $property property/key name * * @return void */ public function setProperty($property) { $this->property = $property; } /** * Set Value * * @param string $value Value to set for key in ini file * * @return void */ public function setValue($value) { $this->value = $value; } /** * Get Property * * @return string */ public function getProperty() { return $this->property; } /** * Get Value * * @return string */ public function getValue() { return $this->value; } /** * Get Section * * @return string */ public function getSection() { return $this->section; } } phing-2.16.0/tasks/ext/inifile/IniFileConfig.php0000644000175000017500000001165313027032674020441 0ustar druiddruid * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ /** * Class for reading/writing ini config file * * This preserves comments etc, unlike parse_ini_file and is based heavily on * a solution provided at: * stackoverflow.com/questions/9594238/good-php-classes-that-manipulate-ini-files * * @category Tasks * @package phing.tasks.ext * @author Ken Guest * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html * @link http://www.phing.info/ */ class IniFileConfig { /** * Lines of ini file * * @var array */ protected $lines = array(); /** * Read ini file * * @param string $file filename * * @return void */ public function read($file) { $this->lines = array(); $section = ''; foreach (file($file) as $line) { if (preg_match('/^\s*(;.*)?$/', $line)) { // comment or whitespace $this->lines[] = array( 'type' => 'comment', 'data' => $line, 'section' => $section ); } elseif (preg_match('/^\s?\[(.*)\]/', $line, $match)) { // section $section = $match[1]; $this->lines[] = array( 'type' => 'section', 'data' => $line, 'section' => $section ); } elseif (preg_match('/^\s*(.*?)\s*=\s*(.*?)\s*$/', $line, $match)) { // entry $this->lines[] = array( 'type' => 'entry', 'data' => $line, 'section' => $section, 'key' => $match[1], 'value' => $match[2] ); } } } /** * Get value of given key in specified section * * @param string $section Section * @param string $key Key * * @return void */ public function get($section, $key) { foreach ($this->lines as $line) { if ($line['type'] != 'entry') { continue; } if ($line['section'] != $section) { continue; } if ($line['key'] != $key) { continue; } return $line['value']; } throw new RuntimeException('Missing Section or Key'); } /** * Set key to value in specified section * * @param string $section Section * @param string $key Key * @param string $value Value * * @return void */ public function set($section, $key, $value) { foreach ($this->lines as &$line) { if ($line['type'] != 'entry') { continue; } if ($line['section'] != $section) { continue; } if ($line['key'] != $key) { continue; } $line['value'] = $value; $line['data'] = $key . " = " . $value . PHP_EOL; return; } throw new RuntimeException('Missing Section or Key'); } /** * Remove key/section from file. * * If key is not specified, then the entire section will be removed. * * @param string $section Section to manipulate/remove * @param string $key Name of key to remove, might be null/empty * * @return void */ public function remove($section, $key) { if ($section == '') { throw new RuntimeException("Section not set."); } if (is_null($key) || ($key == '')) { // remove entire section foreach ($this->lines as $linenum => $line) { if ($line['section'] == $section) { unset($this->lines[$linenum]); } } } else { foreach ($this->lines as $linenum => $line) { if (($line['section'] == $section) && (isset($line['key'])) && ($line['key'] == $key) ) { unset($this->lines[$linenum]); } } } } /** * Write contents out to file * * @param string $file filename * * @return void */ public function write($file) { if (file_exists($file) && !is_writable($file)) { throw new RuntimeException("$file is not writable"); } $fp = fopen($file, 'w'); foreach ($this->lines as $line) { fwrite($fp, $line['data']); } fclose($fp); } } phing-2.16.0/tasks/ext/ThrowTask.php0000644000175000017500000000403613027032674016300 0ustar druiddruid. */ require_once 'phing/tasks/system/FailTask.php'; /** * Exits the active build, giving an additional message * if available. * * @author Hans Lellelid (Phing) * @author Nico Seessle (Ant) * @version $Id: 3b63d08533321a87618f87c564bde9d609b91f36 $ * @package phing.tasks.system */ class ThrowTask extends FailTask { /** * @var Reference */ private $reference = null; /** * @throws BuildException */ public function main() { $reffed = $this->reference !== null ? $this->reference->getReferencedObject($this->getProject()) : null; if ($reffed !== null && $reffed instanceof BuildException) { throw $reffed; } parent::main(); } /** * @param Reference $ref * * @return void */ public function setRefid(Reference $ref) { $this->reference = $ref; } /** * @return Reference */ public function getRefid() { return $this->reference; } } phing-2.16.0/tasks/ext/HttpRequestTask.php0000644000175000017500000001241513027032674017465 0ustar druiddruid. */ require_once 'phing/tasks/ext/HttpTask.php'; /** * A HTTP request task. * Making an HTTP request and try to match the response against an provided * regular expression. * * @package phing.tasks.ext * @author Benjamin Schultz * @version $Id: ab6a2d3903492a67c2a16f15ae667d8866af6c1e $ * @since 2.4.1 */ class HttpRequestTask extends HttpTask { /** * Holds the regular expression that should match the response * * @var string */ protected $responseRegex = ''; /** * Whether to enable detailed logging * * @var boolean */ protected $verbose = false; /** * Holds the events that will be logged * * @var array */ protected $observerEvents = array( 'connect', 'sentHeaders', 'sentBodyPart', 'receivedHeaders', 'receivedBody', 'disconnect', ); /** * Holds the request method * * @var string */ protected $method = null; /** * Holds additional post parameters for the request * * @var Parameter[] */ protected $postParameters = array(); /** * Sets the response regex * * @param string $regex */ public function setResponseRegex($regex) { $this->responseRegex = $regex; } /** * Sets whether to enable detailed logging * * @param boolean $verbose */ public function setVerbose($verbose) { $this->verbose = StringHelper::booleanValue($verbose); } /** * Sets a list of observer events that will be logged if verbose output is enabled. * * @param string $observerEvents List of observer events */ public function setObserverEvents($observerEvents) { $this->observerEvents = array(); $token = ' ,;'; $ext = strtok($observerEvents, $token); while ($ext !== false) { $this->observerEvents[] = $ext; $ext = strtok($token); } } /** * The setter for the method * @param $method */ public function setMethod($method) { $this->method = $method; } /** * Creates post body parameters for this request * * @return Parameter The created post parameter */ public function createPostParameter() { $num = array_push($this->postParameters, new Parameter()); return $this->postParameters[$num - 1]; } /** * Load the necessary environment for running this task. * * @throws BuildException */ public function init() { parent::init(); $this->authScheme = HTTP_Request2::AUTH_BASIC; // Other dependencies that should only be loaded when class is actually used require_once 'HTTP/Request2/Observer/Log.php'; } /** * Creates and configures an instance of HTTP_Request2 * * @return HTTP_Request2 */ protected function createRequest() { $request = parent::createRequest(); if ($this->method == HTTP_Request2::METHOD_POST) { $request->setMethod(HTTP_Request2::METHOD_POST); foreach ($this->postParameters as $postParameter) { $request->addPostParameter($postParameter->getName(), $postParameter->getValue()); } } if ($this->verbose) { $observer = new HTTP_Request2_Observer_Log(); // set the events we want to log $observer->events = $this->observerEvents; $request->attach($observer); } return $request; } /** * Checks whether response body matches the given regexp * * @param HTTP_Request2_Response $response * @return void * @throws BuildException */ protected function processResponse(HTTP_Request2_Response $response) { if ($this->responseRegex !== '') { $matches = array(); preg_match($this->responseRegex, $response->getBody(), $matches); if (count($matches) === 0) { throw new BuildException('The received response body did not match the given regular expression'); } else { $this->log('The response body matched the provided regex.'); } } } } phing-2.16.0/tasks/ext/WikiPublishTask.php0000644000175000017500000002444413027032674017434 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * Publish Wiki document using Wiki API. * * @author Piotr Lewandowski * @package phing.tasks.ext */ class WikiPublishTask extends Task { /** * Wiki API url * * @var string */ private $apiUrl; /** * Wiki API user name * * @var string */ private $apiUser; /** * Wiki API password * * @var string */ private $apiPassword; /** * Wiki document Id. Document can be identified by title instead. * * @var int */ private $id; /** * Wiki document title * * @var string */ private $title; /** * Wiki document content * * @var string */ private $content; /** * Publishing mode (append, prepend, overwrite). * * @var string */ private $mode = 'append'; /** * Publish modes map * @var array */ private $modeMap = array( 'overwrite' => 'text', 'append' => 'appendtext', 'prepend' => 'prependtext', ); /** * Curl handler * * @var resource */ private $curl; /** * Wiki api edit token * * @var string */ private $apiEditToken; /** * Temporary cookies file * * @var string */ private $cookiesFile; /** * @param string $apiPassword */ public function setApiPassword($apiPassword) { $this->apiPassword = $apiPassword; } /** * @return string */ public function getApiPassword() { return $this->apiPassword; } /** * @param string $apiUrl */ public function setApiUrl($apiUrl) { $this->apiUrl = $apiUrl; } /** * @return string */ public function getApiUrl() { return $this->apiUrl; } /** * @param string $apiUser */ public function setApiUser($apiUser) { $this->apiUser = $apiUser; } /** * @return string */ public function getApiUser() { return $this->apiUser; } /** * @param int $id */ public function setId($id) { $this->id = $id; } /** * @return int */ public function getId() { return $this->id; } /** * @param string $mode * @throws BuildException */ public function setMode($mode) { if (false === isset($this->modeMap[$mode])) { throw new BuildException('Mode is invalid (' . $mode . ', should be one of ' . implode( ',', array_keys($this->modeMap) ) . ')'); } $this->mode = $mode; } /** * @return string */ public function getMode() { return $this->mode; } /** * @param string $title */ public function setTitle($title) { $this->title = $title; } /** * @return string */ public function getTitle() { return $this->title; } /** * @param string $content */ public function setContent($content) { $this->content = $content; } /** * @return string */ public function getContent() { return $this->content; } /** * Prepare CURL object * * @throws BuildException */ public function init() { $this->cookiesFile = tempnam(sys_get_temp_dir(), 'WikiPublish.' . uniqid() . '.cookies'); $this->curl = curl_init(); if (false === is_resource($this->curl)) { throw new BuildException('Curl init failed (' . $this->apiUrl . ')'); } curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookiesFile); curl_setopt($this->curl, CURLOPT_COOKIEFILE, $this->cookiesFile); } /** * The main entry point method */ public function main() { $this->validateAttributes(); $this->callApiLogin(); $this->callApiEdit(); } /** * Close curl connection and clean up */ public function __destruct() { if (null !== $this->curl && is_resource($this->curl)) { curl_close($this->curl); } if (null !== $this->cookiesFile && file_exists($this->cookiesFile)) { unlink($this->cookiesFile); } } /** * Validates attributes coming in from XML * * @throws BuildException */ private function validateAttributes() { if (null === $this->apiUrl) { throw new BuildException('Wiki apiUrl is required'); } if (null === $this->id && null === $this->title) { throw new BuildException('Wiki page id or title is required'); } } /** * Call Wiki webapi login action * * @param string|null $token * * @throws BuildException */ private function callApiLogin($token = null) { $postData = array('lgname' => $this->apiUser, 'lgpassword' => $this->apiPassword); if (null !== $token) { $postData['lgtoken'] = $token; } $result = $this->callApi('action=login', $postData); try { $this->checkApiResponseResult('login', $result); } catch (BuildException $e) { if (null !== $token) { throw $e; } // if token is required then call login again with token $this->checkApiResponseResult('login', $result, 'NeedToken'); if (isset($result['login']) && isset($result['login']['token'])) { $this->callApiLogin($result['login']['token']); } else { throw $e; } } } /** * Call Wiki webapi edit action */ private function callApiEdit() { $this->callApiTokens(); $result = $this->callApi('action=edit&token=' . urlencode($this->apiEditToken), $this->getApiEditData()); $this->checkApiResponseResult('edit', $result); } /** * Return prepared data for Wiki webapi edit action * * @return array */ private function getApiEditData() { $result = array( 'minor' => '', ); if (null !== $this->title) { $result['title'] = $this->title; } if (null !== $this->id) { $result['pageid'] = $this->id; } $result[$this->modeMap[$this->mode]] = $this->content; return $result; } /** * Call Wiki webapi tokens action * * @throws BuildException */ private function callApiTokens() { $result = $this->callApi('action=tokens&type=edit'); if (false == isset($result['tokens']) || false == isset($result['tokens']['edittoken'])) { throw new BuildException('Wiki token not found'); } $this->apiEditToken = $result['tokens']['edittoken']; } /** * Call Wiki webapi * * @param string $queryString * @param array|null $postData * * @return array * @throws BuildException */ protected function callApi($queryString, $postData = null) { $this->setPostData($postData); $url = $this->apiUrl . '?' . $queryString . '&format=php'; curl_setopt($this->curl, CURLOPT_URL, $url); $response = curl_exec($this->curl); $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); if (200 !== $responseCode) { throw new BuildException('Wiki webapi call failed (http response ' . $responseCode . ')'); } $result = @unserialize($response); if (false === $result) { throw new BuildException('Couldn\'t unserialize Wiki webapi response'); } return $result; } /** * Set POST data for curl call * * @param array|null $data */ private function setPostData($data = null) { if (null === $data) { curl_setopt($this->curl, CURLOPT_POST, false); return; } $postData = ''; foreach ($data as $key => $value) { $postData .= urlencode($key) . '=' . urlencode($value) . '&'; } if ($postData != '') { curl_setopt($this->curl, CURLOPT_POST, true); curl_setopt($this->curl, CURLOPT_POSTFIELDS, substr($postData, 0, -1)); } } /** * Validate Wiki webapi response * * @param string $action * @param array $response * @param string $expect * * @throws BuildException */ private function checkApiResponseResult($action, $response, $expect = 'Success') { if (isset($response['error'])) { throw new BuildException( 'Wiki response error (action: ' . $action . ', error code: ' . $response['error']['code'] . ')'); } if (false == isset($response[$action]) || false == isset($response[$action]['result'])) { throw new BuildException('Wiki response result not found (action: ' . $action . ')'); } if ($response[$action]['result'] !== $expect) { throw new BuildException( 'Unexpected Wiki response result ' . $response[$action]['result'] . ' (expected: ' . $expect . ')'); } } } phing-2.16.0/tasks/ext/Service/Amazon/S3/S3PutTask.php0000644000175000017500000002570413027032674021272 0ustar druiddruid. */ require_once dirname(dirname(__FILE__)) . '/S3.php'; /** * Stores an object on S3 * * @version $Id: 37e9c57cc495b2eb764a5bbd6221a7d6ad115127 $ * @package phing.tasks.ext * @author Andrei Serdeliuc * @extends Service_Amazon_S3 */ class S3PutTask extends Service_Amazon_S3 { /** * File we're trying to upload * * (default value: null) * * @var string */ protected $_source = null; /** * Content we're trying to upload * * The user can specify either a file to upload or just a bit of content * * (default value: null) * * @var mixed */ protected $_content = null; /** * Collection of filesets * Used for uploading multiple files * * (default value: array()) * * @var array */ protected $_filesets = array(); /** * Whether to try to create buckets or not * * (default value: false) * * @var bool */ protected $_createBuckets = false; /** * File ACL * Use to set the permission to the uploaded files * * (default value: 'private') * * @var string */ protected $_acl = 'private'; /** * File content type * Use this to set the content type of your static files * Set contentType to "auto" if you want to autodetect the content type based on the source file extension * * (default value: 'binary/octet-stream') * * @var string */ protected $_contentType = 'binary/octet-stream'; /** * Object maxage (in seconds). * * @var int */ protected $_maxage = null; /** * Content is gzipped. * * @var boolean */ protected $_gzipped = false; /** * Extension content type mapper * * @var array */ protected $_extensionContentTypeMapper = array( 'js' => 'application/x-javascript', 'css' => 'text/css', 'html' => 'text/html', 'gif' => 'image/gif', 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'txt' => 'text/plain' ); /** * Whether filenames contain paths * * (default value: false) * * @var bool */ protected $_fileNameOnly = false; /** * @param $source * @throws BuildException */ public function setSource($source) { if (!is_readable($source)) { throw new BuildException('Source is not readable: ' . $source); } $this->_source = $source; } /** * @return string * @throws BuildException */ public function getSource() { if ($this->_source === null) { throw new BuildException('Source is not set'); } return $this->_source; } /** * @param $content * @throws BuildException */ public function setContent($content) { if (empty($content) || !is_string($content)) { throw new BuildException('Content must be a non-empty string'); } $this->_content = $content; } /** * @return mixed * @throws BuildException */ public function getContent() { if ($this->_content === null) { throw new BuildException('Content is not set'); } return $this->_content; } /** * @param $object * @throws BuildException */ public function setObject($object) { if (empty($object) || !is_string($object)) { throw new BuildException('Object must be a non-empty string'); } $this->_object = $object; } public function getObject() { if ($this->_object === null) { throw new BuildException('Object is not set'); } return $this->_object; } /** * @param $permission * @throws BuildException */ public function setAcl($permission) { $valid_acl = array('private', 'public-read', 'public-read-write', 'authenticated-read'); if (empty($permission) || !is_string($permission) || !in_array($permission, $valid_acl)) { throw new BuildException('Object must be one of the following values: ' . implode('|', $valid_acl)); } $this->_acl = $permission; } /** * @return string */ public function getAcl() { return $this->_acl; } /** * @param $contentType */ public function setContentType($contentType) { $this->_contentType = $contentType; } /** * @return string * @throws BuildException */ public function getContentType() { if ($this->_contentType === 'auto') { $ext = strtolower(substr(strrchr($this->getSource(), '.'), 1)); if (isset($this->_extensionContentTypeMapper[$ext])) { return $this->_extensionContentTypeMapper[$ext]; } else { return 'binary/octet-stream'; } } else { return $this->_contentType; } } /** * @param $createBuckets */ public function setCreateBuckets($createBuckets) { $this->_createBuckets = (bool) $createBuckets; } /** * @return bool */ public function getCreateBuckets() { return (bool) $this->_createBuckets; } /** * Set seconds in max-age, null value exclude max-age setup. * * @param int $seconds */ public function setMaxage($seconds) { $this->_maxage = $seconds; } /** * Get seconds in max-age or null. * * @return int * Number of seconds in maxage or null. */ public function getMaxage() { return $this->_maxage; } /** * Set if content is gzipped. * * @param boolean $gzipped */ public function setGzip($gzipped) { $this->_gzipped = $gzipped; } /** * Return if content is gzipped. * * @return booleand * Indicate if content is gzipped. */ public function getGzip() { return $this->_gzipped; } /** * Generate HTTPHEader array sent to S3. * * @return array * HttpHeader to set in S3 Object. */ protected function getHttpHeaders() { $headers = array(); if (!is_null($this->_maxage)) { $headers['Cache-Control'] = 'max-age=' . $this->_maxage; } if ($this->_gzipped) { $headers['Content-Encoding'] = 'gzip'; } return $headers; } /** * @param $fileNameOnly */ public function setFileNameOnly($fileNameOnly) { $this->_fileNameOnly = (bool) $fileNameOnly; } /** * creator for _filesets * * @return FileSet */ public function createFileset() { $num = array_push($this->_filesets, new FileSet()); return $this->_filesets[$num - 1]; } /** * getter for _filesets * * @return array */ public function getFilesets() { return $this->_filesets; } /** * Determines what we're going to store in the object * * If _content has been set, this will get stored, * otherwise, we read from _source * * @throws BuildException * @return string */ public function getObjectData() { try { $content = $this->getContent(); } catch (BuildException $e) { $source = $this->getSource(); if (!is_file($source)) { throw new BuildException('Currently only files can be used as source'); } $content = file_get_contents($source); } return $content; } /** * Store the object on S3 * * @throws BuildException * @return void */ public function execute() { if (!$this->isBucketAvailable()) { if (!$this->getCreateBuckets()) { throw new BuildException('Bucket doesn\'t exist and createBuckets not specified'); } else { if (!$this->createBucket()) { throw new BuildException('Bucket cannot be created'); } } } // Filesets take precedence if (!empty($this->_filesets)) { $objects = array(); foreach ($this->_filesets as $fs) { if (!($fs instanceof FileSet)) { continue; } $ds = $fs->getDirectoryScanner($this->getProject()); $objects = array_merge($objects, $ds->getIncludedFiles()); } $fromDir = $fs->getDir($this->getProject())->getAbsolutePath(); if ($this->_fileNameOnly) { foreach ($objects as $object) { $this->_source = $object; $this->saveObject(basename($object), file_get_contents($fromDir . DIRECTORY_SEPARATOR . $object)); } } else { foreach ($objects as $object) { $this->_source = $object; $this->saveObject( str_replace('\\', '/', $object), file_get_contents($fromDir . DIRECTORY_SEPARATOR . $object) ); } } return true; } $this->saveObject($this->getObject(), $this->getObjectData()); } /** * @param $object * @param $data * @throws BuildException */ protected function saveObject($object, $data) { $object = $this->getObjectInstance($object); $object->data = $data; $object->acl = $this->getAcl(); $object->contentType = $this->getContentType(); $object->httpHeaders = $this->getHttpHeaders(); $object->save(); if (!$this->isObjectAvailable($object->key)) { throw new BuildException('Upload failed'); } } } phing-2.16.0/tasks/ext/Service/Amazon/S3/S3GetTask.php0000644000175000017500000000640213027032674021233 0ustar druiddruid. */ require_once dirname(dirname(__FILE__)) . '/S3.php'; /** * Downloads an object off S3 * * @version $Id: 755f7c3784838bc960dba9520a10490c640a61cd $ * @package phing.tasks.ext * @author Andrei Serdeliuc * @extends Service_Amazon_S3 */ class S3GetTask extends Service_Amazon_S3 { /** * This is where we'll store the object * * (default value: null) * * @var mixed */ protected $_target = null; /** * The S3 object we're working with * * (default value: null) * * @var mixed */ protected $_object = null; /** * @param $object * @throws BuildException */ public function setObject($object) { if (empty($object) || !is_string($object)) { throw new BuildException('Object must be a non-empty string'); } $this->_object = $object; } /** * @return mixed * @throws BuildException */ public function getObject() { if ($this->_object === null) { throw new BuildException('Object is not set'); } return $this->_object; } /** * @param $target * @throws BuildException */ public function setTarget($target) { if (!is_file($target) && !is_dir($target) && !is_link($target)) { if (!is_writable(dirname($target))) { throw new BuildException('Target is not writable: ' . $target); } } else { if (!is_writable($target)) { throw new BuildException('Target is not writable: ' . $target); } } $this->_target = $target; } /** * @return mixed * @throws BuildException */ public function getTarget() { if ($this->_target === null) { throw new BuildException('Target is not set'); } return $this->_target; } public function execute() { $target = $this->getTarget(); // Use the object name as the target if the current target is a directory if (is_dir($target)) { $target = rtrim($target, '/') . '/' . $this->getObject(); } file_put_contents($target, $this->getObjectContents($this->getObject())); } } phing-2.16.0/tasks/ext/Service/Amazon/S3.php0000644000175000017500000001131613027032674017463 0ustar druiddruid. */ require_once dirname(dirname(__FILE__)) . "/Amazon.php"; /** * Abstract Service_Amazon_S3 class. * * Provides common methods and properties to all of the S3 tasks * * @version $ID$ * @package phing.tasks.ext * @author Andrei Serdeliuc */ abstract class Service_Amazon_S3 extends Service_Amazon { /** * Services_Amazon_S3 client * * (default value: null) * * @var Services_Amazon_S3 * @see Services_Amazon_S3 */ protected $_client = null; /** * We only instantiate the client once per task call * * @return Services_Amazon_S3 */ public function getClient() { require_once "Services/Amazon/S3.php"; if ($this->_client === null) { $this->_client = Services_Amazon_S3::getAccount($this->getKey(), $this->getSecret()); } return $this->_client; } /** * @param $bucket * @throws BuildException */ public function setBucket($bucket) { if (empty($bucket) || !is_string($bucket)) { throw new BuildException('Bucket must be a non-empty string'); } $this->bucket = (string) $bucket; } /** * @throws BuildException */ public function getBucket() { if (!($bucket = $this->bucket)) { throw new BuildException('Bucket is not set'); } return $this->bucket; } /** * Returns an instance of Services_Amazon_S3_Resource_Object * * @param mixed $object * @return Services_Amazon_S3_Resource_Object */ public function getObjectInstance($object) { return $this->getBucketInstance()->getObject($object); } /** * Check if the object already exists in the current bucket * * @param mixed $object * @return bool */ public function isObjectAvailable($object) { return (bool) $this->getObjectInstance($object)->load(Services_Amazon_S3_Resource_Object::LOAD_METADATA_ONLY); } /** * Returns an instance of Services_Amazon_S3_Resource_Bucket * * @return Services_Amazon_S3_Resource_Bucket */ public function getBucketInstance() { return $this->getClient()->getBucket($this->getBucket()); } /** * Check if the current bucket is available * * @return bool */ public function isBucketAvailable() { return (bool) $this->getBucketInstance($this->getBucket())->load(); } /** * Get the contents of an object (by it's name) * * @param string $object * @throws BuildException * @return mixed */ public function getObjectContents($object) { if (!$this->isBucketAvailable($this->getBucket())) { throw new BuildException('Bucket doesn\'t exist or wrong permissions'); } $bucket = $this->getClient()->getBucket($this->getBucket()); if (!$this->isObjectAvailable($object)) { throw new BuildException('Object not available: ' . $object); } $object = $this->getObjectInstance($object); $object->load(); return $object->data; } /** * Create a bucket * * @return bool */ public function createBucket() { $bucket = $this->getBucketInstance(); $bucket->name = $this->getBucket(); $bucket->save(); return $this->isBucketAvailable(); } /** * Main entry point, doesn't do anything * * @return void */ final public function main() { $this->execute(); } /** * Entry point to children tasks * * @return void */ abstract public function execute(); } phing-2.16.0/tasks/ext/Service/Amazon.php0000644000175000017500000000656513027032674017210 0ustar druiddruid. */ require_once "phing/Task.php"; /** * Abstract Service_Amazon class. * * Implements common methods & properties used by all Amazon services * * @extends Task * @version $ID$ * @package phing.tasks.ext * @author Andrei Serdeliuc * @abstract */ abstract class Service_Amazon extends Task { /** * Collection of set options * * We set these magically so we can also load then from the environment * * (default value: array()) * * @var array */ protected $_options = array(); /** * @param $var * @param $val */ public function __set($var, $val) { $this->_options[$var] = $val; } /** * Property getter * * If the property hasn't been previously set (through the task call normally), * it will try to load it from the project * * This way, we can define global properties for the "Amazon" service, like key and secret * * @param mixed $var * @return mixed */ public function __get($var) { if (!isset($this->$var)) { if (!($val = $this->getProject()->getProperty('amazon.' . strtolower($var)))) { return false; } else { return $val; } } return $this->_options[$var]; } /** * @param $var * @return bool */ public function __isset($var) { return array_key_exists($var, $this->_options); } /** * @param $key * @throws BuildException */ public function setKey($key) { if (empty($key) || !is_string($key)) { throw new BuildException('Key must be a non empty string'); } $this->key = $key; } public function getKey() { if (!($key = $this->key)) { throw new BuildException('Key is not set'); } return $key; } /** * @param $secret * @throws BuildException */ public function setSecret($secret) { if (empty($secret) || !is_string($secret)) { throw new BuildException('Secret must be a non empty string'); } $this->secret = $secret; } public function getSecret() { if (!($secret = $this->secret)) { throw new BuildException('Secret is not set'); } return $this->secret; } } phing-2.16.0/tasks/ext/PatchTask.php0000644000175000017500000001545313027032674016241 0ustar druiddruidpatchFile = $file; } /** * The file to patch * * Optional if it can be inferred from the diff file. * * @param string $file File to patch * @return void */ public function setOriginalFile($file) { $this->originalFile = $file; } /** * The name of a file to send the output to, instead of patching * the file(s) in place * * Optional. * * @param string $file File to send the output to * @return void */ public function setDestFile($file) { if ($file !== null) { $this->cmdArgs [] = "--output=$file"; } } /** * Flag to create backups * * Optional, default - false * * @param bool $backups If true create backups * @return void */ public function setBackups($backups) { if ($backups) { $this->cmdArgs [] = '--backup'; } } /** * Flag to ignore whitespace differences; * * Default - false * * @param bool $ignore If true ignore whitespace differences * @return void */ public function setIgnoreWhiteSpace($ignore) { if ($ignore) { $this->cmdArgs [] = '--ignore-whitespace'; } } /** * Strip the smallest prefix containing num leading slashes * from filenames. * * patch's --strip option. * * @param int $num number of lines to strip * @return void * @throws BuildException if num is < 0, or other errors */ public function setStrip($num) { if ($num < 0) { throw new BuildException('strip has to be >= 0'); } $this->strip = $num; } /** * Work silently unless an error occurs * * Optional, default - false * @param bool $flag If true suppress set the -s option on the patch command * @return void */ public function setQuiet($flag) { if ($flag) { $this->cmdArgs [] = '--silent'; } } /** * Assume patch was created with old and new files swapped * * Optional, default - false * * @param bool $flag If true set the -R option on the patch command * @return void */ public function setReverse($flag) { if ($flag) { $this->cmdArgs [] = '--reverse'; } } /** * The directory to run the patch command in * * Defaults to the project's base directory. * * @param string $directory Directory to run the patch command in * @return void */ public function setDir($directory) { $this->cmdArgs [] = "--directory=$directory"; } /** * Ignore patches that seem to be reversed or already applied * * @param bool $flag If true set the -N (--forward) option * @return void */ public function setForward($flag) { if ($flag) { $this->cmdArgs [] = "--forward"; } } /** * Set the maximum fuzz factor * * Defaults to 0 * * @param string $value Value of a fuzz factor * @return void */ public function setFuzz($value) { $this->cmdArgs [] = "--fuzz=$value"; } /** * If true, stop the build process if the patch command * exits with an error status. * * The default is "false" * * @param bool $value "true" if it should halt, otherwise "false" * @return void */ public function setHaltOnFailure($value) { $this->haltOnFailure = $value; } /** * Main task method * * @return void * @throws BuildException when it all goes a bit pear shaped */ public function main() { if ($this->patchFile == null) { throw new BuildException('patchfile argument is required'); } // Define patch file $this->cmdArgs [] = '-i ' . $this->patchFile; // Define strip factor if ($this->strip != null) { $this->cmdArgs [] = '--strip=' . $this->strip; } // Define original file if specified if ($this->originalFile != null) { $this->cmdArgs [] = $this->originalFile; } $cmd = self::CMD . implode(' ', $this->cmdArgs); $this->log('Applying patch: ' . $this->patchFile); exec($cmd, $output, $exitCode); foreach ($output as $line) { $this->log($line, Project::MSG_VERBOSE); } if ($exitCode != 0 && $this->haltOnFailure) { throw new BuildException("Task exited with code $exitCode"); } } } phing-2.16.0/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php0000644000175000017500000000630513027032674023201 0ustar druiddruid. */ /** * Remove from cache files where contains errors * * @category PHP * @package PHP_CodeSniffer * @author Rui Filipe Da Cunha Alves */ class PHP_CodeSniffer_Reports_PhingRemoveFromCache implements PHP_CodeSniffer_Report { /** * Cache data storage * @var DataStore */ protected static $cache; /** * Set cache object * * @param DataStore $cache */ public static function setCache($cache) { self::$cache = $cache; } /** * Remove file from cache if contains errors * * @param array $report Prepared report data. * @param PHP_CodeSniffer_File $phpcsFile The file being reported on. * @param boolean $showSources Show sources? * @param int $width Maximum allowed line width. * * @return boolean */ public function generateFileReport( $report, PHP_CodeSniffer_File $phpcsFile, $showSources = false, $width = 80 ) { if (!self::$cache || ($report['errors'] === 0 && $report['warnings'] === 0)) { // Nothing to do return false; } self::$cache->remove($report['filename']); return false; } /** * Do nothing * * @param string $cachedData Any partial report data that was returned from * generateFileReport during the run. * @param int $totalFiles Total number of files processed during the run. * @param int $totalErrors Total number of errors found during the run. * @param int $totalWarnings Total number of warnings found during the run. * @param int $totalFixable Total number of problems that can be fixed. * @param boolean $showSources Show sources? * @param int $width Maximum allowed line width. * @param boolean $toScreen Is the report being printed to screen? * * @return void */ public function generate( $cachedData, $totalFiles, $totalErrors, $totalWarnings, $totalFixable, $showSources = false, $width = 80, $toScreen = true ) { // Do nothing } } phing-2.16.0/tasks/ext/phpcs/PhpCodeSnifferTask_Wrapper.php0000644000175000017500000000254313027032674022652 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * Wrapper to disable PHPCS's destructor * * @author Michiel Rook * @version $Id: 0165de67f7d92e363d668430c692ab7f3658dec6 $ * @package phing.tasks.ext */ class PhpCodeSnifferTask_Wrapper extends PHP_CodeSniffer { public function __destruct() { // override destructor } } phing-2.16.0/tasks/ext/JslLintTask.php0000644000175000017500000002547313027032674016564 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/util/DataStore.php'; /** * A Javascript lint task. Checks syntax of Javascript files. * Javascript lint (http://www.javascriptlint.com) must be in the system path. * This class is based on Knut Urdalen's PhpLintTask. * * @author Stefan Priebsch * * @package phing.tasks.ext */ class JslLintTask extends Task { /** @var PhingFile */ protected $file; // the source file (from xml attribute) /** @var array */ protected $filesets = array(); // all fileset objects assigned to this task /** @var bool $showWarnings */ protected $showWarnings = true; /** @var bool */ protected $haltOnFailure = false; /** * @var bool */ protected $haltOnWarning = false; /** * @var bool */ protected $hasErrors = false; /** * @var bool */ protected $hasWarnings = false; /** @var array $badFiles */ private $badFiles = array(); /** @var DataStore */ private $cache = null; /** @var PhingFile */ private $conf = null; /** @var string */ private $executable = "jsl"; /** @var PhingFile */ protected $tofile = null; /** * Sets the flag if warnings should be shown * * @param boolean $show */ public function setShowWarnings($show) { $this->showWarnings = StringHelper::booleanValue($show); } /** * The haltonfailure property * * @param boolean $aValue */ public function setHaltOnFailure($aValue) { $this->haltOnFailure = $aValue; } /** * The haltonwarning property * * @param boolean $aValue */ public function setHaltOnWarning($aValue) { $this->haltOnWarning = $aValue; } /** * File to be performed syntax check on * * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Whether to store last-modified times in cache * * @param PhingFile $file */ public function setCacheFile(PhingFile $file) { $this->cache = new DataStore($file); } /** * jsl config file * * @param PhingFile $file */ public function setConfFile(PhingFile $file) { $this->conf = $file; } /** * @param string $path * * @throws BuildException */ public function setExecutable($path) { $this->executable = $path; if (!@file_exists($path)) { throw new BuildException("JavaScript Lint executable '{$path}' not found"); } } /** * @return string */ public function getExecutable() { return $this->executable; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * File to save error messages to * * @param PhingFile $tofile */ public function setToFile(PhingFile $tofile) { $this->tofile = $tofile; } /** * Execute lint check against PhingFile or a FileSet */ public function main() { if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } if (empty($this->executable)) { throw new BuildException("Missing the 'executable' attribute"); } if ($this->file instanceof PhingFile) { $this->lint($this->file->getPath()); } else { // process filesets $project = $this->getProject(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($project); $files = $ds->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath(); foreach ($files as $file) { $this->lint($dir . DIRECTORY_SEPARATOR . $file); } } } // write list of 'bad files' to file (if specified) if ($this->tofile) { $writer = new FileWriter($this->tofile); foreach ($this->badFiles as $file => $messages) { foreach ($messages as $msg) { $writer->write($file . "=" . $msg . PHP_EOL); } } $writer->close(); } if ($this->haltOnFailure && $this->hasErrors) { throw new BuildException('Syntax error(s) in JS files:' . implode( ', ', array_keys($this->badFiles) )); } if ($this->haltOnWarning && $this->hasWarnings) { throw new BuildException('Syntax warning(s) in JS files:' . implode( ', ', array_keys($this->badFiles) )); } } /** * Performs the actual syntax check * * @param string $file * * @throws BuildException * * @return bool|void */ protected function lint($file) { $command = $this->executable . ' -output-format ' . escapeshellarg( 'file:__FILE__;line:__LINE__;message:__ERROR__' ) . ' '; if (isset($this->conf)) { $command .= '-conf ' . escapeshellarg($this->conf->getPath()) . ' '; } $command .= '-process '; if (file_exists($file)) { if (is_readable($file)) { if ($this->cache) { $lastmtime = $this->cache->get($file); if ($lastmtime >= filemtime($file)) { $this->log("Not linting '" . $file . "' due to cache", Project::MSG_DEBUG); return false; } } $messages = array(); exec($command . '"' . $file . '"', $messages, $return); if ($return > 100) { throw new BuildException("Could not execute Javascript Lint executable '{$this->executable}'"); } $summary = $messages[sizeof($messages) - 1]; preg_match('/(\d+)\serror/', $summary, $matches); $errorCount = (count($matches) > 1 ? $matches[1] : 0); preg_match('/(\d+)\swarning/', $summary, $matches); $warningCount = (count($matches) > 1 ? $matches[1] : 0); $errors = array(); $warnings = array(); if ($errorCount > 0 || $warningCount > 0) { $last = false; foreach ($messages as $message) { $matches = array(); if (preg_match('/^(\.*)\^$/', $message)) { $column = strlen($message); if ($last == 'error') { $errors[count($errors) - 1]['column'] = $column; } else { if ($last == 'warning') { $warnings[count($warnings) - 1]['column'] = $column; } } $last = false; } if (!preg_match('/^file:(.+);line:(\d+);message:(.+)$/', $message, $matches)) { continue; } $msg = $matches[3]; $data = array('filename' => $matches[1], 'line' => $matches[2], 'message' => $msg); if (preg_match('/^.*error:.+$/i', $msg)) { $errors[] = $data; $last = 'error'; } else { if (preg_match('/^.*warning:.+$/i', $msg)) { $warnings[] = $data; $last = 'warning'; } } } } if ($this->showWarnings && $warningCount > 0) { $this->log($file . ': ' . $warningCount . ' warnings detected', Project::MSG_WARN); foreach ($warnings as $warning) { $this->log( '- line ' . $warning['line'] . (isset($warning['column']) ? ' column ' . $warning['column'] : '') . ': ' . $warning['message'], Project::MSG_WARN ); } $this->hasWarnings = true; } if ($errorCount > 0) { $this->log($file . ': ' . $errorCount . ' errors detected', Project::MSG_ERR); if (!isset($this->badFiles[$file])) { $this->badFiles[$file] = array(); } foreach ($errors as $error) { $message = 'line ' . $error['line'] . (isset($error['column']) ? ' column ' . $error['column'] : '') . ': ' . $error['message']; $this->log('- ' . $message, Project::MSG_ERR); array_push($this->badFiles[$file], $message); } $this->hasErrors = true; } else { if (!$this->showWarnings || $warningCount == 0) { $this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE); if ($this->cache) { $this->cache->put($file, filemtime($file)); } } } } else { throw new BuildException('Permission denied: ' . $file); } } else { throw new BuildException('File not found: ' . $file); } } } phing-2.16.0/tasks/ext/PackageAsPathTask.php0000644000175000017500000000370013027032674017626 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * Convert dot-notation packages to relative paths. * * @author Hans Lellelid * @version $Id: 7fee76167437d1ca7bdca2fef13aafc08811085f $ * @package phing.tasks.ext */ class PackageAsPathTask extends Task { /** The package to convert. */ protected $pckg; /** The property to store the conversion in. */ protected $name; /** * Executes the package to patch converstion and stores it * in the user property name. */ public function main() { $this->project->setUserProperty($this->name, strtr($this->pckg, '.', '/')); } /** * @param string $pckg the package to convert */ public function setPackage($pckg) { $this->pckg = $pckg; } /** * @param string $name the property to store the path in */ public function setName($name) { $this->name = $name; } } phing-2.16.0/tasks/ext/ZendCodeAnalyzerTask.php0000644000175000017500000002025113027032674020373 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * ZendCodeAnalyzerTask analyze PHP source code using the ZendCodeAnalyzer included in Zend Studio 5.1 * * Available warnings: * zend-error - %s(line %d): %s * oneline-comment - One-line comment ends with tag. * bool-assign - Assignment seen where boolean expression is expected. Did you mean '==' instead of '='? * bool-print - Print statement used when boolean expression is expected. * bool-array - Array used when boolean expression is expected. * bool-object - Object used when boolean expression is expected. * call-time-ref - Call-time reference is deprecated. Define function as accepting parameter by reference instead. * if-if-else - In if-if-else construction else relates to the closest if. Use braces to make the code clearer. * define-params - define() requires two or three parameters. * define-const - First parameter for define() should be string. Maybe you forgot quotes? * break-var - Break/continue with variable is dangerous - break level can be out of scope. * break-depth - Break/continue with depth more than current nesting level. * var-once - Variable '%s' encountered only once. May be a typo? * var-arg-unused - Function argument '%s' is never used. * var-global-unused - Global variable '%s' is defined but never used. * var-use-before-def - Variable '%s' is used before it was assigned. * var-use-before-def-global - Global variable '%s' is used without being assigned. You are probably relying on register_globals feature of PHP. Note that this feature is off by default. * var-no-global - PHP global variable '%s' is used as local. Maybe you wanted to define '%s' as global? * var-value-unused - Value assigned to variable '%s' is never used * var-ref-notmodified - Function parameter '%s' is passed by reference but never modified. Consider passing by value. * return-empty-val - Function '%s' has both empty return and return with value. * return-empty-used - Function '%s' has empty return but return value is used. * return-noref - Function '%s' returns reference but the value is not assigned by reference. Maybe you meant '=&' instead of '='? * return-end-used - Control reaches the end of function '%s'(file %s, line %d) but return value is used. * sprintf-miss-args - Missing arguments for sprintf: format reqires %d arguments but %d are supplied. * sprintf-extra-args - Extra arguments for sprintf: format reqires %d arguments but %d are supplied. * unreach-code - Unreachable code in function '%s'. * include-var - include/require with user-accessible variable can be dangerous. Consider using constant instead. * non-object - Variable '%s' used as object, but has different type. * bad-escape - Bad escape sequence: \%c, did you mean \\%c? * empty-cond - Condition without a body * expr-unused - Expression result is never used * * @author Knut Urdalen * @version $Id: d1bcb58746c4f9bb6e63c43e61c9074f511ad456 $ * @package phing.tasks.ext */ class ZendCodeAnalyzerTask extends Task { protected $analyzerPath = ""; // Path to ZendCodeAnalyzer binary protected $file = ""; // the source file (from xml attribute) protected $filesets = array(); // all fileset objects assigned to this task protected $counter = 0; protected $disable = array(); protected $enable = array(); private $haltonwarning = false; /** * File to be analyzed * * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Path to ZendCodeAnalyzer binary * * @param string $analyzerPath */ public function setAnalyzerPath($analyzerPath) { $this->analyzerPath = $analyzerPath; } /** * Disable warning levels. Separate warning levels with ',' * * @param string $disable */ public function setDisable($disable) { $this->disable = explode(",", $disable); } /** * Enable warning levels. Separate warning levels with ',' * * @param string $enable */ public function setEnable($enable) { $this->enable = explode(",", $enable); } /** * Sets the haltonwarning flag * @param boolean $value */ public function setHaltonwarning($value) { $this->haltonwarning = $value; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Analyze against PhingFile or a FileSet */ public function main() { if (!isset($this->analyzerPath)) { throw new BuildException("Missing attribute 'analyzerPath'"); } if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } if ($this->file instanceof PhingFile) { $this->analyze($this->file->getPath()); } else { // process filesets $project = $this->getProject(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($project); $files = $ds->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath(); foreach ($files as $file) { $this->analyze($dir . DIRECTORY_SEPARATOR . $file); } } } $this->log("Number of findings: " . $this->counter, Project::MSG_INFO); } /** * Analyze file * * @param string $file * @throws BuildException * @return void */ protected function analyze($file) { if (file_exists($file)) { if (is_readable($file)) { // Construct shell command $cmd = $this->analyzerPath . " "; foreach ($this->enable as $enable) { // Enable warning levels $cmd .= " --enable $enable "; } foreach ($this->disable as $disable) { // Disable warning levels $cmd .= " --disable $disable "; } $cmd .= "$file 2>&1"; // Execute command $result = shell_exec($cmd); $result = explode("\n", $result); for ($i = 2, $size = count($result); $i < ($size - 1); $i++) { $this->counter++; $this->log($result[$i], Project::MSG_WARN); } $total = count($result) - 3; if ($total > 0 && $this->haltonwarning) { throw new BuildException('zendcodeanalyzer detected ' . $total . ' warning' . ($total > 1 ? 's' : '') . ' in ' . $file); } } else { throw new BuildException('Permission denied: ' . $file); } } else { throw new BuildException('File not found: ' . $file); } } } phing-2.16.0/tasks/ext/pearpackage/Fileset.php0000644000175000017500000001676713027032674020226 0ustar druiddruid. */ include_once 'phing/system/io/PhingFile.php'; /** * Builds list of files for PEAR_PackageFileManager using a Phing FileSet. * * Some code here is taken from PEAR_PackageFileManager_File -- getting results from flat * array into the assoc array expected from getFileList(). * * @author Greg Beaver * @author Hans Lellelid * @package phing.tasks.ext.pearpackage * @version $Id: 4287f56d47c2d793bc22417402f8c37daf3745f3 $ */ class PEAR_PackageFileManager_Fileset { /** * Current Phing Project. * @var Project */ private $project; /** * FileSets to use. * @var array FileSet[] */ private $filesets = array(); /** * Set up the FileSet filelist generator * * 'project' and 'filesets' are the only options that this class uses. * * @param PEAR_PackageFileManager * @param array */ public function __construct($options) { if (!is_array($options)) { $options = $options->getOptions(); } $this->project = $options['phing_project']; $this->filesets = $options['phing_filesets']; } /** * Generate the section * of the package file. * * This function performs the backend generation of the array * containing all files in this package * @return array structure of all files to include */ public function getFileList() { $allfiles = array(); foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($this->project); $files = $ds->getIncludedFiles(); // We need to store these files keyed by the basedir from DirectoryScanner // so that we can resolve the fullpath of the file later. if (isset($allfiles[$ds->getBasedir()])) { $allfiles[$ds->getBasedir()] = array_merge($allfiles[$ds->getBasedir()], $files); } else { $allfiles[$ds->getBasedir()] = $files; } } $struc = array(); foreach ($allfiles as $basedir => $files) { foreach ($files as $file) { // paths are relative to $basedir above $path = strtr(dirname($file), DIRECTORY_SEPARATOR, '/'); if (!$path || $path == '.') { $path = '/'; // for array index } $parts = explode('.', basename($file)); $ext = array_pop($parts); if (strlen($ext) == strlen($file)) { $ext = ''; } $f = new PhingFile($basedir, $file); $struc[$path][] = array( 'file' => basename($file), 'ext' => $ext, 'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)), 'fullpath' => $f->getAbsolutePath() ); } } uksort($struc, 'strnatcasecmp'); foreach ($struc as $key => $ind) { usort($ind, array($this, 'sortfiles')); $struc[$key] = $ind; } $tempstruc = $struc; $struc = array('/' => $tempstruc['/']); $bv = 0; foreach ($tempstruc as $key => $ind) { $save = $key; if ($key != '/') { $struc['/'] = $this->setupDirs($struc['/'], explode('/', $key), $tempstruc[$key]); } } uksort($struc['/'], array($this, 'mystrucsort')); return $struc; } /** * Recursively move contents of $struc into associative array * * The contents of $struc have many indexes like 'dir/subdir/subdir2'. * This function converts them to * array('dir' => array('subdir' => array('subdir2'))) * @param array $struc is array('dir' => array of files in dir, * 'dir/subdir' => array of files in dir/subdir,...) * @param $dir * @param $contents * @internal param array $array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2') * @return array same as struc but with array('dir' => * array(file1,file2,'subdir' => array(file1,...))) */ private function setupDirs($struc, $dir, $contents) { if (!count($dir)) { foreach ($contents as $dir => $files) { if (is_string($dir)) { if (strpos($dir, '/')) { $test = true; $a = $contents[$dir]; unset($contents[$dir]); $b = explode('/', $dir); $c = array_shift($b); if (isset($contents[$c])) { $contents[$c] = $this->setDir($contents[$c], $this->setupDirs(array(), $b, $a)); } else { $contents[$c] = $this->setupDirs(array(), $b, $a); } } } } return $contents; } $me = array_shift($dir); if (!isset($struc[$me])) { $struc[$me] = array(); } $struc[$me] = $this->setupDirs($struc[$me], $dir, $contents); return $struc; } /** * Recursively add all the subdirectories of $contents to $dir without erasing anything in * $dir * @param array * @param array * @return array processed $dir */ public function setDir($dir, $contents) { while (list($one, $two) = each($contents)) { if (isset($dir[$one])) { $dir[$one] = $this->setDir($dir[$one], $contents[$one]); } else { $dir[$one] = $two; } } return $dir; } /** * Sorting functions for the file list * @param string * @param string * @return int */ private function sortfiles($a, $b) { return strnatcasecmp($a['file'], $b['file']); } /** * @param $a * @param $b * @return int */ private function mystrucsort($a, $b) { if (is_numeric($a) && is_string($b)) { return 1; } if (is_numeric($b) && is_string($a)) { return -1; } if (is_numeric($a) && is_numeric($b)) { if ($a > $b) { return 1; } if ($a < $b) { return -1; } if ($a == $b) { return 0; } } return strnatcasecmp($a, $b); } } phing-2.16.0/tasks/ext/hg/HgInitTask.php0000644000175000017500000000423013027032674016751 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg init * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgInitTask.php */ class HgInitTask extends HgBaseTask { /** * Path to target directory * * @var string */ protected $targetPath; /** * Set path to source repo * * @param string $targetPath Path to repository used as source * * @return void */ public function setTargetPath($targetPath) { $this->targetPath = $targetPath; } /** * Main entry point for this task. * * @return void */ public function main() { $clone = $this->getFactoryInstance('init'); $this->log('Initializing', Project::MSG_INFO); $clone->setQuiet($this->getQuiet()); $clone->setInsecure($this->getInsecure()); $cwd = getcwd(); if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } if (!is_dir($dir)) { throw new BuildException("$dir is not a directory."); } chdir($dir); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgPullTask.php0000644000175000017500000000411413027032674016763 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg update * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgPullTask.php */ class HgPullTask extends HgBaseTask { /** * Path to target directory * * @var string */ protected $targetPath; /** * Set path to source repo * * @param string $targetPath Path to repository used as source * * @return void */ public function setTargetPath($targetPath) { $this->targetPath = $targetPath; } /** * The main entry point method. * * @throws BuildException * @return void */ public function main() { $clone = $this->getFactoryInstance('pull'); $clone->setInsecure($this->getInsecure()); $clone->setQuiet($this->getQuiet()); $cwd = getcwd(); if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } $this->checkRepositoryIsDirAndExists($dir); chdir($dir); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgBaseTask.php0000644000175000017500000000745013027032674016727 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Base task for integrating phing and mercurial. * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgBaseTask.php */ abstract class HgBaseTask extends Task { /** * Insecure argument * * @var string */ protected $insecure = ''; /** * Repository directory * * @var string */ protected $repository = ''; /** * Whether to be quiet... --quiet argument. * * @var bool */ protected $quiet = false; /** * Username. * * @var string */ protected $user = ''; static $factory = null; /** * Set repository attribute * * @param string $repository Repository * * @return void */ public function setRepository($repository) { $this->repository = $repository; } /** * Set the quiet attribute --quiet * * @param string $quiet yes|no|true|false|1|0 * * @return void */ public function setQuiet($quiet) { $this->quiet = StringHelper::booleanValue($quiet); } /** * Get the quiet attribute value. * * @return bool */ public function getQuiet() { return $this->quiet; } /** * Get Repository attribute/directory. * * @return string */ public function getRepository() { return $this->repository; } /** * Set insecure attribute * * @param string $insecure 'yes', etc. * * @return void */ public function setInsecure($insecure) { $this->insecure = StringHelper::booleanValue($insecure); } /** * Get 'insecure' attribute value. (--insecure or null) * * @return string */ public function getInsecure() { return $this->insecure; } /** * Set user attribute * * @param string $user username/email address. * * @return void */ public function setUser($user) { $this->user = $user; } /** * Get username attribute. * * @return string */ public function getUser() { return $this->user; } /** * Check provided repository directory actually is an existing directory. * * @param string $dir Repository directory * * @return bool * @throws BuildException */ public function checkRepositoryIsDirAndExists($dir) { if (file_exists($dir)) { if (!is_dir($dir)) { throw new BuildException("Repository '$dir' is not a directory."); } } else { throw new BuildException("Repository directory '$dir' does not exist."); } return true; } /** * Initialise the task. * * @return void */ public function init() { if (version_compare(PHP_VERSION, '5.4', "<")) { throw new BuildException('This task requires PHP 5.4+'); } else { /** * Depending on composer for pulling in siad007's VersionControl_HG. */ @include_once 'vendor/autoload.php'; } } public function getFactoryInstance($command, $options = array()) { $vchq = '\\Siad007\\VersionControl\\HG\\Factory'; self::$factory = call_user_func_array( array($vchq, 'getInstance'), array($command, $options) ); return self::$factory; } } phing-2.16.0/tasks/ext/hg/HgLogTask.php0000644000175000017500000000766613027032674016607 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg log * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgLogTask.php */ class HgLogTask extends HgBaseTask { /** * Maximum number of changes to get. See --limit * * @var int */ protected $maxCount = null; /** * Commit format/template. See --template * * @var string */ protected $format = null; /** * Revision * * @var string */ protected $revision = ''; /** * Propery name to set the output to. * * @var string */ protected $outputProperty = null; /** * Set maximum number of changes to get. * * @param int $count Maximum number of log entries to retrieve. * * @return void */ public function setMaxcount($count) { $this->maxCount = $count; } /** * Retrieve max count of commits to limit to. * * @return int */ public function getMaxcount() { return $this->maxCount; } /** * Template/log format. * * @param string $format Log format * * @return string */ public function setFormat($format) { $this->format = $format; } /** * Get the log format/template * * @return string */ public function getFormat() { return $this->format; } /** * Property to assign output to. * * @param string $property name of property to assign output to. * * @return void */ public function setOutputProperty($property) { $this->outputProperty = $property; } /** * Set revision attribute * * @param string $revision Revision * * @return void */ public function setRevision($revision) { $this->revision = $revision; } /** * Main entry point for this task * * @return void */ public function main() { $clone = $this->getFactoryInstance('log'); if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } $clone->setCwd($dir); if ($this->maxCount !== null) { $max = filter_var($this->maxCount, FILTER_VALIDATE_INT); if ($max) { $max = (int) $this->maxCount; } if (!$max || (int) $this->maxCount <= 0) { throw new BuildException("maxcount should be a positive integer."); } $clone->setLimit('' . $this->maxCount); } if ($this->format !== null) { $clone->setTemplate($this->format); } if ($this->revision !== '') { $clone->setRev($this->revision); } try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($this->outputProperty !== null) { $this->project->setProperty($this->outputProperty, $output); } else { if ($output !== '') { $this->log(PHP_EOL . $output); } } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } throw new BuildException($msg); } } } phing-2.16.0/tasks/ext/hg/HgAddTask.php0000644000175000017500000001262213027032674016542 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg add * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgAddTask.php */ class HgAddTask extends HgBaseTask { /** * Linked filesets * * @var string */ protected $filesets = array(); /** * Array of files to ignore * * @var string[] */ protected $ignoreFile = array(); /** * Adds a fileset of files to add to the repository. * * @param FileSet $fileset Set of files to add to the repository. * * @return void */ public function addFileSet(FileSet $fileset) { $this->filesets[] = $fileset; } /** * The main entry point method. * * @throws BuildException * @return void */ public function main() { $filesAdded = false; $clone = $this->getFactoryInstance('add'); $clone->setQuiet($this->getQuiet()); $cwd = getcwd(); $project = $this->getProject(); if ($this->repository === '') { $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } if (!file_exists($dir)) { throw new BuildException("\"$dir\" does not exist."); } elseif (!is_dir($dir)) { throw new BuildException("\"$dir\" is not a directory."); } chdir($dir); if (file_exists('.hgignore')) { $this->loadIgnoreFile(); } if (count($this->filesets)) { $this->log('filesets set', Project::MSG_DEBUG); /** * $fs is a FileSet * * @var $fs FileSet */ foreach ($this->filesets as $fs) { $ds = $fs->getDirectoryScanner($project); $fromDir = $fs->getDir($project); if ($fromDir->getName() === '.') { $statusClone = $this->getFactoryInstance('status'); $statusClone->setUnknown(true); $statusClone->setNoStatus(true); $statusClone->setRepository($this->getRepository()); $statusOut = $statusClone->execute(); if ($statusOut !== '') { $files = explode(PHP_EOL, $statusOut); foreach ($files as $file) { if ($file != '') { $clone->addFile($file); $filesAdded = true; } } } } } } if ($filesAdded) { try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $this->log("Exception: $msg", Project::MSG_INFO); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } } chdir($cwd); } /** * Load .hgignore file. * * @return void */ public function loadIgnoreFile() { $ignores = array(); $lines = file('.hgignore'); foreach ($lines as $line) { $nline = trim($line); $nline = preg_replace('/\/\*$/', '/', $nline); $ignores[] = $nline; } $this->ignoreFile = $ignores; } /** * Determine if a file is to be ignored. * * @param string $file filename * * @return bool */ public function fileIsIgnored($file) { $line = $this->ignoreFile[0]; $mode = 'regexp'; $ignored = false; if (preg_match('#^syntax\s*:\s*(glob|regexp)$#', $line, $matches) || $matches[1] === 'glob' ) { $mode = 'glob'; } if ($mode === 'glob') { $ignored = $this->ignoredByGlob($file); } elseif ($mode === 'regexp') { $ignored = $this->ignoredByRegex($file); } return $ignored; } /** * Determine if file is ignored by glob pattern. * * @param string $file filename * * @return bool */ public function ignoredByGlob($file) { $lfile = $file; if (strpos($lfile, './') === 0) { $lfile = substr($lfile, 2); } foreach ($this->ignoreFile as $line) { if (strpos($lfile, $line) === 0) { return true; } } return false; } /** * Is file ignored by regex? * * @param string $file Filename * * @return bool */ public function ignoredByRegex($file) { return true; } } phing-2.16.0/tasks/ext/hg/HgCloneTask.php0000644000175000017500000000544513027032674017117 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg clone * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgCloneTask.php */ class HgCloneTask extends HgBaseTask { /** * Path to target directory * * @var string */ protected $targetPath = ''; /** * Set path to source repo * * @param string $targetPath Path to repository used as source * * @return void */ public function setTargetPath($targetPath) { $this->targetPath = $targetPath; } /** * Get path to the target directory/repo. * * @return string */ public function getTargetPath() { return $this->targetPath; } /** * The main entry point. * * @return void * @throws BuildException */ public function main() { $clone = $this->getFactoryInstance('clone'); $repository = $this->getRepository(); if ($repository === '') { throw new BuildException('"repository" is a required parameter'); } $target = $this->getTargetPath(); if ($target === '') { throw new BuildException('"targetPath" is a required parameter'); } // Is target path empty? if (file_exists($target)) { $files = scandir($target); if (is_array($files) && count($files) > 2) { throw new BuildException("Directory \"$target\" is not empty"); } if (!is_dir($target)) { throw new BuildException("\"$target\" is not a directory"); } } $msg = sprintf('hg cloning %s to %s', $repository, $target); $this->log($msg, Project::MSG_INFO); $clone->setSource($repository); $clone->setDestination($target); $clone->setInsecure($this->getInsecure()); $clone->setQuiet($this->getQuiet()); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } throw new BuildException($msg); } } } phing-2.16.0/tasks/ext/hg/HgPushTask.php0000644000175000017500000000464713027032674017001 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg push * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgPushTask.php */ class HgPushTask extends HgBaseTask { /** * Whether the task should halt if an error occurs. * * @var bool */ protected $haltonerror = false; /** * Set haltonerror attribute. * * @param string $halt 'yes', or '1' to halt. * * @return void */ public function setHaltonerror($halt) { $this->haltonerror = StringHelper::booleanValue($halt); } /** * Return haltonerror value. * * @return bool */ public function getHaltonerror() { return $this->haltonerror; } /** * The main entry point method. * * @throws BuildException * @return void */ public function main() { $clone = $this->getFactoryInstance('push'); $this->log('Pushing...', Project::MSG_INFO); $clone->setInsecure($this->getInsecure()); $clone->setQuiet($this->getQuiet()); if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } $cwd = getcwd(); $this->checkRepositoryIsDirAndExists($dir); chdir($dir); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); if ($this->haltonerror) { throw new BuildException($msg); } $this->log($msg, Project::MSG_ERR); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgUpdateTask.php0000644000175000017500000000553613027032674017302 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg update * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgUpdateTask.php */ class HgUpdateTask extends HgBaseTask { /** * Branch argument * * Defaults to 'default' * * @var string */ protected $branch = 'default'; /** * Clean argument * * @var bool */ protected $clean = false; /** * Set 'clean' attribute. * * @param string $value Clean attribute value * * @return void */ public function setClean($value) { $this->clean = StringHelper::booleanValue($value); } /** * Get 'clean' attribute. * * @return bool */ public function getClean() { return $this->clean; } /** * Set branch attribute * * @param string $value Branch name * * @return void */ public function setBranch($value) { $this->branch = $value; } /** * Get branch attribute * * @return string */ public function getBranch() { return $this->branch; } /** * The main entry point method. * * @throws BuildException * @return void */ public function main() { $pull = $this->getFactoryInstance('update'); try { $pull->setBranch($this->getBranch()); } catch (Exception $ex) { $this->log("Caught: " . $ex->getMessage(), Project::MSG_DEBUG); } $pull->setClean($this->getClean()); $pull->setQuiet($this->getQuiet()); $cwd = getcwd(); if ($this->repository === '') { $prog = $this->getProject(); $dir = $prog->getProperty('application.startdir'); } else { $dir = $this->repository; } $this->checkRepositoryIsDirAndExists($dir); chdir($dir); try { $this->log("Executing: " . $pull->asString(), Project::MSG_INFO); $output = $pull->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgTagTask.php0000644000175000017500000000651613027032674016572 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg tag * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgTagTask.php */ class HgTagTask extends HgBaseTask { /** * Message to be recorded against tagging. * * @var string */ protected $message = ''; /** * Tag to assign/create. * * @var string */ protected $name = ''; /** * Revision * * @var string */ protected $revision = ''; /** * Set the name argument * * @param string $name Name * * @return void */ public function setName($name) { $this->name = $name; } /** * Get the name of the tag to be used. * * @return void */ public function getName() { return $this->name; } /** * Set message to be used. * * @param string $message Message to use * * @return void */ public function setMessage($message) { $this->message = $message; } /** * Get message to apply for the commit. * * @return string */ public function getMessage() { return $this->message; } /** * Set revision attribute * * @param string $revision Revision * * @return void */ public function setRevision($revision) { $this->revision = $revision; } /** * The main entry point method. * * @return void */ public function main() { $clone = $this->getFactoryInstance('tag'); $cwd = getcwd(); if ($this->name === '') { throw new BuildException("Tag name must be set."); } if ($this->repository === '') { $prog = $this->getProject(); $dir = $prog->getProperty('application.startdir'); } else { $dir = $this->repository; } if ($this->revision !== '') { $clone->setRev($this->revision); } if ($this->user !== null) { $clone->setUser($this->user); } $message = $this->getMessage(); $clone->setMessage($message); $name = $this->getName(); if ($name == '') { throw new BuildException("Name attribute must be set."); } $clone->addName($name); $this->checkRepositoryIsDirAndExists($dir); chdir($dir); try { $this->log("Executing: " . $clone, Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgRevertTask.php0000644000175000017500000000567613027032674017334 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg revert * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgRevertTask.php */ class HgRevertTask extends HgBaseTask { /** * All * * @var bool */ protected $all = false; /** * Name of file to be reverted. * * @var string */ protected $file = null; /** * Revision * * @var string */ protected $revision = ''; /** * Set whether all files are to be reverted. * * @param string $value Jenkins style boolean value * * @return void */ public function setAll($value) { $this->all = StringHelper::booleanValue($value); } /** * Set filename to be reverted. * * @param string $file Filename * * @return void */ public function setFile($file) { $this->file = $file; } /** * Get filename to be reverted. * * @return string */ public function getFile() { return $this->file; } /** * Set revision attribute * * @param string $revision Revision * * @return void */ public function setRevision($revision) { $this->revision = $revision; } /** * The main entry point method. * * @throws BuildException * @return void */ public function main() { $clone = $this->getFactoryInstance('revert'); $clone->setQuiet($this->getQuiet()); $clone->setAll($this->all); if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } $cwd = getcwd(); $this->checkRepositoryIsDirAndExists($dir); chdir($dir); if ($this->revision !== '') { $clone->setRev($this->revision); } if ($this->file !== null) { $clone->addName($this->file); } try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log(PHP_EOL . $output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } throw new BuildException($msg); } } } phing-2.16.0/tasks/ext/hg/HgCommitTask.php0000644000175000017500000000573713027032674017313 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg commit * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgCommitTask.php */ class HgCommitTask extends HgBaseTask { /** * Message to be recorded against commit. * * @var string */ protected $message = ''; /** * Set message to be used. * * @param string $message Message to use * * @return void */ public function setMessage($message) { $this->message = $message; } /** * Get message to apply for the commit. * * @return string */ public function getMessage() { return $this->message; } /** * The main entry point method. * * @throws BuildException If message is not set * @throws BuildException If error occurs during commit * @return void */ public function main() { $message = $this->getMessage(); if ($message === '') { throw new BuildException('"message" is a required parameter'); } $user = $this->getUser(); $clone = $this->getFactoryInstance('commit'); $msg = sprintf("Commit: '%s'", $message); $this->log($msg, Project::MSG_INFO); $clone->setQuiet($this->getQuiet()); $clone->setMessage($message); if (trim($user) === "") { throw new BuildException('"user" parameter can not be set to ""'); } if ($user !== null) { $clone->setUser($user); $this->log("Commit: user = '$user'", Project::MSG_VERBOSE); } if ($this->repository === '') { $project = $this->getProject(); $dir = $project->getProperty('application.startdir'); } else { $dir = $this->repository; } $this->log('DIR:' . $dir, Project::MSG_INFO); $this->log('REPO: ' . $this->repository, Project::MSG_INFO); $cwd = getcwd(); chdir($dir); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log($output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $this->log("Exception: $msg", Project::MSG_INFO); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } chdir($cwd); throw new BuildException($msg); } chdir($cwd); } } phing-2.16.0/tasks/ext/hg/HgArchiveTask.php0000644000175000017500000000432213027032674017431 0ustar druiddruid * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link https://github.com/kenguest/Phing-HG */ /** * Pull in Base class. */ require_once 'phing/tasks/ext/hg/HgBaseTask.php'; /** * Integration/Wrapper for hg archive * * @category Tasks * @package phing.tasks.ext.hg * @author Ken Guest * @license LGPL (see http://www.gnu.org/licenses/lgpl.html) * @link HgArchiveTask.php */ class HgArchiveTask extends HgBaseTask { /** * Which revision to archive. * * @var string */ protected $revision = ''; /** * Name of destination archive file. * * @var string */ protected $destination = null; /** * Set revision attribute * * @param string $revision Revision * * @return void */ public function setRevision($revision) { $this->revision = $revision; } /** * Set Destination attribute * * @param string $destination Destination filename * * @return void */ public function setDestination($destination) { $this->destination = $destination; } /** * The main entry point for the task. * * @return void */ public function main() { $clone = $this->getFactoryInstance('archive'); if ($this->revision !== '') { $clone->setRev($this->revision); } if ($this->destination === null) { throw new BuildException("Destination must be set."); } $clone->setDestination($this->destination); try { $this->log("Executing: " . $clone->asString(), Project::MSG_INFO); $output = $clone->execute(); if ($output !== '') { $this->log(PHP_EOL . $output); } } catch(Exception $ex) { $msg = $ex->getMessage(); $p = strpos($msg, 'hg returned:'); if ($p !== false) { $msg = substr($msg, $p + 13); } throw new BuildException($msg); } } } phing-2.16.0/tasks/ext/phk/PhkPackageWebAccessPath.php0000644000175000017500000000263713027032674021534 0ustar druiddruid. */ /** * @author Alexey Shockov * @package phing.tasks.ext.phk */ class PhkPackageWebAccessPath { /** * @var string */ private $path; /** * @param string $path */ public function addText($path) { $this->path = trim($path); } /** * @return string */ public function getPath() { return $this->path; } } phing-2.16.0/tasks/ext/phk/PhkPackageTask.php0000644000175000017500000001446513027032674017764 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/phk/PhkPackageWebAccess.php'; /** * See {@link http://phk.tekwire.net/} for more information about PHK. * * @author Alexey Shockov * @package phing.tasks.ext.phk */ class PhkPackageTask extends Task { /** * @var string */ private $outputFile; /** * @var string */ private $inputDirectory; /** * @var string */ private $phkCreatorPath; /** * @var PhkPackageWebAccess */ private $webAccess; /** * @var array */ private $modifiers = array(); /** * @var array */ private $options = array(); /** * @return PhkPackageWebAccess */ public function createWebAccess() { return ($this->webAccess = new PhkPackageWebAccess()); } /** * @param string $crcCheck */ public function setCrcCheck($crcCheck) { $this->options['crc_check'] = ('true' == $crcCheck ? true : false); } /** * @param string $webRunScript */ public function setWebRunScript($webRunScript) { $this->options['web_run_script'] = $webRunScript; } /** * @param string $cliRunScript */ public function setCliRunScript($cliRunScript) { $this->options['cli_run_script'] = $cliRunScript; } /** * @param string $libRunScript */ public function setLibRunScript($libRunScript) { $this->options['lib_run_script'] = $libRunScript; } /** * @param string $name */ public function setName($name) { $this->options['name'] = $name; } /** * @param string $webMainRedirect */ public function setWebMainRedirect($webMainRedirect) { $this->options['web_main_redirect'] = ('true' == $webMainRedirect ? true : false); } /** * @param string $pluginClass */ public function setPluginClass($pluginClass) { $this->options['plugin_class'] = $pluginClass; } /** * @param string $version */ public function setVersion($version) { $this->options['version'] = $version; } /** * @param string $summary */ public function setSummary($summary) { $this->options['summary'] = $summary; } /** * @param string $inputDirectory */ public function setInputDirectory($inputDirectory) { $this->inputDirectory = $inputDirectory; } /** * @param string $outputFile */ public function setOutputFile($outputFile) { $this->outputFile = $outputFile; } /** * May be none, gzip or bzip2. * * @param string $compress */ public function setCompress($compress) { $this->modifiers['compress'] = $compress; } /** * True or false. * * @param srting $strip */ public function setStrip($strip) { $this->modifiers['strip'] = $strip; } /** * Path to PHK_Creator.phk file. * * @param srting $path */ public function setPhkCreatorPath($path) { $this->phkCreatorPath = $path; } /** * */ public function init() { } /** * Main method... */ public function main() { /* * Check for empty first - speed ;) */ if (!is_file($this->phkCreatorPath)) { throw new BuildException('You must specify the "phkcreatorpath" attribute for PHK task.'); } if (empty($this->inputDirectory)) { throw new BuildException('You must specify the "inputdirectory" attribute for PHK task.'); } if (empty($this->outputFile)) { throw new BuildException('You must specify the "outputfile" attribute for PHK task.'); } require_once $this->phkCreatorPath; $mountPoint = PHK_Mgr::mount($this->outputFile, PHK::F_CREATOR); $phkManager = PHK_Mgr::instance($mountPoint); /* * Add files. */ $phkManager->ftree()->merge_file_tree('/', $this->inputDirectory, $this->modifiers); /* * Add web_access to options, if present. */ if (!is_null($this->webAccess)) { $webAccessPaths = $this->webAccess->getPaths(); if (!empty($webAccessPaths)) { $this->options['web_access'] = $webAccessPaths; } } $phkManager->set_options($this->options); /* * Intercept output (in PHP we can't intercept stream). */ ob_start(); /* * Create file... */ $phkManager->dump(); /* * Print with Phing log... */ $output = trim(ob_get_clean()); $output = explode("\n", $output); foreach ($output as $line) { /* * Delete all '--- *' lines. Bluh! */ /* * TODO Change preg_math to more faster alternative. */ if (preg_match('/^---/', $line)) { continue; } $this->log($line); } /* * Set rights for generated file... Don't use umask() - see * notes in official documentation for this function. */ chmod($this->outputFile, 0644); } } phing-2.16.0/tasks/ext/phk/PhkPackageWebAccess.php0000644000175000017500000000326613027032674020716 0ustar druiddruid. */ require_once 'phing/tasks/ext/phk/PhkPackageWebAccessPath.php'; /** * @author Alexey Shockov * @package phing.tasks.ext.phk */ class PhkPackageWebAccess { /** * @var array */ private $paths = array(); /** * @return PhkPackageWebAccessPath */ public function createPath() { return ($this->paths[] = new PhkPackageWebAccessPath()); } /** * @return array */ public function getPaths() { /* * Get real paths... */ $paths = array(); foreach ($this->paths as $path) { $paths[] = $path->getPath(); } return $paths; } } phing-2.16.0/tasks/ext/GrowlNotifyTask.php0000644000175000017500000003616113027032674017464 0ustar druiddruid * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the authors nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * 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. * * PHP version 5 * * @category Tasks * @package phing.tasks.ext * @version $Id: 50d0d2d926e6a51ab78d6801407e90f020dcbad9 $ * @author Laurent Laville * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @link https://github.com/llaville/phing-GrowlNotifyTask */ require_once 'phing/Task.php'; /** * Growl notification task for Phing, the PHP build tool. * * PHP version 5 * * @category Tasks * @package phing.tasks.ext * @version $Id: 50d0d2d926e6a51ab78d6801407e90f020dcbad9 $ * @author Laurent Laville * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @link https://github.com/llaville/phing-GrowlNotifyTask */ class GrowlNotifyTask extends Task { protected $growl; protected $name; protected $sticky; protected $message; protected $title; protected $notification; protected $appicon; protected $host; protected $password; protected $priority; protected $protocol; protected $icon; /** * Initializes task with default options * * @param Net_Growl $growl (optional) mock instance */ public function __construct(Net_Growl $growl = null) { $this->growl = $growl; } /** * The init method check if Net_Growl is available * (exists and can be loaded) * * @return void * @throws BuildException */ public function init() { $autoloader = 'Net/Growl/Autoload.php'; if (!$handle = @fopen($autoloader, 'r', true)) { throw new BuildException( 'The Growl Notify task requires the Net_Growl PEAR package.' ); } else { fclose($handle); include_once $autoloader; } $this->setTaskName('GrowlNotify'); $this->setName(); $this->setSticky(false); $this->setMessage(); $this->setTitle(); $this->setNotification(); $this->setAppicon(); $this->setHost(); $this->setPassword(); $this->setPriority(); $this->setProtocol(); $this->setIcon(); } /** * Defines the name of the application sending the notification * * @param string $name (optional) Name of the application * that appears in your Growl preferences * Default: "Growl for Phing" * * @return void * @throws BuildException */ public function setName($name = '') { if ('' == $name) { $name = 'Growl for Phing'; } if (!is_string($name)) { throw new BuildException( '"name" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($name) ); } $this->name = $name; } /** * Indicates if the notification should be sticky * * @param bool $sticky (optional) Notification should be sticky * * @return void */ public function setSticky($sticky = true) { $this->sticky = (bool) $sticky; } /** * The notification's text is required. * Use \n to specify a line break. * * @param string $message Notification's text * * @return void * @throws BuildException */ public function setMessage($message = '') { if (!is_string($message)) { throw new BuildException( '"message" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($message) ); } $this->message = $message; } /** * The notification's title. * Use \n to specify a line break. * * @param string $title (optional) Notification's title * Default: GrowlNotify * * @return void * @throws BuildException */ public function setTitle($title = '') { if ('' == $title) { $title = 'GrowlNotify'; } if (!is_string($title)) { throw new BuildException( '"title" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($title) ); } $this->title = $title; } /** * The notification name/type * * @param string $notification Name/type * Default: "General Notification" * * @return void * @throws BuildException */ public function setNotification($notification = '') { if ('' == $notification) { $notification = 'General Notification'; } if (!is_string($notification)) { throw new BuildException( '"notification" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($notification) ); } $this->notification = $notification; } /** * The icon of the application being registered. * * Must be a valid file type (png, jpg, gif, ico). * Can be any of the following: * - absolute url (http://domain/image.png) * - absolute file path (c:\temp\image.png) * - relative file path (.\folder\image.png) (relative file paths must start * with a dot and are relative to GrowlNotify's phing task location * * @param string $icon Icon of the application * * @return void * @throws BuildException */ public function setAppicon($icon = '') { if (!is_string($icon)) { throw new BuildException( '"appicon" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($icon) ); } // relative location if (strpos($icon, '..') === 0) { $icon = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . $icon); } elseif (strpos($icon, '.') === 0) { $icon = dirname(__FILE__) . substr($icon, 1); } $this->appicon = $icon; } /** * The host address to send the notification to. * * If any value other than 'localhost' or '127.0.0.1' is provided, the host * is considered a remote host and the "pass" attribute must also be provided. * Default: 127.0.0.1 * * @param string $host Remote host name/ip * Default: 127.0.0.1 * * @return void * @throws BuildException */ public function setHost($host = '127.0.0.1') { if (!is_string($host)) { throw new BuildException( '"host" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($host) ); } $this->host = $host; } /** * The password required to send notifications. * * A password is required to send a request to a remote host. If host attribute * is specified and is any value other than 'localhost' or '127.0.0.1', * then "pass" attribute is also required. * Default: no password * * @param string $password Password to send request to a remote host * * @return void * @throws BuildException */ public function setPassword($password = '') { if (!is_string($password)) { throw new BuildException( '"password" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($password) ); } $this->password = $password; } /** * The notification priority. * * Valid values are : low, moderate, normal, high, emergency * Default: normal * * @param string $priority Notification priority * Default: normal * * @return void * @throws BuildException */ public function setPriority($priority = '') { if ('' == $priority) { $priority = 'normal'; } switch ($priority) { case 'low' : $priority = Net_Growl::PRIORITY_LOW; break; case 'moderate' : $priority = Net_Growl::PRIORITY_MODERATE; break; case 'normal' : $priority = Net_Growl::PRIORITY_NORMAL; break; case 'high' : $priority = Net_Growl::PRIORITY_HIGH; break; case 'emergency' : $priority = Net_Growl::PRIORITY_EMERGENCY; break; default : throw new BuildException( '"priority" attribute is invalid.' ); } $this->priority = $priority; } /** * The protocol (and port) to send the notification to. * * With TCP (GNTP) protocol, port is always 23053 * With UDP protocol, port is always 9887 * Default: 23053 * * @param string $protocol Protocol to use to send request to remote host * Default: gntp * * @return void * @throws BuildException */ public function setProtocol($protocol = '') { if ('' == $protocol) { $protocol = 'gntp'; } switch ($protocol) { case 'udp' : case 'gntp' : break; default : throw new BuildException( '"protocol" attribute is invalid.' . ' Expect to be either udp or gntp.' ); } $this->protocol = $protocol; } /** * The icon to show for the notification. * * Must be a valid file type (png, jpg, gif, ico). * Can be any of the following: * - absolute url (http://domain/image.png) * - absolute file path (c:\temp\image.png) * - relative file path (.\folder\image.png) (relative file paths must start * with a dot and are relative to GrowlNotify's phing task location * * @param string $icon Icon of the message * * @return void * @throws BuildException */ public function setIcon($icon = '') { if (!is_string($icon)) { throw new BuildException( '"icon" attribute is invalid.' . ' Expect to be a string, actual is ' . gettype($icon) ); } // relative location if (strpos($icon, '..') === 0) { $icon = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . $icon); } elseif (strpos($icon, '.') === 0) { $icon = dirname(__FILE__) . substr($icon, 1); } $this->icon = $icon; } /** * The main entry point method * * @return void * @throws BuildException */ public function main() { if (empty($this->message)) { throw new BuildException( '"message" attribute cannot be empty' ); } $notifications = array( $this->notification ); $options = array( 'host' => $this->host, 'protocol' => $this->protocol, ); if (!empty($this->appicon)) { $options['AppIcon'] = $this->appicon; } try { if ($this->growl instanceof Net_Growl) { $growl = $this->growl; } else { $growl = Net_Growl::singleton( $this->name, $notifications, $this->password, $options ); } $response = $growl->register(); if ($this->protocol == 'gntp') { if ($response->getStatus() != 'OK') { throw new BuildException( 'Growl Error ' . $response->getErrorCode() . ' - ' . $response->getErrorDescription() ); } } $this->log( 'Application ' . $this->name . ' registered', Project::MSG_VERBOSE ); $logRequest = array( 'Application-Name' => $this->name, 'Application-Icon' => $this->appicon, 'Notification-Name' => $this->notification, 'Notification-Title' => $this->title, 'Notification-Text' => $this->message, 'Notification-Priority' => $this->priority, 'Notification-Icon' => $this->icon, 'Notification-Sticky' => $this->sticky, ); foreach ($logRequest as $key => $value) { $this->log($key . ': ' . $value, Project::MSG_DEBUG); } $options = array( 'sticky' => $this->sticky, 'priority' => $this->priority, 'icon' => $this->icon, ); $response = $growl->publish( $this->notification, $this->title, $this->message, $options ); if ($this->protocol == 'gntp') { if ($response->getStatus() != 'OK') { throw new BuildException( 'Growl Error ' . $response->getErrorCode() . ' - ' . $response->getErrorDescription() ); } } $this->log('Notification was sent to remote host ' . $this->host); } catch (Net_Growl_Exception $e) { throw new BuildException( 'Growl Exception : ' . $e->getMessage() ); } } } phing-2.16.0/tasks/ext/phpmd/PHPMDFormatterElement.php0000644000175000017500000001073013027032674021526 0ustar druiddruid. */ require_once 'phing/system/io/PhingFile.php'; /** * A wrapper for the implementations of PHPMDResultFormatter. * * @package phing.tasks.ext.phpmd * @author Benjamin Schultz * @version $Id: fa23de508582a5bc1d36fab6153d64df333099c6 $ * @since 2.4.1 */ class PHPMDFormatterElement { /** * @var PHPMDResultFormatter */ protected $formatter = null; /** * The type of the formatter. * * @var string */ protected $type = ""; /** * @var string */ protected $className = ""; /** * Whether to use file (or write output to phing log). * * @var boolean */ protected $useFile = true; /** * Output file for formatter. * * @var PhingFile */ protected $outfile = null; /** * Sets the formatter type. * * @param string $type Type of the formatter * * @throws BuildException */ public function setType($type) { $this->type = $type; switch ($this->type) { case 'xml': $this->className = 'XMLRenderer'; break; case 'html': $this->className = 'HTMLRenderer'; break; case 'text': $this->className = 'TextRenderer'; break; default: throw new BuildException('Formatter "' . $this->type . '" not implemented'); } } /** * Get the formatter type * * @return string */ public function getType() { return $this->type; } /** * Set whether to write formatter results to file or not. * * @param boolean $useFile True or false. */ public function setUseFile($useFile) { $this->useFile = StringHelper::booleanValue($useFile); } /** * Return whether to write formatter results to file or not. * * @return boolean */ public function getUseFile() { return $this->useFile; } /** * Sets the output file for the formatter results. * * @param PhingFile $outfile The output file */ public function setOutfile(PhingFile $outfile) { $this->outfile = $outfile; } /** * Get the output file. * * @return PhingFile */ public function getOutfile() { return $this->outfile; } /** * Creates a report renderer instance based on the formatter type. * * @return PHP_PMD_AbstractRenderer * @throws BuildException When the specified renderer does not exist. */ public function getRenderer() { if (!class_exists('\\PHPMD\\Writer\\StreamWriter')) { $renderClass = 'PHP_PMD_RENDERER_' . $this->className; $writerClass = 'PHP_PMD_Writer_Stream'; include_once 'PHP/PMD/Renderer/' . $this->className . '.php'; include_once 'PHP/PMD/Writer/Stream.php'; } else { $renderClass = 'PHPMD\Renderer\\' . $this->className; $writerClass = '\PHPMD\Writer\StreamWriter'; } $renderer = new $renderClass(); // Create a report stream if ($this->getUseFile() === false || $this->getOutfile() === null) { $stream = STDOUT; } else { $stream = fopen($this->getOutfile()->getAbsoluteFile(), 'wb'); } $renderer->setWriter(new $writerClass($stream)); return $renderer; } } phing-2.16.0/tasks/ext/phpmd/PHPMDTask.php0000644000175000017500000002457513027032674017167 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/phpmd/PHPMDFormatterElement.php'; /** * Runs PHP Mess Detector. Checking PHP files for several potential problems * based on rulesets. * * @package phing.tasks.ext.phpmd * @author Benjamin Schultz * @version $Id: 6de5c80e97545cd52494c53490e96c09aa61e703 $ * @since 2.4.1 */ class PHPMDTask extends Task { /** * A php source code filename or directory * * @var PhingFile */ protected $file = null; /** * All fileset objects assigned to this task * * @var FileSet[] */ protected $filesets = array(); /** * The rule-set filenames or identifier. * * @var string */ protected $rulesets = 'codesize,unusedcode'; /** * The minimum priority for rules to load. * * @var integer */ protected $minimumPriority = 0; /** * List of valid file extensions for analyzed files. * * @var array */ protected $allowedFileExtensions = array('php'); /** * List of exclude directory patterns. * * @var array */ protected $ignorePatterns = array('.git', '.svn', 'CVS', '.bzr', '.hg'); /** * The format for the report * * @var string */ protected $format = 'text'; /** * Formatter elements. * * @var PHPMDFormatterElement[] */ protected $formatters = array(); /** * @var bool */ protected $newVersion = true; /** * @var string */ protected $pharLocation = ""; /** * Cache data storage * * @var DataStore */ protected $cache; /** * Set the input source file or directory. * * @param PhingFile $file The input source file or directory. */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets the minimum rule priority. * * @param integer $minimumPriority Minimum rule priority. */ public function setMinimumPriority($minimumPriority) { $this->minimumPriority = $minimumPriority; } /** * Sets the rule-sets. * * @param string $ruleSetFileNames Comma-separated string of rule-set filenames or identifier. */ public function setRulesets($ruleSetFileNames) { $this->rulesets = $ruleSetFileNames; } /** * Sets a list of filename extensions for valid php source code files. * * @param string $fileExtensions List of valid file extensions without leading dot. */ public function setAllowedFileExtensions($fileExtensions) { $this->allowedFileExtensions = array(); $token = ' ,;'; $ext = strtok($fileExtensions, $token); while ($ext !== false) { $this->allowedFileExtensions[] = $ext; $ext = strtok($token); } } /** * Sets a list of ignore patterns that is used to exclude directories from the source analysis. * * @param string $ignorePatterns List of ignore patterns. */ public function setIgnorePatterns($ignorePatterns) { $this->ignorePatterns = array(); $token = ' ,;'; $pattern = strtok($ignorePatterns, $token); while ($pattern !== false) { $this->ignorePatterns[] = $pattern; $pattern = strtok($token); } } /** * Create object for nested formatter element. * * @return PHPMDFormatterElement */ public function createFormatter() { $num = array_push($this->formatters, new PHPMDFormatterElement()); return $this->formatters[$num - 1]; } /** * @param string $format */ public function setFormat($format) { $this->format = $format; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Whether to store last-modified times in cache * * @param PhingFile $file */ public function setCacheFile(PhingFile $file) { $this->cache = new DataStore($file); } /** * Find PHPMD * * @return string * @throws BuildException */ protected function loadDependencies() { if (!empty($this->pharLocation)) { include_once 'phar://' . $this->pharLocation . '/vendor/autoload.php'; } $className = '\PHPMD\PHPMD'; if (!class_exists($className)) { @include_once 'PHP/PMD.php'; $className = "PHP_PMD"; $this->newVersion = false; } if (!class_exists($className)) { throw new BuildException( 'PHPMDTask depends on PHPMD being installed and on include_path or listed in pharLocation.', $this->getLocation() ); } if ($this->newVersion) { //weird syntax to allow 5.2 parser compatibility $minPriority = constant('\PHPMD\AbstractRule::LOWEST_PRIORITY'); require_once 'phing/tasks/ext/phpmd/PHPMDRendererRemoveFromCache.php'; } else { require_once 'PHP/PMD/AbstractRule.php'; $minPriority = PHP_PMD_AbstractRule::LOWEST_PRIORITY; } if (!$this->minimumPriority) { $this->minimumPriority = $minPriority; } return $className; } /** * Return the list of files to parse * * @return string[] list of absolute files to parse */ protected function getFilesToParse() { $filesToParse = array(); if ($this->file instanceof PhingFile) { $filesToParse[] = $this->file->getPath(); } else { // append any files in filesets foreach ($this->filesets as $fs) { $dir = $fs->getDir($this->project)->getAbsolutePath(); foreach ($fs->getDirectoryScanner($this->project)->getIncludedFiles() as $filename) { $fileAbsolutePath = $dir . DIRECTORY_SEPARATOR . $filename; if ($this->cache) { $lastMTime = $this->cache->get($fileAbsolutePath); $currentMTime = filemtime($fileAbsolutePath); if ($lastMTime >= $currentMTime) { continue; } else { $this->cache->put($fileAbsolutePath, $currentMTime); } } $filesToParse[] = $fileAbsolutePath; } } } return $filesToParse; } /** * Executes PHPMD against PhingFile or a FileSet * * @throws BuildException - if the phpmd classes can't be loaded. */ public function main() { $className = $this->loadDependencies(); if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException('Missing either a nested fileset or attribute "file" set'); } if (count($this->formatters) == 0) { // turn legacy format attribute into formatter $fmt = new PHPMDFormatterElement(); $fmt->setType($this->format); $fmt->setUseFile(false); $this->formatters[] = $fmt; } $reportRenderers = array(); foreach ($this->formatters as $fe) { if ($fe->getType() == '') { throw new BuildException('Formatter missing required "type" attribute.'); } if ($fe->getUsefile() && $fe->getOutfile() === null) { throw new BuildException('Formatter requires "outfile" attribute when "useFile" is true.'); } $reportRenderers[] = $fe->getRenderer(); } if ($this->newVersion && $this->cache) { $reportRenderers[] = new PHPMDRendererRemoveFromCache($this->cache); } else { $this->cache = null; // cache not compatible to old version } // Create a rule set factory if ($this->newVersion) { $ruleSetClass = '\PHPMD\RuleSetFactory'; $ruleSetFactory = new $ruleSetClass(); //php 5.2 parser compatibility } else { if (!class_exists("PHP_PMD_RuleSetFactory")) { @include 'PHP/PMD/RuleSetFactory.php'; } $ruleSetFactory = new PHP_PMD_RuleSetFactory(); } $ruleSetFactory->setMinimumPriority($this->minimumPriority); /** * @var PHPMD\PHPMD $phpmd */ $phpmd = new $className(); $phpmd->setFileExtensions($this->allowedFileExtensions); $phpmd->setIgnorePattern($this->ignorePatterns); $filesToParse = $this->getFilesToParse(); if (count($filesToParse) > 0) { $inputPath = implode(',', $filesToParse); $this->log('Processing files...'); $phpmd->processFiles($inputPath, $this->rulesets, $reportRenderers, $ruleSetFactory); if ($this->cache) { $this->cache->commit(); } $this->log('Finished processing files'); } else { $this->log('No files to process'); } } } phing-2.16.0/tasks/ext/phpmd/PHPMDRendererRemoveFromCache.php0000644000175000017500000000370413027032674022750 0ustar druiddruid. */ require_once 'phing/util/DataStore.php'; use PHPMD\AbstractRenderer; use PHPMD\Report; /** * This class will remove files with violations from cache * * @category PHP * @package PHPMD * @author Rui Filipe Da Cunha Alves */ class PHPMDRendererRemoveFromCache extends AbstractRenderer { /** * Cache data storage * @var DataStore */ protected $cache; /** * Constructor * * @param DataStore $cache */ public function __construct($cache) { $this->cache = $cache; } /** * This method will be called when the engine has finished the source * analysis phase. To remove file with violations from cache. * * @param Report $report * @return void */ public function renderReport(Report $report) { foreach ($report->getRuleViolations() as $violation) { $fileName = $violation->getFileName(); $this->cache->remove($fileName, null); } } } phing-2.16.0/tasks/ext/pdepend/PhpDependAnalyzerElement.php0000644000175000017500000000513613027032674022662 0ustar druiddruid. */ require_once 'phing/system/io/PhingFile.php'; /** * Analyzer element for the PhpDependTask * * @package phing.tasks.ext.pdepend * @author Benjamin Schultz * @version $Id: e97cb62953c381f62ab548dfe073b26071f0eb0a $ * @since 2.4.1 */ class PhpDependAnalyzerElement { /** * The type of the analyzer * * @var string */ protected $type = ''; /** * The value(s) for the analyzer option * * @var array */ protected $value = array(); /** * Sets the analyzer type * * @param string $type Type of the analyzer * * @throws BuildException */ public function setType($type) { $this->type = $type; switch ($this->type) { case 'coderank-mode': break; default: throw new BuildException('Analyzer "' . $this->type . '" not implemented'); } } /** * Get the analyzer type * * @return string */ public function getType() { return $this->type; } /** * Sets the value for the analyzer * * @param string $value Value for the analyzer */ public function setValue($value) { $this->value = array(); $token = ' ,;'; $values = strtok($value, $token); while ($values !== false) { $this->value[] = $values; $values = strtok($token); } } /** * Get the analyzer value * * @return string */ public function getValue() { return $this->value; } } phing-2.16.0/tasks/ext/pdepend/PhpDependLoggerElement.php0000644000175000017500000000506113027032674022311 0ustar druiddruid. */ require_once 'phing/system/io/PhingFile.php'; /** * Logger element for the PhpDependTask. * * @package phing.tasks.ext.pdepend * @author Benjamin Schultz * @version $Id: c5b569118db6a6d66c6568702f14e8ae37fad9a3 $ * @since 2.4.1 */ class PhpDependLoggerElement { /** * The type of the logger. * * @var string */ protected $type = ''; /** * Output file for logger. * * @var PhingFile */ protected $outfile = null; /** * Sets the logger type. * * @param string $type Type of the logger * * @throws BuildException */ public function setType($type) { $this->type = $type; switch ($this->type) { case 'jdepend-chart': case 'jdepend-xml': case 'overview-pyramid': case 'phpunit-xml': case 'summary-xml': break; default: throw new BuildException('Logger "' . $this->type . '" not implemented'); } } /** * Get the logger type * * @return string */ public function getType() { return $this->type; } /** * Sets the output file for the logger results. * * @param PhingFile $outfile The output file */ public function setOutfile(PhingFile $outfile) { $this->outfile = $outfile; } /** * Get the output file. * * @return PhingFile */ public function getOutfile() { return $this->outfile; } } phing-2.16.0/tasks/ext/pdepend/PhpDependTask.php0000644000175000017500000003626613027032674020475 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/tasks/ext/pdepend/PhpDependLoggerElement.php'; require_once 'phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php'; /** * Runs the PHP_Depend software analyzer and metric tool. * Performs static code analysis on a given source base. * * @package phing.tasks.ext.pdepend * @author Benjamin Schultz * @version $Id: 7ef44b418426e61cb1ea3b8cf87b289d79f663aa $ * @since 2.4.1 */ class PhpDependTask extends Task { /** * A php source code filename or directory * * @var PhingFile */ protected $file = null; /** * All fileset objects assigned to this task * * @var FileSet[] */ protected $filesets = array(); /** * List of allowed file extensions. Default file extensions are php * and

php5. * * @var array */ protected $allowedFileExtensions = array('php', 'php5'); /** * List of exclude directories. Default exclude dirs are .git, * .svn and CVS. * * @var array */ protected $excludeDirectories = array('.git', '.svn', 'CVS'); /** * List of exclude packages * * @var array */ protected $excludePackages = array(); /** * Should the parse ignore doc comment annotations? * * @var boolean */ protected $withoutAnnotations = false; /** * Should PHP_Depend treat +global as a regular project package? * * @var boolean */ protected $supportBadDocumentation = false; /** * Flag for enable/disable debugging * * @var boolean */ protected $debug = false; /** * PHP_Depend configuration file * * @var PhingFile */ protected $configFile = null; /** * Logger elements * * @var PhpDependLoggerElement[] */ protected $loggers = array(); /** * Analyzer elements * * @var PhpDependAnalyzerElement[] */ protected $analyzers = array(); /** * Holds the PHP_Depend runner instance * * @var PHP_Depend_TextUI_Runner */ protected $runner = null; /** * Flag that determines whether to halt on error * * @var boolean */ protected $haltonerror = false; /** * @var bool */ private $oldVersion = false; /** * @var string */ protected $pharLocation = ""; /** * Load the necessary environment for running PHP_Depend * * @throws BuildException */ protected function requireDependencies() { if (!empty($this->pharLocation)) { include_once 'phar://' . $this->pharLocation . '/vendor/autoload.php'; } // check 2.x version (composer/phar) if (class_exists('PDepend\\TextUI\\Runner')) { return; } $this->oldVersion = true; // check 1.x version (composer) if (class_exists('PHP_Depend_TextUI_Runner')) { // include_path hack for PHP_Depend 1.1.3 $rc = new ReflectionClass('PHP_Depend'); set_include_path(get_include_path() . ":" . realpath(dirname($rc->getFileName()) . "/../")); return; } @include_once 'PHP/Depend/Autoload.php'; if (!class_exists('PHP_Depend_Autoload')) { throw new BuildException( 'PhpDependTask depends on PHP_Depend being installed and on include_path', $this->getLocation() ); } // register PHP_Depend autoloader $autoload = new PHP_Depend_Autoload(); $autoload->register(); } /** * Set the input source file or directory * * @param PhingFile $file The input source file or directory */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets a list of filename extensions for valid php source code files * * @param string $fileExtensions List of valid file extensions */ public function setAllowedFileExtensions($fileExtensions) { $this->allowedFileExtensions = array(); $token = ' ,;'; $ext = strtok($fileExtensions, $token); while ($ext !== false) { $this->allowedFileExtensions[] = $ext; $ext = strtok($token); } } /** * Sets a list of exclude directories * * @param string $excludeDirectories List of exclude directories */ public function setExcludeDirectories($excludeDirectories) { $this->excludeDirectories = array(); $token = ' ,;'; $pattern = strtok($excludeDirectories, $token); while ($pattern !== false) { $this->excludeDirectories[] = $pattern; $pattern = strtok($token); } } /** * Sets a list of exclude packages * * @param string $excludePackages Exclude packages */ public function setExcludePackages($excludePackages) { $this->excludePackages = array(); $token = ' ,;'; $pattern = strtok($excludePackages, $token); while ($pattern !== false) { $this->excludePackages[] = $pattern; $pattern = strtok($token); } } /** * Should the parser ignore doc comment annotations? * * @param boolean $withoutAnnotations */ public function setWithoutAnnotations($withoutAnnotations) { $this->withoutAnnotations = StringHelper::booleanValue($withoutAnnotations); } /** * Should PHP_Depend support projects with a bad documentation. If this * option is set to true, PHP_Depend will treat the default package * +global as a regular project package. * * @param boolean $supportBadDocumentation */ public function setSupportBadDocumentation($supportBadDocumentation) { $this->supportBadDocumentation = StringHelper::booleanValue($supportBadDocumentation); } /** * Set debugging On/Off * * @param boolean $debug */ public function setDebug($debug) { $this->debug = StringHelper::booleanValue($debug); } /** * Set halt on error * * @param boolean $haltonerror */ public function setHaltonerror($haltonerror) { $this->haltonerror = StringHelper::booleanValue($haltonerror); } /** * Set the configuration file * * @param PhingFile $configFile The configuration file */ public function setConfigFile(PhingFile $configFile) { $this->configFile = $configFile; } /** * Create object for nested logger element * * @return PhpDependLoggerElement */ public function createLogger() { $num = array_push($this->loggers, new PhpDependLoggerElement()); return $this->loggers[$num - 1]; } /** * Create object for nested analyzer element * * @return PhpDependAnalyzerElement */ public function createAnalyzer() { $num = array_push($this->analyzers, new PhpDependAnalyzerElement()); return $this->analyzers[$num - 1]; } /** * @param string $pharLocation */ public function setPharLocation($pharLocation) { $this->pharLocation = $pharLocation; } /** * Executes PHP_Depend_TextUI_Runner against PhingFile or a FileSet * * @throws BuildException */ public function main() { $this->requireDependencies(); if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException('Missing either a nested fileset or attribute "file" set'); } if (count($this->loggers) == 0) { throw new BuildException('Missing nested "logger" element'); } $this->validateLoggers(); $this->validateAnalyzers(); $filesToParse = $this->getFilesToParse(); $runner = $this->createRunner(); $runner->setSourceArguments($filesToParse); foreach ($this->loggers as $logger) { // Register logger if ($this->oldVersion) { $runner->addLogger( $logger->getType(), $logger->getOutfile()->__toString() ); } else { $runner->addReportGenerator( $logger->getType(), $logger->getOutfile()->__toString() ); } } foreach ($this->analyzers as $analyzer) { // Register additional analyzer $runner->addOption( $analyzer->getType(), $analyzer->getValue() ); } // Disable annotation parsing if ($this->withoutAnnotations) { $runner->setWithoutAnnotations(); } // Enable bad documentation support if ($this->supportBadDocumentation) { $runner->setSupportBadDocumentation(); } // Check for suffix if (count($this->allowedFileExtensions) > 0) { $runner->setFileExtensions($this->allowedFileExtensions); } // Check for ignore directories if (count($this->excludeDirectories) > 0) { $runner->setExcludeDirectories($this->excludeDirectories); } // Check for exclude packages if (count($this->excludePackages) > 0) { $runner->setExcludePackages($this->excludePackages); } $runner->run(); if ($runner->hasParseErrors() === true) { $this->log('Following errors occurred:'); foreach ($runner->getParseErrors() as $error) { $this->log($error); } if ($this->haltonerror === true) { throw new BuildException('Errors occurred during parse process'); } } } /** * Validates the available loggers * * @throws BuildException */ protected function validateLoggers() { foreach ($this->loggers as $logger) { if ($logger->getType() === '') { throw new BuildException('Logger missing required "type" attribute'); } if ($logger->getOutfile() === null) { throw new BuildException('Logger requires "outfile" attribute'); } } } /** * Validates the available analyzers * * @throws BuildException */ protected function validateAnalyzers() { foreach ($this->analyzers as $analyzer) { if ($analyzer->getType() === '') { throw new BuildException('Analyzer missing required "type" attribute'); } if (count($analyzer->getValue()) === 0) { throw new BuildException('Analyzer missing required "value" attribute'); } } } /** * @return array */ private function getFilesToParse() { $filesToParse = array(); if ($this->file instanceof PhingFile) { $filesToParse[] = $this->file->__toString(); return $filesToParse; } else { // append any files in filesets foreach ($this->filesets as $fs) { $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); foreach ($files as $filename) { $f = new PhingFile($fs->getDir($this->project), $filename); $filesToParse[] = $f->getAbsolutePath(); } } return $filesToParse; } } /** * @return object */ private function createRunner() { if ($this->oldVersion) { return $this->createLegacyRunner(); } $applicationClassName = 'PDepend\\Application'; $application = new $applicationClassName(); $runner = $application->getRunner(); $configuration = $this->getConfiguration(); if ($configuration === null) { $configuration = $application->getConfiguration(); } if ($this->debug) { // Enable debug logging call_user_func('PDepend\\Util\\Log::setSeverity', 1); } call_user_func('PDepend\\Util\\ConfigurationInstance::set', $configuration); return $runner; } /** * @return PHP_Depend_TextUI_Runner */ private function createLegacyRunner() { $runner = new PHP_Depend_TextUI_Runner(); $runner->addProcessListener(new PHP_Depend_TextUI_ResultPrinter()); if ($this->debug) { require_once 'PHP/Depend/Util/Log.php'; // Enable debug logging PHP_Depend_Util_Log::setSeverity(PHP_Depend_Util_Log::DEBUG); } $configuration = $this->getConfiguration(); if ($configuration === null) { $configurationFactory = new PHP_Depend_Util_Configuration_Factory(); $configuration = $configurationFactory->createDefault(); } PHP_Depend_Util_ConfigurationInstance::set($configuration); $runner->setConfiguration($configuration); return $runner; } /** * Loads configuration file * @return null|PHP_Depend_Util_Configuration * @throws BuildException */ private function getConfiguration() { // Check for configuration option if ($this->configFile == null || ! ($this->configFile instanceof PhingFile)) { return null; } if (file_exists($this->configFile->__toString()) === false) { throw new BuildException( 'The configuration file "' . $this->configFile->__toString() . '" doesn\'t exist.' ); } if ($this->oldVersion) { $configurationClassName = 'PHP_Depend_Util_Configuration'; } else { $configurationClassName = 'PDepend\\Util\\Configuration'; } return new $configurationClassName( $this->configFile->__toString(), null, true ); } } phing-2.16.0/tasks/ext/CapsuleTask.php0000644000175000017500000003635013027032674016575 0ustar druiddruid. */ include_once 'phing/Task.php'; include_once 'phing/BuildException.php'; include_once 'phing/lib/Capsule.php'; include_once 'phing/util/StringHelper.php'; /** * A phing task for generating output by using Capsule. * * This is based on the interface to TexenTask from Apache's Velocity engine. * * @author Hans Lellelid * * @package phing.tasks.ext */ class CapsuleTask extends Task { /** * Capsule "template" engine. * @var Capsule */ protected $context; /** * Any vars assigned via the build file. * @var array AssignedVar[] */ protected $assignedVars = array(); /** * This is the control template that governs the output. * It may or may not invoke the services of worker * templates. * @var string */ protected $controlTemplate; /** * This is where Velocity will look for templates * using the file template loader. * @var string */ protected $templatePath; /** * This is where texen will place all the output * that is a product of the generation process. * @var string */ protected $outputDirectory; /** * This is the file where the generated text * will be placed. * @var string */ protected $outputFile; /** *

* These are properties that are fed into the * initial context from a properties file. This * is simply a convenient way to set some values * that you wish to make available in the context. *

*

* These values are not critical, like the template path * or output path, but allow a convenient way to * set a value that may be specific to a particular * generation task. *

*

* For example, if you are generating scripts to allow * user to automatically create a database, then * you might want the $databaseName * to be placed * in the initial context so that it is available * in a script that might look something like the * following: *

     * #!bin/sh
     *
     * echo y | mysqladmin create $databaseName
     * 
* The value of $databaseName isn't critical to * output, and you obviously don't want to change * the ant task to simply take a database name. * So initial context values can be set with * properties file. * * @var array */ protected $contextProperties; // ----------------------------------------------------------------------- // The following getters & setters are used by phing to set properties // specified in the XML for the capsule task. // ----------------------------------------------------------------------- /** * [REQUIRED] Set the control template for the * generating process. * @param string $controlTemplate * @return void */ public function setControlTemplate($controlTemplate) { $this->controlTemplate = $controlTemplate; } /** * Get the control template for the * generating process. * @return string */ public function getControlTemplate() { return $this->controlTemplate; } /** * [REQUIRED] Set the path where Velocity will look * for templates using the file template * loader. * @param $templatePath * @return void */ public function setTemplatePath($templatePath) { $resolvedPath = ""; $tok = strtok($templatePath, ","); while ($tok) { // resolve relative path from basedir and leave // absolute path untouched. $fullPath = $this->project->resolveFile($tok); $cpath = $fullPath->getCanonicalPath(); if ($cpath === false) { $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); } else { $resolvedPath .= $cpath; } $tok = strtok(","); if ($tok) { $resolvedPath .= ","; } } $this->templatePath = $resolvedPath; } /** * Get the path where Velocity will look * for templates using the file template * loader. * @return string */ public function getTemplatePath() { return $this->templatePath; } /** * [REQUIRED] Set the output directory. It will be * created if it doesn't exist. * @param PhingFile $outputDirectory * @return void * @throws Exception */ public function setOutputDirectory(PhingFile $outputDirectory) { try { if (!$outputDirectory->exists()) { $this->log( "Output directory does not exist, creating: " . $outputDirectory->getPath(), Project::MSG_VERBOSE ); if (!$outputDirectory->mkdirs()) { throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); } } $this->outputDirectory = $outputDirectory->getCanonicalPath(); } catch (IOException $ioe) { throw new BuildException($ioe); } } /** * Get the output directory. * @return string */ public function getOutputDirectory() { return $this->outputDirectory; } /** * [REQUIRED] Set the output file for the * generation process. * @param string $outputFile (TODO: change this to File) * @return void */ public function setOutputFile($outputFile) { $this->outputFile = $outputFile; } /** * Get the output file for the * generation process. * @return string */ public function getOutputFile() { return $this->outputFile; } /** * Set the context properties that will be * fed into the initial context be the * generating process starts. * @param string $file * @throws BuildException * @return void */ public function setContextProperties($file) { $sources = explode(",", $file); $this->contextProperties = new Properties(); // Always try to get the context properties resource // from a file first. Templates may be taken from a JAR // file but the context properties resource may be a // resource in the filesystem. If this fails than attempt // to get the context properties resource from the // classpath. for ($i = 0, $sourcesLength = count($sources); $i < $sourcesLength; $i++) { $source = new Properties(); try { // resolve relative path from basedir and leave // absolute path untouched. $fullPath = $this->project->resolveFile($sources[$i]); $this->log("Using contextProperties file: " . $fullPath->toString()); $source->load($fullPath); } catch (Exception $e) { throw new BuildException("Context properties file " . $sources[$i] . " could not be found in the file system!"); } $keys = $source->keys(); foreach ($keys as $key) { $name = $key; $value = $this->project->replaceProperties($source->getProperty($name)); $this->contextProperties->setProperty($name, $value); } } } /** * Get the context properties that will be * fed into the initial context be the * generating process starts. * @return Properties */ public function getContextProperties() { return $this->contextProperties; } /** * Creates an "AssignedVar" class. */ public function createAssign() { $a = new AssignedVar(); $this->assignedVars[] = $a; return $a; } // --------------------------------------------------------------- // End of XML setters & getters // --------------------------------------------------------------- /** * Creates a Smarty object. * * @return Capsule initialized (cleared) Smarty context. * @throws Exception the execute method will catch * and rethrow as a BuildException */ public function initControlContext() { $this->context->clear(); foreach ($this->assignedVars as $var) { $this->context->put($var->getName(), $var->getValue()); } return $this->context; } /** * Execute the input script with Velocity * * @throws BuildException * BuildExceptions are thrown when required attributes are missing. * Exceptions thrown by Velocity are rethrown as BuildExceptions. */ public function main() { // Make sure the template path is set. if (empty($this->templatePath)) { throw new BuildException("The template path needs to be defined!"); } // Make sure the control template is set. if ($this->controlTemplate === null) { throw new BuildException("The control template needs to be defined!"); } // Make sure the output directory is set. if ($this->outputDirectory === null) { throw new BuildException("The output directory needs to be defined!"); } // Make sure there is an output file. if ($this->outputFile === null) { throw new BuildException("The output file needs to be defined!"); } // Setup Smarty runtime. // Smarty uses one object to store properties and to store // the context for the template (unlike Velocity). We setup this object, calling it // $this->context, and then initControlContext simply zeros out // any assigned variables. $this->context = new Capsule(); if ($this->templatePath !== null) { $this->log("Using templatePath: " . $this->templatePath); $this->context->setTemplatePath($this->templatePath); } // Make sure the output directory exists, if it doesn't // then create it. $outputDir = new PhingFile($this->outputDirectory); if (!$outputDir->exists()) { $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath()); $outputDir->mkdirs(); } $this->context->setOutputDirectory($outputDir->getAbsolutePath()); $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; $this->log("Generating to file " . $path); //$writer = new FileWriter($path); // The generator and the output path should // be placed in the init context here and // not in the generator class itself. $c = $this->initControlContext(); // Set any variables that need to always // be loaded $this->populateInitialContext($c); // Feed all the options into the initial // control context so they are available // in the control/worker templates. if ($this->contextProperties !== null) { foreach ($this->contextProperties->keys() as $property) { $value = $this->contextProperties->getProperty($property); // Special exception (from Texen) // for properties ending in file.contents: // in that case we dump the contents of the file // as the "value" for the Property. if (preg_match('/file\.contents$/', $property)) { // pull in contents of file specified $property = substr($property, 0, strpos($property, "file.contents") - 1); // reset value, and then // read in the contents of the file into that var $value = ""; $f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath()); if ($f->exists()) { $fr = new FileReader($f); $fr->readInto($value); } } // if ends with file.contents if (StringHelper::isBoolean($value)) { $value = StringHelper::booleanValue($value); } $c->put($property, $value); } // foreach property } // if contextProperties !== null try { $this->log("Parsing control template: " . $this->controlTemplate); $c->parse($this->controlTemplate, $path); } catch (Exception $ioe) { throw new BuildException("Cannot write parsed template: " . $ioe->getMessage()); } $this->cleanup(); } /** * Place useful objects into the initial context. * * * @param Capsule $context The context to populate, as retrieved from * {@link #initControlContext()}. * @return void * @throws Exception Error while populating context. The {@link * #main()} method will catch and rethrow as a * BuildException. */ protected function populateInitialContext(Capsule $context) { $this->context->put("now", strftime("%c", time())); $this->context->put("task", $this); } /** * A hook method called at the end of {@link #execute()} which can * be overridden to perform any necessary cleanup activities (such * as the release of database connections, etc.). By default, * does nothing. * * @return void */ protected function cleanup() { } } /** * An "inner" class for holding assigned var values. * May be need to expand beyond name/value in the future. * * @package phing.tasks.ext */ class AssignedVar { private $name; private $value; /** * @param string $v */ public function setName($v) { $this->name = $v; } /** * @param mixed $v */ public function setValue($v) { $this->value = $v; } /** * @return string */ public function getName() { return $this->name; } /** * @return mixed */ public function getValue() { return $this->value; } } phing-2.16.0/tasks/ext/sonar/SonarProperty.php0000644000175000017500000000342713027032674020326 0ustar druiddruid. */ /** * A property element nested in SonarTask. * * @author Bernhard Mendl * @package phing.tasks.ext.sonar */ class SonarProperty { /** * * @var string */ private $name; /** * * @var string */ private $value; /** * * @return string */ public function getName() { return $this->name; } /** * * @param string $name * @return void */ public function setName($name) { $this->name = (string) $name; } /** * * @return string */ public function getValue() { return $this->value; } /** * * @param string $value * @return void */ public function setValue($value) { $this->value = (string) $value; } } phing-2.16.0/tasks/ext/sonar/SonarTask.php0000644000175000017500000003051113027032674017376 0ustar druiddruid. */ require_once 'phing/BuildException.php'; require_once 'phing/Project.php'; require_once 'phing/Task.php'; require_once 'phing/tasks/ext/sonar/SonarConfigurationFileParser.php'; require_once 'phing/tasks/ext/sonar/SonarProperty.php'; /** * Runs SonarQube Scanner. * * @author Bernhard Mendl * @package phing.tasks.ext.sonar * @see http://www.sonarqube.org */ class SonarTask extends Task { const EXIT_SUCCESS = 0; /** * * @var string|null */ private $executable = null; /** * * @var string */ private $errors = 'false'; /** * * @var string */ private $debug = 'false'; /** * * @var string|null */ private $configuration = null; /** * * @var array Nested *Property* elements. * @see Property */ private $propertyElements = array(); /** * The command-line options passed to the SonarQube Scanner executable. * * @var array */ private $commandLineOptions = array(); /** * Map containing SonarQube's "analysis parameters". * * Map keys are SonarQube parameter names. Map values are parameter values. * See {@link http://docs.sonarqube.org/display/SONAR/Analysis+Parameters}. * * @var array */ private $properties = array(); /** * Sets the path of the SonarQube Scanner executable. * * If the SonarQube Scanner is included in the PATH environment variable, * the file name is sufficient. * * @param string $executable * @return void */ public function setExecutable($executable) { $this->executable = (string) $executable; $message = sprintf("Set executable to [%s].", $this->executable); $this->log($message, Project::MSG_DEBUG); } /** * Sets or unsets the "--errors" flag of SonarQube Scanner. * * @param string $errors * Allowed values are "true"/"false", "yes"/"no", or "1"/"0". * @return void */ public function setErrors($errors) { $this->errors = strtolower((string) $errors); $message = sprintf("Set errors flag to [%s].", $this->errors); $this->log($message, Project::MSG_DEBUG); } /** * Sets or unsets the "--debug" flag of SonarQube Scanner. * * @param string $debug * Allowed values are "true"/"false", "yes"/"no", or "1"/"0". * @return void */ public function setDebug($debug) { $this->debug = strtolower((string) $debug); $message = sprintf("Set debug flag to [%s].", $this->debug); $this->log($message, Project::MSG_DEBUG); } /** * Sets the path of a configuration file for SonarQube Scanner. * * @param string $configuration * @return void */ public function setConfiguration($configuration) { $this->configuration = (string) $configuration; $message = sprintf("Set configuration to [%s].", $this->configuration); $this->log($message, Project::MSG_DEBUG); } /** * Adds a nested Property element. * * @param SonarProperty $property * @return void */ public function addProperty(SonarProperty $property) { $this->propertyElements[] = $property; $message = sprintf("Added property: [%s] = [%s].", $property->getName(), $property->getValue()); $this->log($message, Project::MSG_DEBUG); } /** * * {@inheritdoc} * * @see Task::init() */ public function init() { $this->checkExecAllowed(); } /** * * {@inheritdoc} * * @see Task::main() */ public function main() { $this->validateErrors(); $this->validateDebug(); $this->validateConfiguration(); $this->validateProperties(); $this->validateExecutable(); $command = sprintf('%s %s', escapeshellcmd($this->executable), $this->constructOptionsString()); $message = sprintf('Executing: [%s]', $command); $this->log($message, Project::MSG_VERBOSE); exec($command, $output, $returnCode); foreach ($output as $line) { $this->log($line); } if ($returnCode !== self::EXIT_SUCCESS) { throw new BuildException('Execution of SonarQube Scanner failed.'); } } /** * Constructs command-line options string for SonarQube Scanner. * * @return string */ private function constructOptionsString() { $options = implode(' ', $this->commandLineOptions); foreach ($this->properties as $name => $value) { $arg = sprintf('%s=%s', $name, $value); $options .= ' -D ' . escapeshellarg($arg); } return $options; } /** * Check whether PHP function 'exec()' is available. * * @throws BuildException * @return void */ private function checkExecAllowed() { if (! function_exists('exec') || ! is_callable('exec')) { $message = 'Cannot execute SonarQube Scanner because calling PHP function exec() is not permitted by PHP configuration.'; throw new BuildException($message); } } /** * * @throws BuildException * @return void */ private function validateExecutable() { if (($this->executable === null) || ($this->executable === '')) { $message = 'You must specify the path of the SonarQube Scanner using the "executable" attribute.'; throw new BuildException($message); } // Note that executable is used as argument here. $escapedExecutable = escapeshellarg($this->executable); if ($this->isWindows()) { $message = 'Assuming a Windows system. Looking for SonarQube Scanner ...'; $command = 'where ' . $escapedExecutable; } else { $message = 'Assuming a Linux or Mac system. Looking for SonarQube Scanner ...'; $command = 'which ' . $escapedExecutable; } $this->log($message, Project::MSG_VERBOSE); unset($output); exec($command, $output, $returnCode); if ($returnCode !== self::EXIT_SUCCESS) { $message = sprintf('Cannot find SonarQube Scanner: [%s].', $this->executable); throw new BuildException($message); } // Verify that executable is indeed SonarQube Scanner ... $escapedExecutable = escapeshellcmd($this->executable); unset($output); exec($escapedExecutable . ' --version', $output, $returnCode); if ($returnCode !== self::EXIT_SUCCESS) { $message = sprintf('Could not check version string. Executable appears not to be SonarQube Scanner: [%s].', $this->executable); throw new BuildException($message); } $isOk = false; foreach ($output as $line) { if (preg_match('/SonarQube Scanner [0-9]+\\.[0-9]+/', $line) === 1) { $isOk = true; break; } } if ($isOk) { $message = sprintf('Found SonarQube Scanner: [%s].', $this->executable); $this->log($message, Project::MSG_VERBOSE); } else { $message = sprintf('Could not find name of SonarQube Scanner in version string. Executable appears not to be SonarQube Scanner: [%s].', $this->executable); throw new BuildException($message); } } /** * * @throws BuildException * @return void */ private function validateErrors() { if (($this->errors === '1') || ($this->errors === 'true') || ($this->errors === 'yes')) { $errors = true; } elseif (($this->errors === '0') || ($this->errors === 'false') || ($this->errors === 'no')) { $errors = false; } else { throw new BuildException('Expected a boolean value.'); } if ($errors) { $this->commandLineOptions[] = '--errors'; } } /** * * @throws BuildException * @return void */ private function validateDebug() { if (($this->debug === '1') || ($this->debug === 'true') || ($this->debug === 'yes')) { $debug = true; } elseif (($this->debug === '0') || ($this->debug === 'false') || ($this->debug === 'no')) { $debug = false; } else { throw new BuildException('Expected a boolean value.'); } if ($debug) { $this->commandLineOptions[] = '--debug'; } } /** * * @throws BuildException * @return void */ private function validateConfiguration() { if (($this->configuration === null) || ($this->configuration === '')) { // NOTE: Ignore an empty configuration. This allows for // using Phing properties as attribute values, e.g. // . return; } if (! @file_exists($this->configuration)) { $message = sprintf('Cannot find configuration file [%s].', $this->configuration); throw new BuildException($message); } if (! @is_readable($this->configuration)) { $message = sprintf('Cannot read configuration file [%s].', $this->configuration); throw new BuildException($message); } // TODO: Maybe check file type? } /** * * @throws BuildException * @return void */ private function validateProperties() { $this->properties = $this->parseConfigurationFile(); foreach ($this->propertyElements as $property) { $name = $property->getName(); $value = $property->getValue(); if ($name === null || $name === '') { throw new BuildException('Property name must not be null or empty.'); } if (array_key_exists($name, $this->properties)) { $message = sprintf('Property [%s] overwritten: old value [%s], new value [%s].', $name, $this->properties[$name], $value); $this->log($message, Project::MSG_WARN); } $this->properties[$name] = $value; } // Check if all properties required by SonarQube Scanner are set ... $requiredProperties = array( 'sonar.projectKey', 'sonar.projectName', 'sonar.projectVersion', 'sonar.sources' ); $intersection = array_intersect($requiredProperties, array_keys($this->properties)); if (count($intersection) < count($requiredProperties)) { $message = 'SonarQube Scanner misses some parameters. The following properties are mandatory: ' . implode(', ', $requiredProperties) . '.'; throw new BuildException($message); } } /** * * @return array */ private function parseConfigurationFile() { if (($this->configuration === null) || ($this->configuration === '')) { return array(); } $parser = new SonarConfigurationFileParser($this->configuration, $this->project); return $parser->parse(); } /** * * @return boolean */ private function isWindows() { $operatingSystemName = php_uname('s'); return strtoupper(substr($operatingSystemName, 0, 3)) === 'WIN'; } } phing-2.16.0/tasks/ext/sonar/SonarConfigurationFileParser.php0000644000175000017500000001273613027032674023271 0ustar druiddruid. */ require_once 'phing/BuildException.php'; require_once 'phing/Project.php'; require_once 'phing/tasks/ext/sonar/SonarProperty.php'; /** * * @author Bernhard Mendl * @package phing.tasks.ext.sonar */ class SonarConfigurationFileParser { /** * * @var Project */ private $project; /** * * @var string */ private $file; /** * This map holds the properties read from the configuration file. * * @var array */ private $properties; /** * Name of currently parsed property. * * @var string|null */ private $name; /** * Value of currently parsed property. * * @var string */ private $value; /** * * @param string $file * The properties file. */ public function __construct($file, Project $project) { if (($file === null) || ($file === '')) { throw new BuildException('File name must not be null or empty.'); } $this->file = $file; $this->project = $project; } /** * * @throws BuildException * @return array */ public function parse() { $this->properties = array(); $contents = @file_get_contents($this->file); if ($contents === false) { $message = sprintf('Could not read file [%s].', $this->file); throw new BuildException($message); } $lines = explode("\n", $contents); $count = count($lines); $isMultiLine = false; for ($i = 0; $i < $count; $i ++) { $line = $lines[$i]; if ($isMultiLine) { $isMultiLine = $this->extractContinuedValue($line); } else { $this->name = null; $this->value = ''; $isMultiLine = $this->extractNameAndValue($line); } if (($this->name !== null) && (! $isMultiLine)) { if (array_key_exists($this->name, $this->properties)) { $message = sprintf('Property [%s] overwritten: old value [%s], new value [%s].', $this->name, $this->properties[$this->name], $this->value); $this->project->log($message, Project::MSG_WARN); } // Unescape backslashes. $this->value = str_replace('\\\\', '\\', $this->value); $this->properties[$this->name] = $this->value; } } if ($isMultiLine) { $message = sprintf('Last property looks like a multi-lined value, but end of file found. Name = [%s].', $this->name); throw new BuildException($message); } return $this->properties; } /** * * @param string $line * @return boolean */ private function extractNameAndValue($line) { $isMultiLine = false; if ($this->isCommentLine($line)) { return $isMultiLine; } // Find key and value. $hasMatch = preg_match('/\\s*([^=:]*[^=:\\s]+)\\s*[=:]\\s*(.*)$/s', $line, $matches); if (($hasMatch === 1) && (count($matches) === 3)) { $this->name = $matches[1]; $this->value = $matches[2]; $isMultiLine = $this->checkMultiLine(); } return $isMultiLine; } /** * * @param string $line * @return boolean */ private function extractContinuedValue($line) { $isMultiLine = false; if ($this->isCommentLine($line)) { return $isMultiLine; } // Find continued value. $hasMatch = preg_match('/\\s*(.*)$/s', $line, $matches); if (($hasMatch === 1) && (count($matches) === 2)) { $this->value .= $matches[1]; $isMultiLine = $this->checkMultiLine(); } return $isMultiLine; } /** * * @return boolean */ private function checkMultiLine() { $isMultiLine = false; // Is there a single(!) backslash at the end of the line? if (preg_match('/[^\\\]\\\$/', $this->value) === 1) { // Remove last char, i.e. the backslash. $this->value = substr($this->value, 0, -1); $isMultiLine = true; } return $isMultiLine; } /** * * @param string $line * @return boolean */ private function isCommentLine($line) { return preg_match('/^\\s*[!#]/', $line) === 1; } } phing-2.16.0/tasks/ext/FileSizeTask.php0000644000175000017500000000653713027032674016717 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * fileHash * * Calculate either MD5 or SHA hash value of a specified file and retun the * value in a property * * @author Johan Persson * @version $Id: d4b97a2e512ffe10394e203d6a94c498e11ca986 $ * @package phing.tasks.ext */ class FileSizeTask extends Task { /** * Property for File * @var PhingFile file */ private $file; /** * Property where the file size will be stored * @var string $property */ private $propertyName = "filesize"; /** * Which file to calculate the file size of * @param PhingFile $file */ public function setFile($file) { $this->file = $file; } /** * Set the name of the property to store the file size * @param $property * @return void */ public function setPropertyName($property) { $this->propertyName = $property; } /** * Main-Method for the Task * * @return void * @throws BuildException */ public function main() { $this->checkFile(); $this->checkPropertyName(); $size = filesize($this->file); if ($size === false) { throw new BuildException(sprintf('[FileSize] Cannot determine size of file: %s', $this->file)); } // publish hash value $this->project->setProperty($this->propertyName, $size); } /** * checks file attribute * @return void * @throws BuildException */ private function checkFile() { // check File if ($this->file === null || strlen($this->file) == 0 ) { throw new BuildException('[FileSize] You must specify an input file.', $this->file); } if (!is_readable($this->file)) { throw new BuildException(sprintf( '[FileSize] Input file does not exist or is not readable: %s', $this->file )); } } /** * checks property attribute * @return void * @throws BuildException */ private function checkPropertyName() { if (is_null($this->propertyName) || strlen($this->propertyName) === 0 ) { throw new BuildException('[FileSize] Property name for publishing file size is not set'); } } } phing-2.16.0/tasks/ext/coverage/CoverageReportTask.php0000644000175000017500000004641213027032674021723 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/system/io/PhingFile.php'; require_once 'phing/system/io/Writer.php'; require_once 'phing/system/util/Properties.php'; require_once 'phing/tasks/ext/phpunit/PHPUnitUtil.php'; require_once 'phing/tasks/ext/coverage/CoverageReportTransformer.php'; /** * Transforms information in a code coverage database to XML * * @author Michiel Rook * @version $Id: 9a15437e8ba7eb26f59aa20fd6c10e682b26e697 $ * @package phing.tasks.ext.coverage * @since 2.1.0 */ class CoverageReportTask extends Task { private $outfile = "coverage.xml"; private $transformers = array(); /** the classpath to use (optional) */ private $classpath = null; /** the path to the GeSHi library (optional) */ private $geshipath = ""; /** the path to the GeSHi language files (optional) */ private $geshilanguagespath = ""; /** * @param Path $classpath */ public function setClasspath(Path $classpath) { if ($this->classpath === null) { $this->classpath = $classpath; } else { $this->classpath->append($classpath); } } /** * @return null|Path */ public function createClasspath() { $this->classpath = new Path(); return $this->classpath; } /** * @param $path */ public function setGeshiPath($path) { $this->geshipath = $path; } /** * @param $path */ public function setGeshiLanguagesPath($path) { $this->geshilanguagespath = $path; } /** * */ public function __construct() { $this->doc = new DOMDocument(); $this->doc->encoding = 'UTF-8'; $this->doc->formatOutput = true; $this->doc->appendChild($this->doc->createElement('snapshot')); } /** * @param $outfile */ public function setOutfile($outfile) { $this->outfile = $outfile; } /** * Generate a report based on the XML created by this task */ public function createReport() { $transformer = new CoverageReportTransformer($this); $this->transformers[] = $transformer; return $transformer; } /** * @param $packageName * @return null */ protected function getPackageElement($packageName) { $packages = $this->doc->documentElement->getElementsByTagName('package'); foreach ($packages as $package) { if ($package->getAttribute('name') == $packageName) { return $package; } } return null; } /** * @param $packageName * @param $element */ protected function addClassToPackage($packageName, $element) { $package = $this->getPackageElement($packageName); if ($package === null) { $package = $this->doc->createElement('package'); $package->setAttribute('name', $packageName); $this->doc->documentElement->appendChild($package); } $package->appendChild($element); } /** * Adds a subpackage to their package * * @param string $packageName The name of the package * @param string $subpackageName The name of the subpackage * * @author Benjamin Schultz * @return void */ protected function addSubpackageToPackage($packageName, $subpackageName) { $package = $this->getPackageElement($packageName); $subpackage = $this->getSubpackageElement($subpackageName); if ($package === null) { $package = $this->doc->createElement('package'); $package->setAttribute('name', $packageName); $this->doc->documentElement->appendChild($package); } if ($subpackage === null) { $subpackage = $this->doc->createElement('subpackage'); $subpackage->setAttribute('name', $subpackageName); } $package->appendChild($subpackage); } /** * Returns the subpackage element * * @param string $subpackageName The name of the subpackage * * @author Benjamin Schultz * @return DOMNode|null null when no DOMNode with the given name exists */ protected function getSubpackageElement($subpackageName) { $subpackages = $this->doc->documentElement->getElementsByTagName('subpackage'); foreach ($subpackages as $subpackage) { if ($subpackage->getAttribute('name') == $subpackageName) { return $subpackage; } } return null; } /** * Adds a class to their subpackage * * @param string $classname The name of the class * @param DOMNode $element The dom node to append to the subpackage element * * @author Benjamin Schultz * @return void */ protected function addClassToSubpackage($classname, $element) { $subpackageName = PHPUnitUtil::getSubpackageName($classname); $subpackage = $this->getSubpackageElement($subpackageName); if ($subpackage === null) { $subpackage = $this->doc->createElement('subpackage'); $subpackage->setAttribute('name', $subpackageName); $this->doc->documentElement->appendChild($subpackage); } $subpackage->appendChild($element); } /** * @param $source * @return string */ protected function stripDiv($source) { $openpos = strpos($source, "", $openpos); $line = substr($source, $closepos + 1); $tagclosepos = strpos($line, ""); $line = substr($line, 0, $tagclosepos); return $line; } /** * @param $filename * @return array */ protected function highlightSourceFile($filename) { if ($this->geshipath) { require_once $this->geshipath . '/geshi.php'; $source = file_get_contents($filename); $geshi = new GeSHi($source, 'php', $this->geshilanguagespath); $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS); $geshi->enable_strict_mode(true); $geshi->enable_classes(true); $geshi->set_url_for_keyword_group(3, ''); $html = $geshi->parse_code(); $lines = preg_split("##", $html); // skip first and last line array_pop($lines); array_shift($lines); $lines = array_filter($lines); $lines = array_map(array($this, 'stripDiv'), $lines); return $lines; } else { $lines = file($filename); for ($i = 0; $i < count($lines); $i++) { $line = $lines[$i]; $line = rtrim($line); if (function_exists('mb_check_encoding') && mb_check_encoding($line, 'UTF-8')) { $lines[$i] = $line; } else { if (function_exists('mb_convert_encoding')) { $lines[$i] = mb_convert_encoding($line, 'UTF-8'); } else { $lines[$i] = utf8_encode($line); } } } return $lines; } } /** * @param $filename * @param $coverageInformation * @param int $classStartLine * @return DOMElement */ protected function transformSourceFile($filename, $coverageInformation, $classStartLine = 1) { $sourceElement = $this->doc->createElement('sourcefile'); $sourceElement->setAttribute('name', basename($filename)); /** * Add original/full filename to document */ $sourceElement->setAttribute('sourcefile', $filename); $filelines = $this->highlightSourceFile($filename); $linenr = 1; foreach ($filelines as $line) { $lineElement = $this->doc->createElement('sourceline'); $lineElement->setAttribute( 'coveredcount', (isset($coverageInformation[$linenr]) ? $coverageInformation[$linenr] : '0') ); if ($linenr == $classStartLine) { $lineElement->setAttribute('startclass', 1); } $textnode = $this->doc->createTextNode($line); $lineElement->appendChild($textnode); $sourceElement->appendChild($lineElement); $linenr++; } return $sourceElement; } /** * Transforms the coverage information * * @param string $filename The filename * @param array $coverageInformation Array with covergae information * * @author Michiel Rook * @author Benjamin Schultz * @return void */ protected function transformCoverageInformation($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); if (is_array($classes)) { foreach ($classes as $classname) { $reflection = new ReflectionClass($classname); $methods = $reflection->getMethods(); if (method_exists($reflection, 'getShortName')) { $className = $reflection->getShortName(); } else { $className = $reflection->getName(); } $classElement = $this->doc->createElement('class'); $classElement->setAttribute('name', $className); $packageName = PHPUnitUtil::getPackageName($reflection->getName()); $subpackageName = PHPUnitUtil::getSubpackageName($reflection->getName()); if ($subpackageName !== null) { $this->addSubpackageToPackage($packageName, $subpackageName); $this->addClassToSubpackage($reflection->getName(), $classElement); } else { $this->addClassToPackage($packageName, $classElement); } $classStartLine = $reflection->getStartLine(); $methodscovered = 0; $methodcount = 0; // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off if ($reflection->getParentClass() == null && count($reflection->getInterfaces()) == 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } // Remove out-of-bounds info unset($coverageInformation[0]); reset($coverageInformation); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$method->getStartLine()])) { unset($coverageInformation[$method->getStartLine()]); } if (isset($coverageInformation[$method->getEndLine()])) { unset($coverageInformation[$method->getEndLine()]); } if ($method->isAbstract()) { continue; } $linenr = key($coverageInformation); while ($linenr !== null && $linenr < $method->getStartLine()) { next($coverageInformation); $linenr = key($coverageInformation); } $methodCoveredCount = 0; $methodTotalCount = 0; $methodHasCoveredLine = false; while ($linenr !== null && $linenr <= $method->getEndLine()) { $methodTotalCount++; $methodHasCoveredLine = true; // set covered when CODE is other than -1 (not executed) if ($coverageInformation[$linenr] > 0 || $coverageInformation[$linenr] == -2) { $methodCoveredCount++; } next($coverageInformation); $linenr = key($coverageInformation); } if (($methodTotalCount == $methodCoveredCount) && $methodHasCoveredLine) { $methodscovered++; } $methodcount++; } $statementcount = count( array_filter( $coverageInformation, create_function('$var', 'return ($var != -2);') ) ); $statementscovered = count( array_filter( $coverageInformation, create_function('$var', 'return ($var >= 0);') ) ); $classElement->appendChild( $this->transformSourceFile($filename, $coverageInformation, $classStartLine) ); $classElement->setAttribute('methodcount', $methodcount); $classElement->setAttribute('methodscovered', $methodscovered); $classElement->setAttribute('statementcount', $statementcount); $classElement->setAttribute('statementscovered', $statementscovered); $classElement->setAttribute('totalcount', $methodcount + $statementcount); $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); } } } protected function calculateStatistics() { $packages = $this->doc->documentElement->getElementsByTagName('package'); $totalmethodcount = 0; $totalmethodscovered = 0; $totalstatementcount = 0; $totalstatementscovered = 0; foreach ($packages as $package) { $methodcount = 0; $methodscovered = 0; $statementcount = 0; $statementscovered = 0; $subpackages = $package->getElementsByTagName('subpackage'); foreach ($subpackages as $subpackage) { $subpackageMethodCount = 0; $subpackageMethodsCovered = 0; $subpackageStatementCount = 0; $subpackageStatementsCovered = 0; $subpackageClasses = $subpackage->getElementsByTagName('class'); foreach ($subpackageClasses as $subpackageClass) { $subpackageMethodCount += $subpackageClass->getAttribute('methodcount'); $subpackageMethodsCovered += $subpackageClass->getAttribute('methodscovered'); $subpackageStatementCount += $subpackageClass->getAttribute('statementcount'); $subpackageStatementsCovered += $subpackageClass->getAttribute('statementscovered'); } $subpackage->setAttribute('methodcount', $subpackageMethodCount); $subpackage->setAttribute('methodscovered', $subpackageMethodsCovered); $subpackage->setAttribute('statementcount', $subpackageStatementCount); $subpackage->setAttribute('statementscovered', $subpackageStatementsCovered); $subpackage->setAttribute('totalcount', $subpackageMethodCount + $subpackageStatementCount); $subpackage->setAttribute('totalcovered', $subpackageMethodsCovered + $subpackageStatementsCovered); } $classes = $package->getElementsByTagName('class'); foreach ($classes as $class) { $methodcount += $class->getAttribute('methodcount'); $methodscovered += $class->getAttribute('methodscovered'); $statementcount += $class->getAttribute('statementcount'); $statementscovered += $class->getAttribute('statementscovered'); } $package->setAttribute('methodcount', $methodcount); $package->setAttribute('methodscovered', $methodscovered); $package->setAttribute('statementcount', $statementcount); $package->setAttribute('statementscovered', $statementscovered); $package->setAttribute('totalcount', $methodcount + $statementcount); $package->setAttribute('totalcovered', $methodscovered + $statementscovered); $totalmethodcount += $methodcount; $totalmethodscovered += $methodscovered; $totalstatementcount += $statementcount; $totalstatementscovered += $statementscovered; } $this->doc->documentElement->setAttribute('methodcount', $totalmethodcount); $this->doc->documentElement->setAttribute('methodscovered', $totalmethodscovered); $this->doc->documentElement->setAttribute('statementcount', $totalstatementcount); $this->doc->documentElement->setAttribute('statementscovered', $totalstatementscovered); $this->doc->documentElement->setAttribute('totalcount', $totalmethodcount + $totalstatementcount); $this->doc->documentElement->setAttribute('totalcovered', $totalmethodscovered + $totalstatementscovered); } public function main() { $coverageDatabase = $this->project->getProperty('coverage.database'); if (!$coverageDatabase) { throw new BuildException("Property coverage.database is not set - please include coverage-setup in your build file"); } $database = new PhingFile($coverageDatabase); $this->log("Transforming coverage report"); $props = new Properties(); $props->load($database); foreach ($props->keys() as $filename) { $file = unserialize($props->getProperty($filename)); $this->transformCoverageInformation($file['fullname'], $file['coverage']); } $this->calculateStatistics(); $this->doc->save($this->outfile); foreach ($this->transformers as $transformer) { $transformer->setXmlDocument($this->doc); $transformer->transform(); } } } phing-2.16.0/tasks/ext/coverage/CoverageSetupTask.php0000644000175000017500000001143213027032674021542 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/system/io/PhingFile.php'; require_once 'phing/system/io/Writer.php'; require_once 'phing/system/util/Properties.php'; require_once 'phing/tasks/ext/coverage/CoverageMerger.php'; /** * Initializes a code coverage database * * @author Michiel Rook * @version $Id: bde7020012ba4f24e0d97768c76a5a8af99a6fbb $ * @package phing.tasks.ext.coverage * @since 2.1.0 */ class CoverageSetupTask extends Task { /** the list of filesets containing the .php filename rules */ private $filesets = array(); /** Any filelists of files containing the .php filenames */ private $filelists = array(); /** the filename of the coverage database */ private $database = "coverage.db"; /** the classpath to use (optional) */ private $classpath = null; /** * Add a new fileset containing the .php files to process * * @param FileSet the new fileset containing .php files */ public function addFileSet(FileSet $fileset) { $this->filesets[] = $fileset; } /** * Supports embedded element. * @return FileList */ public function createFileList() { $num = array_push($this->filelists, new FileList()); return $this->filelists[$num - 1]; } /** * Sets the filename of the coverage database to use * * @param string the filename of the database */ public function setDatabase($database) { $this->database = $database; } /** * @param Path $classpath */ public function setClasspath(Path $classpath) { if ($this->classpath === null) { $this->classpath = $classpath; } else { $this->classpath->append($classpath); } } /** * @return null|Path */ public function createClasspath() { $this->classpath = new Path(); return $this->classpath; } /** * Iterate over all filesets and return the filename of all files. * * @return array an array of (basedir, filenames) pairs */ private function getFilenames() { $files = array(); foreach ($this->filelists as $fl) { try { $list = $fl->getFiles($this->project); foreach ($list as $file) { $fs = new PhingFile(strval($fl->getDir($this->project)), $file); $files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath()); } } catch (BuildException $be) { $this->log($be->getMessage(), Project::MSG_WARN); } } foreach ($this->filesets as $fileset) { $ds = $fileset->getDirectoryScanner($this->project); $ds->scan(); $includedFiles = $ds->getIncludedFiles(); foreach ($includedFiles as $file) { $fs = new PhingFile(realpath($ds->getBaseDir()), $file); $files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath()); } } return $files; } public function init() { } public function main() { $files = $this->getFilenames(); $this->log("Setting up coverage database for " . count($files) . " files"); $props = new Properties(); foreach ($files as $file) { $fullname = $file['fullname']; $filename = $file['key']; $props->setProperty($filename, serialize(array('fullname' => $fullname, 'coverage' => array()))); } $dbfile = new PhingFile($this->database); $props->store($dbfile); $this->project->setProperty('coverage.database', $dbfile->getAbsolutePath()); } } phing-2.16.0/tasks/ext/coverage/CoverageThresholdTask.php0000644000175000017500000003521013027032674022376 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/system/io/PhingFile.php'; require_once 'phing/system/util/Properties.php'; require_once 'phing/types/Excludes.php'; /** * Stops the build if any of the specified coverage threshold was not reached * * @author Benjamin Schultz * @version $Id: 1cf68f1a4ec652811a5fd9db8353cae9a88ee03e $ * @package phing.tasks.ext.coverage * @since 2.4.1 */ class CoverageThresholdTask extends Task { /** * Holds an optional classpath * * @var Path */ private $_classpath = null; /** * Holds the exclusions * * @var Excludes */ private $_excludes = null; /** * Holds an optional database file * * @var PhingFile */ private $_database = null; /** * Holds the coverage threshold for the entire project * * @var integer */ private $_perProject = 25; /** * Holds the coverage threshold for any class * * @var integer */ private $_perClass = 25; /** * Holds the coverage threshold for any method * * @var integer */ private $_perMethod = 25; /** * Holds the minimum found coverage value for a class * * @var integer */ private $_minClassCoverageFound = null; /** * Holds the minimum found coverage value for a method * * @var integer */ private $_minMethodCoverageFound = null; /** * Number of statements in the entire project * * @var integer */ private $_projectStatementCount = 0; /** * Number of covered statements in the entire project * * @var integer */ private $_projectStatementsCovered = 0; /** * Whether to enable detailed logging * * @var boolean */ private $_verbose = false; /** * Sets an optional classpath * * @param Path $classpath The classpath */ public function setClasspath(Path $classpath) { if ($this->_classpath === null) { $this->_classpath = $classpath; } else { $this->_classpath->append($classpath); } } /** * Sets the optional coverage database to use * * @param PhingFile The database file */ public function setDatabase(PhingFile $database) { $this->_database = $database; } /** * Create classpath object * * @return Path */ public function createClasspath() { $this->_classpath = new Path(); return $this->_classpath; } /** * Sets the coverage threshold for entire project * * @param integer $threshold Coverage threshold for entire project */ public function setPerProject($threshold) { $this->_perProject = $threshold; } /** * Sets the coverage threshold for any class * * @param integer $threshold Coverage threshold for any class */ public function setPerClass($threshold) { $this->_perClass = $threshold; } /** * Sets the coverage threshold for any method * * @param integer $threshold Coverage threshold for any method */ public function setPerMethod($threshold) { $this->_perMethod = $threshold; } /** * Sets whether to enable detailed logging or not * * @param boolean $verbose */ public function setVerbose($verbose) { $this->_verbose = StringHelper::booleanValue($verbose); } /** * Filter covered statements * * @param integer $var Coverage CODE/count * @return boolean */ protected function filterCovered($var) { return ($var >= 0 || $var === -2); } /** * Create excludes object * * @return Excludes */ public function createExcludes() { $this->_excludes = new Excludes($this->project); return $this->_excludes; } /** * Calculates the coverage threshold * * @param string $filename The filename to analyse * @param array $coverageInformation Array with coverage information * @throws BuildException */ protected function calculateCoverageThreshold($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->_classpath); if (is_array($classes)) { foreach ($classes as $className) { // Skip class if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($className, $this->_excludes->getExcludedClasses())) { continue; } } $reflection = new ReflectionClass($className); $classStartLine = $reflection->getStartLine(); // Strange PHP5 reflection bug, classes without parent class // or implemented interfaces seem to start one line off if ($reflection->getParentClass() === null && count($reflection->getInterfaces()) === 0 ) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); $methods = $reflection->getMethods(); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class // to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // Skip method if excluded from coverage threshold validation if ($this->_excludes !== null) { $excludedMethods = $this->_excludes->getExcludedMethods(); if (isset($excludedMethods[$className])) { if (in_array($method->getName(), $excludedMethods[$className]) || in_array($method->getName() . '()', $excludedMethods[$className]) ) { continue; } } } $methodStartLine = $method->getStartLine(); $methodEndLine = $method->getEndLine(); // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$methodStartLine])) { unset($coverageInformation[$methodStartLine]); } if (isset($coverageInformation[$methodEndLine])) { unset($coverageInformation[$methodEndLine]); } if ($method->isAbstract()) { continue; } $lineNr = key($coverageInformation); while ($lineNr !== null && $lineNr < $methodStartLine) { next($coverageInformation); $lineNr = key($coverageInformation); } $methodStatementsCovered = 0; $methodStatementCount = 0; while ($lineNr !== null && $lineNr <= $methodEndLine) { $methodStatementCount++; $lineCoverageInfo = $coverageInformation[$lineNr]; // set covered when CODE is other than -1 (not executed) if ($lineCoverageInfo > 0 || $lineCoverageInfo === -2) { $methodStatementsCovered++; } next($coverageInformation); $lineNr = key($coverageInformation); } if ($methodStatementCount > 0) { $methodCoverage = ($methodStatementsCovered / $methodStatementCount) * 100; } else { $methodCoverage = 0; } if ($methodCoverage < $this->_perMethod && !$method->isAbstract() ) { throw new BuildException( 'The coverage (' . round($methodCoverage, 2) . '%) ' . 'for method "' . $method->getName() . '" is lower' . ' than the specified threshold (' . $this->_perMethod . '%), see file: "' . $filename . '"' ); } elseif ($methodCoverage < $this->_perMethod && $method->isAbstract() && $this->_verbose === true ) { $this->log( 'Skipped coverage threshold for abstract method "' . $method->getName() . '"' ); } // store the minimum coverage value for logging (see #466) if ($this->_minMethodCoverageFound !== null) { if ($this->_minMethodCoverageFound > $methodCoverage) { $this->_minMethodCoverageFound = $methodCoverage; } } else { $this->_minMethodCoverageFound = $methodCoverage; } } $classStatementCount = count($coverageInformation); $classStatementsCovered = count( array_filter( $coverageInformation, array($this, 'filterCovered') ) ); if ($classStatementCount > 0) { $classCoverage = ($classStatementsCovered / $classStatementCount) * 100; } else { $classCoverage = 0; } if ($classCoverage < $this->_perClass && !$reflection->isAbstract() ) { throw new BuildException( 'The coverage (' . round($classCoverage, 2) . '%) for class "' . $reflection->getName() . '" is lower than the ' . 'specified threshold (' . $this->_perClass . '%), ' . 'see file: "' . $filename . '"' ); } elseif ($classCoverage < $this->_perClass && $reflection->isAbstract() && $this->_verbose === true ) { $this->log( 'Skipped coverage threshold for abstract class "' . $reflection->getName() . '"' ); } // store the minimum coverage value for logging (see #466) if ($this->_minClassCoverageFound !== null) { if ($this->_minClassCoverageFound > $classCoverage) { $this->_minClassCoverageFound = $classCoverage; } } else { $this->_minClassCoverageFound = $classCoverage; } $this->_projectStatementCount += $classStatementCount; $this->_projectStatementsCovered += $classStatementsCovered; } } } public function main() { if ($this->_database === null) { $coverageDatabase = $this->project ->getProperty('coverage.database'); if (!$coverageDatabase) { throw new BuildException( 'Either include coverage-setup in your build file or set ' . 'the "database" attribute' ); } $database = new PhingFile($coverageDatabase); } else { $database = $this->_database; } $this->log( 'Calculating coverage threshold: min. ' . $this->_perProject . '% per project, ' . $this->_perClass . '% per class and ' . $this->_perMethod . '% per method is required' ); $props = new Properties(); $props->load($database); foreach ($props->keys() as $filename) { $file = unserialize($props->getProperty($filename)); // Skip file if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($file['fullname'], $this->_excludes->getExcludedFiles())) { continue; } } $this->calculateCoverageThreshold( $file['fullname'], $file['coverage'] ); } if ($this->_projectStatementCount > 0) { $coverage = ($this->_projectStatementsCovered / $this->_projectStatementCount) * 100; } else { $coverage = 0; } if ($coverage < $this->_perProject) { throw new BuildException( 'The coverage (' . round($coverage, 2) . '%) for the entire project ' . 'is lower than the specified threshold (' . $this->_perProject . '%)' ); } $this->log( 'Passed coverage threshold. Minimum found coverage values are: ' . round($coverage, 2) . '% per project, ' . round($this->_minClassCoverageFound, 2) . '% per class and ' . round($this->_minMethodCoverageFound, 2) . '% per method' ); } } phing-2.16.0/tasks/ext/coverage/CoverageMergerTask.php0000644000175000017500000000543413027032674021670 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/system/io/PhingFile.php'; require_once 'phing/system/io/Writer.php'; require_once 'phing/system/util/Properties.php'; require_once 'phing/tasks/ext/coverage/CoverageMerger.php'; /** * Merges code coverage snippets into a code coverage database * * @author Michiel Rook * @version $Id: 6d4732d2b352c992dc03cd92cd83ad1b81bf9e45 $ * @package phing.tasks.ext.coverage * @since 2.1.0 */ class CoverageMergerTask extends Task { /** the list of filesets containing the .php filename rules */ private $filesets = array(); /** * Add a new fileset containing the .php files to process * * @param FileSet the new fileset containing .php files */ public function addFileSet(FileSet $fileset) { $this->filesets[] = $fileset; } /** * Iterate over all filesets and return all the filenames. * * @return array an array of filenames */ private function getFilenames() { $files = array(); foreach ($this->filesets as $fileset) { $ds = $fileset->getDirectoryScanner($this->project); $ds->scan(); $includedFiles = $ds->getIncludedFiles(); foreach ($includedFiles as $file) { $fs = new PhingFile(basename($ds->getBaseDir()), $file); $files[] = $fs->getAbsolutePath(); } } return $files; } public function main() { $files = $this->getFilenames(); $this->log("Merging " . count($files) . " coverage files"); foreach ($files as $file) { $coverageInformation = unserialize(file_get_contents($file)); CoverageMerger::merge($this->project, array($coverageInformation)); } } } phing-2.16.0/tasks/ext/coverage/CoverageMerger.php0000644000175000017500000001245013027032674021041 0ustar druiddruid. */ require_once 'phing/system/util/Properties.php'; /** * Saves coverage output of the test to a specified database * * @author Michiel Rook * @version $Id: 18a66018595b27816f2bd0ac5f2d67a42ea16416 $ * @package phing.tasks.ext.coverage * @since 2.1.0 */ class CoverageMerger { /** * @param $left * @param $right * @return array */ private static function mergeCodeCoverage($left, $right) { $coverageMerged = array(); reset($left); reset($right); while (current($left) !== false && current($right) !== false) { $linenr_left = key($left); $linenr_right = key($right); if ($linenr_left < $linenr_right) { $coverageMerged[$linenr_left] = current($left); next($left); } elseif ($linenr_right < $linenr_left) { $coverageMerged[$linenr_right] = current($right); next($right); } else { if ((current($left) < 0) || (current($right) < 0)) { $coverageMerged[$linenr_right] = current($right); } else { $coverageMerged[$linenr_right] = current($left) + current($right); } next($left); next($right); } } while (current($left) !== false) { $coverageMerged[key($left)] = current($left); next($left); } while (current($right) !== false) { $coverageMerged[key($right)] = current($right); next($right); } return $coverageMerged; } /** * @param Project $project * @return Properties * @throws BuildException */ protected static function _getDatabase($project) { $coverageDatabase = $project->getProperty('coverage.database'); if (!$coverageDatabase) { throw new BuildException("Property coverage.database is not set - please include coverage-setup in your build file"); } $database = new PhingFile($coverageDatabase); $props = new Properties(); $props->load($database); return $props; } /** * @param $project * @return array * @throws BuildException */ public static function getWhiteList($project) { $whitelist = array(); $props = self::_getDatabase($project); foreach ($props->getProperties() as $property) { $data = unserialize($property); $whitelist[] = $data['fullname']; } return $whitelist; } /** * @param $project * @param $codeCoverageInformation * @throws BuildException * @throws IOException */ public static function merge($project, $codeCoverageInformation) { $props = self::_getDatabase($project); $coverageTotal = $codeCoverageInformation; foreach ($coverageTotal as $filename => $data) { $lines = array(); $filename = strtolower($filename); if ($props->getProperty($filename) != null) { foreach ($data as $_line => $_data) { if ($_data === null) { continue; } if (is_array($_data)) { $count = count($_data); if ($count == 0) { $count = -1; } } else { if ($_data == -1) { // not executed $count = -1; } else { if ($_data == -2) { // dead code $count = -2; } } } $lines[$_line] = $count; } ksort($lines); $file = unserialize($props->getProperty($filename)); $left = $file['coverage']; $coverageMerged = CoverageMerger::mergeCodeCoverage($left, $lines); $file['coverage'] = $coverageMerged; $props->setProperty($filename, serialize($file)); } } $props->store(); } } phing-2.16.0/tasks/ext/coverage/CoverageReportTransformer.php0000644000175000017500000001207013027032674023314 0ustar druiddruid. */ require_once 'phing/Task.php'; require_once 'phing/system/io/PhingFile.php'; require_once 'phing/system/io/FileWriter.php'; require_once 'phing/util/ExtendedFileStream.php'; /** * Transform a Phing/Xdebug code coverage xml report. * The default transformation generates an html report in framed style. * * @author Michiel Rook * @version $Id: d3a5fbec986f8d4d1fde4875192fb243c82f1e68 $ * @package phing.tasks.ext.coverage * @since 2.1.0 */ class CoverageReportTransformer { private $task = null; private $styleDir = ""; /** * @var PhingFile */ private $toDir = ""; private $document = null; /** title of the project, used in the coverage report */ private $title = ""; /** * Whether to use the sorttable JavaScript library, defaults to false * See {@link http://www.kryogenix.org/code/browser/sorttable/)} * * @var boolean */ private $useSortTable = false; /** * @param Task $task */ public function __construct(Task $task) { $this->task = $task; } /** * @param $styleDir */ public function setStyleDir($styleDir) { $this->styleDir = $styleDir; } /** * @param PhingFile $toDir */ public function setToDir(PhingFile $toDir) { $this->toDir = $toDir; } /** * @param $document */ public function setXmlDocument($document) { $this->document = $document; } /** * Setter for title parameter * @param $title */ public function setTitle($title) { $this->title = $title; } /** * Sets whether to use the sorttable JavaScript library, defaults to false * See {@link http://www.kryogenix.org/code/browser/sorttable/)} * * @param boolean $useSortTable */ public function setUseSortTable($useSortTable) { $this->useSortTable = (boolean) $useSortTable; } public function transform() { if (!$this->toDir->exists()) { throw new BuildException("Directory '" . $this->toDir . "' does not exist"); } $xslfile = $this->getStyleSheet(); $xsl = new DOMDocument(); $xsl->load($xslfile->getAbsolutePath()); $proc = new XSLTProcessor(); if (defined('XSL_SECPREF_WRITE_FILE')) { if (version_compare(PHP_VERSION, '5.4', "<")) { ini_set("xsl.security_prefs", XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY); } else { $proc->setSecurityPrefs(XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY); } } $proc->importStyleSheet($xsl); ExtendedFileStream::registerStream(); $toDir = (string) $this->toDir; // urlencode() the path if we're on Windows if (FileSystem::getFileSystem()->getSeparator() == '\\') { $toDir = urlencode($toDir); } // no output for the framed report // it's all done by extension... $proc->setParameter('', 'output.dir', $toDir); $proc->setParameter('', 'output.sorttable', $this->useSortTable); $proc->setParameter('', 'document.title', $this->title); $proc->transformToXML($this->document); ExtendedFileStream::unregisterStream(); } /** * @return PhingFile * @throws BuildException */ private function getStyleSheet() { $xslname = "coverage-frames.xsl"; if ($this->styleDir) { $file = new PhingFile($this->styleDir, $xslname); } else { $path = Phing::getResourcePath("phing/etc/$xslname"); if ($path === null) { $path = Phing::getResourcePath("etc/$xslname"); if ($path === null) { throw new BuildException("Could not find $xslname in resource path"); } } $file = new PhingFile($path); } if (!$file->exists()) { throw new BuildException("Could not find file " . $file->getPath()); } return $file; } } phing-2.16.0/tasks/ext/zendguard/ZendGuardEncodeTask.php0000644000175000017500000003631313027032674022164 0ustar druiddruid. */ require_once 'phing/tasks/system/MatchingTask.php'; include_once 'phing/util/SourceFileScanner.php'; include_once 'phing/mappers/MergeMapper.php'; include_once 'phing/util/StringHelper.php'; /** * Encodes files using Zeng Guard Encoder * * @author Petr Rybak * @version $Id: aacbd9ea1b3f9e13178cea0f5ff625f921076a32 $ * @package phing.tasks.ext.zendguard * @since 2.4.3 */ class ZendGuardEncodeTask extends MatchingTask { protected $filesets = array(); protected $encodeCommand; /** * TASK PROPERTIES * * See http://static.zend.com/topics/Zend-Guard-User-Guidev5x.pdf * for more information on how to use ZendGuard * */ /** * Permanently deletes (see warning below) the original source files specified in the * SourceInputPath and saves the encoded files in its place. * This option has no option parameter. * When this option is use, do not use the output_file parameter. * * Warning: * To avoid permanent loss of non-encoded scripts, make a backup. Deleted files * cannot be restored or recovered and will be permanently deleted with this option. * If you are unsure about deleting the source files, use the ––rename-source option * instead * * @var bool */ protected $deleteSource = true; /** * Move the original source file to . and save the encoded file in its * place. * * If specified deleteSource will be automatically disabled. * * @var string */ protected $renameSourceExt = null; /** * Turns short PHP tag (“zendEncoderPath = $value; } /** * @param $value */ public function setPrivateKeyPath($value) { $this->privateKeyPath = $value; } /** * @param $value */ public function setShortTags($value) { $this->shortTags = (bool) $value; } /** * @param $value */ public function setAspTags($value) { $this->aspTags = (bool) $value; } /** * @param $value */ public function setDeleteSource($value) { $this->shortTags = (bool) $value; } /** * @param $value */ public function setUseCrypto($value) { $this->useCrypto = (bool) $value; } /** * @param $value */ public function setObfuscationLevel($value) { $this->obfuscationLevel = (int) $value; } /** * @param $value */ public function setLicenseProduct($value) { $this->licenseProduct = (bool) $value; } /** * @param $value */ public function setPrologFile($value) { $this->prologFile = $value; } /** * @param $value */ public function setSignProduct($value) { $this->signProduct = (bool) $value; } /** * @param $value */ public function setForceEncode($value) { $this->forceEncode = (bool) $value; } /** * @param $value */ public function setEncodedOnly($value) { $this->encodedOnly = (bool) $value; } /** * @param $value */ public function setIgnoreFileModes($value) { $this->ignoreFileModes = (bool) $value; } /** * @param $value */ public function setExpires($value) { $this->expires = $value; } /** * @param $value */ public function setProductName($value) { $this->productName = $value; } /** * @param $value */ public function setOptMask($value) { $this->optMask = (int) $value; } /** * @param $value */ public function setRenameSourceExt($value) { $this->renameSourceExt = $value; } /** * @param $value */ public function setNoHeader($value) { $this->noHeader = (bool) $value; } /** * Add a new fileset. * * @return FileSet */ public function createFileSet() { $this->fileset = new ZendGuardFileSet(); $this->filesets[] = $this->fileset; return $this->fileset; } /** * Verifies that the configuration is correct * * @throws BuildException */ protected function verifyConfiguration() { // Check that the zend encoder path is specified if (empty($this->zendEncoderPath)) { throw new BuildException("Zend Encoder path must be specified"); } // verify that the zend encoder binary exists if (!file_exists($this->zendEncoderPath)) { throw new BuildException("Zend Encoder not found on path " . $this->zendEncoderPath); } // if either sign or license is required the private key path needs to be defined // and the file has to exist and product name has to be specified if ($this->signProduct || $this->licenseProduct) { if (empty($this->privateKeyPath)) { throw new BuildException("Licensing or signing requested but privateKeyPath not provided."); } if (!is_readable($this->privateKeyPath)) { throw new BuildException("Licensing or signing requested but private key path doesn't exist or is unreadable."); } if (empty($this->productName)) { throw new BuildException("Licensing or signing requested but product name not provided."); } } // verify prolog file exists if (!empty($this->prologFile)) { if (!file_exists($this->prologFile)) { throw new BuildException("The prolog file doesn't exist: " . $this->prologFile); } } } /** * Do the work * * @throws BuildException */ public function main() { $this->verifyConfiguration(); $this->prepareEncoderCommand(); try { if (empty($this->filesets)) { throw new BuildException("You must supply nested fileset.", $this->getLocation()); } $encodedFilesCounter = 0; foreach ($this->filesets as $fs) { /* @var $fs FileSet */ /* @var $fsBasedir PhingFile */ $fsBasedir = $fs->getDir($this->project)->getAbsolutePath(); $files = $fs->getFiles($this->project, false); foreach ($files as $file) { $f = new PhingFile($fsBasedir, $file); if ($f->isFile()) { $path = $f->getAbsolutePath(); $this->log("Encoding " . $path, Project::MSG_VERBOSE); $this->encodeFile($path); $encodedFilesCounter++; } } } $this->log("Encoded files: " . $encodedFilesCounter); } catch (IOException $ioe) { $msg = "Problem encoding files: " . $ioe->getMessage(); throw new BuildException($msg, $ioe, $this->getLocation()); } } /** * Prepares the main part of the command that will be * used to encode the given file(s). */ protected function prepareEncoderCommand() { $command = $this->zendEncoderPath . " "; if (!empty($this->renameSourceExt)) { $command .= " --rename-source " . $this->renameSourceExt . " "; } elseif ($this->deleteSource) { // delete source $command .= " --delete-source "; } // short tags $command .= " --short-tags " . (($this->shortTags) ? 'on' : 'off') . " "; // asp tags $command .= " --asp-tags " . (($this->aspTags) ? 'on' : 'off') . " "; // use crypto if ($this->useCrypto) { $command .= " --use-crypto "; } // ignore file modes if ($this->ignoreFileModes) { $command .= " --ignore-file-modes "; } // force encode if ($this->forceEncode) { $command .= " --force-encode "; } // expires if (!empty($this->expires)) { $command .= " --expires " . $this->expires . " "; } // insert prolog file name or no-header if (!empty($this->prologFile)) { $command .= " --prolog-filename " . $this->prologFile . " "; } elseif ($this->noHeader) { // no-header $command .= " --no-header "; } // obfuscation level if ($this->obfuscationLevel > 0) { $command .= " --obfuscation-level " . $this->obfuscationLevel . " "; } // encoded only if ($this->encodedOnly) { $command .= " --encoded-only "; } // opt mask if (null !== $this->optMask) { $command .= " --optimizations " . $this->optMask . " "; } // Signing or licensing if ($this->signProduct) { $command .= " --sign-product " . $this->productName . " --private-key " . $this->privateKeyPath . " "; } elseif ($this->licenseProduct) { $command .= " --license-product " . $this->productName . " --private-key " . $this->privateKeyPath . " "; } // add a blank space $command .= " "; $this->encodeCommand = $command; } /** * Encodes a file using currently defined Zend Guard settings * * @param string $filePath Path to the encoded file * @throws BuildException * @return bool */ protected function encodeFile($filePath) { $command = $this->encodeCommand . $filePath . ' 2>&1'; $this->log('Running: ' . $command, Project::MSG_VERBOSE); $tmp = exec($command, $output, $return_var); if ($return_var !== 0) { throw new BuildException("Encoding failed. \n Msg: " . $tmp . " \n Encode command: " . $command); } return true; } } /** * This is a FileSet with the to specify permissions. * * Permissions are currently not implemented by PEAR Archive_Tar, * but hopefully they will be in the future. * * @package phing.tasks.ext.zendguard */ class ZendGuardFileSet extends FileSet { private $files = null; /** * Get a list of files and directories specified in the fileset. * @param Project $p * @param bool $includeEmpty * @throws BuildException * @return array a list of file and directory names, relative to * the baseDir for the project. */ public function getFiles(Project $p, $includeEmpty = true) { if ($this->files === null) { $ds = $this->getDirectoryScanner($p); $this->files = $ds->getIncludedFiles(); } // if ($this->files===null) return $this->files; } } phing-2.16.0/tasks/ext/zendguard/ZendGuardLicenseTask.php0000644000175000017500000004121613027032674022347 0ustar druiddruid. */ /** * Produce license files using Zeng Guard. * The task can produce a license file from the given * license properties or it can use a template. * * @author Petr Rybak * @version $Id: 2e1e3730b96f5d5ea32d54fda8d9333b34eeaaba $ * @package phing.tasks.ext.zendguard * @since 2.4.3 */ class ZendGuardLicenseTask extends Task { protected $zendsignCommand; private $tmpLicensePath; /** * TASK PROPERTIES * * See http://static.zend.com/topics/Zend-Guard-User-Guidev5x.pdf * for more information on how to use ZendGuard * */ /** * Path to Zend Guard zendenc_sign executable * * @var string */ protected $zendsignPath; /** * Path to private key that will be used to sign the license * * @var string */ protected $privateKeyPath; /** * Where to store the signed license file * * @var string */ protected $outputFile; /** * Path to license template. If specified all * license properties will be ignored and the * template will be used to generate the file. * * @var string */ protected $licenseTemplate; /** * The name assigned to Product. This must be the same name used when encoding * the PHP files. * * REQUIRED * * @var string */ protected $productName; /** * The Name of the Registered owner of the license. * * REQUIRED * * @var string */ protected $registeredTo; /** * Expiration date of the license. Used if the license is issued with a date restriction. * Possible values: * - 'Never', '0' or false: the license won't expire * - A Date in format DD-MM-YYYY to set expiration for that date * - Relative date supported by the PHP strtotime function (e.g. +1 month) * * REQUIRED * * @var string */ protected $expires; /** * Limits the use of the license to IP addresses that fall within specification. Supports * wildcards for any of the IP place holders, as well as the two types of net masks * (filters). * Netmask pair An IP a.b.c.d, and a netmask w.x.y.z. (That is., 10.1.0.0/255.255.0.0), * where the binary of mask is applied to filter IP addresses. * ip/nnn (similar to a CIDR specification) This mask consists of nnn high-order 1 bits. * (That is, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0). Instead of spelling out * the bits of the subnet mask, this mask notation is simply listed as the number of 1s * bits that start the mask. Rather than writing the address and subnet mask as * 192.60.128.0/255.255.252.0 the network address would be written simply as: * 192.60.128.0/22 which indicates starting address of the network and number of 1s * bits (22) in the network portion of the address. The mask in binary is * (11111111.11111111.11111100.00000000). * * OPTIONAL * * Example (Wildcard): * IP-Range = 10.1.*.* * Example (Net Mask): * IP-Range = 10.1.0.0/255.255.0.0 * Example (Net Mask): * IP-Range = 10.1.0.0/16 * * @var string */ protected $ipRange; /** * Coded string (Zend Host ID) used to lock the license to a specific hardware. The * Zend Host ID obtained from the machine where the encoded files and license are * to be installed. The Zend Host ID code can be obtained by using the zendid utility. * For more details, see Getting the Zend Host ID. * * REQUIRED if Hardware-Locked is set equal to YES. * Meaningless if Hardware-Locked is set equal to NO. * * User semicolon to enter more than one Host-ID * * Example: * Host-ID = H:MFM43-Q9CXC-B9EDX-GWYSU;H:MFM43-Q9CXC-B9EDX-GWYTY * * @var string */ protected $hostID; /** * Option that indicates if the license will be locked to a specific machine * using the Zend Host ID code(s). If set to YES, the Host-ID is required. * * OPTIONAL * * @var bool */ protected $hardwareLocked; /** * Semi-colon separated user defined values that will be part of the license. These values * CANNOT be modified after the license is produced. Modification * would invalidate the license. * * OPTIONAL * Example: * Tea=Mint Flavor;Coffee=Arabica * * @var string */ protected $userDefinedValues; /** * Semi-colon separated user defined x-values that will be part of the license. These values * CAN be modified after the license is produced. Modification * won't invalidate the license. * * OPTIONAL * Example: * Tea=Mint Flavor;Coffee=Arabica * * @var string */ protected $xUserDefinedValues; /** * @param $value */ public function setLicenseTemplate($value) { $this->licenseTemplate = $value; } /** * @param $productName */ public function setProductName($productName) { $this->productName = $productName; } /** * @param $registeredTo */ public function setRegisteredTo($registeredTo) { $this->registeredTo = $registeredTo; } /** * Process the expires property. If the value is * empty (false, '', ...) it will set the value to 'Never' * Otherwise it will run the value through strtotime so relative * date and time notation can be used (e.g. +1 month) * * @param mixed $expires * * @throws BuildException * @return string */ public function setExpires($expires) { // process the expires value if (false === $expires || '0' === $expires || strtolower($expires) == 'never' || '' === $expires) { $this->expires = 'Never'; } else { $time = strtotime($expires); if (!$time) { throw new BuildException("Unsupported expires format: " . $expires); } $this->expires = date('d-M-Y', $time); } } /** * @param $iprange */ public function setIpRange($iprange) { $this->ipRange = $iprange; } /** * @param $hostID */ public function setHostID($hostID) { $this->hostID = $hostID; } /** * @param $hardwareLocked */ public function setHardwareLocked($hardwareLocked) { $this->hardwareLocked = (bool) $hardwareLocked; } /** * @param $userDefinedValues */ public function setUserDefinedValues($userDefinedValues) { $this->userDefinedValues = $userDefinedValues; } /** * @param $xUserDefinedValues */ public function setXUserDefinedValues($xUserDefinedValues) { $this->xUserDefinedValues = $xUserDefinedValues; } /** * @param $zendsignPath */ public function setZendsignPath($zendsignPath) { $this->zendsignPath = $zendsignPath; } /** * @param $privateKeyPath */ public function setPrivateKeyPath($privateKeyPath) { $this->privateKeyPath = $privateKeyPath; } /** * @param $outputFile */ public function setOutputFile($outputFile) { $this->outputFile = $outputFile; } /** * Verifies that the configuration is correct * * @throws BuildException */ protected function verifyConfiguration() { // Check that the zend encoder path is specified if (empty($this->zendsignPath)) { throw new BuildException("Zendenc_sign path must be specified"); } // verify that the zend encoder binary exists if (!file_exists($this->zendsignPath)) { throw new BuildException("Zendenc_sign not found on path " . $this->zendsignPath); } // verify that the private key path is defined if (empty($this->privateKeyPath)) { throw new BuildException("You must define privateKeyPath."); } // verify that the private key file is readable if (!is_readable($this->privateKeyPath)) { throw new BuildException("Private key file is not readable: " . $this->privateKeyPath); } // if template is passed, verify that it is readable if (!empty($this->licenseTemplate)) { if (!is_readable($this->licenseTemplate)) { throw new BuildException("License template file is not readable " . $this->licenseTemplate); } } // check that output file path is defined if (empty($this->outputFile)) { throw new BuildException("Path where to store the result file needs to be defined in outputFile property"); } // if license template is NOT provided check that all required parameters are defined if (empty($this->licenseTemplate)) { // check productName if (empty($this->productName)) { throw new BuildException("Property must be defined: productName"); } // check expires if (null === $this->expires) { throw new BuildException("Property must be defined: expires"); } // check registeredTo if (empty($this->registeredTo)) { throw new BuildException("Property must be defined: registeredTo"); } // check hardwareLocked if (null === $this->hardwareLocked) { throw new BuildException("Property must be defined: hardwareLocked"); } // if hardwareLocked is set to true, check that Host-ID is set if ($this->hardwareLocked) { if (empty($this->hostID)) { throw new BuildException("If you set hardwareLocked to true hostID must be provided"); } } } } /** * Do the work * * @throws BuildException */ public function main() { try { $this->verifyConfiguration(); $this->generateLicense(); } catch (Exception $e) { // remove the license temp file if it was created $this->cleanupTmpFiles(); throw $e; } $this->cleanupTmpFiles(); } /** * If temporary license file was created during the process * this will remove it * * @return void */ private function cleanupTmpFiles() { if (!empty($this->tmpLicensePath) && file_exists($this->tmpLicensePath)) { $this->log("Deleting temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE); unlink($this->tmpLicensePath); } } /** * Prepares and returns the command that will be * used to create the license. * * @return string */ protected function prepareSignCommand() { $command = $this->zendsignPath; // add license path $command .= ' ' . $this->getLicenseTemplatePath(); // add result file path $command .= ' ' . $this->outputFile; // add key path $command .= ' ' . $this->privateKeyPath; $this->zendsignCommand = $command; return $command; } /** * Checks if the license template path is defined * and returns it. * If it the license template path is not defined * it will generate a temporary template file and * provide it as a template. * * @return string */ protected function getLicenseTemplatePath() { if (!empty($this->licenseTemplate)) { return $this->licenseTemplate; } else { return $this->generateLicenseTemplate(); } } /** * Creates the signed license at the defined output path * * @throws BuildException * @return void */ protected function generateLicense() { $command = $this->prepareSignCommand() . ' 2>&1'; $this->log('Creating license at ' . $this->outputFile); $this->log('Running: ' . $command, Project::MSG_VERBOSE); $tmp = exec($command, $output, $return_var); // Check for exit value 1. Zendenc_sign command for some reason // returns 0 in case of failure and 1 in case of success... if ($return_var !== 1) { throw new BuildException("Creating license failed. \n\nZendenc_sign msg:\n" . join("\n", $output) . "\n\n"); } } /** * It will generate a temporary license template * based on the properties defined. * * @throws BuildException * @return string Path of the temporary license template file */ protected function generateLicenseTemplate() { $this->tmpLicensePath = tempnam(sys_get_temp_dir(), 'zendlicense'); $this->log("Creating temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE); if (file_put_contents($this->tmpLicensePath, $this->generateLicenseTemplateContent()) === false) { throw new BuildException("Unable to create temporary template license file: " . $this->tmpLicensePath); } return $this->tmpLicensePath; } /** * Generates license template content based * on the defined parameters * * @return string */ protected function generateLicenseTemplateContent() { $contentArr = array(); // Product Name $contentArr[] = array('Product-Name', $this->productName); // Registered to $contentArr[] = array('Registered-To', $this->registeredTo); // Hardware locked $contentArr[] = array('Hardware-Locked', ($this->hardwareLocked ? 'Yes' : 'No')); // Expires $contentArr[] = array('Expires', $this->expires); // IP-Range if (!empty($this->ipRange)) { $contentArr[] = array('IP-Range', $this->ipRange); } // Host-ID if (!empty($this->hostID)) { foreach (explode(';', $this->hostID) as $hostID) { $contentArr[] = array('Host-ID', $hostID); } } else { $contentArr[] = array('Host-ID', 'Not-Locked'); } // parse user defined fields if (!empty($this->userDefinedValues)) { $this->parseAndAddUserDefinedValues($this->userDefinedValues, $contentArr); } // parse user defined x-fields if (!empty($this->xUserDefinedValues)) { $this->parseAndAddUserDefinedValues($this->xUserDefinedValues, $contentArr, 'X-'); } // merge all the values $content = ''; foreach ($contentArr as $valuePair) { list($key, $value) = $valuePair; $content .= $key . " = " . $value . "\n"; } return $content; } /** * Parse the given string in format like key1=value1;key2=value2;... and * converts it to array * (key1=>value1, key2=value2, ...) * * @param string $valueString Semi-colon separated value pairs * @param array $valueArray Array to which the values will be added * @param string $keyPrefix Prefix to use when adding the key * * @param string $pairSeparator * @return void */ protected function parseAndAddUserDefinedValues( $valueString, array &$valueArray, $keyPrefix = '', $pairSeparator = ';' ) { // explode the valueString (semicolon) $valuePairs = explode($pairSeparator, $valueString); if (!empty($valuePairs)) { foreach ($valuePairs as $valuePair) { list($key, $value) = explode('=', $valuePair, 2); // add pair into the valueArray $valueArray[] = array($keyPrefix . $key, $value); } } } } phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php0000644000175000017500000000622713027032674024146 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * Class ZendServerDeploymentToolTask * * @author Siad Ardroumli * @package phing.tasks.ext.zendserverdevelopmenttools */ abstract class zsdtBaseTask extends Task { protected $action; protected $arguments = ''; /** @var string $descriptor */ protected $descriptor; /** @var string $schema */ protected $schema; /** @var array $path */ private $path = array( 'NIX' => '/usr/local/zend/bin/zdpack', 'WIN' => 'C:\Program Files (x86)\Zend\ZendServer\bin\zdpack', 'USR' => '' ); /** * The package descriptor file. * * @param string $descriptor * * @return void */ public function setDescriptor($descriptor) { $this->descriptor = escapeshellarg($descriptor); } /** * The path to the package descriptor schema used for validation. * * @param string $schema * * @return void */ public function setSchema($schema) { $this->schema = escapeshellarg($schema); } /** * @param string $path * * @return void */ public function setPath($path) { $this->path['USR'] = $path; } /** * {@inheritdoc} */ public function main() { $this->validate(); $command = ''; if ($this->path['USR'] !== '') { $command .= $this->path['USR']; } elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $command .= escapeshellarg($this->path['WIN']); } else { $command .= $this->path['NIX']; } $commandString = sprintf('%s %s %s', $command, $this->action, $this->arguments); $msg = exec($commandString . ' 2>&1', $output, $code); if ($code !== 0) { throw new BuildException("Build package failed. \n Msg: " . $msg . " \n Pack command: " . $commandString); } } /** * Validates argument list. * * @return void */ protected function validate() { if ($this->schema !== null) { $this->arguments .= "--schema=$this->schema "; } } } phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtValidateTask.php0000644000175000017500000000342113027032674025016 0ustar druiddruid. */ require_once 'phing/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php'; /** * Class ZendServerDeploymentToolTask * * @author Siad Ardroumli * @package phing.tasks.ext.zendserverdevelopmenttools */ class zsdtValidateTask extends zsdtBaseTask { /** * @inheritdoc} * * @return void */ public function init() { $this->action = 'validate'; } /** * {@inheritdoc} * * @throws BuildException * * @return void */ protected function validate() { parent::validate(); if ($this->descriptor === null) { throw new BuildException('The package descriptor file have to be set.'); } $this->arguments .= $this->descriptor; } } phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtPackTask.php0000644000175000017500000001133413027032674024145 0ustar druiddruid. */ require_once 'phing/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php'; /** * Class ZendServerDeploymentToolTask * * @author Siad Ardroumli * @package phing.tasks.ext.zendserverdevelopmenttools */ class zsdtPackTask extends zsdtBaseTask { /** @var string $package */ private $package; /** @var string $source */ private $source; /** @var string $scripts */ private $scripts; /** @var string $output */ private $output; /** @var string $phpbin */ private $phpbin; /** @var bool $lint */ private $lint = false; /** * A directory containing the data and the script directories, in addition to the package descriptor file. * * @param string $package * * @return void */ public function setPackage($package) { $this->package = escapeshellarg($package); } /** * Performs a PHP lint test on the deployment scripts before creating the package. * * @param boolean $lint * * @return void */ public function setLint($lint) { $this->lint = $lint; } /** * The directory in which the package is created. * The package name will be created as "-.zpk". * * @param string $output * * @return void */ public function setOutput($output) { $this->output = escapeshellarg($output); } /** * The PHP executable to use for lint. * * @param string $phpbin * * @return void */ public function setPhpbin($phpbin) { $this->phpbin = escapeshellarg($phpbin); } /** * The directory which contains the package deployment scripts. * The Deployment Tool will search this directory for the expected files and then packs them. * * @param string $scripts * * @return void */ public function setScripts($scripts) { $this->scripts = escapeshellarg($scripts); } /** * The directory that contains the application resources (PHP sources, JavaScript, etc.). * The directory's internal structure must match the necessary structure for the application to be functional. * * @param string $source * * @return void */ public function setSource($source) { $this->source = escapeshellarg($source); } /** * {@inheritdoc} * * @return void */ public function init() { $this->action = 'pack'; } /** * {@inheritdoc} * * @return void * * @throws BuildException */ protected function validate() { if ($this->descriptor === null || $this->scripts === null || $this->package === null) { throw new BuildException( 'The deployment tool needs at least the project descriptor, ' . 'the scripts folder and package folder to be set.' ); } elseif ($this->lint !== false && $this->phpbin === null) { throw new BuildException('You set the lint option but not the path to the php executable.'); } parent::validate(); if ($this->lint !== false) { $this->arguments .= '--lint '; } if ($this->source !== null) { $this->arguments .= "--src-dir=$this->source "; } if ($this->output !== null) { $this->arguments .= "--output-dir=$this->output "; } if ($this->phpbin !== null) { $this->arguments .= "--php-exe=$this->phpbin "; } $this->arguments .= "--scripts-dir=$this->scripts "; $this->arguments .= "--package-descriptor=$this->descriptor "; $this->arguments .= $this->package; } } phing-2.16.0/tasks/ext/PhpCodeSnifferTask.php0000644000175000017500000005677113027032674020051 0ustar druiddruid. */ require_once 'phing/Task.php'; /** * A PHP code sniffer task. Checking the style of one or more PHP source files. * * @author Dirk Thomas * @version $Id: 1cb309b7992d03271825878803e5cabb757b9d63 $ * @package phing.tasks.ext */ class PhpCodeSnifferTask extends Task { /** * A php source code filename or directory * * @var PhingFile */ protected $file; // the source file (from xml attribute) /** * All fileset objects assigned to this task * * @var FileSet[] */ protected $filesets = array(); // all fileset objects assigned to this task // parameters for php code sniffer protected $standards = array('Generic'); protected $sniffs = array(); protected $showWarnings = true; protected $showSources = false; protected $reportWidth = 80; protected $verbosity = 0; protected $tabWidth = 0; protected $allowedFileExtensions = array('php', 'inc', 'js', 'css'); protected $allowedTypes = array(); protected $ignorePatterns = false; protected $noSubdirectories = false; protected $configData = array(); protected $encoding = 'iso-8859-1'; // parameters to customize output protected $showSniffs = false; protected $format = 'full'; /** * @var PhpCodeSnifferTask_FormatterElement[] */ protected $formatters = array(); /** * Holds the type of the doc generator * * @var string */ protected $docGenerator = ''; /** * Holds the outfile for the documentation * * @var PhingFile */ protected $docFile = null; private $haltonerror = false; private $haltonwarning = false; private $skipversioncheck = false; private $propertyName = null; /** * Cache data storage * @var DataStore */ protected $cache; /** * Load the necessary environment for running PHP_CodeSniffer. * * @return void */ public function init() { } /** * File to be performed syntax check on * @param PhingFile $file */ public function setFile(PhingFile $file) { $this->file = $file; } /** * Nested adder, adds a set of files (nested fileset attribute). * * @param FileSet $fs * @return void */ public function addFileSet(FileSet $fs) { $this->filesets[] = $fs; } /** * Sets the coding standard to test for * * @param string $standards The coding standards * * @return void */ public function setStandard($standards) { $this->standards = array(); $token = ' ,;'; $ext = strtok($standards, $token); while ($ext !== false) { $this->standards[] = $ext; $ext = strtok($token); } } /** * Sets the sniffs which the standard should be restricted to * @param string $sniffs */ public function setSniffs($sniffs) { $token = ' ,;'; $sniff = strtok($sniffs, $token); while ($sniff !== false) { $this->sniffs[] = $sniff; $sniff = strtok($token); } } /** * Sets the type of the doc generator * * @param string $generator HTML or Text * * @return void */ public function setDocGenerator($generator) { $this->docGenerator = $generator; } /** * Sets the outfile for the documentation * * @param PhingFile $file The outfile for the doc * * @return void */ public function setDocFile(PhingFile $file) { $this->docFile = $file; } /** * Sets the flag if warnings should be shown * @param boolean $show */ public function setShowWarnings($show) { $this->showWarnings = StringHelper::booleanValue($show); } /** * Sets the flag if sources should be shown * * @param boolean $show Whether to show sources or not * * @return void */ public function setShowSources($show) { $this->showSources = StringHelper::booleanValue($show); } /** * Sets the width of the report * * @param int $width How wide the screen reports should be. * * @return void */ public function setReportWidth($width) { $this->reportWidth = (int) $width; } /** * Sets the verbosity level * @param int $level */ public function setVerbosity($level) { $this->verbosity = (int) $level; } /** * Sets the tab width to replace tabs with spaces * @param int $width */ public function setTabWidth($width) { $this->tabWidth = (int) $width; } /** * Sets file encoding * @param string $encoding */ public function setEncoding($encoding) { $this->encoding = $encoding; } /** * Sets the allowed file extensions when using directories instead of specific files * @param array $extensions */ public function setAllowedFileExtensions($extensions) { $this->allowedFileExtensions = array(); $token = ' ,;'; $ext = strtok($extensions, $token); while ($ext !== false) { $this->allowedFileExtensions[] = $ext; $ext = strtok($token); } } /** * Sets the allowed types for the PHP_CodeSniffer::suggestType() * @param array $types */ public function setAllowedTypes($types) { $this->allowedTypes = array(); $token = ' ,;'; $type = strtok($types, $token); while ($type !== false) { $this->allowedTypes[] = $type; $type = strtok($token); } } /** * Sets the ignore patterns to skip files when using directories instead of specific files * @param $patterns * @internal param array $extensions */ public function setIgnorePatterns($patterns) { $this->ignorePatterns = array(); $token = ' ,;'; $pattern = strtok($patterns, $token); while ($pattern !== false) { $this->ignorePatterns[$pattern] = 'relative'; $pattern = strtok($token); } } /** * Sets the flag if subdirectories should be skipped * @param boolean $subdirectories */ public function setNoSubdirectories($subdirectories) { $this->noSubdirectories = StringHelper::booleanValue($subdirectories); } /** * Creates a config parameter for this task * * @return Parameter The created parameter */ public function createConfig() { $num = array_push($this->configData, new Parameter()); return $this->configData[$num - 1]; } /** * Sets the flag if the used sniffs should be listed * @param boolean $show */ public function setShowSniffs($show) { $this->showSniffs = StringHelper::booleanValue($show); } /** * Sets the output format * @param string $format */ public function setFormat($format) { $this->format = $format; } /** * Create object for nested formatter element. * @return PhpCodeSnifferTask_FormatterElement */ public function createFormatter() { $num = array_push( $this->formatters, new PhpCodeSnifferTask_FormatterElement() ); return $this->formatters[$num - 1]; } /** * Sets the haltonerror flag * @param boolean $value */ public function setHaltonerror($value) { $this->haltonerror = $value; } /** * Sets the haltonwarning flag * @param boolean $value */ public function setHaltonwarning($value) { $this->haltonwarning = $value; } /** * Sets the skipversioncheck flag * @param boolean $value */ public function setSkipVersionCheck($value) { $this->skipversioncheck = $value; } /** * Sets the name of the property to use * @param $propertyName */ public function setPropertyName($propertyName) { $this->propertyName = $propertyName; } /** * Returns the name of the property to use */ public function getPropertyName() { return $this->propertyName; } /** * Whether to store last-modified times in cache * * @param PhingFile $file */ public function setCacheFile(PhingFile $file) { $this->cache = new DataStore($file); } /** * Return the list of files to parse * * @return string[] list of absolute files to parse */ protected function getFilesToParse() { $filesToParse = array(); if ($this->file instanceof PhingFile) { $filesToParse[] = $this->file->getPath(); } else { // append any files in filesets foreach ($this->filesets as $fs) { $dir = $fs->getDir($this->project)->getAbsolutePath(); foreach ($fs->getDirectoryScanner($this->project)->getIncludedFiles() as $filename) { $fileAbsolutePath = $dir . DIRECTORY_SEPARATOR . $filename; if ($this->cache) { $lastMTime = $this->cache->get($fileAbsolutePath); $currentMTime = filemtime($fileAbsolutePath); if ($lastMTime >= $currentMTime) { continue; } else { $this->cache->put($fileAbsolutePath, $currentMTime); } } $filesToParse[] = $fileAbsolutePath; } } } return $filesToParse; } /** * Executes PHP code sniffer against PhingFile or a FileSet */ public function main() { if (!class_exists('PHP_CodeSniffer')) { @include_once 'PHP/CodeSniffer.php'; if (!class_exists('PHP_CodeSniffer')) { throw new BuildException("This task requires the PHP_CodeSniffer package installed and available on the include path", $this->getLocation( )); } } /** * Determine PHP_CodeSniffer version number */ if (!$this->skipversioncheck) { if (defined('PHP_CodeSniffer::VERSION')) { preg_match('/\d\.\d\.\d/', PHP_CodeSniffer::VERSION, $version); } else { preg_match('/\d\.\d\.\d/', shell_exec('phpcs --version'), $version); } if (version_compare($version[0], '1.2.2') < 0) { throw new BuildException( 'PhpCodeSnifferTask requires PHP_CodeSniffer version >= 1.2.2', $this->getLocation() ); } } if (!isset($this->file) and count($this->filesets) == 0) { throw new BuildException("Missing either a nested fileset or attribute 'file' set"); } if (count($this->formatters) == 0) { // turn legacy format attribute into formatter $fmt = new PhpCodeSnifferTask_FormatterElement(); $fmt->setType($this->format); $fmt->setUseFile(false); $this->formatters[] = $fmt; } $fileList = $this->getFilesToParse(); $cwd = getcwd(); // Save command line arguments because it confuses PHPCS (version 1.3.0) $oldArgs = $_SERVER['argv']; $_SERVER['argv'] = array(); $_SERVER['argc'] = 0; include_once 'phing/tasks/ext/phpcs/PhpCodeSnifferTask_Wrapper.php'; $codeSniffer = new PhpCodeSnifferTask_Wrapper($this->verbosity, $this->tabWidth, $this->encoding); $codeSniffer->setAllowedFileExtensions($this->allowedFileExtensions); if ($this->allowedTypes) { PhpCodeSnifferTask_Wrapper::$allowedTypes = $this->allowedTypes; } if (is_array($this->ignorePatterns)) { $codeSniffer->setIgnorePatterns($this->ignorePatterns); } foreach ($this->configData as $configData) { $codeSniffer->setConfigData($configData->getName(), $configData->getValue(), true); } /* * Verifying if standard is installed only after setting config data. * Custom standard paths could be provided via installed_paths config parameter. */ foreach($this->standards as $standard) { if (PHP_CodeSniffer::isInstalledStandard($standard) === false) { // They didn't select a valid coding standard, so help them // out by letting them know which standards are installed. $installedStandards = PHP_CodeSniffer::getInstalledStandards(); $numStandards = count($installedStandards); $errMsg = ''; if ($numStandards === 0) { $errMsg = 'No coding standards are installed.'; } else { $lastStandard = array_pop($installedStandards); if ($numStandards === 1) { $errMsg = 'The only coding standard installed is ' . $lastStandard; } else { $standardList = implode(', ', $installedStandards); $standardList .= ' and ' . $lastStandard; $errMsg = 'The installed coding standards are ' . $standardList; } } throw new BuildException( 'ERROR: the "' . $standard . '" coding standard is not installed. ' . $errMsg, $this->getLocation() ); } } if (!$this->showWarnings) { $codeSniffer->cli->warningSeverity = 0; } // nasty integration hack $values = $codeSniffer->cli->getDefaults(); $_SERVER['argv'] = array('t'); $_SERVER['argc'] = 1; foreach ($this->formatters as $fe) { if ($fe->getUseFile()) { $_SERVER['argv'][] = '--report-' . $fe->getType() . '=' . $fe->getOutfile(); } else { $_SERVER['argv'][] = '--report-' . $fe->getType(); } $_SERVER['argc']++; } if ($this->cache) { require_once 'phing/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php'; PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache($this->cache); // add a fake report to remove from cache $_SERVER['argv'][] = '--report-phingRemoveFromCache='; $_SERVER['argc']++; } $codeSniffer->process($fileList, $this->standards, $this->sniffs, $this->noSubdirectories); $_SERVER['argv'] = array(); $_SERVER['argc'] = 0; if ($this->cache) { PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache(null); $this->cache->commit(); } $this->printErrorReport($codeSniffer); // generate the documentation if ($this->docGenerator !== '' && $this->docFile !== null) { ob_start(); $codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator); $output = ob_get_contents(); ob_end_clean(); // write to file $outputFile = $this->docFile->getPath(); $check = file_put_contents($outputFile, $output); if ($check === false) { throw new BuildException('Error writing doc to ' . $outputFile); } } elseif ($this->docGenerator !== '' && $this->docFile === null) { $codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator); } if ($this->haltonerror && $codeSniffer->reporting->totalErrors > 0) { throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalErrors . ' error' . ($codeSniffer->reporting->totalErrors > 1 ? 's' : '')); } if ($this->haltonwarning && $codeSniffer->reporting->totalWarnings > 0) { throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalWarnings . ' warning' . ($codeSniffer->reporting->totalWarnings > 1 ? 's' : '')); } $_SERVER['argv'] = $oldArgs; $_SERVER['argc'] = count($oldArgs); chdir($cwd); } /** * Prints the error report. * * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing * the errors. */ protected function printErrorReport($phpcs) { $sniffs = $phpcs->getSniffs(); $sniffStr = ''; foreach ($sniffs as $sniff) { if (is_string($sniff)) { $sniffStr .= '- ' . $sniff . PHP_EOL; } else { $sniffStr .= '- ' . get_class($sniff) . PHP_EOL; } } $this->project->setProperty($this->getPropertyName(), (string) $sniffStr); if ($this->showSniffs) { $this->log('The list of used sniffs (#' . count($sniffs) . '): ' . PHP_EOL . $sniffStr, Project::MSG_INFO); } // process output $reporting = $phpcs->reporting; foreach ($this->formatters as $fe) { $reportFile = null; if ($fe->getUseFile()) { $reportFile = $fe->getOutfile(); //ob_start(); } // Crude check, but they broke backwards compatibility // with a minor version release. if (PHP_CodeSniffer::VERSION >= '2.2.0') { $cliValues = array('colors' => false); $reporting->printReport($fe->getType(), $this->showSources, $cliValues, $reportFile, $this->reportWidth); } else { $reporting->printReport($fe->getType(), $this->showSources, $reportFile, $this->reportWidth); } // reporting class uses ob_end_flush(), but we don't want // an output if we use a file if ($fe->getUseFile()) { //ob_end_clean(); } } } /** * Outputs the results with a custom format * * @param array $report Packaged list of all errors in each file */ protected function outputCustomFormat($report) { $files = $report['files']; foreach ($files as $file => $attributes) { $errors = $attributes['errors']; $warnings = $attributes['warnings']; $messages = $attributes['messages']; if ($errors > 0) { $this->log( $file . ': ' . $errors . ' error' . ($errors > 1 ? 's' : '') . ' detected', Project::MSG_ERR ); $this->outputCustomFormatMessages($messages, 'ERROR'); } else { $this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE); } if ($warnings > 0) { $this->log( $file . ': ' . $warnings . ' warning' . ($warnings > 1 ? 's' : '') . ' detected', Project::MSG_WARN ); $this->outputCustomFormatMessages($messages, 'WARNING'); } } $totalErrors = $report['totals']['errors']; $totalWarnings = $report['totals']['warnings']; $this->log(count($files) . ' files were checked', Project::MSG_INFO); if ($totalErrors > 0) { $this->log($totalErrors . ' error' . ($totalErrors > 1 ? 's' : '') . ' detected', Project::MSG_ERR); } else { $this->log('No syntax errors detected', Project::MSG_INFO); } if ($totalWarnings > 0) { $this->log($totalWarnings . ' warning' . ($totalWarnings > 1 ? 's' : '') . ' detected', Project::MSG_INFO); } } /** * Outputs the messages of a specific type for one file * @param array $messages * @param string $type */ protected function outputCustomFormatMessages($messages, $type) { foreach ($messages as $line => $messagesPerLine) { foreach ($messagesPerLine as $column => $messagesPerColumn) { foreach ($messagesPerColumn as $message) { $msgType = $message['type']; if ($type == $msgType) { $logLevel = Project::MSG_INFO; if ($msgType == 'ERROR') { $logLevel = Project::MSG_ERR; } else { if ($msgType == 'WARNING') { $logLevel = Project::MSG_WARN; } } $text = $message['message']; $string = $msgType . ' in line ' . $line . ' column ' . $column . ': ' . $text; $this->log($string, $logLevel); } } } } } } //end phpCodeSnifferTask /** * @package phing.tasks.ext */ class PhpCodeSnifferTask_FormatterElement extends DataType { /** * Type of output to generate * @var string */ protected $type = ""; /** * Output to file? * @var bool */ protected $useFile = true; /** * Output file. * @var string */ protected $outfile = ""; /** * Validate config. */ public function parsingComplete() { if (empty($this->type)) { throw new BuildException("Format missing required 'type' attribute."); } if ($this->useFile && empty($this->outfile)) { throw new BuildException("Format requires 'outfile' attribute when 'useFile' is true."); } } /** * @param $type */ public function setType($type) { $this->type = $type; } /** * @return string */ public function getType() { return $this->type; } /** * @param $useFile */ public function setUseFile($useFile) { $this->useFile = $useFile; } /** * @return bool */ public function getUseFile() { return $this->useFile; } /** * @param $outfile */ public function setOutfile($outfile) { $this->outfile = $outfile; } /** * @return string */ public function getOutfile() { return $this->outfile; } } //end FormatterElement phing-2.16.0/tasks/ext/PearPackage2Task.php0000644000175000017500000002551613027032674017430 0ustar druiddruid. */ require_once 'phing/tasks/ext/PearPackageTask.php'; /** * A task to create a PEAR package.xml version 2.0 file. * * This class uses the PEAR_PackageFileManager2 class to perform the work. * * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o * requiring changes to this class. We've accomplished this by having generic