summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/tasks/ext
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/tasks/ext')
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/CapsuleTask.php18
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ExportPropertiesTask.php141
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ExtractBaseTask.php199
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/FileHashTask.php147
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/FileSizeTask.php120
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/FtpDeployTask.php233
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/HttpGetTask.php170
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/HttpRequestTask.php286
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/JslLintTask.php284
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/MailTask.php144
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ManifestTask.php343
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/PackageAsPathTask.php4
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/ParallelTask.php83
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/PatchTask.php301
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/PearPackage2Task.php279
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/PearPackageTask.php115
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php648
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/PhpLintTask.php326
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ReplaceRegexpTask.php204
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ScpTask.php380
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/Service/Amazon.php120
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3.php188
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3GetTask.php108
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3PutTask.php243
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/SmartyTask.php10
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/SshTask.php224
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/Arg.php96
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/SymfonyConsoleTask.php113
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/SymlinkTask.php309
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/TarTask.php139
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/UntarTask.php89
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/UnzipTask.php77
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/VersionTask.php217
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/XmlLintTask.php113
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/XmlPropertyTask.php273
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php272
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/ZipTask.php193
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/apigen/ApiGenTask.php439
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php221
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php102
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php894
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php219
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php257
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageThresholdTask.php458
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php (renamed from buildscripts/phing/classes/phing/tasks/ext/CreoleSQLExecTask.php)78
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/creole/CreoleTask.php (renamed from buildscripts/phing/classes/phing/tasks/ext/CreoleTask.php)6
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php436
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php34
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php67
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php37
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php37
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxOracle.php37
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php36
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php37
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/docblox/DocBloxTask.php221
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitBaseTask.php134
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitBranchTask.php296
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitCheckoutTask.php256
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitCloneTask.php128
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitCommitTask.php179
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitFetchTask.php284
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitGcTask.php158
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitInitTask.php81
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitLogTask.php270
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitMergeTask.php258
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitPullTask.php373
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitPushTask.php255
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/git/GitTagTask.php406
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php29
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php908
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php262
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMin.php292
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMinTask.php145
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/AbstractLiquibaseTask.php184
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseChangeLogTask.php39
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDbDocTask.php86
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDiffTask.php137
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseRollbackTask.php72
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseTagTask.php75
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseUpdateTask.php39
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php109
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependLoggerElement.php105
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependTask.php506
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/pdo/DefaultPDOQuerySplitter.php151
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/pdo/PDOQuerySplitter.php (renamed from buildscripts/phing/classes/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php)75
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php84
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php313
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php606
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/pdo/PDOTask.php215
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/pdo/PgsqlPDOQuerySplitter.php291
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php130
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php141
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/pearpackage/Fileset.php21
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadata.php55
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadataElement.php80
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phar/PharPackageTask.php362
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageTask.php248
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccess.php57
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccessPath.php46
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php177
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDTask.php312
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php58
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php40
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php51
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpdoc/PHPDocumentorTask.php157
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php98
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php230
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentor2Task.php224
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php265
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php480
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDFormatterElement.php181
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDTask.php284
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/BatchTest.php230
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php178
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php248
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php378
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php312
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php141
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/CloverPHPUnitResultFormatter.php87
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php203
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PlainPHPUnitResultFormatter.php128
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/SummaryPHPUnitResultFormatter.php62
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/XMLPHPUnitResultFormatter.php120
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/BatchTest.php171
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/FormatterElement.php120
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php162
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php154
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Task.php239
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php107
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Util.php114
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php117
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php117
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/rSTTask.php476
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php41
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php119
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php134
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php118
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php261
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php43
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php430
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php244
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php455
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php67
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnCommitTask.php113
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnCopyTask.php70
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/svn/SvnExportTask.php70
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnInfoTask.php112
-rwxr-xr-x[-rw-r--r--]buildscripts/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php123
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/svn/SvnListTask.php128
-rwxr-xr-xbuildscripts/phing/classes/phing/tasks/ext/svn/SvnLogTask.php108
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnSwitchTask.php73
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php67
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardEncodeTask.php510
-rw-r--r--buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php524
154 files changed, 26134 insertions, 3863 deletions
diff --git a/buildscripts/phing/classes/phing/tasks/ext/CapsuleTask.php b/buildscripts/phing/classes/phing/tasks/ext/CapsuleTask.php
index aa43a0e4..13ccd73d 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/CapsuleTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/CapsuleTask.php
@@ -1,7 +1,7 @@
<?php
/*
- * $Id: CapsuleTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 205bc55fd1f7f36783d105ff2d0e27357282bbed $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -31,7 +31,7 @@ include_once 'phing/util/StringHelper.php';
* This is based on the interface to TexenTask from Apache's Velocity engine.
*
* @author Hans Lellelid <hans@xmpl.org>
- * @version $Revision: 1.17 $
+ * @version $Id: 205bc55fd1f7f36783d105ff2d0e27357282bbed $
* @package phing.tasks.ext
*/
class CapsuleTask extends Task {
@@ -185,7 +185,7 @@ class CapsuleTask extends Task {
public function setOutputDirectory(PhingFile $outputDirectory) {
try {
if (!$outputDirectory->exists()) {
- $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE);
+ $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());
}
@@ -393,7 +393,7 @@ class CapsuleTask extends Task {
// reset value, and then
// read in teh contents of the file into that var
$value = "";
- $f = new PhingFile($project->resolveFile($value)->getCanonicalPath());
+ $f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath());
if ($f->exists()) {
$fr = new FileReader($f);
$fr->readInto($value);
@@ -453,25 +453,27 @@ class CapsuleTask extends Task {
/**
* 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;
- function setName($v) {
+ public function setName($v) {
$this->name = $v;
}
- function setValue($v) {
+ public function setValue($v) {
$this->value = $v;
}
- function getName() {
+ public function getName() {
return $this->name;
}
- function getValue() {
+ public function getValue() {
return $this->value;
}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ExportPropertiesTask.php b/buildscripts/phing/classes/phing/tasks/ext/ExportPropertiesTask.php
new file mode 100644
index 00000000..8bc64bbb
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ExportPropertiesTask.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * $Id: 7d96a453b74edc40fdea85ba8befe6459334016d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once "phing/Task.php";
+
+/**
+ * Saves currently defined properties into a specified file
+ *
+ * @author Andrei Serdeliuc
+ * @extends Task
+ * @version $Id: 7d96a453b74edc40fdea85ba8befe6459334016d $
+ * @package phing.tasks.ext
+ */
+class ExportPropertiesTask extends Task
+{
+ /**
+ * Array of project properties
+ *
+ * (default value: null)
+ *
+ * @var array
+ * @access private
+ */
+ private $_properties = null;
+
+ /**
+ * Target file for saved properties
+ *
+ * (default value: null)
+ *
+ * @var string
+ * @access private
+ */
+ private $_targetFile = null;
+
+ /**
+ * Exclude properties starting with these prefixes
+ *
+ * @var array
+ * @access private
+ */
+ private $_disallowedPropertyPrefixes = array(
+ 'host.',
+ 'phing.',
+ 'os.',
+ 'php.',
+ 'line.',
+ 'env.',
+ 'user.'
+ );
+
+ /**
+ * setter for _targetFile
+ *
+ * @access public
+ * @param string $file
+ * @return bool
+ */
+ public function setTargetFile($file)
+ {
+ if(!is_dir(dirname($file))) {
+ throw new BuildException("Parent directory of target file doesn't exist");
+ }
+
+ if(!is_writable(dirname($file)) && (file_exists($file) && !is_writable($file))) {
+ throw new BuildException("Target file isn't writable");
+ }
+
+ $this->_targetFile = $file;
+ return true;
+ }
+
+ /**
+ * setter for _disallowedPropertyPrefixes
+ *
+ * @access public
+ * @param string $file
+ * @return bool
+ */
+ public function setDisallowedPropertyPrefixes($prefixes)
+ {
+ $this->_disallowedPropertyPrefixes = explode(",", $prefixes);
+ return true;
+ }
+
+ public function main()
+ {
+ // Sets the currently declared properties
+ $this->_properties = $this->getProject()->getProperties();
+
+ if(is_array($this->_properties) && !empty($this->_properties) && null !== $this->_targetFile) {
+ $propertiesString = '';
+ foreach($this->_properties as $propertyName => $propertyValue) {
+ if(!$this->isDisallowedPropery($propertyName)) {
+ $propertiesString .= $propertyName . "=" . $propertyValue . PHP_EOL;
+ }
+ }
+
+ if(!file_put_contents($this->_targetFile, $propertiesString)) {
+ throw new BuildException('Failed writing to ' . $this->_targetFile);
+ }
+ }
+ }
+
+ /**
+ * Checks if a property name is disallowed
+ *
+ * @access protected
+ * @param string $propertyName
+ * @return bool
+ */
+ protected function isDisallowedPropery($propertyName)
+ {
+ foreach($this->_disallowedPropertyPrefixes as $property) {
+ if(substr($propertyName, 0, strlen($property)) == $property) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ExtractBaseTask.php b/buildscripts/phing/classes/phing/tasks/ext/ExtractBaseTask.php
new file mode 100644
index 00000000..e47acc24
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ExtractBaseTask.php
@@ -0,0 +1,199 @@
+<?php
+/*
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+
+/**
+ * Base class for extracting tasks such as Unzip and Untar.
+ *
+ * @author Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @version $Id: 8aa7996b72792da30f1ec94174f09b9c612bcc1a $
+ * @package phing.tasks.ext
+ * @since 2.2.0
+ */
+abstract class ExtractBaseTask extends MatchingTask {
+ /**
+ * @var PhingFile $file
+ */
+ protected $file;
+ /**
+ * @var PhingFile $todir
+ */
+ protected $todir;
+ protected $removepath;
+ protected $filesets = array(); // all fileset objects assigned to this task
+
+ /**
+ * Set to true to always extract (and possibly overwrite)
+ * all files from the archive
+ * @var boolean
+ */
+ protected $forceExtract = false;
+
+ /**
+ * Add a new fileset.
+ * @return FileSet
+ */
+ public function createFileSet() {
+ $this->fileset = new FileSet();
+ $this->filesets[] = $this->fileset;
+ return $this->fileset;
+ }
+
+ /**
+ * Set the name of the zip file to extract.
+ * @param PhingFile $file zip file to extract
+ */
+ public function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ /**
+ * This is the base directory to look in for things to zip.
+ * @param PhingFile $baseDir
+ */
+ public function setToDir(PhingFile $todir) {
+ $this->todir = $todir;
+ }
+
+ public function setRemovePath($removepath)
+ {
+ $this->removepath = $removepath;
+ }
+
+ /**
+ * Sets the forceExtract attribute
+ * @param boolean $forceExtract
+ */
+ public function setForceExtract($forceExtract)
+ {
+ $this->forceExtract = (bool) $forceExtract;
+ }
+
+ /**
+ * do the work
+ * @throws BuildException
+ */
+ public function main() {
+
+ $this->validateAttributes();
+
+ $filesToExtract = array();
+ if ($this->file !== null) {
+ if(!$this->isDestinationUpToDate($this->file)) {
+ $filesToExtract[] = $this->file;
+ } else {
+ $this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' . $this->file->getCanonicalPath(), Project::MSG_INFO);
+ }
+ }
+
+ foreach($this->filesets as $compressedArchiveFileset) {
+ $compressedArchiveDirScanner = $compressedArchiveFileset->getDirectoryScanner($this->project);
+ $compressedArchiveFiles = $compressedArchiveDirScanner->getIncludedFiles();
+ $compressedArchiveDir = $compressedArchiveFileset->getDir($this->project);
+
+ foreach ($compressedArchiveFiles as $compressedArchiveFilePath) {
+ $compressedArchiveFile = new PhingFile($compressedArchiveDir, $compressedArchiveFilePath);
+ if($compressedArchiveFile->isDirectory())
+ {
+ throw new BuildException($compressedArchiveFile->getAbsolutePath() . ' compressed archive cannot be a directory.');
+ }
+
+ if ($this->forceExtract || !$this->isDestinationUpToDate($compressedArchiveFile)) {
+ $filesToExtract[] = $compressedArchiveFile;
+ } else {
+ $this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' . $compressedArchiveFile->getCanonicalPath(), Project::MSG_INFO);
+ }
+ }
+ }
+
+ foreach ($filesToExtract as $compressedArchiveFile) {
+ $this->extractArchive($compressedArchiveFile);
+ }
+ }
+
+ abstract protected function extractArchive(PhingFile $compressedArchiveFile);
+
+ /**
+ * @param array $files array of filenames
+ * @param PhingFile $dir
+ * @return boolean
+ */
+ protected function isDestinationUpToDate(PhingFile $compressedArchiveFile) {
+ if (!$compressedArchiveFile->exists()) {
+ throw new BuildException("Could not find file " . $compressedArchiveFile->__toString() . " to extract.");
+ }
+
+ $compressedArchiveContent = $this->listArchiveContent($compressedArchiveFile);
+ if(is_array($compressedArchiveContent)) {
+
+ $fileSystem = FileSystem::getFileSystem();
+ foreach ($compressedArchiveContent as $compressArchivePathInfo) {
+ $compressArchiveFilename = $compressArchivePathInfo['filename'];
+ if(!empty($this->removepath) && strlen($compressArchiveFilename) >= strlen($this->removepath))
+ {
+ $compressArchiveFilename = preg_replace('/^' . $this->removepath . '/','', $compressArchiveFilename);
+ }
+ $compressArchivePath = new PhingFile($this->todir, $compressArchiveFilename);
+
+ if(!$compressArchivePath->exists() ||
+ $fileSystem->compareMTimes($compressedArchiveFile->getCanonicalPath(), $compressArchivePath->getCanonicalPath()) == 1) {
+ return false;
+ }
+ }
+
+ }
+
+ return true;
+ }
+
+ abstract protected function listArchiveContent(PhingFile $compressedArchiveFile);
+
+ /**
+ * Validates attributes coming in from XML
+ *
+ * @access private
+ * @return void
+ * @throws BuildException
+ */
+ protected function validateAttributes() {
+
+ if ($this->file === null && count($this->filesets) === 0) {
+ throw new BuildException("Specify at least one source compressed archive - a file or a fileset.");
+ }
+
+ if ($this->todir === null) {
+ throw new BuildException("todir must be set.");
+ }
+
+ if ($this->todir !== null && $this->todir->exists() && !$this->todir->isDirectory()) {
+ throw new BuildException("todir must be a directory.");
+ }
+
+ if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+ throw new BuildException("Compressed archive file cannot be a directory.");
+ }
+
+ if ($this->file !== null && !$this->file->exists()) {
+ throw new BuildException("Could not find compressed archive file " . $this->file->__toString() . " to extract.");
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/FileHashTask.php b/buildscripts/phing/classes/phing/tasks/ext/FileHashTask.php
new file mode 100644
index 00000000..5660e793
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/FileHashTask.php
@@ -0,0 +1,147 @@
+<?php
+/*
+ * $Id: c59aff266a03f0e2cf22dc33143f2decf2d5e05c $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+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 <johan162@gmail.com>
+ * @version $Id: c59aff266a03f0e2cf22dc33143f2decf2d5e05c $
+ * @package phing.tasks.ext
+ */
+class FileHashTask extends Task
+{
+ /**
+ * Property for File
+ * @var PhingFile file
+ */
+ private $file;
+
+ /**
+ * Property to be set
+ * @var string $property
+ */
+ private $propertyName = "filehashvalue";
+
+ /**
+ * Specify which hash algorithm to use.
+ * 0 = MD5
+ * 1 = SHA1
+ *
+ * @var integer $hashtype
+ */
+ private $hashtype=0;
+
+
+ /**
+ * Specify if MD5 or SHA1 hash should be used
+ * @param integer $type 0=MD5, 1=SHA1
+ */
+ public function setHashtype($type)
+ {
+ $this->hashtype = $type;
+ }
+
+ /**
+ * Which file to calculate the hash value of
+ * @param PhingFile $file
+ */
+ public function setFile($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Set the name of the property to store the hash value in
+ * @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();
+
+ // read file
+ if( (int)$this->hashtype === 0 ) {
+ $this->log("Calculating MD5 hash from: ".$this->file);
+ $hashValue = md5_file($this->file,false);
+ }
+ elseif( (int)$this->hashtype === 1 ) {
+ $this->log("Calculating SHA1 hash from: ".$this->file);
+ $hashValue = sha1_file($this->file,false);
+ }
+ else {
+ throw new BuildException(
+ sprintf('[FileHash] Unknown hashtype specified %d. Must be either 0 (=MD5) or 1 (=SHA1).',$this->hashtype));
+
+ }
+
+ // publish hash value
+ $this->project->setProperty($this->propertyName, $hashValue);
+
+ }
+
+ /**
+ * checks file attribute
+ * @return void
+ * @throws BuildException
+ */
+ private function checkFile()
+ {
+ // check File
+ if ($this->file === null ||
+ strlen($this->file) == 0) {
+ throw new BuildException('[FileHash] You must specify an input file.', $this->file);
+ }
+
+ if( ! is_readable($this->file) ) {
+ throw new BuildException(sprintf('[FileHash] 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('Property name for publishing hashvalue is not set');
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/FileSizeTask.php b/buildscripts/phing/classes/phing/tasks/ext/FileSizeTask.php
new file mode 100644
index 00000000..120197dd
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/FileSizeTask.php
@@ -0,0 +1,120 @@
+<?php
+/*
+ * $Id: 2a59c1a9b46f3fd71df0fd3b50908eff268fd630 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+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 <johan162@gmail.com>
+ * @version $Id: 2a59c1a9b46f3fd71df0fd3b50908eff268fd630 $
+ * @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');
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/FtpDeployTask.php b/buildscripts/phing/classes/phing/tasks/ext/FtpDeployTask.php
new file mode 100644
index 00000000..136c0ac7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/FtpDeployTask.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * $Id: 87063ecf88b18eae74c2bca3918a1b4ac9f52807 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * FtpDeployTask
+ *
+ * Deploys a set of files to a remote FTP server.
+ *
+ *
+ * Example usage:
+ * <ftpdeploy host="host" port="21" username="user" password="password" dir="public_html" mode="ascii" clearfirst="true">
+ * <fileset dir=".">
+ * <include name="**"/>
+ * <exclude name="phing"/>
+ * <exclude name="build.xml"/>
+ * <exclude name="images/**.png"/>
+ * <exclude name="images/**.gif"/>
+ * <exclude name="images/**.jpg"/>
+ * </fileset>
+ * </ftpdeploy>
+ *
+ * @author Jorrit Schippers <jorrit at ncode dot nl>
+ * @version $Id: 87063ecf88b18eae74c2bca3918a1b4ac9f52807 $
+ * @since 2.3.1
+ * @package phing.tasks.ext
+ */
+class FtpDeployTask extends Task
+{
+ private $host = null;
+ private $port = 21;
+ private $username = null;
+ private $password = null;
+ private $dir = null;
+ private $filesets;
+ private $completeDirMap;
+ private $mode = FTP_BINARY;
+ private $clearFirst = false;
+ private $passive = false;
+
+ protected $logLevel = Project::MSG_VERBOSE;
+
+ public function __construct() {
+ $this->filesets = array();
+ $this->completeDirMap = array();
+ }
+
+ public function setHost($host) {
+ $this->host = $host;
+ }
+
+ public function setPort($port) {
+ $this->port = (int) $port;
+ }
+
+ public function setUsername($username) {
+ $this->username = $username;
+ }
+
+ public function setPassword($password) {
+ $this->password = $password;
+ }
+
+ public function setDir($dir) {
+ $this->dir = $dir;
+ }
+
+ public function setMode($mode) {
+ switch(strtolower($mode)) {
+ case 'ascii':
+ $this->mode = FTP_ASCII;
+ break;
+ case 'binary':
+ case 'bin':
+ $this->mode = FTP_BINARY;
+ break;
+ }
+ }
+
+ public function setPassive($passive)
+ {
+ $this->passive = (bool) $passive;
+ }
+
+ public function setClearFirst($clearFirst) {
+ $this->clearFirst = (bool) $clearFirst;
+ }
+
+ public function createFileSet() {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Set level of log messages generated (default = info)
+ * @param string $level
+ */
+ public function setLevel($level)
+ {
+ switch ($level)
+ {
+ case "error": $this->logLevel = Project::MSG_ERR; break;
+ case "warning": $this->logLevel = Project::MSG_WARN; break;
+ case "info": $this->logLevel = Project::MSG_INFO; break;
+ case "verbose": $this->logLevel = Project::MSG_VERBOSE; break;
+ case "debug": $this->logLevel = Project::MSG_DEBUG; break;
+ }
+ }
+
+ /**
+ * The init method: check if Net_FTP is available
+ */
+ public function init() {
+ require_once 'PEAR.php';
+
+ $paths = explode(PATH_SEPARATOR, get_include_path());
+ foreach($paths as $path) {
+ if(file_exists($path.DIRECTORY_SEPARATOR.'Net'.DIRECTORY_SEPARATOR.'FTP.php')) {
+ return true;
+ }
+ }
+ throw new BuildException('The FTP Deploy task requires the Net_FTP PEAR package.');
+ }
+
+ /**
+ * The main entry point method.
+ */
+ public function main() {
+ $project = $this->getProject();
+
+ require_once 'Net/FTP.php';
+ $ftp = new Net_FTP($this->host, $this->port);
+ $ret = $ftp->connect();
+ if(@PEAR::isError($ret)) {
+ throw new BuildException('Could not connect to FTP server '.$this->host.' on port '.$this->port.': '.$ret->getMessage());
+ } else {
+ $this->log('Connected to FTP server ' . $this->host . ' on port ' . $this->port, $this->logLevel);
+ }
+
+ $ret = $ftp->login($this->username, $this->password);
+ if(@PEAR::isError($ret)) {
+ throw new BuildException('Could not login to FTP server '.$this->host.' on port '.$this->port.' with username '.$this->username.': '.$ret->getMessage());
+ } else {
+ $this->log('Logged in to FTP server with username ' . $this->username, $this->logLevel);
+ }
+
+ if ($this->passive) {
+ $this->log('Setting passive mode', $this->logLevel);
+ $ret = $ftp->setPassive();
+ if(@PEAR::isError($ret)) {
+ $ftp->disconnect();
+ throw new BuildException('Could not set PASSIVE mode: '.$ret->getMessage());
+ }
+ }
+
+ // append '/' to the end if necessary
+ $dir = substr($this->dir, -1) == '/' ? $this->dir : $this->dir.'/';
+
+ if($this->clearFirst) {
+ // TODO change to a loop through all files and directories within current directory
+ $this->log('Clearing directory '.$dir, $this->logLevel);
+ $ftp->rm($dir, true);
+ }
+
+ // Create directory just in case
+ $ret = $ftp->mkdir($dir, true);
+ if(@PEAR::isError($ret)) {
+ $ftp->disconnect();
+ throw new BuildException('Could not create directory '.$dir.': '.$ret->getMessage());
+ }
+
+ $ret = $ftp->cd($dir);
+ if(@PEAR::isError($ret)) {
+ $ftp->disconnect();
+ throw new BuildException('Could not change to directory '.$dir.': '.$ret->getMessage());
+ } else {
+ $this->log('Changed directory ' . $dir, $this->logLevel);
+ }
+
+ $fs = FileSystem::getFileSystem();
+ $convert = $fs->getSeparator() == '\\';
+
+ foreach($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($project);
+ $fromDir = $fs->getDir($project);
+ $srcFiles = $ds->getIncludedFiles();
+ $srcDirs = $ds->getIncludedDirectories();
+ foreach($srcDirs as $dirname) {
+ if($convert)
+ $dirname = str_replace('\\', '/', $dirname);
+ $this->log('Will create directory '.$dirname, $this->logLevel);
+ $ret = $ftp->mkdir($dirname, true);
+ if(@PEAR::isError($ret)) {
+ $ftp->disconnect();
+ throw new BuildException('Could not create directory '.$dirname.': '.$ret->getMessage());
+ }
+ }
+ foreach($srcFiles as $filename) {
+ $file = new PhingFile($fromDir->getAbsolutePath(), $filename);
+ if($convert)
+ $filename = str_replace('\\', '/', $filename);
+ $this->log('Will copy '.$file->getCanonicalPath().' to '.$filename, $this->logLevel);
+ $ret = $ftp->put($file->getCanonicalPath(), $filename, true, $this->mode);
+ if(@PEAR::isError($ret)) {
+ $ftp->disconnect();
+ throw new BuildException('Could not deploy file '.$filename.': '.$ret->getMessage());
+ }
+ }
+ }
+
+ $ftp->disconnect();
+ $this->log('Disconnected from FTP server', $this->logLevel);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/HttpGetTask.php b/buildscripts/phing/classes/phing/tasks/ext/HttpGetTask.php
new file mode 100755
index 00000000..114b80a1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/HttpGetTask.php
@@ -0,0 +1,170 @@
+<?php
+/*
+ * $Id: f3fa317b72e2f70f1e483fa49dbf089094e2a476 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.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 Ole Markus With <o.with@sportradar.com>
+ * @version $Id: f3fa317b72e2f70f1e483fa49dbf089094e2a476 $
+ */
+class HttpGetTask extends Task
+{
+ /**
+ * Holds the request URL
+ *
+ * @var string
+ */
+ protected $url = null;
+
+ /**
+ * Holds the filename to store the output in
+ *
+ * @var string
+ */
+ protected $filename = null;
+
+ /**
+ * Holds the save location
+ *
+ * @var string
+ */
+ protected $dir = null;
+
+ /**
+ * Holds the proxy
+ *
+ * @var string
+ */
+ protected $_proxy = null;
+
+ /**
+ * Load the necessary environment for running this task.
+ *
+ * @throws BuildException
+ */
+ public function init()
+ {
+ @include_once 'HTTP/Request2.php';
+
+ if (! class_exists('HTTP_Request2')) {
+ throw new BuildException(
+ 'HttpRequestTask depends on HTTP_Request2 being installed '
+ . 'and on include_path.',
+ $this->getLocation()
+ );
+ }
+ }
+
+
+ /**
+ * Make the GET request
+ *
+ * @throws BuildException
+ */
+ public function main()
+ {
+ if (!isset($this->url)) {
+ throw new BuildException("Missing attribute 'url'");
+ }
+
+ if (!isset($this->dir)) {
+ throw new BuildException("Missing attribute 'dir'");
+ }
+
+ $config = array();
+ if (isset($this->_proxy) && $url = parse_url($this->_proxy)) {
+ $config['proxy_user'] = $url['user'];
+ $config['proxy_password'] = $url['pass'];
+ $config['proxy_host'] = $url['host'];
+ $config['proxy_port'] = $url['port'];
+ }
+
+ $this->log("Fetching " . $this->url);
+
+ $request = new HTTP_Request2($this->url, '', $config);
+ $response = $request->send();
+ if ($response->getStatus() != 200) {
+ throw new BuildException("Request unsuccessful. Response from server: " . $response->getStatus() . " " . $response->getReasonPhrase());
+ }
+
+ $content = $response->getBody();
+ $disposition = $response->getHeader('content-disposition');
+
+ if ($this->filename) {
+ $filename = $this->filename;
+ } elseif ($disposition && 0 == strpos($disposition, 'attachment')
+ && preg_match('/filename="([^"]+)"/', $disposition, $m)) {
+ $filename = basename($m[1]);
+ } else {
+ $filename = basename(parse_url($this->url, PHP_URL_PATH));
+ }
+
+ if (!is_writable($this->dir)) {
+ throw new BuildException("Cannot write to directory: " . $this->dir);
+ }
+
+ $filename = $this->dir . "/" . $filename;
+ file_put_contents($filename, $content);
+
+ $this->log("Contents from " . $this->url . " saved to $filename");
+ }
+
+ /**
+ * Sets the request URL
+ *
+ * @param string $url
+ */
+ public function setUrl($url) {
+ $this->url = $url;
+ }
+
+ /**
+ * Sets the filename to store the output in
+ *
+ * @param string $filename
+ */
+ public function setFilename($filename) {
+ $this->filename = $filename;
+ }
+
+ /**
+ * Sets the save location
+ *
+ * @param string $dir
+ */
+ public function setDir($dir) {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Sets the proxy
+ *
+ * @param string $proxy
+ */
+ public function setProxy($proxy) {
+ $this->_proxy = $proxy;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/HttpRequestTask.php b/buildscripts/phing/classes/phing/tasks/ext/HttpRequestTask.php
new file mode 100644
index 00000000..e6f15075
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/HttpRequestTask.php
@@ -0,0 +1,286 @@
+<?php
+/*
+ * $Id: 495c02bc3a90d24694d8a4bf2d43ac077e0f9ec6 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.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 <bschultz@proqrent.de>
+ * @version $Id: 495c02bc3a90d24694d8a4bf2d43ac077e0f9ec6 $
+ * @since 2.4.1
+ */
+class HttpRequestTask extends Task
+{
+ /**
+ * Holds the request URL
+ *
+ * @var string
+ */
+ protected $_url = null;
+
+ /**
+ * Holds the regular expression that should match the response
+ *
+ * @var string
+ */
+ protected $_responseRegex = '';
+
+ /**
+ * Whether to enable detailed logging
+ *
+ * @var boolean
+ */
+ protected $_verbose = false;
+
+ /**
+ * Holds additional header data
+ *
+ * @var array<Parameter>
+ */
+ protected $_headers = array();
+
+ /**
+ * Holds additional config data for HTTP_Request2
+ *
+ * @var array<Parameter>
+ */
+ protected $_configData = array();
+
+ /**
+ * Holds the authentication user name
+ *
+ * @var string
+ */
+ protected $_authUser = null;
+
+ /**
+ * Holds the authentication password
+ *
+ * @var string
+ */
+ protected $_authPassword = '';
+
+ /**
+ * Holds the authentication scheme
+ *
+ * @var string
+ */
+ protected $_authScheme;
+
+ /**
+ * Holds the events that will be logged
+ *
+ * @var array<string>
+ */
+ protected $_observerEvents = array(
+ 'connect',
+ 'sentHeaders',
+ 'sentBodyPart',
+ 'receivedHeaders',
+ 'receivedBody',
+ 'disconnect',
+ );
+
+ /**
+ * Sets the request URL
+ *
+ * @param string $url
+ */
+ public function setUrl($url)
+ {
+ $this->_url = $url;
+ }
+
+ /**
+ * Sets the response regex
+ *
+ * @param string $regex
+ */
+ public function setResponseRegex($regex)
+ {
+ $this->_responseRegex = $regex;
+ }
+
+ /**
+ * Sets the authentication user name
+ *
+ * @param string $user
+ */
+ public function setAuthUser($user)
+ {
+ $this->_authUser = $user;
+ }
+
+ /**
+ * Sets the authentication password
+ *
+ * @param string $password
+ */
+ public function setAuthPassword($password)
+ {
+ $this->_authPassword = $password;
+ }
+
+ /**
+ * Sets the authentication scheme
+ *
+ * @param string $scheme
+ */
+ public function setAuthScheme($scheme)
+ {
+ $this->_authScheme = $scheme;
+ }
+
+ /**
+ * 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
+ *
+ * @return void
+ */
+ public function setObserverEvents($observerEvents)
+ {
+ $this->_observerEvents = array();
+
+ $token = ' ,;';
+ $ext = strtok($observerEvents, $token);
+
+ while ($ext !== false) {
+ $this->_observerEvents[] = $ext;
+ $ext = strtok($token);
+ }
+ }
+
+ /**
+ * Creates an additional header for this task
+ *
+ * @return Parameter The created header
+ */
+ public function createHeader()
+ {
+ $num = array_push($this->_headers, new Parameter());
+ return $this->_headers[$num-1];
+ }
+
+ /**
+ * 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];
+ }
+
+ /**
+ * Load the necessary environment for running this task.
+ *
+ * @throws BuildException
+ */
+ public function init()
+ {
+ @include_once 'HTTP/Request2.php';
+
+ if (! class_exists('HTTP_Request2')) {
+ throw new BuildException(
+ 'HttpRequestTask depends on HTTP_Request2 being installed '
+ . 'and on include_path.',
+ $this->getLocation()
+ );
+ }
+
+ $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';
+ }
+
+ /**
+ * Make the http request
+ */
+ public function main()
+ {
+ if (!isset($this->_url)) {
+ throw new BuildException("Missing attribute 'url' set");
+ }
+
+ $request = new HTTP_Request2($this->_url);
+
+ // set the authentication data
+ if (!empty($this->_authUser)) {
+ $request->setAuth(
+ $this->_authUser,
+ $this->_authPassword,
+ $this->_authScheme
+ );
+ }
+
+ foreach ($this->_configData as $config) {
+ $request->setConfig($config->getName(), $config->getValue());
+ }
+
+ foreach ($this->_headers as $header) {
+ $request->setHeader($header->getName(), $header->getValue());
+ }
+
+ if ($this->_verbose) {
+ $observer = new HTTP_Request2_Observer_Log();
+
+ // set the events we want to log
+ $observer->events = $this->_observerEvents;
+
+ $request->attach($observer);
+ }
+
+ $response = $request->send();
+
+ 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.');
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/JslLintTask.php b/buildscripts/phing/classes/phing/tasks/ext/JslLintTask.php
new file mode 100644
index 00000000..77a4aad5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/JslLintTask.php
@@ -0,0 +1,284 @@
+<?php
+/*
+ * $Id: 551de2e94aa21f44e19dd0806051f1eabf8b20f9 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <stefan.priebsch@e-novative.de>
+ * @version $Id: 551de2e94aa21f44e19dd0806051f1eabf8b20f9 $
+ * @package phing.tasks.ext
+ */
+class JslLintTask extends Task
+{
+ protected $file; // the source file (from xml attribute)
+ protected $filesets = array(); // all fileset objects assigned to this task
+
+ protected $showWarnings = true;
+ protected $haltOnFailure = false;
+ protected $hasErrors = false;
+ private $badFiles = array();
+
+ private $cache = null;
+ private $conf = null;
+
+ 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ public function setExecutable($path){
+ $this->executable = $path;
+
+ if (!@file_exists($path)) {
+ throw new BuildException("JavaScript Lint executable '{$path}' not found");
+ }
+ }
+
+ public function getExecutable(){
+ return $this->executable;
+ }
+
+ /**
+ * 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];
+ }
+
+ /**
+ * File to save error messages to
+ *
+ * @param PhingFile $file
+ */
+ 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)));
+ }
+
+ /**
+ * Performs the actual syntax check
+ *
+ * @param string $file
+ * @return 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);
+ }
+ }
+
+ 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);
+ }
+ }
+}
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/MailTask.php b/buildscripts/phing/classes/phing/tasks/ext/MailTask.php
index 16d29fb8..0fff88cc 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/MailTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/MailTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: MailTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 901fb0efa435ae78d249a50ed0e0f6e5d31e0d32 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -22,56 +22,138 @@
include_once 'phing/Task.php';
/**
- * Send a message by mail()
+ * Send an e-mail message
*
- * <mail to="user@example.org" subject="build complete">The build process is a success...</mail>
+ * <mail tolist="user@example.org" subject="build complete">The build process is a success...</mail>
*
- * @author Francois Harvey at SecuriWeb (http://www.securiweb.net)
- * @version $Revision: 1.1 $
- * @package phing.tasks.ext
+ * @author Michiel Rook <mrook@php.net>
+ * @author Francois Harvey at SecuriWeb (http://www.securiweb.net)
+ * @version $Id: 901fb0efa435ae78d249a50ed0e0f6e5d31e0d32 $
+ * @package phing.tasks.ext
*/
-class MailTask extends Task {
-
- protected $recipient;
-
- protected $subject;
+class MailTask extends Task
+{
+ protected $tolist = null;
+ protected $subject = null;
+ protected $msg = null;
+ protected $from = null;
+
+ protected $filesets = array();
- protected $msg;
+ public function main()
+ {
+ if (empty($this->from)) {
+ throw new BuildException('Missing "from" attribute');
+ }
+
+ $this->log('Sending mail to ' . $this->tolist);
+
+ if (!empty($this->filesets)) {
+ @require_once 'Mail.php';
+ @require_once 'Mail/mime.php';
+
+ if (!class_exists('Mail_mime')) {
+ throw new BuildException('Need the PEAR Mail_mime package to send attachments');
+ }
+
+ $mime = new Mail_mime();
+ $hdrs = array(
+ 'From' => $this->from,
+ 'Subject' => $this->subject
+ );
+ $mime->setTXTBody($this->msg);
+
+ foreach ($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $fromDir = $fs->getDir($this->project);
+ $srcFiles = $ds->getIncludedFiles();
- function main() {
- $this->log('Sending mail to ' . $this->recipient );
- mail($this->recipient, $this->subject, $this->msg);
+ foreach ($srcFiles as $file) {
+ $mime->addAttachment($fromDir . DIRECTORY_SEPARATOR . $file, 'application/octet-stream');
+ }
+ }
+
+ $body = $mime->get();
+ $hdrs = $mime->headers($hdrs);
+
+ $mail = Mail::factory('mail');
+ $mail->send($this->tolist, $hdrs, $body);
+ } else {
+ mail($this->tolist, $this->subject, $this->msg, "From: {$this->from}\n");
+ }
}
- /** setter for message */
- function setMsg($msg) {
+ /**
+ * Setter for message
+ */
+ public function setMsg($msg)
+ {
$this->setMessage($msg);
}
- /** alias setter */
- function setMessage($msg) {
+ /**
+ * Alias setter
+ */
+ public function setMessage($msg)
+ {
$this->msg = (string) $msg;
}
- /** setter for subject **/
- function setSubject($subject) {
- $this->subject = (string) $subject;
+ /**
+ * Setter for subject
+ */
+ public function setSubject($subject)
+ {
+ $this->subject = (string) $subject;
}
- /** setter for recipient **/
- function setRecipient($recipient) {
- $this->recipient = (string) $recipient;
+ /**
+ * Setter for tolist
+ */
+ public function setToList($tolist)
+ {
+ $this->tolist = $tolist;
+ }
+
+ /**
+ * Alias for (deprecated) recipient
+ */
+ public function setRecipient($recipient)
+ {
+ $this->tolist = (string) $recipient;
}
- /** alias for recipient **/
- function setTo($recipient) {
- $this->recipient = (string) $recipient;
+ /**
+ * Alias for to
+ */
+ public function setTo($to)
+ {
+ $this->tolist = (string) $to;
}
- /** Supporting the <mail>Message</mail> syntax. */
- function addText($msg)
+ /**
+ * Supports the <mail>Message</mail> syntax.
+ */
+ public function addText($msg)
{
$this->msg = (string) $msg;
}
+
+ /**
+ * Sets email address of sender
+ */
+ public function setFrom($from)
+ {
+ $this->from = $from;
+ }
+
+ /**
+ * Adds a fileset
+ */
+ public function createFileSet()
+ {
+ $fileset = new FileSet();
+ $this->filesets[] = $fileset;
+ return $fileset;
+ }
}
-
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ManifestTask.php b/buildscripts/phing/classes/phing/tasks/ext/ManifestTask.php
new file mode 100644
index 00000000..b9cfae64
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ManifestTask.php
@@ -0,0 +1,343 @@
+<?php
+/**
+ * $Id: 7f8f119fe5dd44ca9f374e24d776a1a764260e33 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once "phing/Task.php";
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * ManifestTask
+ *
+ * Generates a simple Manifest file with optional checksums.
+ *
+ *
+ * Manifest schema:
+ * ...
+ * path/to/file CHECKSUM [CHECKSUM2] [CHECKSUM3]
+ * path/to/secondfile CHECKSUM [CHECKSUM2] [CHECKSUM3]
+ * ...
+ *
+ * Example usage:
+ * <manifest checksum="crc32" file="${dir_build}/Manifest">
+ * <fileset refid="files_build" />
+ * </manifest>
+ *
+ * <manifest checksum="md5,adler32,sha256" file="${dir_build}/Manifest">
+ * <fileset refid="files_build" />
+ * </manifest>
+ *
+ *
+ *
+ * @author David Persson <davidpersson at qeweurope dot org>
+ * @package phing.tasks.ext
+ * @version $Id: 7f8f119fe5dd44ca9f374e24d776a1a764260e33 $
+ * @since 2.3.1
+ */
+class ManifestTask extends Task
+{
+ var $taskname = 'manifest';
+
+ /**
+ * Action
+ *
+ * "w" for reading in files from fileSet
+ * and writing manifest
+ *
+ * or
+ *
+ * "r" for reading in files from fileSet
+ * and checking against manifest
+ *
+ * @var string "r" or "w"
+ */
+ private $action = 'w';
+
+ /**
+ * The target file passed in the buildfile.
+ */
+ private $destFile = null;
+
+ /**
+ * Holds filesets
+ *
+ * @var array An Array of objects
+ */
+ private $filesets = array();
+
+ /**
+ * Enable/Disable checksuming or/and select algorithm
+ * true defaults to md5
+ * false disables checksuming
+ * string "md5,sha256,..." enables generation of multiple checksums
+ * string "sha256" generates sha256 checksum only
+ *
+ * @var mixed
+ */
+ private $checksum = false;
+
+ /**
+ * A string used in hashing method
+ *
+ * @var string
+ */
+ private $salt = '';
+
+ /**
+ * Holds some data collected during runtime
+ *
+ * @var array
+ */
+ private $meta = array('totalFileCount' => 0,'totalFileSize' => 0);
+
+
+ /**
+ * The setter for the attribute "file"
+ * This is where the manifest will be written to/read from
+ *
+ * @param string Path to readable file
+ * @return void
+ */
+ public function setFile(PhingFile $file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * The setter for the attribute "checksum"
+ *
+ * @param mixed $mixed
+ * @return void
+ */
+ public function setChecksum($mixed)
+ {
+ if(is_string($mixed)) {
+ $data = array(strtolower($mixed));
+
+ if(strpos($data[0],',')) {
+ $data = explode(',',$mixed);
+ }
+
+ $this->checksum = $data;
+
+ } elseif($mixed === true) {
+ $this->checksum = array('md5');
+
+ }
+ }
+
+ /**
+ * The setter for the optional attribute "salt"
+ *
+ * @param string $string
+ * @return void
+ */
+ public function setSalt($string)
+ {
+ $this->salt = $string;
+ }
+
+ /**
+ * Nested creator, creates a FileSet for this task
+ *
+ * @access public
+ * @return object The created fileset object
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * The init method: Do init steps.
+ */
+ public function init()
+ {
+ // nothing to do here
+ }
+
+ /**
+ * Delegate the work
+ */
+ public function main()
+ {
+ $this->validateAttributes();
+
+ if($this->action == 'w') {
+ $this->write();
+
+ } elseif($this->action == 'r') {
+ $this->read();
+
+ }
+ }
+
+ /**
+ * Creates Manifest file
+ * Writes to $this->file
+ *
+ * @throws BuildException
+ */
+ private function write()
+ {
+ $project = $this->getProject();
+
+ if(!touch($this->file->getPath())) {
+ throw new BuildException("Unable to write to ".$this->file->getPath().".");
+ }
+
+ $this->log("Writing to " . $this->file->__toString(), Project::MSG_INFO);
+
+ if(is_array($this->checksum)) {
+ $this->log("Using " . implode(', ',$this->checksum)." for checksuming.", Project::MSG_INFO);
+ }
+
+ foreach($this->filesets as $fs) {
+
+ $dir = $fs->getDir($this->project)->getPath();
+
+ $ds = $fs->getDirectoryScanner($project);
+ $fromDir = $fs->getDir($project);
+ $srcFiles = $ds->getIncludedFiles();
+ $srcDirs = $ds->getIncludedDirectories();
+
+ foreach($ds->getIncludedFiles() as $file_path) {
+ $line = $file_path;
+ if($this->checksum) {
+ foreach($this->checksum as $algo) {
+ if(!$hash = $this->hashFile($dir.'/'.$file_path,$algo)) {
+ throw new BuildException("Hashing $dir/$file_path with $algo failed!");
+ }
+
+ $line .= "\t".$hash;
+ }
+ }
+ $line .= "\n";
+ $manifest[] = $line;
+ $this->log("Adding file ".$file_path,Project::MSG_VERBOSE);
+ $this->meta['totalFileCount'] ++;
+ $this->meta['totalFileSize'] += filesize($dir.'/'.$file_path);
+ }
+
+ }
+
+ file_put_contents($this->file,$manifest);
+
+ $this->log("Done. Total files: ".$this->meta['totalFileCount'].". Total file size: ".$this->meta['totalFileSize']." bytes.", Project::MSG_INFO);
+ }
+
+ /**
+ * @todo implement
+ */
+ private function read()
+ {
+ throw new BuildException("Checking against manifest not yet supported.");
+ }
+
+ /**
+ * Wrapper method for hash generation
+ * Automatically selects extension
+ * Falls back to built-in functions
+ *
+ * @link http://www.php.net/mhash
+ * @link http://www.php.net/hash
+ *
+ * @param string $msg The string that should be hashed
+ * @param string $algo Algorithm
+ * @return mixed String on success, false if $algo is not available
+ */
+ private function hash($msg,$algo)
+ {
+ if(extension_loaded('hash')) {
+ $algo = strtolower($algo);
+
+ if(in_array($algo,hash_algos())) {
+ return hash($algo,$this->salt.$msg);
+ }
+
+ }
+
+ if(extension_loaded('mhash')) {
+ $algo = strtoupper($algo);
+
+ if(defined('MHASH_'.$algo)) {
+ return mhash('MHASH_'.$algo,$this->salt.$msg);
+
+ }
+ }
+
+ switch(strtolower($algo)) {
+ case 'md5':
+ return md5($this->salt.$msg);
+ case 'crc32':
+ return abs(crc32($this->salt.$msg));
+ }
+
+ return false;
+ }
+
+ /**
+ * Hash a files contents
+ * plus it's size an modification time
+ *
+ * @param string $file
+ * @param string $algo
+ * @return mixed String on success, false if $algo is not available
+ */
+ private function hashFile($file,$algo)
+ {
+ if(!file_exists($file)) {
+ return false;
+ }
+
+ $msg = file_get_contents($file).filesize($file).filemtime($file);
+
+ return $this->hash($msg,$algo);
+ }
+
+ /**
+ * Validates attributes coming in from XML
+ *
+ * @access private
+ * @return void
+ * @throws BuildException
+ */
+ protected function validateAttributes()
+ {
+ if($this->action != 'r' && $this->action != 'w') {
+ throw new BuildException("'action' attribute has non valid value. Use 'r' or 'w'");
+ }
+
+ if(empty($this->salt)) {
+ $this->log("No salt provided. Specify one with the 'salt' attribute.", Project::MSG_WARN);
+ }
+
+ if (is_null($this->file) && count($this->filesets) === 0) {
+ throw new BuildException("Specify at least sources and destination - a file or a fileset.");
+ }
+
+ if (!is_null($this->file) && $this->file->exists() && $this->file->isDirectory()) {
+ throw new BuildException("Destination file cannot be a directory.");
+ }
+
+ }
+}
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PackageAsPathTask.php b/buildscripts/phing/classes/phing/tasks/ext/PackageAsPathTask.php
index b8664aac..2db5ad69 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/PackageAsPathTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/PackageAsPathTask.php
@@ -1,7 +1,7 @@
<?php
/*
- * $Id: PackageAsPathTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 976dafaf4cafd9ff8f47907a09943ae3963aea79 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -26,7 +26,7 @@ require_once 'phing/Task.php';
* Convert dot-notation packages to relative paths.
*
* @author Hans Lellelid <hans@xmpl.org>
- * @version $Revision: 1.5 $
+ * @version $Id: 976dafaf4cafd9ff8f47907a09943ae3963aea79 $
* @package phing.tasks.ext
*/
class PackageAsPathTask extends Task {
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ParallelTask.php b/buildscripts/phing/classes/phing/tasks/ext/ParallelTask.php
new file mode 100755
index 00000000..b8da5cb4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ParallelTask.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * $Id: 860b2b6cdbd797754660fe2c1554e22ab2db4967 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ *
+ * @package phing.tasks.ext
+ */
+
+/**
+ * Uses the DocBlox_Parallel library to run nested Phing tasks concurrently.
+ *
+ * WARNING: this task is highly experimental!
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 860b2b6cdbd797754660fe2c1554e22ab2db4967 $
+ * @package phing.tasks.ext
+ * @see https://github.com/phpdocumentor/Parallel
+ * @since 2.4.10
+ */
+class ParallelTask extends SequentialTask
+{
+ /**
+ * Maximum number of threads / processes
+ * @var int
+ */
+ private $threadCount = 2;
+
+ /**
+ * Sets the maximum number of threads / processes to use
+ * @param int $threadCount
+ */
+ public function setThreadCount($threadCount)
+ {
+ $this->threadCount = $threadCount;
+ }
+
+ public function init()
+ {
+ }
+
+ public function main()
+ {
+ @include_once 'phing/contrib/DocBlox/Parallel/Manager.php';
+ @include_once 'phing/contrib/DocBlox/Parallel/Worker.php';
+ @include_once 'phing/contrib/DocBlox/Parallel/WorkerPipe.php';
+ if (!class_exists('DocBlox_Parallel_Worker')) {
+ throw new BuildException(
+ 'ParallelTask depends on DocBlox being installed and on include_path.',
+ $this->getLocation()
+ );
+ }
+
+ $mgr = new DocBlox_Parallel_Manager();
+ $mgr->setProcessLimit($this->threadCount);
+
+ foreach ($this->nestedTasks as $task) {
+ $worker = new DocBlox_Parallel_Worker(
+ array($task, 'perform'),
+ array($task)
+ );
+
+ $mgr->addWorker($worker);
+ }
+
+ $mgr->execute();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PatchTask.php b/buildscripts/phing/classes/phing/tasks/ext/PatchTask.php
new file mode 100755
index 00000000..162f5fe5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/PatchTask.php
@@ -0,0 +1,301 @@
+<?php
+/**
+ * Patches a file by applying a 'diff' file to it
+ *
+ * Requires "patch" to be on the execution path.
+ *
+ * Based on Apache Ant PatchTask:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Patches a file by applying a 'diff' file to it
+ *
+ * Requires "patch" to be on the execution path.
+ *
+ * @package phing.tasks.ext
+ */
+class PatchTask extends Task
+{
+ /**
+ * Base command to be executed (must end with a space character!)
+ * @var string
+ */
+ const CMD = 'patch --batch --silent ';
+
+ /**
+ * File to be patched
+ * @var string
+ */
+ private $originalFile;
+
+ /**
+ * Patch file
+ *
+ * @var string
+ */
+ private $patchFile;
+
+ /**
+ * Value for a "-p" option
+ * @var int
+ */
+ private $strip;
+
+ /**
+ * Command line arguments for patch binary
+ * @var array
+ */
+ private $cmdArgs = array();
+
+ /**
+ * Halt on error return value from patch invocation.
+ * @var bool
+ */
+ private $haltOnFailure = false;
+
+ /**
+ * The file containing the diff output
+ *
+ * Required.
+ *
+ * @param string $file File containing the diff output
+ * @return void
+ * @throws BuildException if $file not exists
+ */
+ public function setPatchFile($file)
+ {
+ if (!is_file($file))
+ {
+ throw new BuildException(sprintf('Patchfile %s doesn\'t exist', $file));
+ }
+ $this->patchFile = $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 <i>num</i> leading slashes
+ * from filenames.
+ *
+ * patch's <i>--strip</i> 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" );
+ }
+
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PearPackage2Task.php b/buildscripts/phing/classes/phing/tasks/ext/PearPackage2Task.php
new file mode 100644
index 00000000..f42231f7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/PearPackage2Task.php
@@ -0,0 +1,279 @@
+<?php
+/*
+ * $Id: 1b20dbb6595bd4c41d1e5f1430900e3bf95de411 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <option> and <mapping>
+ * nested elements. All options are set using PEAR_PackageFileManager2::setOptions().
+ *
+ * The <option> tag is used to set a simple option value.
+ * <code>
+ * <option name="option_name" value="option_value"/>
+ * or <option name="option_name">option_value</option>
+ * </code>
+ *
+ * The <mapping> tag represents a complex data type. You can use nested <element> (and nested <element> with
+ * <element> tags) to represent the full complexity of the structure. Bear in mind that what you are creating
+ * will be mapped to an associative array that will be passed in via PEAR_PackageFileManager2::setOptions().
+ * <code>
+ * <mapping name="option_name">
+ * <element key="key_name" value="key_val"/>
+ * <element key="key_name" value="key_val"/>
+ * </mapping>
+ * </code>
+ *
+ * Here's an over-simple example of how this could be used:
+ * <code>
+ * <pearpkg2 name="phing" dir="${build.src.dir}">
+ * <fileset dir="src">
+ * <include name="**"/>
+ * </fileset>
+ * <option name="outputdirectory" value="./build"/>
+ * <option name="packagefile" value="package2.xml"/>
+ * <option name="packagedirectory" value="./${build.dist.dir}"/>
+ * <option name="baseinstalldir" value="${pkg.prefix}"/>
+ * <option name="channel" value="my.pear-channel.com"/>
+ * <option name="summary" value="${pkg.summary}"/>
+ * <option name="description" value="${pkg.description}"/>
+ * <option name="apiversion" value="${pkg.version}"/>
+ * <option name="apistability" value="beta"/>
+ * <option name="releaseversion" value="${pkg.version}"/>
+ * <option name="releasestability" value="beta"/>
+ * <option name="license" value="none"/>
+ * <option name="phpdep" value="5.0.0"/>
+ * <option name="pearinstallerdep" value="1.4.6"/>
+ * <option name="packagetype" value="php"/>
+ * <option name="notes" value="${pkg.relnotes}"/>
+ * <mapping name="maintainers">
+ * <element>
+ * <element key="handle" value="hlellelid"/>
+ * <element key="name" value="Hans"/>
+ * <element key="email" value="hans@xmpl.org"/>
+ * <element key="role" value="lead"/>
+ * <element key="active" value="yes"/>
+ * </element>
+ * </mapping>
+ * </pearpkg2>
+ * </code>
+ *
+ * Look at the build.xml in the Phing base directory (assuming you have the full distro / CVS version of Phing) to
+ * see a more complete example of how to call this script.
+ *
+ * @author Stuart Binge <stuart.binge@complinet.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext
+ * @version $Id: 1b20dbb6595bd4c41d1e5f1430900e3bf95de411 $
+ */
+class PearPackage2Task extends PearPackageTask {
+
+ public function init() {
+ include_once 'PEAR/PackageFileManager2.php';
+ if (!class_exists('PEAR_PackageFileManager2')) {
+ throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml version 2.0 file.");
+ }
+ }
+
+ protected function setVersion2Options()
+ {
+ $this->pkg->setPackage($this->package);
+ $this->pkg->setDate(strftime('%Y-%m-%d'));
+ $this->pkg->setTime(strftime('%H:%M:%S'));
+
+ $newopts = array();
+ foreach ($this->options as $opt) {
+ switch ($opt->getName()) {
+ case 'summary':
+ $this->pkg->setSummary($opt->getValue());
+ break;
+
+ case 'description':
+ $this->pkg->setDescription($opt->getValue());
+ break;
+
+ case 'uri':
+ $this->pkg->setUri($opt->getValue());
+ break;
+
+ case 'license':
+ $this->pkg->setLicense($opt->getValue());
+ break;
+
+ case 'channel':
+ $this->pkg->setChannel($opt->getValue());
+ break;
+
+ case 'apiversion':
+ $this->pkg->setAPIVersion($opt->getValue());
+ break;
+
+ case 'releaseversion':
+ $this->pkg->setReleaseVersion($opt->getValue());
+ break;
+
+ case 'releasestability':
+ $this->pkg->setReleaseStability($opt->getValue());
+ break;
+
+ case 'apistability':
+ $this->pkg->setAPIStability($opt->getValue());
+ break;
+
+ case 'notes':
+ $this->pkg->setNotes($opt->getValue());
+ break;
+
+ case 'packagetype':
+ $this->pkg->setPackageType($opt->getValue());
+ break;
+
+ case 'phpdep':
+ $this->pkg->setPhpDep($opt->getValue());
+ break;
+
+ case 'pearinstallerdep':
+ $this->pkg->setPearinstallerDep($opt->getValue());
+ break;
+
+ default:
+ $newopts[] = $opt;
+ break;
+ }
+ }
+ $this->options = $newopts;
+
+ $newmaps = array();
+ foreach ($this->mappings as $map) {
+ switch ($map->getName()) {
+ case 'deps':
+ $deps = $map->getValue();
+ foreach ($deps as $dep) {
+ $type = isset($dep['optional']) ? 'optional' : 'required';
+ $min = isset($dep['min']) ? $dep['min'] : $dep['version'];
+ $max = isset($dep['max']) ? $dep['max'] : null;
+ $rec = isset($dep['recommended']) ? $dep['recommended'] : null;
+ $channel = isset($dep['channel']) ? $dep['channel'] : false;
+ $uri = isset($dep['uri']) ? $dep['uri'] : false;
+
+ if (!empty($channel)) {
+ $this->pkg->addPackageDepWithChannel(
+ $type, $dep['name'], $channel, $min, $max, $rec
+ );
+ } elseif (!empty($uri)) {
+ $this->pkg->addPackageDepWithUri(
+ $type, $dep['name'], $uri
+ );
+ }
+ };
+ break;
+
+ case 'extdeps':
+ $deps = $map->getValue();
+ foreach ($deps as $dep) {
+ $type = isset($dep['optional']) ? 'optional' : 'required';
+ $min = isset($dep['min']) ? $dep['min'] : $dep['version'];
+ $max = isset($dep['max']) ? $dep['max'] : $dep['version'];
+ $rec = isset($dep['recommended']) ? $dep['recommended'] : $dep['version'];
+
+ $this->pkg->addExtensionDep(
+ $type, $dep['name'], $min, $max, $rec
+ );
+ };
+ break;
+
+ case 'maintainers':
+ $maintainers = $map->getValue();
+
+ foreach ($maintainers as $maintainer) {
+ if (!isset($maintainer['active'])) {
+ $maintainer['active'] = 'yes';
+ } else {
+ $maintainer['active'] = $maintainer['active'] === false ? 'no' : 'yes';
+ }
+ $this->pkg->addMaintainer(
+ $maintainer['role'],
+ $maintainer['handle'],
+ $maintainer['name'],
+ $maintainer['email'],
+ $maintainer['active']
+ );
+ }
+ break;
+
+ case 'replacements':
+ $replacements = $map->getValue();
+
+ foreach($replacements as $replacement) {
+ $this->pkg->addReplacement(
+ $replacement['path'],
+ $replacement['type'],
+ $replacement['from'],
+ $replacement['to']
+ );
+ }
+ break;
+
+ case 'role':
+ foreach ($map->getValue() as $role) {
+ $this->pkg->addRole($role['extension'], $role['role']);
+ }
+ break;
+
+ default:
+ $newmaps[] = $map;
+ }
+ }
+ $this->mappings = $newmaps;
+ }
+
+ /**
+ * Main entry point.
+ * @return void
+ */
+ public function main()
+ {
+ if ($this->dir === null) {
+ throw new BuildException("You must specify the \"dir\" attribute for PEAR package 2 task.");
+ }
+
+ if ($this->package === null) {
+ throw new BuildException("You must specify the \"name\" attribute for PEAR package 2 task.");
+ }
+
+ $this->pkg = new PEAR_PackageFileManager2();
+
+ $this->setVersion2Options();
+ $this->setOptions();
+
+ $this->pkg->addRelease();
+ $this->pkg->generateContents();
+ $e = $this->pkg->writePackageFile();
+ if (PEAR::isError($e)) {
+ throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PearPackageTask.php b/buildscripts/phing/classes/phing/tasks/ext/PearPackageTask.php
index 4f8ee3ab..47945998 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/PearPackageTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/PearPackageTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: PearPackageTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 2078fd5bab3dd6dcea0345a12fce86a24586c765 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -74,15 +74,15 @@ include_once 'phing/types/FileSet.php';
*
* @author Hans Lellelid <hans@xmpl.org>
* @package phing.tasks.ext
- * @version $Revision: 1.9 $
+ * @version $Id: 2078fd5bab3dd6dcea0345a12fce86a24586c765 $
*/
class PearPackageTask extends MatchingTask {
/** */
- private $package;
+ protected $package;
/** Base directory for reading files. */
- private $dir;
+ protected $dir;
/** Package file */
private $packageFile;
@@ -91,15 +91,21 @@ class PearPackageTask extends MatchingTask {
private $filesets = array();
/** @var PEAR_PackageFileManager */
- private $pkg;
+ protected $pkg;
private $preparedOptions = array();
/** @var array PearPkgOption[] */
- private $options = array();
+ protected $options = array();
/** Nested <mapping> (complex options) types. */
- private $mappings = array();
+ protected $mappings = array();
+
+ /**
+ * Nested <role> elements
+ * @var PearPkgRole[]
+ */
+ protected $roles = array();
public function init() {
include_once 'PEAR/PackageFileManager.php';
@@ -112,7 +118,7 @@ class PearPackageTask extends MatchingTask {
* Sets PEAR package.xml options, based on class properties.
* @return void
*/
- private function setOptions() {
+ protected function setOptions() {
// 1) first prepare/populate options
$this->populateOptions();
@@ -147,6 +153,11 @@ class PearPackageTask extends MatchingTask {
if (PEAR::isError($e)) {
throw new BuildException("Unable to set options.", new Exception($e->getMessage()));
}
+
+ // convert roles
+ foreach ($this->roles as $role) {
+ $this->pkg->addRole($role->getExtension(), $role->getRole());
+ }
}
/**
@@ -180,9 +191,9 @@ class PearPackageTask extends MatchingTask {
$this->preparedOptions['packagefile'] = $f->getName();
// must end in trailing slash
$this->preparedOptions['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
- $this->log("Creating package file: " . $f->__toString(), PROJECT_MSG_INFO);
+ $this->log("Creating package file: " . $f->__toString(), Project::MSG_INFO);
} else {
- $this->log("Creating [default] package.xml file in base directory.", PROJECT_MSG_INFO);
+ $this->log("Creating [default] package.xml file in base directory.", Project::MSG_INFO);
}
// converts option objects and mapping objects into
@@ -244,11 +255,12 @@ class PearPackageTask extends MatchingTask {
/**
* Nested creator, creates a FileSet for this task
*
- * @return FileSet The created fileset object
+ * @param FileSet $fileset Set of files to add to the package
+ *
+ * @return void
*/
- function createFileSet() {
- $num = array_push($this->filesets, new FileSet());
- return $this->filesets[$num-1];
+ public function addFileSet(FileSet $fs) {
+ $this->filesets[] = $fs;
}
/**
@@ -289,7 +301,7 @@ class PearPackageTask extends MatchingTask {
/**
* Handles nested generic <option> elements.
*/
- function createOption() {
+ public function createOption() {
$o = new PearPkgOption();
$this->options[] = $o;
return $o;
@@ -298,17 +310,30 @@ class PearPackageTask extends MatchingTask {
/**
* Handles nested generic <option> elements.
*/
- function createMapping() {
+ public function createMapping() {
$o = new PearPkgMapping();
$this->mappings[] = $o;
return $o;
}
+
+ /**
+ * Handles nested <role> elements
+ * @return PearPkgRole
+ */
+ public function createRole()
+ {
+ $role = new PearPkgRole();
+ $this->roles[] = $role;
+ return $role;
+ }
}
/**
* Generic option class is used for non-complex options.
+ *
+ * @package phing.tasks.ext
*/
class PearPkgOption {
@@ -326,6 +351,8 @@ class PearPkgOption {
/**
* Handles complex options <mapping> elements which are hashes (assoc arrays).
+ *
+ * @package phing.tasks.ext
*/
class PearPkgMapping {
@@ -369,6 +396,8 @@ class PearPkgMapping {
/**
* Sub-element of <mapping>.
+ *
+ * @package phing.tasks.ext
*/
class PearPkgMappingElement {
@@ -419,3 +448,57 @@ class PearPkgMappingElement {
}
}
+
+/**
+ * Encapsulates file roles
+ *
+ * @package phing.tasks.ext
+ */
+class PearPkgRole
+{
+ /**
+ * @var string
+ */
+ private $extension;
+
+ /**
+ * @var string
+ */
+ private $role;
+
+ /**
+ * Sets the file extension
+ * @param string $extension
+ */
+ public function setExtension($extension)
+ {
+ $this->extension = $extension;
+ }
+
+ /**
+ * Retrieves the file extension
+ * @return string
+ */
+ public function getExtension()
+ {
+ return $this->extension;
+ }
+
+ /**
+ * Sets the role
+ * @param string $role
+ */
+ public function setRole($role)
+ {
+ $this->role = $role;
+ }
+
+ /**
+ * Retrieves the role
+ * @return string
+ */
+ public function getRole()
+ {
+ return $this->role;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php b/buildscripts/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php
new file mode 100644
index 00000000..de40ae36
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php
@@ -0,0 +1,648 @@
+<?php
+/*
+ * $Id: 8c8f9369e06a3467e34fc8d89f6355df048ece90 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * A PHP code sniffer task. Checking the style of one or more PHP source files.
+ *
+ * @author Dirk Thomas <dirk.thomas@4wdmedia.de>
+ * @version $Id: 8c8f9369e06a3467e34fc8d89f6355df048ece90 $
+ * @package phing.tasks.ext
+ */
+class PhpCodeSnifferTask extends Task {
+
+ protected $file; // the source file (from xml attribute)
+ protected $filesets = array(); // all fileset objects assigned to this task
+
+ // parameters for php code sniffer
+ protected $standard = 'Generic';
+ protected $sniffs = array();
+ protected $showWarnings = true;
+ protected $showSources = false;
+ protected $reportWidth = 80;
+ protected $verbosity = 0;
+ protected $tabWidth = 0;
+ protected $allowedFileExtensions = array('php');
+ protected $ignorePatterns = false;
+ protected $noSubdirectories = false;
+ protected $configData = array();
+ protected $encoding = 'iso-8859-1';
+
+ // parameters to customize output
+ protected $showSniffs = false;
+ protected $format = 'default';
+ 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;
+
+ /**
+ * 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 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];
+ }
+
+ /**
+ * Sets the coding standard to test for
+ *
+ * @param string $standard The coding standard
+ *
+ * @return void
+ */
+ public function setStandard($standard)
+ {
+ $this->standard = $standard;
+ }
+
+ /**
+ * 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 ignore patterns to skip files when using directories instead of specific files
+ * @param array $extensions
+ */
+ public function setIgnorePatterns($patterns)
+ {
+ $this->ignorePatterns = array();
+ $token = ' ,;';
+ $pattern = strtok($patterns, $token);
+ while ($pattern !== false) {
+ $this->ignorePatterns[] = $pattern;
+ $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 CodeSniffer_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;
+ }
+
+ /**
+ * 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) {
+ 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 (PHP_CodeSniffer::isInstalledStandard($this->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 "' . $this->standard . '" coding standard is not installed. ' . $errMsg,
+ $this->getLocation()
+ );
+ }
+
+ 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;
+ }
+
+ if (!isset($this->file))
+ {
+ $fileList = array();
+ $project = $this->getProject();
+ foreach ($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($project);
+ $files = $ds->getIncludedFiles();
+ $dir = $fs->getDir($this->project)->getAbsolutePath();
+ foreach ($files as $file) {
+ $fileList[] = $dir.DIRECTORY_SEPARATOR.$file;
+ }
+ }
+ }
+
+ $cwd = getcwd();
+ // Save command line arguments because it confuses PHPCS (version 1.3.0)
+ $oldArgs = $_SERVER['argv'];
+ $_SERVER['argv'] = array();
+ $_SERVER['argc'] = 0;
+ $codeSniffer = new PHP_CodeSniffer($this->verbosity, $this->tabWidth, $this->encoding);
+ $codeSniffer->setAllowedFileExtensions($this->allowedFileExtensions);
+ if (is_array($this->ignorePatterns)) $codeSniffer->setIgnorePatterns($this->ignorePatterns);
+ foreach ($this->configData as $configData) {
+ $codeSniffer->setConfigData($configData->getName(), $configData->getValue(), true);
+ }
+
+ if ($this->file instanceof PhingFile) {
+ $codeSniffer->process($this->file->getPath(), $this->standard, $this->sniffs, $this->noSubdirectories);
+
+ } else {
+ $codeSniffer->process($fileList, $this->standard, $this->sniffs, $this->noSubdirectories);
+ }
+ // Restore command line arguments
+ $_SERVER['argv'] = $oldArgs;
+ $_SERVER['argc'] = count($oldArgs);
+ chdir($cwd);
+
+ $report = $this->printErrorReport($codeSniffer);
+
+ // generate the documentation
+ if ($this->docGenerator !== '' && $this->docFile !== null) {
+ ob_start();
+
+ $codeSniffer->generateDocs($this->standard, $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 (is_bool($check) && !$check) {
+ throw new BuildException('Error writing doc to ' . $outputFile);
+ }
+ } elseif ($this->docGenerator !== '' && $this->docFile === null) {
+ $codeSniffer->generateDocs($this->standard, $this->sniffs, $this->docGenerator);
+ }
+
+ if ($this->haltonerror && $report['totals']['errors'] > 0)
+ {
+ throw new BuildException('phpcodesniffer detected ' . $report['totals']['errors']. ' error' . ($report['totals']['errors'] > 1 ? 's' : ''));
+ }
+
+ if ($this->haltonwarning && $report['totals']['warnings'] > 0)
+ {
+ throw new BuildException('phpcodesniffer detected ' . $report['totals']['warnings'] . ' warning' . ($report['totals']['warnings'] > 1 ? 's' : ''));
+ }
+ }
+
+ /**
+ * Prints the error report.
+ *
+ * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing
+ * the errors.
+ *
+ * @return int The number of error and warning messages shown.
+ */
+ protected function printErrorReport($phpcs)
+ {
+ if ($this->showSniffs) {
+ $sniffs = $phpcs->getSniffs();
+ $sniffStr = '';
+ foreach ($sniffs as $sniff) {
+ $sniffStr .= '- ' . $sniff.PHP_EOL;
+ }
+ $this->log('The list of used sniffs (#' . count($sniffs) . '): ' . PHP_EOL . $sniffStr, Project::MSG_INFO);
+ }
+
+ $filesViolations = $phpcs->getFilesErrors();
+ $reporting = new PHP_CodeSniffer_Reporting();
+ $report = $reporting->prepare($filesViolations, $this->showWarnings);
+
+ // process output
+ foreach ($this->formatters as $fe) {
+ switch ($fe->getType()) {
+ case 'default':
+ // default format goes to logs, no buffering
+ $this->outputCustomFormat($report);
+ $fe->setUseFile(false);
+ break;
+
+ default:
+ $reportFile = null;
+
+ if ($fe->getUseFile()) {
+ $reportFile = $fe->getOutfile();
+ ob_start();
+ }
+
+ // Determine number of parameters required to
+ // ensure backwards compatibility
+ $rm = new ReflectionMethod('PHP_CodeSniffer_Reporting', 'printReport');
+
+ if ($rm->getNumberOfParameters() == 5) {
+ $reporting->printReport(
+ $fe->getType(),
+ $filesViolations,
+ $this->showSources,
+ $reportFile,
+ $this->reportWidth
+ );
+ } else {
+ $reporting->printReport(
+ $fe->getType(),
+ $filesViolations,
+ $this->showWarnings,
+ $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();
+ }
+ break;
+ }
+ }
+
+ return $report;
+ }
+
+ /**
+ * 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 where 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 ($useFile && empty($this->outfile)) {
+ throw new BuildException("Format requires 'outfile' attribute when 'useFile' is true.");
+ }
+
+ }
+
+ public function setType ($type) {
+ $this->type = $type;
+ }
+
+ public function getType () {
+ return $this->type;
+ }
+
+ public function setUseFile ($useFile) {
+ $this->useFile = $useFile;
+ }
+
+ public function getUseFile () {
+ return $this->useFile;
+ }
+
+ public function setOutfile ($outfile) {
+ $this->outfile = $outfile;
+ }
+
+ public function getOutfile () {
+ return $this->outfile;
+ }
+
+} //end FormatterElement
diff --git a/buildscripts/phing/classes/phing/tasks/ext/PhpLintTask.php b/buildscripts/phing/classes/phing/tasks/ext/PhpLintTask.php
index 2fd89fc3..63ec1812 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/PhpLintTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/PhpLintTask.php
@@ -1,82 +1,278 @@
<?php
+/*
+ * $Id: 524bae55e1007bc9778c232dd7b437964a66c5a4 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
require_once 'phing/Task.php';
+require_once 'phing/util/DataStore.php';
+require_once 'phing/system/io/FileWriter.php';
/**
* A PHP lint task. Checking syntax of one or more PHP source file.
*
* @author Knut Urdalen <knut.urdalen@telio.no>
+ * @author Stefan Priebsch <stefan.priebsch@e-novative.de>
+ * @version $Id: 524bae55e1007bc9778c232dd7b437964a66c5a4 $
* @package phing.tasks.ext
*/
class PhpLintTask extends Task {
- protected $file; // the source file (from xml attribute)
- protected $filesets = array(); // all fileset objects assigned to this task
-
- /**
- * File to be performed syntax check on
- * @param PhingFile $file
- */
- public function setFile(PhingFile $file) {
- $this->file = $file;
- }
-
- /**
- * Nested creator, creates a FileSet for this task
- *
- * @return FileSet The created fileset object
- */
- function createFileSet() {
- $num = array_push($this->filesets, new FileSet());
- return $this->filesets[$num-1];
- }
-
- /**
- * 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");
+ protected $file; // the source file (from xml attribute)
+ protected $filesets = array(); // all fileset objects assigned to this task
+
+ protected $errorProperty;
+ protected $haltOnFailure = false;
+ protected $hasErrors = false;
+ protected $badFiles = array();
+ protected $interpreter = ''; // php interpreter to use for linting
+
+ protected $logLevel = Project::MSG_VERBOSE;
+
+ protected $cache = null;
+
+ protected $tofile = null;
+
+ protected $deprecatedAsError = false;
+
+ /**
+ * Initialize the interpreter with the Phing property
+ */
+ public function __construct() {
+ $this->setInterpreter(Phing::getProperty('php.interpreter'));
+ }
+
+ /**
+ * Override default php interpreter
+ * @todo Do some sort of checking if the path is correct but would
+ * require traversing the systems executeable path too
+ * @param string $sPhp
+ */
+ public function setInterpreter($sPhp) {
+ $this->Interpreter = $sPhp;
+ }
+
+ /**
+ * The haltonfailure property
+ * @param boolean $aValue
+ */
+ public function setHaltOnFailure($aValue) {
+ $this->haltOnFailure = $aValue;
+ }
+
+ /**
+ * File to be performed syntax check on
+ * @param PhingFile $file
+ */
+ public function setFile(PhingFile $file) {
+ $this->file = $file;
+ }
+
+ /**
+ * Set an property name in which to put any errors.
+ * @param string $propname
+ */
+ public function setErrorproperty($propname)
+ {
+ $this->errorProperty = $propname;
+ }
+
+ /**
+ * Whether to store last-modified times in cache
+ *
+ * @param PhingFile $file
+ */
+ public function setCacheFile(PhingFile $file)
+ {
+ $this->cache = new DataStore($file);
+ }
+
+ /**
+ * File to save error messages to
+ *
+ * @param PhingFile $file
+ */
+ public function setToFile(PhingFile $tofile)
+ {
+ $this->tofile = $tofile;
+ }
+
+ /**
+ * 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];
+ }
+
+ /**
+ * Set level of log messages generated (default = info)
+ * @param string $level
+ */
+ public function setLevel($level)
+ {
+ switch ($level)
+ {
+ case "error": $this->logLevel = Project::MSG_ERR; break;
+ case "warning": $this->logLevel = Project::MSG_WARN; break;
+ case "info": $this->logLevel = Project::MSG_INFO; break;
+ case "verbose": $this->logLevel = Project::MSG_VERBOSE; break;
+ case "debug": $this->logLevel = Project::MSG_DEBUG; break;
+ }
+ }
+
+ /**
+ * Sets whether to treat deprecated warnings (introduced in PHP 5.3) as errors
+ * @param boolean $deprecatedAsError
+ */
+ public function setDeprecatedAsError($deprecatedAsError)
+ {
+ $this->deprecatedAsError = $deprecatedAsError;
}
- 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);
- }
- }
+ /**
+ * 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($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();
+ }
+
+ $message = '';
+ foreach ($this->badFiles as $file => $messages) {
+ foreach ($messages as $msg) {
+ $message .= $file . "=" . $msg . PHP_EOL;
+ }
+ }
+
+ // save list of 'bad files' with errors to property errorproperty (if specified)
+ if ($this->errorProperty) {
+ $this->project->setProperty($this->errorProperty, $message);
+ }
+
+ if (!empty($this->cache)) {
+ $this->cache->commit();
+ }
+
+ if ($this->haltOnFailure && $this->hasErrors) {
+ throw new BuildException('Syntax error(s) in PHP files: ' . $message);
+ }
}
- }
-
- /**
- * Performs the actual syntax check
- *
- * @param string $file
- * @return void
- */
- protected function lint($file) {
- $command = 'php -l ';
- if(file_exists($file)) {
- if(is_readable($file)) {
- $message = array();
- exec($command.$file, $message);
- if(!preg_match('/^No syntax errors detected/', $message[0])) {
- $this->log($message[1], PROJECT_MSG_ERR);
- } else {
- $this->log($file.': No syntax errors detected', PROJECT_MSG_INFO);
- }
- } else {
- throw new BuildException('Permission denied: '.$file);
- }
- } else {
- throw new BuildException('File not found: '.$file);
+
+ /**
+ * Performs the actual syntax check
+ *
+ * @param string $file
+ * @return void
+ */
+ protected function lint($file) {
+ $command = $this->Interpreter == ''
+ ? 'php'
+ : $this->Interpreter;
+ $command .= ' -n -l ';
+
+ if ($this->deprecatedAsError) {
+ $command .= '-d error_reporting=32767 ';
+ }
+
+ 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();
+ $errorCount = 0;
+
+ exec($command.'"'.$file.'" 2>&1', $messages);
+
+ for ($i = 0; $i < count($messages) - 1; $i++) {
+ $message = $messages[$i];
+ if (trim($message) == '') {
+ continue;
+ }
+
+ if ((!preg_match('/^(.*)Deprecated:/', $message) || $this->deprecatedAsError) && !preg_match('/^No syntax errors detected/', $message)) {
+ $this->log($message, Project::MSG_ERR);
+
+ if (!isset($this->badFiles[$file])) {
+ $this->badFiles[$file] = array();
+ }
+
+ array_push($this->badFiles[$file], $message);
+
+ $this->hasErrors = true;
+ $errorCount++;
+ }
+ }
+
+ if (!$errorCount) {
+ $this->log($file.': No syntax errors detected', $this->logLevel);
+
+ if ($this->cache)
+ {
+ $this->cache->put($file, filemtime($file));
+ }
+ }
+ } else {
+ throw new BuildException('Permission denied: '.$file);
+ }
+ } else {
+ throw new BuildException('File not found: '.$file);
+ }
}
- }
}
-?> \ No newline at end of file
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ReplaceRegexpTask.php b/buildscripts/phing/classes/phing/tasks/ext/ReplaceRegexpTask.php
new file mode 100644
index 00000000..dc4ccbf7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ReplaceRegexpTask.php
@@ -0,0 +1,204 @@
+<?php
+/*
+ * $Id: f81043cad2c0ffe0a2571a0a8dc16a98651eac51 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * ReplaceRegExp is a directory based task for replacing the occurrence of a given regular expression with a substitution
+ * pattern in a selected file or set of files.
+ *
+ * <code>
+ * <replaceregexp file="${src}/build.properties"
+ * match="OldProperty=(.*)"
+ * replace="NewProperty=\1"
+ * byline="true"/>
+ * </code>
+ *
+ * @author Jonathan Bond-Caron <jbondc@openmv.com>
+ * @version $Id: f81043cad2c0ffe0a2571a0a8dc16a98651eac51 $
+ * @package phing.tasks.system
+ * @link http://ant.apache.org/manual/OptionalTasks/replaceregexp.html
+ */
+class ReplaceRegexpTask extends Task {
+
+ /** Single file to process. */
+ private $file;
+
+ /** Any filesets that should be processed. */
+ private $filesets = array();
+
+ /**
+ * Regular expression
+ *
+ * @var RegularExpression
+ */
+ private $_regexp;
+
+ /**
+ * File to apply regexp on
+ *
+ * @param string $path
+ */
+ public function setFile(PhingFile $path)
+ {
+ $this->file = $path;
+ }
+
+ /**
+ * Sets the regexp match pattern
+ *
+ * @param string $regexp
+ */
+ public function setMatch( $regexp )
+ {
+ $this->_regexp->setPattern( $regexp );
+ }
+
+ /**
+ * @see setMatch()
+ */
+ public function setPattern( $regexp )
+ {
+ $this->setMatch( $regexp );
+ }
+
+ /**
+ * Sets the replacement string
+ *
+ * @param string $string
+ */
+ public function setReplace( $string )
+ {
+ $this->_regexp->setReplace( $string );
+ }
+
+ /**
+ * Sets the regexp flags
+ *
+ * @param string $flags
+ */
+ public function setFlags( $flags )
+ {
+ // TODO... $this->_regexp->setFlags( $flags );
+ }
+
+ /**
+ * Match only per line
+ *
+ * @param bool $yesNo
+ */
+ public function setByline( $yesNo )
+ {
+ // TODO... $this->_regexp->
+ }
+
+ /** Nested creator, adds a set of files (nested fileset attribute). */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ public function init()
+ {
+ $this->_regexp = new RegularExpression;
+ }
+
+ public function main()
+ {
+ if ($this->file === null && empty($this->filesets)) {
+ throw new BuildException("You must specify a file or fileset(s) for the <ReplaceRegexp> task.");
+ }
+
+ // compile a list of all files to modify, both file attrib and fileset elements
+ // can be used.
+ $files = array();
+
+ if ($this->file !== null) {
+ $files[] = $this->file;
+ }
+
+ if (!empty($this->filesets)) {
+ $filenames = array();
+ foreach($this->filesets as $fs) {
+ try {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $filenames = $ds->getIncludedFiles(); // get included filenames
+ $dir = $fs->getDir($this->project);
+ foreach ($filenames as $fname) {
+ $files[] = new PhingFile($dir, $fname);
+ }
+ } catch (BuildException $be) {
+ $this->log($be->getMessage(), Project::MSG_WARN);
+ }
+ }
+ }
+
+ $this->log("Applying Regexp processing to " . count($files) . " files.");
+
+ // These "slots" allow filters to retrieve information about the currently-being-process files
+ $slot = $this->getRegisterSlot("currentFile");
+ $basenameSlot = $this->getRegisterSlot("currentFile.basename");
+
+ $filter = new FilterChain($this->project);
+
+ $r = new ReplaceRegexp;
+ $r->setRegexps(array($this->_regexp));
+
+ $filter->addReplaceRegexp($r);
+ $filters = array($filter);
+
+ foreach($files as $file) {
+ // set the register slots
+
+ $slot->setValue($file->getPath());
+ $basenameSlot->setValue($file->getName());
+
+ // 1) read contents of file, pulling through any filters
+ $in = null;
+ try {
+ $contents = "";
+ $in = FileUtils::getChainedReader(new FileReader($file), $filters, $this->project);
+ while(-1 !== ($buffer = $in->read())) {
+ $contents .= $buffer;
+ }
+ $in->close();
+ } catch (Exception $e) {
+ if ($in) $in->close();
+ $this->log("Error reading file: " . $e->getMessage(), Project::MSG_WARN);
+ }
+
+ try {
+ // now create a FileWriter w/ the same file, and write to the file
+ $out = new FileWriter($file);
+ $out->write($contents);
+ $out->close();
+ $this->log("Applying regexp processing to " . $file->getPath(), Project::MSG_VERBOSE);
+ } catch (Exception $e) {
+ if ($out) $out->close();
+ $this->log("Error writing file back: " . $e->getMessage(), Project::MSG_WARN);
+ }
+
+ }
+
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ScpTask.php b/buildscripts/phing/classes/phing/tasks/ext/ScpTask.php
new file mode 100644
index 00000000..f6ceadd1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/ScpTask.php
@@ -0,0 +1,380 @@
+<?php
+/*
+ * $Id: 300efdab5b721c6312491450bc2ba93ffc8124b4 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Copy files to and from a remote host using scp.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @author Johan Van den Brande <johan@vandenbrande.com>
+ * @version $Id: 300efdab5b721c6312491450bc2ba93ffc8124b4 $
+ * @package phing.tasks.ext
+ */
+
+class ScpTask extends Task
+{
+ protected $file = "";
+ protected $filesets = array(); // all fileset objects assigned to this task
+ protected $todir = "";
+ protected $mode = null;
+
+ protected $host = "";
+ protected $port = 22;
+ protected $username = "";
+ protected $password = "";
+ protected $autocreate = true;
+ protected $fetch = false;
+ protected $localEndpoint = "";
+ protected $remoteEndpoint = "";
+
+ protected $pubkeyfile = '';
+ protected $privkeyfile = '';
+ protected $privkeyfilepassphrase = '';
+
+ protected $connection = null;
+ protected $sftp = null;
+
+ protected $count = 0;
+
+ protected $logLevel = Project::MSG_VERBOSE;
+
+ /**
+ * Sets the remote host
+ */
+ public function setHost($h)
+ {
+ $this->host = $h;
+ }
+
+ /**
+ * Returns the remote host
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Sets the remote host port
+ */
+ public function setPort($p)
+ {
+ $this->port = $p;
+ }
+
+ /**
+ * Returns the remote host port
+ */
+ public function getPort()
+ {
+ return $this->port;
+ }
+
+ /**
+ * Sets the mode value
+ */
+ public function setMode($value)
+ {
+ $this->mode = $value;
+ }
+
+ /**
+ * Returns the mode value
+ */
+ public function getMode()
+ {
+ return $this->mode;
+ }
+
+ /**
+ * Sets the username of the user to scp
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+
+ /**
+ * Returns the username
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ /**
+ * Sets the password of the user to scp
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+
+ /**
+ * Returns the password
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * Sets the public key file of the user to scp
+ */
+ public function setPubkeyfile($pubkeyfile)
+ {
+ $this->pubkeyfile = $pubkeyfile;
+ }
+
+ /**
+ * Returns the pubkeyfile
+ */
+ public function getPubkeyfile()
+ {
+ return $this->pubkeyfile;
+ }
+
+ /**
+ * Sets the private key file of the user to scp
+ */
+ public function setPrivkeyfile($privkeyfile)
+ {
+ $this->privkeyfile = $privkeyfile;
+ }
+
+ /**
+ * Returns the private keyfile
+ */
+ public function getPrivkeyfile()
+ {
+ return $this->privkeyfile;
+ }
+
+ /**
+ * Sets the private key file passphrase of the user to scp
+ */
+ public function setPrivkeyfilepassphrase($privkeyfilepassphrase)
+ {
+ $this->privkeyfilepassphrase = $privkeyfilepassphrase;
+ }
+
+ /**
+ * Returns the private keyfile passphrase
+ */
+ public function getPrivkeyfilepassphrase($privkeyfilepassphrase)
+ {
+ return $this->privkeyfilepassphrase;
+ }
+
+ /**
+ * Sets whether to autocreate remote directories
+ */
+ public function setAutocreate($autocreate)
+ {
+ $this->autocreate = (bool) $autocreate;
+ }
+
+ /**
+ * Returns whether to autocreate remote directories
+ */
+ public function getAutocreate()
+ {
+ return $this->autocreate;
+ }
+
+ /**
+ * Set destination directory
+ */
+ public function setTodir($todir)
+ {
+ $this->todir = $todir;
+ }
+
+ /**
+ * Returns the destination directory
+ */
+ public function getTodir()
+ {
+ return $this->todir;
+ }
+
+ /**
+ * Sets local filename
+ */
+ public function setFile($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Returns local filename
+ */
+ public function getFile()
+ {
+ return $this->file;
+ }
+
+ /**
+ * Sets whether to send (default) or fetch files
+ */
+ public function setFetch($fetch)
+ {
+ $this->fetch = (bool) $fetch;
+ }
+
+ /**
+ * Returns whether to send (default) or fetch files
+ */
+ public function getFetch()
+ {
+ return $this->fetch;
+ }
+
+ /**
+ * 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];
+ }
+
+ /**
+ * Set level of log messages generated (default = verbose)
+ * @param string $level
+ */
+ public function setLevel($level)
+ {
+ switch ($level)
+ {
+ case "error": $this->logLevel = Project::MSG_ERR; break;
+ case "warning": $this->logLevel = Project::MSG_WARN; break;
+ case "info": $this->logLevel = Project::MSG_INFO; break;
+ case "verbose": $this->logLevel = Project::MSG_VERBOSE; break;
+ case "debug": $this->logLevel = Project::MSG_DEBUG; break;
+ }
+ }
+
+ public function init()
+ {
+ }
+
+ public function main()
+ {
+ if (!function_exists('ssh2_connect')) {
+ throw new BuildException("To use ScpTask, you need to install the PHP SSH2 extension.");
+ }
+
+ if ($this->file == "" && empty($this->filesets)) {
+ throw new BuildException("Missing either a nested fileset or attribute 'file'");
+ }
+
+ if ($this->host == "" || $this->username == "") {
+ throw new BuildException("Attribute 'host' and 'username' must be set");
+ }
+
+ $this->connection = ssh2_connect($this->host, $this->port);
+ if (is_null($this->connection)) {
+ throw new BuildException("Could not establish connection to " . $this->host . ":" . $this->port . "!");
+ }
+
+ $could_auth = null;
+ if ( $this->pubkeyfile ) {
+ $could_auth = ssh2_auth_pubkey_file($this->connection, $this->username, $this->pubkeyfile, $this->privkeyfile, $this->privkeyfilepassphrase);
+ } else {
+ $could_auth = ssh2_auth_password($this->connection, $this->username, $this->password);
+ }
+ if (!$could_auth) {
+ throw new BuildException("Could not authenticate connection!");
+ }
+
+ // prepare sftp resource
+ if ($this->autocreate) {
+ $this->sftp = ssh2_sftp($this->connection);
+ }
+
+ if ($this->file != "") {
+ $this->copyFile($this->file, basename($this->file));
+ } else {
+ if ($this->fetch) {
+ throw new BuildException("Unable to use filesets to retrieve files from remote server");
+ }
+
+ foreach($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $files = $ds->getIncludedFiles();
+ $dir = $fs->getDir($this->project)->getPath();
+ foreach($files as $file) {
+ $path = $dir.DIRECTORY_SEPARATOR.$file;
+
+ // Translate any Windows paths
+ $this->copyFile($path, strtr($file, '\\', '/'));
+ }
+ }
+ }
+
+ $this->log("Copied " . $this->counter . " file(s) " . ($this->fetch ? "from" : "to") . " '" . $this->host . "'");
+
+ // explicitly close ssh connection
+ @ssh2_exec($this->connection, 'exit');
+ }
+
+ protected function copyFile($local, $remote)
+ {
+ $path = rtrim($this->todir, "/") . "/";
+
+ if ($this->fetch) {
+ $localEndpoint = $path . $remote;
+ $remoteEndpoint = $local;
+
+ $this->log('Will fetch ' . $remoteEndpoint . ' to ' . $localEndpoint, $this->logLevel);
+
+ $ret = @ssh2_scp_recv($this->connection, $remoteEndpoint, $localEndpoint);
+
+ if ($ret === false) {
+ throw new BuildException("Could not fetch remote file '" . $remoteEndpoint . "'");
+ }
+ } else {
+ $localEndpoint = $local;
+ $remoteEndpoint = $path . $remote;
+
+ if ($this->autocreate) {
+ ssh2_sftp_mkdir($this->sftp, dirname($remoteEndpoint), (is_null($this->mode) ? 0777 : $this->mode), true);
+ }
+
+ $this->log('Will copy ' . $localEndpoint . ' to ' . $remoteEndpoint, $this->logLevel);
+
+ if (!is_null($this->mode)) {
+ $ret = @ssh2_scp_send($this->connection, $localEndpoint, $remoteEndpoint, $this->mode);
+ } else {
+ $ret = @ssh2_scp_send($this->connection, $localEndpoint, $remoteEndpoint);
+ }
+
+ if ($ret === false) {
+ throw new BuildException("Could not create remote file '" . $remoteEndpoint . "'");
+ }
+ }
+
+ $this->counter++;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon.php b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon.php
new file mode 100644
index 00000000..6e8fa8e0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon.php
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * $Id: 81e9d8cbc94bac15a6a32ed0bb23c04d2b0ff439 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <andrei@serdeliuc.ro>
+ * @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
+ * @access protected
+ */
+ protected $_options = array();
+
+ 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
+ *
+ * @access public
+ * @param mixed $var
+ * @return void
+ */
+ 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];
+ }
+
+ public function __isset($var)
+ {
+ return array_key_exists($var, $this->_options);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3.php b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3.php
new file mode 100644
index 00000000..7bed642e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * $Id: a205dcffd1f42b70a8101808242d66620e3dabbd $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once dirname(dirname(__FILE__)) . "/Amazon.php";
+
+/**
+ * Abstract Service_Amazon_S3 class.
+ *
+ * Provides common methods and properties to all of the S3 tasks
+ *
+ * @extends Service_Amazon
+ * @version $ID$
+ * @package phing.tasks.ext
+ * @author Andrei Serdeliuc <andrei@serdeliuc.ro>
+ * @abstract
+ */
+abstract class Service_Amazon_S3 extends Service_Amazon
+{
+ /**
+ * Services_Amazon_S3 client
+ *
+ * (default value: null)
+ *
+ * @var Services_Amazon_S3
+ * @see Services_Amazon_S3
+ * @access protected
+ */
+ protected $_client = null;
+
+ /**
+ * We only instantiate the client once per task call
+ *
+ * @access public
+ * @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;
+ }
+
+ public function setBucket($bucket)
+ {
+ if(empty($bucket) || !is_string($bucket)) {
+ throw new BuildException('Bucket must be a non-empty string');
+ }
+
+ $this->bucket = (string) $bucket;
+ }
+
+ 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
+ *
+ * @access public
+ * @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
+ *
+ * @access public
+ * @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
+ *
+ * @access public
+ * @return Services_Amazon_S3_Resource_Bucket
+ */
+ public function getBucketInstance()
+ {
+ return $this->getClient()->getBucket($this->getBucket());
+ }
+
+ /**
+ * Check if the current bucket is available
+ *
+ * @access public
+ * @return bool
+ */
+ public function isBucketAvailable()
+ {
+ return (bool) $this->getBucketInstance($this->getBucket())->load();
+ }
+
+ /**
+ * Get the contents of an object (by it's name)
+ *
+ * @access public
+ * @param string $object
+ * @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
+ *
+ * @access public
+ * @return void
+ */
+ public function createBucket()
+ {
+ $bucket = $this->getBucketInstance();
+ $bucket->name = $this->getBucket();
+ $bucket->save();
+
+ return $this->isBucketAvailable();
+ }
+
+ /**
+ * Main entry point, doesn't do anything
+ *
+ * @access public
+ * @final
+ * @return void
+ */
+ final public function main()
+ {
+ $this->execute();
+ }
+
+ /**
+ * Entry point to children tasks
+ *
+ * @access public
+ * @abstract
+ * @return void
+ */
+ abstract public function execute();
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3GetTask.php b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3GetTask.php
new file mode 100644
index 00000000..37b4e817
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3GetTask.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * $Id: 214ed107be71d8dbc0f68ffc90bfd8b11a76b36d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once dirname(dirname(__FILE__)) . '/S3.php';
+
+/**
+ * Downloads an object off S3
+ *
+ * @version $Id: 214ed107be71d8dbc0f68ffc90bfd8b11a76b36d $
+ * @package phing.tasks.ext
+ * @author Andrei Serdeliuc <andrei@serdeliuc.ro>
+ * @extends Service_Amazon_S3
+ */
+class S3GetTask extends Service_Amazon_S3
+{
+ /**
+ * This is where we'll store the object
+ *
+ * (default value: null)
+ *
+ * @var mixed
+ * @access protected
+ */
+ protected $_target = null;
+
+ /**
+ * The S3 object we're working with
+ *
+ * (default value: null)
+ *
+ * @var mixed
+ * @access protected
+ */
+ protected $_object = null;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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()));
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3PutTask.php b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3PutTask.php
new file mode 100644
index 00000000..dbb18b56
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/Service/Amazon/S3/S3PutTask.php
@@ -0,0 +1,243 @@
+<?php
+/*
+ * $Id: 84b1d6039427591cbf43dbe1a82691063ae4238a $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once dirname(dirname(__FILE__)) . '/S3.php';
+
+/**
+ * Stores an object on S3
+ *
+ * @version $Id: 84b1d6039427591cbf43dbe1a82691063ae4238a $
+ * @package phing.tasks.ext
+ * @author Andrei Serdeliuc <andrei@serdeliuc.ro>
+ * @extends Service_Amazon_S3
+ */
+class S3PutTask extends Service_Amazon_S3
+{
+ /**
+ * File we're trying to upload
+ *
+ * (default value: null)
+ *
+ * @var string
+ * @access protected
+ */
+ 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
+ * @access protected
+ */
+ protected $_content = null;
+
+ /**
+ * Collection of filesets
+ * Used for uploading multiple files
+ *
+ * (default value: array())
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_filesets = array();
+
+ /**
+ * Whether to try to create buckets or not
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access protected
+ */
+ protected $_createBuckets = false;
+
+ public function setSource($source)
+ {
+ if(!is_readable($source)) {
+ throw new BuildException('Source is not readable: ' . $source);
+ }
+
+ $this->_source = $source;
+ }
+
+ public function getSource()
+ {
+ if($this->_source === null) {
+ throw new BuildException('Source is not set');
+ }
+
+ return $this->_source;
+ }
+
+ public function setContent($content)
+ {
+ if(empty($content) || !is_string($content)) {
+ throw new BuildException('Content must be a non-empty string');
+ }
+
+ $this->_content = $content;
+ }
+
+ public function getContent()
+ {
+ if($this->_content === null) {
+ throw new BuildException('Content is not set');
+ }
+
+ return $this->_content;
+ }
+
+ 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;
+ }
+
+ public function setCreateBuckets($createBuckets)
+ {
+ $this->_createBuckets = (bool) $createBuckets;
+ }
+
+ public function getCreateBuckets()
+ {
+ return (bool) $this->_createBuckets;
+ }
+
+ /**
+ * creator for _filesets
+ *
+ * @access public
+ * @return FileSet
+ */
+ public function createFileset()
+ {
+ $num = array_push($this->_filesets, new FileSet());
+ return $this->_filesets[$num-1];
+ }
+
+ /**
+ * getter for _filesets
+ *
+ * @access public
+ * @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
+ *
+ * @access public
+ * @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
+ *
+ * @access public
+ * @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();
+
+ foreach($objects as $object) {
+ $this->saveObject($object, file_get_contents($fromDir . DIRECTORY_SEPARATOR . $object));
+ }
+
+ return true;
+ }
+
+ $this->saveObject($this->getObject(), $this->getObjectData());
+ }
+
+ protected function saveObject($object, $data)
+ {
+ $object = $this->getObjectInstance($object);
+ $object->data = $data;
+ $object->save();
+
+ if(!$this->isObjectAvailable($object->key)) {
+ throw new BuildException('Upload failed');
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/SmartyTask.php b/buildscripts/phing/classes/phing/tasks/ext/SmartyTask.php
index 97eada3d..69c7b8f8 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/SmartyTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/SmartyTask.php
@@ -1,7 +1,7 @@
<?php
/*
- * $Id: SmartyTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 1fe8b2aa2668db628554e59b3099520c0e1c03e4 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -37,7 +37,7 @@ include_once 'phing/util/StringHelper.php';
* @author Hans Lellelid <hans@xmpl.org> (SmartyTask)
* @author Jason van Zyl <jvanzyl@apache.org> (TexenTask)
* @author Robert Burrell Donkin <robertdonkin@mac.com>
- * @version $Id: SmartyTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @version $Id: 1fe8b2aa2668db628554e59b3099520c0e1c03e4 $
* @package phing.tasks.ext
*/
class SmartyTask extends Task {
@@ -233,7 +233,7 @@ class SmartyTask extends Task {
public function setOutputDirectory(PhingFile $outputDirectory) {
try {
if (!$outputDirectory->exists()) {
- $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE);
+ $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());
}
@@ -494,7 +494,7 @@ class SmartyTask extends Task {
$smartyCompilePath = new PhingFile($this->context->compile_dir);
if (!$smartyCompilePath->exists()) {
- $this->log("Compile directory does not exist, creating: " . $smartyCompilePath->getPath(), PROJECT_MSG_VERBOSE);
+ $this->log("Compile directory does not exist, creating: " . $smartyCompilePath->getPath(), Project::MSG_VERBOSE);
if (!$smartyCompilePath->mkdirs()) {
throw new BuildException("Smarty needs a place to compile templates; specify a 'compilePath' or create ".$this->context->compile_dir);
}
@@ -543,7 +543,7 @@ class SmartyTask extends Task {
// reset value, and then
// read in teh contents of the file into that var
$value = "";
- $f = new PhingFile($project->resolveFile($value)->getCanonicalPath());
+ $f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath());
if ($f->exists()) {
try {
$fr = new FileReader($f);
diff --git a/buildscripts/phing/classes/phing/tasks/ext/SshTask.php b/buildscripts/phing/classes/phing/tasks/ext/SshTask.php
new file mode 100644
index 00000000..9c2349a8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/SshTask.php
@@ -0,0 +1,224 @@
+<?php
+/*
+ * $Id: e0fe77ed287d359bd7449d459769370e6192417f $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Execute commands on a remote host using ssh.
+ *
+ * @author Johan Van den Brande <johan@vandenbrande.com>
+ * @version $Id: e0fe77ed287d359bd7449d459769370e6192417f $
+ * @package phing.tasks.ext
+ */
+class SshTask extends Task {
+
+ private $host = "";
+ private $port = 22;
+ private $username = "";
+ private $password = "";
+ private $command = "";
+ private $pubkeyfile = '';
+ private $privkeyfile = '';
+ private $privkeyfilepassphrase = '';
+
+ /**
+ * The name of the property to capture (any) output of the command
+ * @var string
+ */
+ private $property = "";
+
+ /**
+ * Whether to display the output of the command
+ * @var boolean
+ */
+ private $display = true;
+
+ public function setHost($host)
+ {
+ $this->host = $host;
+ }
+
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ public function setPort($port)
+ {
+ $this->port = $port;
+ }
+
+ public function getPort()
+ {
+ return $this->port;
+ }
+
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * Sets the public key file of the user to scp
+ */
+ public function setPubkeyfile($pubkeyfile)
+ {
+ $this->pubkeyfile = $pubkeyfile;
+ }
+
+ /**
+ * Returns the pubkeyfile
+ */
+ public function getPubkeyfile()
+ {
+ return $this->pubkeyfile;
+ }
+
+ /**
+ * Sets the private key file of the user to scp
+ */
+ public function setPrivkeyfile($privkeyfile)
+ {
+ $this->privkeyfile = $privkeyfile;
+ }
+
+ /**
+ * Returns the private keyfile
+ */
+ public function getPrivkeyfile()
+ {
+ return $this->privkeyfile;
+ }
+
+ /**
+ * Sets the private key file passphrase of the user to scp
+ */
+ public function setPrivkeyfilepassphrase($privkeyfilepassphrase)
+ {
+ $this->privkeyfilepassphrase = $privkeyfilepassphrase;
+ }
+
+ /**
+ * Returns the private keyfile passphrase
+ */
+ public function getPrivkeyfilepassphrase($privkeyfilepassphrase)
+ {
+ return $this->privkeyfilepassphrase;
+ }
+
+ public function setCommand($command)
+ {
+ $this->command = $command;
+ }
+
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * Sets the name of the property to capture (any) output of the command
+ * @param string $property
+ */
+ public function setProperty($property)
+ {
+ $this->property = $property;
+ }
+
+ /**
+ * Sets whether to display the output of the command
+ * @param boolean $display
+ */
+ public function setDisplay($display)
+ {
+ $this->display = (boolean) $display;
+ }
+
+ public function init()
+ {
+ }
+
+ public function main()
+ {
+ if (!function_exists('ssh2_connect')) {
+ throw new BuildException("To use SshTask, you need to install the PHP SSH2 extension.");
+ }
+
+ $this->connection = ssh2_connect($this->host, $this->port);
+ if (is_null($this->connection)) {
+ throw new BuildException("Could not establish connection to " . $this->host . ":" . $this->port . "!");
+ }
+
+ $could_auth = null;
+ if ( $this->pubkeyfile ) {
+ $could_auth = ssh2_auth_pubkey_file($this->connection, $this->username, $this->pubkeyfile, $this->privkeyfile, $this->privkeyfilepassphrase);
+ } else {
+ $could_auth = ssh2_auth_password($this->connection, $this->username, $this->password);
+ }
+ if (!$could_auth) {
+ throw new BuildException("Could not authenticate connection!");
+ }
+
+ $stream = ssh2_exec($this->connection, $this->command);
+ if (!$stream) {
+ throw new BuildException("Could not execute command!");
+ }
+
+ $this->log("Executing command {$this->command}", Project::MSG_VERBOSE);
+
+ stream_set_blocking($stream, true);
+ $result = stream_get_contents($stream);
+
+ if (!strlen($result)) {
+ $stderr_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
+ stream_set_blocking($stderr_stream, true);
+ $result = stream_get_contents($stderr_stream);
+ }
+
+ if ($this->display) {
+ print($result);
+ }
+
+ if (!empty($this->property)) {
+ $this->project->setProperty($this->property, $result);
+ }
+
+ fclose($stream);
+ if (isset($stderr_stream)) {
+ fclose($stderr_stream);
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/Arg.php b/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/Arg.php
new file mode 100644
index 00000000..564fdef4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/Arg.php
@@ -0,0 +1,96 @@
+<?php
+require_once "phing/types/DataType.php";
+
+
+/**
+ * Implementation of console argument
+ *
+ * @author nuno costa <nuno@francodacosta.com>
+ * @license GPL
+ */
+class Arg extends DataType
+{
+ private $name = null;
+ private $value = null;
+ private $quotes = false;
+
+ /**
+ * Gets the argment name
+ * @return String
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the argument name
+ * @param String $name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the argument value
+ * @return String
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Sets the argument value
+ * @param String $value
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Should the argument value be enclosed in double quotes
+ * @return boolean
+ */
+ public function getQuotes()
+ {
+ return $this->quotes;
+ }
+
+ /**
+ * Should the argument value be enclosed in double quotes
+ * @param boolean $quotes
+ */
+ public function setQuotes( $quotes)
+ {
+ $this->quotes = $quotes;
+ }
+
+ /**
+ * Transforms the argument object into a string, takes into consideration
+ * the quotes and the argument value
+ * @return String
+ */
+ public function __toString()
+ {
+ $name = "";
+ $value = "";
+ $quote = $this->getQuotes() ? '"' : '';
+
+ if (!is_null($this->getValue())) {
+ $value = $quote . $this->getValue() . $quote ;
+ }
+
+ if (!is_null($this->getName())) {
+ $name = '--' . $this->getName();
+ }
+
+ if (strlen($name) > 0 && strlen($value) > 0) {
+ $value = '=' . $value;
+ }
+ return $name . ' ' . $value;
+ }
+
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/SymfonyConsoleTask.php b/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/SymfonyConsoleTask.php
new file mode 100644
index 00000000..64c1f02b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/SymfonyConsole/SymfonyConsoleTask.php
@@ -0,0 +1,113 @@
+<?php
+require_once "phing/Task.php";
+require_once dirname(__FILE__) . "/Arg.php";
+/**
+ * Symfony Console Task
+ * @author nuno costa <nuno@francodacosta.com>
+ * @license GPL
+ *
+ */
+class SymfonyConsoleTask extends Task
+{
+
+ /**
+ *
+ * @var Array of Arg a collection of Arg objects
+ */
+ private $args = array();
+
+ /**
+ *
+ * @var string the Symfony console command to execute
+ */
+ private $command = null;
+
+ /**
+ *
+ * @var string path to symfony console application
+ */
+ private $console = 'app/console';
+
+
+ /**
+ * sets the symfony console command to execute
+ * @param string $command
+ */
+ public function setCommand($command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * return the symfony console command to execute
+ * @return String
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * sets the path to symfony console application
+ * @param string $console
+ */
+ public function setConsole($console)
+ {
+ $this->console = $console;
+ }
+
+ /**
+ * returns the path to symfony console application
+ * @return string
+ */
+ public function getConsole()
+ {
+ return $this->console;
+ }
+
+ /**
+ * appends an arg tag to the arguments stack
+ *
+ * @return Arg Argument object
+ */
+
+ public function createArg()
+ {
+ $num = array_push($this->args, new Arg());
+ return $this->args[$num-1];
+ }
+
+ /**
+ * return the argumments passed to this task
+ * @return array of Arg()
+ */
+ public function getArgs()
+ {
+ return $this->args;
+ }
+
+
+ /**
+ * Gets the command string to be executed
+ * @return string
+ */
+ public function getCmdString() {
+ $cmd = array(
+ $this->console,
+ $this->command,
+ implode(' ', $this->args)
+ );
+ $cmd = implode(' ', $cmd);
+ return $cmd;
+ }
+ /**
+ * executes the synfony consile application
+ */
+ public function main()
+ {
+ $cmd = $this->getCmdString();
+
+ $this->log("executing $cmd");
+ passthru ($cmd);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/SymlinkTask.php b/buildscripts/phing/classes/phing/tasks/ext/SymlinkTask.php
new file mode 100644
index 00000000..57738398
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/SymlinkTask.php
@@ -0,0 +1,309 @@
+<?php
+
+/*
+ * $Id: 6efb50d5b7cb94f2f22db6e876010e718aa25b22 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once "phing/Task.php";
+
+/**
+ * Generates symlinks based on a target / link combination.
+ * Can also symlink contents of a directory, individually
+ *
+ * Single target symlink example:
+ * <code>
+ * <symlink target="/some/shared/file" link="${project.basedir}/htdocs/my_file" />
+ * </code>
+ *
+ * Symlink entire contents of directory
+ *
+ * This will go through the contents of "/my/shared/library/*"
+ * and create a symlink for each entry into ${project.basedir}/library/
+ * <code>
+ * <symlink link="${project.basedir}/library">
+ * <fileset dir="/my/shared/library">
+ * <include name="*" />
+ * </fileset>
+ * </symlink>
+ * </code>
+ *
+ * @author Andrei Serdeliuc <andrei@serdeliuc.ro>
+ * @extends Task
+ * @version $ID$
+ * @package phing.tasks.ext
+ */
+class SymlinkTask extends Task
+{
+ /**
+ * What we're symlinking from
+ *
+ * (default value: null)
+ *
+ * @var string
+ * @access private
+ */
+ private $_target = null;
+
+ /**
+ * Symlink location
+ *
+ * (default value: null)
+ *
+ * @var string
+ * @access private
+ */
+ private $_link = null;
+
+ /**
+ * Collection of filesets
+ * Used when linking contents of a directory
+ *
+ * (default value: array())
+ *
+ * @var array
+ * @access private
+ */
+ private $_filesets = array();
+
+ /**
+ * Whether to override the symlink if it exists but points
+ * to a different location
+ *
+ * (default value: false)
+ *
+ * @var boolean
+ * @access private
+ */
+ private $_overwrite = false;
+
+ /**
+ * setter for _target
+ *
+ * @access public
+ * @param string $target
+ * @return void
+ */
+ public function setTarget($target)
+ {
+ $this->_target = $target;
+ }
+
+ /**
+ * setter for _link
+ *
+ * @access public
+ * @param string $link
+ * @return void
+ */
+ public function setLink($link)
+ {
+ $this->_link = $link;
+ }
+
+ /**
+ * creator for _filesets
+ *
+ * @access public
+ * @return FileSet
+ */
+ public function createFileset()
+ {
+ $num = array_push($this->_filesets, new FileSet());
+ return $this->_filesets[$num-1];
+ }
+
+ /**
+ * setter for _overwrite
+ *
+ * @access public
+ * @param boolean $overwrite
+ * @return void
+ */
+ public function setOverwrite($overwrite)
+ {
+ $this->_overwrite = $overwrite;
+ }
+
+ /**
+ * getter for _target
+ *
+ * @access public
+ * @return string
+ */
+ public function getTarget()
+ {
+ if($this->_target === null) {
+ throw new BuildException('Target not set');
+ }
+
+ return $this->_target;
+ }
+
+ /**
+ * getter for _link
+ *
+ * @access public
+ * @return string
+ */
+ public function getLink()
+ {
+ if($this->_link === null) {
+ throw new BuildException('Link not set');
+ }
+
+ return $this->_link;
+ }
+
+ /**
+ * getter for _filesets
+ *
+ * @access public
+ * @return array
+ */
+ public function getFilesets()
+ {
+ return $this->_filesets;
+ }
+
+ /**
+ * getter for _overwrite
+ *
+ * @access public
+ * @return boolean
+ */
+ public function getOverwrite()
+ {
+ return $this->_overwrite;
+ }
+
+ /**
+ * Generates an array of directories / files to be linked
+ * If _filesets is empty, returns getTarget()
+ *
+ * @access protected
+ * @return array|string
+ */
+ protected function getMap()
+ {
+ $fileSets = $this->getFilesets();
+
+ // No filesets set
+ // We're assuming single file / directory
+ if(empty($fileSets)) {
+ return $this->getTarget();
+ }
+
+ $targets = array();
+
+ foreach($fileSets as $fs) {
+ if(!($fs instanceof FileSet)) {
+ continue;
+ }
+
+ // We need a directory to store the links
+ if(!is_dir($this->getLink())) {
+ throw new BuildException('Link must be an existing directory when using fileset');
+ }
+
+ $fromDir = $fs->getDir($this->getProject())->getAbsolutePath();
+
+ if(!is_dir($fromDir)) {
+ $this->log('Directory doesn\'t exist: ' . $fromDir, Project::MSG_WARN);
+ continue;
+ }
+
+ $fsTargets = array();
+
+ $ds = $fs->getDirectoryScanner($this->getProject());
+
+ $fsTargets = array_merge(
+ $fsTargets,
+ $ds->getIncludedDirectories(),
+ $ds->getIncludedFiles()
+ );
+
+ // Add each target to the map
+ foreach($fsTargets as $target) {
+ if(!empty($target)) {
+ $targets[$target] = $fromDir . DIRECTORY_SEPARATOR . $target;
+ }
+ }
+ }
+
+ return $targets;
+ }
+
+ /**
+ * Main entry point for task
+ *
+ * @access public
+ * @return bool
+ */
+ public function main()
+ {
+ $map = $this->getMap();
+
+ // Single file symlink
+ if(is_string($map)) {
+ return $this->symlink($map, $this->getLink());
+ }
+
+ // Multiple symlinks
+ foreach($map as $name => $targetPath) {
+ $this->symlink($targetPath, $this->getLink() . DIRECTORY_SEPARATOR . $name);
+ }
+
+ return true;
+ }
+
+ /**
+ * Create the actual link
+ *
+ * @access protected
+ * @param string $target
+ * @param string $link
+ * @return bool
+ */
+ protected function symlink($target, $link)
+ {
+ $fs = FileSystem::getFileSystem();
+
+ if (is_link($link) && readlink($link) == $target) {
+ $this->log('Link exists: ' . $link, Project::MSG_INFO);
+ return true;
+ } elseif (file_exists($link)) {
+ if (!$this->getOverwrite()) {
+ $this->log('Not overwriting existing link ' . $link, Project::MSG_ERR);
+ return false;
+ }
+
+ if (is_link($link) || is_file($link)) {
+ $fs->unlink($link);
+ $this->log('Link removed: ' . $link, Project::MSG_INFO);
+ } else {
+ $fs->rmdir($link, true);
+ $this->log('Directory removed: ' . $link, Project::MSG_INFO);
+ }
+ }
+
+ $this->log('Linking: ' . $target . ' to ' . $link, Project::MSG_INFO);
+
+ return $fs->symlink($target, $link);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/TarTask.php b/buildscripts/phing/classes/phing/tasks/ext/TarTask.php
index 8d6bb47f..95d915d7 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/TarTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/TarTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: TarTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: c3ac5fcdf4d7cdb199d57b021e3f015c9c7fd3f8 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -31,7 +31,7 @@ include_once 'phing/util/StringHelper.php';
* @author Stefano Mazzocchi <stefano@apache.org> (Ant)
* @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
* @author Magesh Umasankar
- * @version $Revision: 1.10 $
+ * @version $Id: c3ac5fcdf4d7cdb199d57b021e3f015c9c7fd3f8 $
* @package phing.tasks.ext
*/
class TarTask extends MatchingTask {
@@ -44,7 +44,8 @@ class TarTask extends MatchingTask {
private $tarFile;
private $baseDir;
-
+ private $includeEmpty = true; // Whether to include empty dirs in the TAR
+
private $longFileMode = "warn";
private $filesets = array();
@@ -59,6 +60,13 @@ class TarTask extends MatchingTask {
* Compression mode. Available options "gzip", "bzip2", "none" (null).
*/
private $compression = null;
+
+ /**
+ * File path prefix in the tar archive
+ *
+ * @var string
+ */
+ private $prefix = null;
/**
* Ensures that PEAR lib exists.
@@ -108,6 +116,16 @@ class TarTask extends MatchingTask {
}
/**
+ * Set the include empty dirs flag.
+ * @param boolean Flag if empty dirs should be tarred too
+ * @return void
+ * @access public
+ */
+ public function setIncludeEmptyDirs($bool) {
+ $this->includeEmpty = (boolean) $bool;
+ }
+
+ /**
* Set how to handle long files, those with a path&gt;100 chars.
* Optional, default=warn.
* <p>
@@ -145,10 +163,21 @@ class TarTask extends MatchingTask {
$this->compression = null;
break;
default:
- $this->log("Ignoring unknown compression mode: ".$mode, PROJECT_MSG_WARN);
+ $this->log("Ignoring unknown compression mode: ".$mode, Project::MSG_WARN);
$this->compression = null;
}
}
+
+ /**
+ * Sets the file path prefix for file in the tar file.
+ *
+ * @param string $prefix Prefix
+ *
+ * @return void
+ */
+ public function setPrefix($prefix) {
+ $this->prefix = $prefix;
+ }
/**
* do the work
@@ -175,13 +204,14 @@ class TarTask extends MatchingTask {
try {
if ($this->baseDir !== null) {
if (!$this->baseDir->exists()) {
- throw new BuildException("basedir does not exist!", $this->getLocation());
+ throw new BuildException("basedir '" . (string) $this->baseDir . "' does not exist!", $this->getLocation());
+ }
+ if (empty($this->filesets)) { // if there weren't any explicit filesets specivied, then
+ // create a default, all-inclusive fileset using the specified basedir.
+ $mainFileSet = new TarFileSet($this->fileset);
+ $mainFileSet->setDir($this->baseDir);
+ $this->filesets[] = $mainFileSet;
}
-
- // add the main fileset to the list of filesets to process.
- $mainFileSet = new TarFileSet($this->fileset);
- $mainFileSet->setDir($this->baseDir);
- $this->filesets[] = $mainFileSet;
}
if (empty($this->filesets)) {
@@ -190,27 +220,27 @@ class TarTask extends MatchingTask {
$this->getLocation());
}
- // check if tar is out of date with respect to each
- // fileset
- $upToDate = true;
- foreach($this->filesets as $fs) {
- $files = $fs->getFiles($this->project);
- if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) {
- $upToDate = false;
- }
- for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
- if ($this->tarFile->equals(new PhingFile($fs->getDir($this->project), $files[$i]))) {
- throw new BuildException("A tar file cannot include itself", $this->getLocation());
+ // check if tar is out of date with respect to each fileset
+ if($this->tarFile->exists()) {
+ $upToDate = true;
+ foreach($this->filesets as $fs) {
+ $files = $fs->getFiles($this->project, $this->includeEmpty);
+ if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) {
+ $upToDate = false;
+ }
+ for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
+ if ($this->tarFile->equals(new PhingFile($fs->getDir($this->project), $files[$i]))) {
+ throw new BuildException("A tar file cannot include itself", $this->getLocation());
+ }
}
}
+ if ($upToDate) {
+ $this->log("Nothing to do: " . $this->tarFile->__toString() . " is up to date.", Project::MSG_INFO);
+ return;
+ }
}
- if ($upToDate) {
- $this->log("Nothing to do: " . $this->tarFile->__toString() . " is up to date.", PROJECT_MSG_INFO);
- return;
- }
-
- $this->log("Building tar: " . $this->tarFile->__toString(), PROJECT_MSG_INFO);
+ $this->log("Building tar: " . $this->tarFile->__toString(), Project::MSG_INFO);
$tar = new Archive_Tar($this->tarFile->getAbsolutePath(), $this->compression);
@@ -218,25 +248,21 @@ class TarTask extends MatchingTask {
$tar->setErrorHandling(PEAR_ERROR_PRINT);
foreach($this->filesets as $fs) {
- $files = $fs->getFiles($this->project);
+ $files = $fs->getFiles($this->project, $this->includeEmpty);
if (count($files) > 1 && strlen($fs->getFullpath()) > 0) {
throw new BuildException("fullpath attribute may only "
. "be specified for "
. "filesets that specify a "
. "single file.");
}
- // FIXME
- // Current model is only adding directories implicitly. This
- // won't add any empty directories. Perhaps modify TarFileSet::getFiles()
- // to also include empty directories. Not high priority, since non-inclusion
- // of empty dirs is probably not unexpected behavior for TarTask.
$fsBasedir = $fs->getDir($this->project);
$filesToTar = array();
for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
$f = new PhingFile($fsBasedir, $files[$i]);
- $filesToTar[] = $f->getAbsolutePath();
+ $filesToTar[] = $f->getAbsolutePath();
+ $this->log("Adding file " . $f->getPath() . " to archive.", Project::MSG_VERBOSE);
}
- $tar->addModify($filesToTar, '', $fsBasedir->getAbsolutePath());
+ $tar->addModify($filesToTar, $this->prefix, $fsBasedir->getAbsolutePath());
}
@@ -270,6 +296,7 @@ class TarTask extends MatchingTask {
* Permissions are currently not implemented by PEAR Archive_Tar,
* but hopefully they will be in the future.
*
+ * @package phing.tasks.ext
*/
class TarFileSet extends FileSet {
@@ -288,11 +315,49 @@ class TarFileSet extends FileSet {
* @return array a list of file and directory names, relative to
* the baseDir for the project.
*/
- public function getFiles(Project $p) {
+ public function getFiles(Project $p, $includeEmpty = true) {
+
if ($this->files === null) {
+
$ds = $this->getDirectoryScanner($p);
$this->files = $ds->getIncludedFiles();
- }
+
+ if ($includeEmpty) {
+
+ // first any empty directories that will not be implicitly added by any of the files
+ $implicitDirs = array();
+ foreach($this->files as $file) {
+ $implicitDirs[] = dirname($file);
+ }
+
+ $incDirs = $ds->getIncludedDirectories();
+
+ // we'll need to add to that list of implicit dirs any directories
+ // that contain other *directories* (and not files), since otherwise
+ // we get duplicate directories in the resulting tar
+ foreach($incDirs as $dir) {
+ foreach($incDirs as $dircheck) {
+ if (!empty($dir) && $dir == dirname($dircheck)) {
+ $implicitDirs[] = $dir;
+ }
+ }
+ }
+
+ $implicitDirs = array_unique($implicitDirs);
+
+ // Now add any empty dirs (dirs not covered by the implicit dirs)
+ // to the files array.
+
+ foreach($incDirs as $dir) { // we cannot simply use array_diff() since we want to disregard empty/. dirs
+ if ($dir != "" && $dir != "." && !in_array($dir, $implicitDirs)) {
+ // it's an empty dir, so we'll add it.
+ $this->files[] = $dir;
+ }
+ }
+ } // if $includeEmpty
+
+ } // if ($this->files===null)
+
return $this->files;
}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/UntarTask.php b/buildscripts/phing/classes/phing/tasks/ext/UntarTask.php
new file mode 100644
index 00000000..74777322
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/UntarTask.php
@@ -0,0 +1,89 @@
+<?php
+/*
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/ExtractBaseTask.php';
+
+/**
+ * Extracts one or several tar archives using PEAR Archive_Tar
+ *
+ * @author Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @version $Id: f77612833e0415725e7b816a0515db4a4f0f4c93 $
+ * @package phing.tasks.ext
+ * @since 2.2.0
+ */
+class UntarTask extends ExtractBaseTask {
+
+ /**
+ * Ensures that PEAR lib exists.
+ */
+ public function init() {
+ include_once 'Archive/Tar.php';
+ if (!class_exists('Archive_Tar')) {
+ throw new BuildException("You must have installed the PEAR Archive_Tar class in order to use UntarTask.");
+ }
+ }
+
+ protected function extractArchive(PhingFile $tarfile)
+ {
+ $this->log("Extracting tar file: " . $tarfile->__toString() . ' to ' . $this->todir->__toString(), Project::MSG_INFO);
+
+ try {
+ $tar = $this->initTar($tarfile);
+ if(!$tar->extractModify($this->todir->getAbsolutePath(), $this->removepath)) {
+ throw new BuildException('Failed to extract tar file: ' . $tarfile->getAbsolutePath());
+ }
+ } catch (IOException $ioe) {
+ $msg = "Could not extract tar file: " . $ioe->getMessage();
+ throw new BuildException($msg, $ioe, $this->getLocation());
+ }
+ }
+
+ protected function listArchiveContent(PhingFile $tarfile)
+ {
+ $tar = $this->initTar($tarfile);
+ return $tar->listContent();
+ }
+
+ /**
+ * Init a Archive_Tar class with correct compression for the given file.
+ *
+ * @param PhingFile $tarfile
+ * @return Archive_Tar the tar class instance
+ */
+ private function initTar(PhingFile $tarfile)
+ {
+ $compression = null;
+ $tarfileName = $tarfile->getName();
+ $mode = strtolower(substr($tarfileName, strrpos($tarfileName, '.')));
+
+ $compressions = array(
+ 'gz' => array('.gz', '.tgz',),
+ 'bz2' => array('.bz2',),
+ );
+ foreach ($compressions as $algo => $ext) {
+ if (array_search($mode, $ext) !== false) {
+ $compression = $algo;
+ break;
+ }
+ }
+
+ return new Archive_Tar($tarfile->getAbsolutePath(), $compression);
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/UnzipTask.php b/buildscripts/phing/classes/phing/tasks/ext/UnzipTask.php
new file mode 100644
index 00000000..ef7c3e7d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/UnzipTask.php
@@ -0,0 +1,77 @@
+<?php
+/*
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/ExtractBaseTask.php';
+require_once 'phing/system/io/FileSystem.php';
+
+/**
+ * Extracts one or several zip archives using ZipArchive class.
+ *
+ * @author Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @author George Miroshnikov <laggy.luke@gmail.com>
+ * @version $Id: 9c4afd9af5e81250ca6c7afbc6e646c2a0f0148c $
+ * @package phing.tasks.ext
+ */
+class UnzipTask extends ExtractBaseTask
+{
+ /**
+ * Extract archive content into $this->todir directory
+ * @param PhingFile Zip file to extract
+ * @return boolean
+ */
+ protected function extractArchive(PhingFile $zipfile)
+ {
+ $this->log("Extracting zip: " . $zipfile->__toString() . ' to ' . $this->todir->__toString(), Project::MSG_INFO);
+
+ $zip = new ZipArchive();
+
+ $result = $zip->open($zipfile->getAbsolutePath());
+ if (!$result) {
+ $this->log("Unable to open zipfile " . $zipfile->__toString(), Project::MSG_ERR);
+ return false;
+ }
+
+ $result = $zip->extractTo($this->todir->getAbsolutePath());
+ if (!$result) {
+ $this->log("Unable to extract zipfile " . $zipfile->__toString(), Project::MSG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * List archive content
+ * @param PhingFile Zip file to list content
+ * @return array List of files inside $zipfile
+ */
+ protected function listArchiveContent(PhingFile $zipfile)
+ {
+ $zip = new ZipArchive();
+ $zip->open($zipfile->getAbsolutePath());
+
+ $content = array();
+ for ($i = 0; $i < $zip->numFiles; $i++) {
+ $content[] = $zip->getNameIndex($i);
+ }
+ return $content;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/VersionTask.php b/buildscripts/phing/classes/phing/tasks/ext/VersionTask.php
new file mode 100755
index 00000000..b8268870
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/VersionTask.php
@@ -0,0 +1,217 @@
+<?php
+/*
+ * $Id: 7fb6793b55e9c1c8c7b3cd8a87b694d720b32749 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+require_once 'phing/Task.php';
+
+/**
+ * VersionTask
+ *
+ * Increments a three-part version number from a given file
+ * and writes it back to the file.
+ * Incrementing is based on given releasetype, which can be one
+ * of Major, Minor and Bugfix.
+ * Resulting version number is also published under supplied property.
+ *
+ * @author Mike Wittje <mw@mike.wittje.de>
+ * @version $Id: 7fb6793b55e9c1c8c7b3cd8a87b694d720b32749 $ $Rev $Id$ $Author$
+ * @package phing.tasks.ext
+ */
+class VersionTask extends Task
+{
+ /**
+ * Property for Releasetype
+ * @var string $releasetype
+ */
+ private $releasetype;
+
+ /**
+ * Property for File
+ * @var PhingFile file
+ */
+ private $file;
+
+ /**
+ * Property to be set
+ * @var string $property
+ */
+ private $property;
+
+ /* Allowed Releastypes */
+ const RELEASETYPE_MAJOR = 'MAJOR';
+ const RELEASETYPE_MINOR = 'MINOR';
+ const RELEASETYPE_BUGFIX = 'BUGFIX';
+
+ /**
+ * Set Property for Releasetype (Minor, Major, Bugfix)
+ * @param string $releasetype
+ */
+ public function setReleasetype($releasetype)
+ {
+ $this->releasetype = strtoupper($releasetype);
+ }
+
+ /**
+ * Set Property for File containing versioninformation
+ * @param PhingFile $file
+ */
+ public function setFile($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Set name of property to be set
+ * @param $property
+ * @return void
+ */
+ public function setProperty($property)
+ {
+ $this->property = $property;
+ }
+
+ /**
+ * Main-Method for the Task
+ *
+ * @return void
+ * @throws BuildException
+ */
+ public function main()
+ {
+ // check supplied attributes
+ $this->checkReleasetype();
+ $this->checkFile();
+ $this->checkProperty();
+
+ // read file
+ $filecontent = trim(file_get_contents($this->file));
+
+ // get new version
+ $newVersion = $this->getVersion($filecontent);
+
+ // write new Version to file
+ file_put_contents($this->file, $newVersion . "\n");
+
+ // publish new version number as property
+ $this->project->setProperty($this->property, $newVersion);
+
+ }
+
+ /**
+ * Returns new version number corresponding to Release type
+ *
+ * @param string $filecontent
+ * @return string
+ */
+ private function getVersion($filecontent)
+ {
+ // init
+ $newVersion = '';
+
+ // Extract version
+ list($major, $minor, $bugfix) = explode(".", $filecontent);
+
+ // Return new version number
+ switch ($this->releasetype) {
+ case self::RELEASETYPE_MAJOR:
+ $newVersion = sprintf("%d.%d.%d", ++$major,
+ 0,
+ 0);
+ break;
+
+ case self::RELEASETYPE_MINOR:
+ $newVersion = sprintf("%d.%d.%d", $major,
+ ++$minor,
+ 0);
+ break;
+
+ case self::RELEASETYPE_BUGFIX:
+ $newVersion = sprintf("%d.%d.%d", $major,
+ $minor,
+ ++$bugfix);
+ break;
+ }
+
+ return $newVersion;
+ }
+
+
+ /**
+ * checks releasetype attribute
+ * @return void
+ * @throws BuildException
+ */
+ private function checkReleasetype()
+ {
+ // check Releasetype
+ if (is_null($this->releasetype)) {
+ throw new BuildException('releasetype attribute is required', $this->location);
+ }
+ // known releasetypes
+ $releaseTypes = array(
+ self::RELEASETYPE_MAJOR,
+ self::RELEASETYPE_MINOR,
+ self::RELEASETYPE_BUGFIX
+ );
+
+ if (!in_array($this->releasetype, $releaseTypes)) {
+ throw new BuildException(sprintf('Unknown Releasetype %s..Must be one of Major, Minor or Bugfix',
+ $this->releasetype), $this->location);
+ }
+ }
+
+ /**
+ * checks file attribute
+ * @return void
+ * @throws BuildException
+ */
+ private function checkFile()
+ {
+ // check File
+ if ($this->file === null ||
+ strlen($this->file) == 0) {
+ throw new BuildException('You must specify a file containing the version number', $this->location);
+ }
+
+ $content = file_get_contents($this->file);
+ if (strlen($content) == 0) {
+ throw new BuildException(sprintf('Supplied file %s is empty', $this->file), $this->location);
+ }
+
+ // check for three-part number
+ $split = explode('.', $content);
+ if (count($split) !== 3) {
+ throw new BuildException('Unknown version number format', $this->location);
+ }
+
+ }
+
+ /**
+ * checks property attribute
+ * @return void
+ * @throws BuildException
+ */
+ private function checkProperty()
+ {
+ if (is_null($this->property) ||
+ strlen($this->property) === 0) {
+ throw new BuildException('Property for publishing version number is not set', $this->location);
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/XmlLintTask.php b/buildscripts/phing/classes/phing/tasks/ext/XmlLintTask.php
index 866e954d..15200d37 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/XmlLintTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/XmlLintTask.php
@@ -1,10 +1,31 @@
<?php
+/*
+ * $Id: 6261b2f19844b353c379c46daf3ffb13b7a2ddb8 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
require_once 'phing/Task.php';
/**
* A XML lint task. Checking syntax of one or more XML files against an XML Schema using the DOM extension.
*
* @author Knut Urdalen <knut.urdalen@telio.no>
+ * @version $Id: 6261b2f19844b353c379c46daf3ffb13b7a2ddb8 $
* @package phing.tasks.ext
*/
class XmlLintTask extends Task {
@@ -12,6 +33,9 @@ class XmlLintTask extends Task {
protected $file; // the source file (from xml attribute)
protected $schema; // the schema file (from xml attribute)
protected $filesets = array(); // all fileset objects assigned to this task
+ protected $useRNG = false;
+
+ protected $haltonfailure = true;
/**
* File to be performed syntax check on
@@ -31,26 +55,42 @@ class XmlLintTask extends Task {
$this->schema = $schema;
}
+
+ /**
+ * Use RNG instead of DTD schema validation
+ *
+ * @param bool $bool
+ */
+ public function setUseRNG($bool) {
+ $this->useRNG = (boolean)$bool;
+ }
+
+
/**
* Nested creator, creates a FileSet for this task
*
* @return FileSet The created fileset object
*/
- function createFileSet() {
+ public function createFileSet() {
$num = array_push($this->filesets, new FileSet());
return $this->filesets[$num-1];
}
+
+ /**
+ * Sets the haltonfailure attribute
+ *
+ * @param bool $haltonfailure
+ */
+ public function setHaltonfailure($haltonfailure) {
+ $this->haltonfailure = (bool) $haltonfailure;
+ }
/**
* Execute lint check against PhingFile or a FileSet
*/
public function main() {
- if(!isset($this->schema)) {
- throw new BuildException("Missing attribute 'schema'");
- }
- $schema = $this->schema->getPath();
- if(!file_exists($schema)) {
- throw new BuildException("File not found: ".$schema);
+ if(isset($this->schema) && !file_exists($this->schema->getPath())) {
+ throw new BuildException("Schema file not found: ".$this->schema->getPath());
}
if(!isset($this->file) and count($this->filesets) == 0) {
throw new BuildException("Missing either a nested fileset or attribute 'file' set");
@@ -62,16 +102,24 @@ class XmlLintTask extends Task {
} 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);
- }
+ $ds = $fs->getDirectoryScanner($project);
+ $files = $ds->getIncludedFiles();
+ $dir = $fs->getDir($this->project)->getPath();
+ foreach($files as $file) {
+ $this->lint($dir.DIRECTORY_SEPARATOR.$file);
+ }
}
}
restore_error_handler();
}
+
+ protected function logError($message) {
+ if ($this->haltonfailure) {
+ throw new BuildException($message);
+ } else {
+ $this->log($message, Project::MSG_ERR);
+ }
+ }
/**
* Performs validation
@@ -81,19 +129,35 @@ class XmlLintTask extends Task {
*/
protected function lint($file) {
if(file_exists($file)) {
- if(is_readable($file)) {
- $dom = new DOMDocument();
- $dom->load($file);
- if($dom->schemaValidate($this->schema->getPath())) {
- $this->log($file.' validated', PROJECT_MSG_INFO);
- } else {
- $this->log($file.' fails to validate (See messages above)', PROJECT_MSG_ERR);
- }
+ if(is_readable($file)) {
+ $dom = new DOMDocument();
+ if ($dom->load($file) === false) {
+ $error = libxml_get_last_error();
+ $this->logError($file.' is not well-formed (See messages above)');
+ } else {
+ if(isset($this->schema)) {
+ if( $this->useRNG ) {
+ if($dom->relaxNGValidate($this->schema->getPath())) {
+ $this->log($file.' validated with RNG grammar', Project::MSG_INFO);
+ } else {
+ $this->logError($file.' fails to validate (See messages above)');
+ }
+ } else {
+ if($dom->schemaValidate($this->schema->getPath())) {
+ $this->log($file.' validated with schema', Project::MSG_INFO);
+ } else {
+ $this->logError($file.' fails to validate (See messages above)');
+ }
+ }
+ } else {
+ $this->log($file.' is well-formed (not validated due to missing schema specification)', Project::MSG_INFO);
+ }
+ }
} else {
- throw new BuildException('Permission denied: '.$file);
+ $this->logError('Permission denied to read file: '.$file);
}
} else {
- throw new BuildException('File not found: '.$file);
+ $this->logError('File not found: '.$file);
}
}
@@ -108,9 +172,8 @@ class XmlLintTask extends Task {
public function errorHandler($level, $message, $file, $line, $context) {
$matches = array();
preg_match('/^.*\(\): (.*)$/', $message, $matches);
- $this->log($matches[1], PROJECT_MSG_ERR);
+ $this->log($matches[1], Project::MSG_ERR);
}
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/XmlPropertyTask.php b/buildscripts/phing/classes/phing/tasks/ext/XmlPropertyTask.php
new file mode 100755
index 00000000..d32cd78e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/XmlPropertyTask.php
@@ -0,0 +1,273 @@
+<?php
+
+/*
+ * $Id: c7a3e7eff0b94828f9ec634c3612d89f2740fead $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/tasks/system/PropertyTask.php';
+
+/**
+ * Task for setting properties from an XML file in buildfiles.
+ *
+ * @author Jonathan Bond-Caron <jbondc@openmv.com>
+ * @version $Id: c7a3e7eff0b94828f9ec634c3612d89f2740fead $
+ * @package phing.tasks.ext
+ * @since 2.4.0
+ * @link http://ant.apache.org/manual/CoreTasks/xmlproperty.html
+ */
+class XmlPropertyTask extends PropertyTask {
+
+ private $_keepRoot = true;
+ private $_collapseAttr = false;
+ private $_delimiter = ',';
+ private $_required = false;
+
+ /** Set a file to use as the source for properties. */
+ public function setFile($file) {
+ if (is_string($file)) {
+ $file = new PhingFile($file);
+ }
+ $this->file = $file;
+ }
+
+ /** Get the PhingFile that is being used as property source. */
+ public function getFile() {
+ return $this->file;
+ }
+
+ /**
+ * Prefix to apply to properties loaded using <code>file</code>.
+ * A "." is appended to the prefix if not specified.
+ * @param string $prefix prefix string
+ * @return void
+ * @since 2.0
+ */
+ public function setPrefix($prefix) {
+ $this->prefix = $prefix;
+ if (!StringHelper::endsWith(".", $prefix)) {
+ $this->prefix .= ".";
+ }
+ }
+
+ /**
+ * @return string
+ * @since 2.0
+ */
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
+ /**
+ * Keep the xml root tag as the first value in the property name
+ *
+ * @param bool $yesNo
+ */
+ public function setKeepRoot($yesNo) {
+ $this->_keepRoot = (bool)$yesNo;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getKeepRoot() {
+ return $this->_keepRoot;
+ }
+
+ /**
+ * Treat attributes as nested elements.
+ *
+ * @param bool $yesNo
+ */
+ public function setCollapseAttributes($yesNo) {
+ $this->_collapseAttr = (bool)$yesNo;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getCollapseAttributes() {
+ return $this->_collapseAttr;
+ }
+
+ /**
+ * Delimiter for splitting multiple values.
+ *
+ * @param string $d
+ */
+ public function setDelimiter($d) {
+ $this->_delimiter = $d;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDelimiter() {
+ return $this->_delimiter;
+ }
+
+ /**
+ * File required or not.
+ *
+ * @param string $d
+ */
+ public function setRequired($d) {
+ $this->_required = $d;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRequired() {
+ return $this->_required;
+ }
+
+ /**
+ * set the property in the project to the value.
+ * if the task was give a file or env attribute
+ * here is where it is loaded
+ */
+ public function main() {
+
+ if ($this->file === null ) {
+ throw new BuildException("You must specify file to load properties from", $this->getLocation());
+ }
+
+ $this->loadFile($this->file);
+ }
+
+ /**
+ * load properties from an XML file.
+ * @param PhingFile $file
+ */
+ protected function loadFile(PhingFile $file) {
+ $props = new Properties();
+ $this->log("Loading ". $file->getAbsolutePath(), Project::MSG_INFO);
+ try { // try to load file
+ if ($file->exists()) {
+
+ $this->addProperties($this->_getProperties($file));
+
+ } else {
+ if ($this->getRequired()){
+ throw new BuildException("Could not load required properties file.", $ioe);
+ } else {
+ $this->log("Unable to find property file: ". $file->getAbsolutePath() ."... skipped", Project::MSG_WARN);
+ }
+ }
+ } catch (IOException $ioe) {
+ throw new BuildException("Could not load properties from file.", $ioe);
+ }
+ }
+
+ /**
+ * Parses an XML file and returns properties
+ *
+ * @param string $filePath
+ *
+ * @return Properties
+ */
+ protected function _getProperties($filePath) {
+
+ // load() already made sure that file is readable
+ // but we'll double check that when reading the file into
+ // an array
+
+ if (($lines = @file($filePath)) === false) {
+ throw new IOException("Unable to parse contents of $filePath");
+ }
+
+ $prop = new Properties;
+
+ $xml = simplexml_load_file($filePath);
+
+ if($xml === false)
+ throw new IOException("Unable to parse XML file $filePath");
+
+ $path = array();
+
+ if($this->_keepRoot) {
+ $path[] = dom_import_simplexml($xml)->tagName;
+
+ $prefix = implode('.', $path);
+
+ if (!empty($prefix))
+ $prefix .= '.';
+
+ // Check for attributes
+ foreach($xml->attributes() as $attribute => $val) {
+ if($this->_collapseAttr)
+ $prop->setProperty($prefix . "$attribute", (string)$val);
+ else
+ $prop->setProperty($prefix . "($attribute)", (string)$val);
+ }
+ }
+
+ $this->_addNode($xml, $path, $prop);
+
+ return $prop;
+ }
+
+ /**
+ * Adds an XML node
+ *
+ * @param SimpleXMLElement $node
+ * @param array $path Path to this node
+ * @param Properties $prop Properties will be added as they are found (by reference here)
+ *
+ * @return void
+ */
+ protected function _addNode($node, $path, $prop) {
+ foreach($node as $tag => $value) {
+
+ $prefix = implode('.', $path);
+
+ if (!empty($prefix) > 0)
+ $prefix .= '.';
+
+ // Check for attributes
+ foreach($value->attributes() as $attribute => $val) {
+ if($this->_collapseAttr)
+ $prop->setProperty($prefix . "$tag.$attribute", (string)$val);
+ else
+ $prop->setProperty($prefix . "$tag($attribute)", (string)$val);
+ }
+
+ // Add tag
+ if(count($value->children())) {
+ $this->_addNode($value, array_merge($path, array($tag)), $prop);
+ } else {
+ $val = (string)$value;
+
+ /* Check for * and ** on 'exclude' and 'include' tag / ant seems to do this? could use FileSet here
+ if($tag == 'exclude') {
+ }*/
+
+ // When property already exists, i.e. multiple xml tag
+ // <project>
+ // <exclude>file/a.php</exclude>
+ // <exclude>file/a.php</exclude>
+ // </project>
+ //
+ // Would be come project.exclude = file/a.php,file/a.php
+ $p = empty($prefix) ? $tag : $prefix . $tag;
+ $prop->append($p, (string)$val, $this->_delimiter);
+ }
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php b/buildscripts/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php
index 490ee797..5093fabe 100644
--- a/buildscripts/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php
@@ -1,4 +1,24 @@
<?php
+/*
+ * $Id: 5b7e3fb304bb5f406c919407d6881449a70b8a28 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
require_once 'phing/Task.php';
/**
@@ -6,7 +26,7 @@ require_once 'phing/Task.php';
*
* Available warnings:
* <b>zend-error</b> - %s(line %d): %s
- * <b>oneline-comment</b> - One-line comment ends with ?> tag.
+ * <b>oneline-comment</b> - One-line comment ends with tag.
* <b>bool-assign</b> - Assignment seen where boolean expression is expected. Did you mean '==' instead of '='?
* <b>bool-print</b> - Print statement used when boolean expression is expected.
* <b>bool-array</b> - Array used when boolean expression is expected.
@@ -38,126 +58,150 @@ require_once 'phing/Task.php';
* <b>empty-cond</b> - Condition without a body
* <b>expr-unused</b> - Expression result is never used
*
- * @author Knut Urdalen <knut.urdalen@telio.no>
+ * @author Knut Urdalen <knut.urdalen@gmail.com>
+ * @version $Id: 5b7e3fb304bb5f406c919407d6881449a70b8a28 $
* @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 $warnings = array();
- protected $counter = 0;
- protected $disable = array();
- protected $enable = array();
-
- /**
- * 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. Seperate warning levels with ','
- *
- * @param string $disable
- */
- public function setDisable($disable) {
- $this->disable = explode(",", $disable);
- }
-
- /**
- * Enable warning levels. Seperate warning levels with ','
- *
- * @param string $enable
- */
- public function setEnable($enable) {
- $this->enable = explode(",", $enable);
- }
-
- /**
- * Nested creator, creates a FileSet for this task
- *
- * @return FileSet The created fileset object
- */
- function createFileSet() {
- $num = array_push($this->filesets, new FileSet());
- return $this->filesets[$num-1];
- }
+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;
- /**
- * Analyze against PhingFile or a FileSet
- */
- public function main() {
- if(!isset($this->analyzerPath)) {
- throw new BuildException("Missing attribute 'analyzerPath'");
+ /**
+ * File to be analyzed
+ *
+ * @param PhingFile $file
+ */
+ public function setFile(PhingFile $file) {
+ $this->file = $file;
}
- if(!isset($this->file) and count($this->filesets) == 0) {
- throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+
+ /**
+ * Path to ZendCodeAnalyzer binary
+ *
+ * @param string $analyzerPath
+ */
+ public function setAnalyzerPath($analyzerPath) {
+ $this->analyzerPath = $analyzerPath;
+ }
+
+ /**
+ * Disable warning levels. Seperate warning levels with ','
+ *
+ * @param string $disable
+ */
+ public function setDisable($disable) {
+ $this->disable = explode(",", $disable);
+ }
+
+ /**
+ * Enable warning levels. Seperate 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;
}
- 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);
- }
- }
+ /**
+ * 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];
+ }
+
+ /**
+ * 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);
}
- $this->log("Number of findings: ".$this->counter, PROJECT_MSG_INFO);
- }
- /**
- * Analyze file
- *
- * @param string $file
- * @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);
- }
- } else {
- throw new BuildException('Permission denied: '.$file);
- }
- } else {
- throw new BuildException('File not found: '.$file);
+ /**
+ * Analyze file
+ *
+ * @param string $file
+ * @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);
+ }
}
- }
}
-
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ZipTask.php b/buildscripts/phing/classes/phing/tasks/ext/ZipTask.php
index 33ef16ae..72bf42fd 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/ZipTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/ZipTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: ZipTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 6997b3f3abffedf1b2efabc40c3b2d012b2379cb $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -23,31 +23,48 @@ 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';
-include_once 'phing/lib/Zip.php';
/**
- * Creates a zip archive using PEAR Archive_Zip (which is presently unreleased
- * and included with Phing).
+ * Creates a zip archive using PHP ZipArchive extension/
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Revision: 1.2 $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 6997b3f3abffedf1b2efabc40c3b2d012b2379cb $
* @package phing.tasks.ext
* @since 2.1.0
*/
class ZipTask extends MatchingTask {
+ /**
+ * @var PhingFile
+ */
private $zipFile;
+
+ /**
+ * @var PhingFile
+ */
private $baseDir;
-
+
+ /**
+ * Whether to include empty dirs in the archive.
+ */
+ private $includeEmpty = true;
+
private $filesets = array();
private $fileSetFiles = array();
/**
+ * File path prefix in zip archive
+ *
+ * @var string
+ */
+ private $prefix = null;
+
+ /**
* Add a new fileset.
* @return FileSet
*/
public function createFileSet() {
- $this->fileset = new FileSet();
+ $this->fileset = new ZipFileSet();
$this->filesets[] = $this->fileset;
return $this->fileset;
}
@@ -69,6 +86,27 @@ class ZipTask extends MatchingTask {
}
/**
+ * Sets the file path prefix for file in the zip file.
+ *
+ * @param string $prefix Prefix
+ *
+ * @return void
+ */
+ public function setPrefix($prefix) {
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Set the include empty dirs flag.
+ * @param boolean Flag if empty dirs should be tarred too
+ * @return void
+ * @access public
+ */
+ public function setIncludeEmptyDirs($bool) {
+ $this->includeEmpty = (boolean) $bool;
+ }
+
+ /**
* do the work
* @throws BuildException
*/
@@ -93,13 +131,16 @@ class ZipTask extends MatchingTask {
try {
if ($this->baseDir !== null) {
if (!$this->baseDir->exists()) {
- throw new BuildException("basedir does not exist!", $this->getLocation());
+ throw new BuildException("basedir '" . (string) $this->baseDir . "' does not exist!", $this->getLocation());
+ }
+
+ if (empty($this->filesets))
+ {
+ // add the main fileset to the list of filesets to process.
+ $mainFileSet = new ZipFileSet($this->fileset);
+ $mainFileSet->setDir($this->baseDir);
+ $this->filesets[] = $mainFileSet;
}
-
- // add the main fileset to the list of filesets to process.
- $mainFileSet = new FileSet($this->fileset);
- $mainFileSet->setDir($this->baseDir);
- $this->filesets[] = $mainFileSet;
}
if (empty($this->filesets)) {
@@ -112,8 +153,7 @@ class ZipTask extends MatchingTask {
// fileset
$upToDate = true;
foreach($this->filesets as $fs) {
- $ds = $fs->getDirectoryScanner($this->project);
- $files = $ds->getIncludedFiles();
+ $files = $fs->getFiles($this->project, $this->includeEmpty);
if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) {
$upToDate = false;
}
@@ -125,33 +165,47 @@ class ZipTask extends MatchingTask {
}
if ($upToDate) {
- $this->log("Nothing to do: " . $this->zipFile->__toString() . " is up to date.", PROJECT_MSG_INFO);
+ $this->log("Nothing to do: " . $this->zipFile->__toString() . " is up to date.", Project::MSG_INFO);
return;
}
- $this->log("Building zip: " . $this->zipFile->__toString(), PROJECT_MSG_INFO);
+ $this->log("Building zip: " . $this->zipFile->__toString(), Project::MSG_INFO);
- $zip = new Archive_Zip($this->zipFile->getAbsolutePath());
+ $zip = new ZipArchive();
+ $res = $zip->open($this->zipFile->getAbsolutePath(), ZIPARCHIVE::CREATE);
- foreach($this->filesets as $fs) {
- $ds = $fs->getDirectoryScanner($this->project);
- $files = $ds->getIncludedFiles();
-
- // FIXME
- // Current model is only adding directories implicitly. This
- // won't add any empty directories. Perhaps modify FileSet::getFiles()
- // to also include empty directories. Not high priority, since non-inclusion
- // of empty dirs is probably not unexpected behavior for ZipTask.
- $fsBasedir = $fs->getDir($this->project);
+ if ($res !== true)
+ {
+ throw new Exception("ZipArchive::open() failed with code " . $res);
+ }
+
+ foreach($this->filesets as $fs) {
+ $fsBasedir = (null != $this->baseDir) ? $this->baseDir :
+ $fs->getDir($this->project);
+
+ $files = $fs->getFiles($this->project, $this->includeEmpty);
+
$filesToZip = array();
for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
$f = new PhingFile($fsBasedir, $files[$i]);
- $filesToZip[] = $f->getAbsolutePath();
- }
- $zip->add($filesToZip, array('remove_path' => $fsBasedir->getPath()));
+
+ $pathInZip = $this->prefix
+ . $f->getPathWithoutBase($fsBasedir);
+
+ $pathInZip = str_replace('\\', '/', $pathInZip);
+
+ if ($f->isDirectory()) {
+ if ($pathInZip != '.') {
+ $zip->addEmptyDir($pathInZip);
+ }
+ } else {
+ $zip->addFile($f->getPath(), $pathInZip);
+ }
+ $this->log("Adding " . $f->getPath() . " as " . $pathInZip . " to archive.", Project::MSG_VERBOSE);
+ }
}
-
-
+
+ $zip->close();
} catch (IOException $ioe) {
$msg = "Problem creating ZIP: " . $ioe->getMessage();
$this->filesets = $savedFileSets;
@@ -174,3 +228,74 @@ class ZipTask extends MatchingTask {
}
}
+
+
+
+
+/**
+ * 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
+ */
+class ZipFileSet extends FileSet {
+
+ private $files = null;
+
+ /**
+ * Get a list of files and directories specified in the fileset.
+ * @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();
+
+ // build a list of directories implicitly added by any of the files
+ $implicitDirs = array();
+ foreach($this->files as $file) {
+ $implicitDirs[] = dirname($file);
+ }
+
+ $incDirs = $ds->getIncludedDirectories();
+
+ // we'll need to add to that list of implicit dirs any directories
+ // that contain other *directories* (and not files), since otherwise
+ // we get duplicate directories in the resulting tar
+ foreach($incDirs as $dir) {
+ foreach($incDirs as $dircheck) {
+ if (!empty($dir) && $dir == dirname($dircheck)) {
+ $implicitDirs[] = $dir;
+ }
+ }
+ }
+
+ $implicitDirs = array_unique($implicitDirs);
+
+ $emptyDirectories = array();
+
+ if ($includeEmpty) {
+ // Now add any empty dirs (dirs not covered by the implicit dirs)
+ // to the files array.
+
+ foreach($incDirs as $dir) { // we cannot simply use array_diff() since we want to disregard empty/. dirs
+ if ($dir != "" && $dir != "." && !in_array($dir, $implicitDirs)) {
+ // it's an empty dir, so we'll add it.
+ $emptyDirectories[] = $dir;
+ }
+ }
+ } // if $includeEmpty
+
+ $this->files = array_merge($implicitDirs, $emptyDirectories, $this->files);
+ sort($this->files);
+ } // if ($this->files===null)
+
+ return $this->files;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/apigen/ApiGenTask.php b/buildscripts/phing/classes/phing/tasks/ext/apigen/ApiGenTask.php
new file mode 100644
index 00000000..d8438b3e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/apigen/ApiGenTask.php
@@ -0,0 +1,439 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * ApiGen task (http://apigen.org).
+ *
+ * @package phing.tasks.ext.apigen
+ * @author Martin Srank <martin@smasty.net>
+ * @author Jaroslav Hanslík <kukulich@kukulich.cz>
+ * @since 2.4.10
+ */
+class ApiGenTask extends Task
+{
+ /**
+ * Default ApiGen executable name.
+ *
+ * @var string
+ */
+ private $executable = 'apigen';
+
+ /**
+ * Default options for ApiGen.
+ *
+ * @var array
+ */
+ private $options = array(
+ 'progressbar' => false,
+ 'colors' => false,
+ 'update-check' => false
+ );
+
+ /**
+ * Sets the ApiGen executable name.
+ *
+ * @param string $executable
+ */
+ public function setExecutable($executable)
+ {
+ $this->executable = (string) $executable;
+ }
+
+ /**
+ * 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 a name prefix to exclude elements from documentation generating.
+ *
+ * @param string $skipDocPrefix
+ */
+ public function setSkipDocPrefix($skipDocPrefix)
+ {
+ $this->options['skip-doc-prefix'] = explode(',', $skipDocPrefix);
+ }
+
+ /**
+ * 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 a list of HTML tags allowed in the documentation.
+ *
+ * @param string $allowedHtml
+ */
+ public function setAllowedHtml($allowedHtml)
+ {
+ $this->options['allowed-html'] = (string) $allowedHtml;
+ }
+
+ /**
+ * Sets how elements should be grouped in the menu.
+ *
+ * @param string $groups
+ */
+ public function setGroups($groups)
+ {
+ $this->options['groups'] = (string) $groups;
+ }
+
+ /**
+ * Sets element types for search input autocomplete.
+ *
+ * @param string $autocomplete
+ */
+ public function setAutocomplete($autocomplete)
+ {
+ $this->options['autocomplete'] = (string) $autocomplete;
+ }
+
+ /**
+ * 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 if documentation for elements marked as internal and internal documentation parts should be generated.
+ *
+ * @param boolean $internal
+ */
+ public function setInternal($internal)
+ {
+ $this->options['internal'] = (bool) $internal;
+ }
+
+ /**
+ * Sets if documentation for PHP internal classes should be generated.
+ *
+ * @param boolean $php
+ */
+ public function setPhp($php)
+ {
+ $this->options['php'] = (bool) $php;
+ }
+
+ /**
+ * Sets if tree view of classes, interfaces, traits and exceptions should be generated.
+ *
+ * @param boolean $tree
+ */
+ public function setTree($tree)
+ {
+ $this->options['tree'] = (bool) $tree;
+ }
+
+ /**
+ * Sets if documentation for deprecated elements should be generated.
+ *
+ * @param boolean $deprecated
+ */
+ public function setDeprecated($deprecated)
+ {
+ $this->options['deprecated'] = (bool) $deprecated;
+ }
+
+ /**
+ * Sets if documentation of tasks should be generated.
+ *
+ * @param boolean $todo
+ */
+ public function setTodo($todo)
+ {
+ $this->options['todo'] = (bool) $todo;
+ }
+
+ /**
+ * Sets if highlighted source code files should be generated.
+ *
+ * @param boolean $sourceCode
+ */
+ public function setSourceCode($sourceCode)
+ {
+ $this->options['source-code'] = (bool) $sourceCode;
+ }
+
+ /**
+ * Sets if a link to download documentation as a ZIP archive should be generated.
+ *
+ * @param boolean $download
+ */
+ public function setDownload($download)
+ {
+ $this->options['download'] = (bool) $download;
+ }
+
+ /**
+ * Sets a file name for checkstyle report of poorly documented elements.
+ *
+ * @param string $report
+ */
+ public function setReport($report)
+ {
+ $this->options['report'] = (string) $report;
+ }
+
+ /**
+ * Sets if the destination directory should be wiped out first.
+ *
+ * @param boolean $wipeout
+ */
+ public function setWipeout($wipeout)
+ {
+ $this->options['wipeout'] = (bool) $wipeout;
+ }
+
+ /**
+ * Enables/disables scaning and generating messages.
+ *
+ * @param boolean $quiet
+ */
+ public function setQuiet($quiet)
+ {
+ $this->options['quiet'] = (bool) $quiet;
+ }
+
+ /**
+ * Enables/disables the check for ApiGen updates.
+ *
+ * @param boolean $updateCheck
+ */
+ public function setUpdateCheck($updateCheck)
+ {
+ $this->options['update-check'] = (bool) $updateCheck;
+ }
+
+ /**
+ * Enables/disables the debug mode.
+ *
+ * @param boolean $debug
+ */
+ public function setDebug($debug)
+ {
+ $this->options['debug'] = (bool) $debug;
+ }
+
+ /**
+ * 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) . ' ' . $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);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php
index 99bcc7c4..71eba460 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: CoverageMerger.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 83f3748d0690f9fc69c2618191f272e5661c0501 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,104 +24,131 @@ require_once 'phing/system/util/Properties.php';
/**
* Saves coverage output of the test to a specified database
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: CoverageMerger.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 83f3748d0690f9fc69c2618191f272e5661c0501 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageMerger
{
- private static function mergeCodeCoverage($left, $right)
- {
- $coverageMerged = array();
-
- reset($left);
- reset($right);
-
- while (current($left) && current($right))
- {
- $linenr_left = key($left);
- $linenr_right = key($right);
-
- if ($linenr_left < $linenr_right)
- {
- $coverageMerged[$linenr_left] = current($left);
-
- next($left);
- }
- else
- if ($linenr_right < $linenr_left)
- {
- $coverageMerged[$linenr_right] = current($right);
- next($right);
- }
- else
- {
- if (current($left) < 0)
- {
- $coverageMerged[$linenr_right] = current($right);
- }
- else
- if (current($right) < 0)
- {
- $coverageMerged[$linenr_right] = current($left);
- }
- else
- {
- $coverageMerged[$linenr_right] = current($left) + current($right);
- }
-
- next($left);
- next($right);
- }
- }
-
- while (current($left))
- {
- $coverageMerged[key($left)] = current($left);
- next($left);
- }
-
- while (current($right))
- {
- $coverageMerged[key($right)] = current($right);
- next($right);
- }
-
- return $coverageMerged;
- }
-
- static function merge($project, $codeCoverageInformation)
- {
- $database = new PhingFile($project->getProperty('coverage.database'));
-
- $props = new Properties();
- $props->load($database);
-
- $coverageTotal = $codeCoverageInformation;
-
- foreach ($coverageTotal as $coverage)
- {
- foreach ($coverage as $filename => $coverageFile)
- {
- $filename = strtolower($filename);
-
- if ($props->getProperty($filename) != null)
- {
- $file = unserialize($props->getProperty($filename));
- $left = $file['coverage'];
- $right = $coverageFile;
-
- $coverageMerged = CoverageMerger::mergeCodeCoverage($left, $right);
-
- $file['coverage'] = $coverageMerged;
-
- $props->setProperty($filename, serialize($file));
- }
- }
- }
-
- $props->store($database);
- }
-}
-?> \ No newline at end of file
+ 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;
+ }
+
+ public static function getWhiteList($project)
+ {
+ $whitelist = array();
+ $props = self::_getDatabase($project);
+
+ foreach ($props->getProperties() as $property) {
+ $data = unserialize($property);
+ $whitelist[] = $data['fullname'];
+ }
+
+ return $whitelist;
+ }
+
+ public static function merge($project, $codeCoverageInformation)
+ {
+ $props = self::_getDatabase($project);
+
+ $coverageTotal = $codeCoverageInformation;
+
+ foreach ($coverageTotal as $filename => $data) {
+ $ignoreLines = PHP_CodeCoverage_Util::getLinesToBeIgnored($filename);
+
+ $lines = array();
+ $filename = strtolower($filename);
+
+ if ($props->getProperty($filename) != null) {
+ foreach ($data as $_line => $_data) {
+ if (is_array($_data)) {
+ $count = count($_data);
+ } else if(isset($ignoreLines[$_line])) {
+ // line is marked as ignored
+ $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();
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php
index 4a78df6f..fd141cb5 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: CoverageMergerTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 324ec42a8015e3b82e90ee3bfaad1bc069fec409 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -28,65 +28,65 @@ require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
/**
* Merges code coverage snippets into a code coverage database
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: CoverageMergerTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 324ec42a8015e3b82e90ee3bfaad1bc069fec409 $
* @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();
+ /** 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
- */
- function addFileSet(FileSet $fileset)
- {
- $this->filesets[] = $fileset;
- }
+ /**
+ * Add a new fileset containing the .php files to process
+ *
+ * @param FileSet the new fileset containing .php files
+ */
+ 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();
+ /**
+ * 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();
+ 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();
- }
- }
+ $includedFiles = $ds->getIncludedFiles();
+
+ foreach ($includedFiles as $file)
+ {
+ $fs = new PhingFile(basename($ds->getBaseDir()), $file);
+
+ $files[] = $fs->getAbsolutePath();
+ }
+ }
- return $files;
- }
-
- function main()
- {
- $files = $this->getFilenames();
-
- $this->log("Merging " . count($files) . " coverage files");
+ return $files;
+ }
+
+ 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));
- }
- }
+ foreach ($files as $file)
+ {
+ $coverageInformation = unserialize(file_get_contents($file));
+
+ CoverageMerger::merge($this->project, array($coverageInformation));
+ }
+ }
}
-?>
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php
index 72fa57a7..dbfc3093 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: CoverageReportTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 564bbde3ec5084ed2db570958548af2b9d1c1127 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -23,384 +23,542 @@ 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/phpunit2/PHPUnit2Util.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 <michiel@trendserver.nl>
- * @version $Id: CoverageReportTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 564bbde3ec5084ed2db570958548af2b9d1c1127 $
* @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 = "";
-
- function setClasspath(Path $classpath)
- {
- if ($this->classpath === null)
- {
- $this->classpath = $classpath;
- }
- else
- {
- $this->classpath->append($classpath);
- }
- }
-
- function createClasspath()
- {
- $this->classpath = new Path();
- return $this->classpath;
- }
-
- function setGeshiPath($path)
- {
- $this->geshipath = $path;
- }
-
- function setGeshiLanguagesPath($path)
- {
- $this->geshilanguagespath = $path;
- }
-
- function __construct()
- {
- $this->doc = new DOMDocument();
- $this->doc->encoding = 'UTF-8';
- $this->doc->formatOutput = true;
- $this->doc->appendChild($this->doc->createElement('snapshot'));
- }
-
- function setOutfile($outfile)
- {
- $this->outfile = $outfile;
- }
-
- /**
- * Generate a report based on the XML created by this task
- */
- function createReport()
- {
- $transformer = new CoverageReportTransformer($this);
- $this->transformers[] = $transformer;
- return $transformer;
- }
-
- protected function getPackageElement($packageName)
- {
- $packages = $this->doc->documentElement->getElementsByTagName('package');
-
- foreach ($packages as $package)
- {
- if ($package->getAttribute('name') == $packageName)
- {
- return $package;
- }
- }
-
- return NULL;
- }
-
- protected function addClassToPackage($classname, $element)
- {
- $packageName = PHPUnit2Util::getPackageName($classname);
-
- $package = $this->getPackageElement($packageName);
-
- if ($package === NULL)
- {
- $package = $this->doc->createElement('package');
- $package->setAttribute('name', $packageName);
- $this->doc->documentElement->appendChild($package);
- }
-
- $package->appendChild($element);
- }
-
- protected function stripDiv($source)
- {
- $openpos = strpos($source, "<div");
- $closepos = strpos($source, ">", $openpos);
-
- $line = substr($source, $closepos + 1);
-
- $tagclosepos = strpos($line, "</div>");
-
- $line = substr($line, 0, $tagclosepos);
-
- return $line;
- }
-
- 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 = split("<li>|</li>", $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);
-
- $lines[$i] = utf8_encode($line);
- }
-
- return $lines;
- }
- }
-
- protected function transformSourceFile($filename, $coverageInformation, $classStartLine = 1)
- {
- $sourceElement = $this->doc->createElement('sourcefile');
- $sourceElement->setAttribute('name', basename($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;
- }
-
- protected function filterCovered($var)
- {
- return ($var >= 0);
- }
-
- protected function transformCoverageInformation($filename, $coverageInformation)
- {
- $classes = PHPUnit2Util::getDefinedClasses($filename, $this->classpath);
-
- if (is_array($classes))
- {
- foreach ($classes as $classname)
- {
- $reflection = new ReflectionClass($classname);
-
- $methods = $reflection->getMethods();
-
- $classElement = $this->doc->createElement('class');
- $classElement->setAttribute('name', $reflection->getName());
-
- $this->addClassToPackage($reflection->getName(), $classElement);
-
- $classStartLine = $reflection->getStartLine();
-
- $methodscovered = 0;
- $methodcount = 0;
-
- end($coverageInformation);
- unset($coverageInformation[key($coverageInformation)]);
-
- // 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);
-
- 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 < $method->getStartLine())
- {
- next($coverageInformation);
- $linenr = key($coverageInformation);
- }
-
- if (current($coverageInformation) > 0 && $method->getStartLine() <= $linenr && $linenr <= $method->getEndLine())
- {
- $methodscovered++;
- }
-
- $methodcount++;
- }
-
- $statementcount = count($coverageInformation);
- $statementscovered = count(array_filter($coverageInformation, array($this, 'filterCovered')));
-
- $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;
-
- $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);
- }
-
- function main()
- {
- $this->log("Transforming coverage report");
-
- $database = new PhingFile($this->project->getProperty('coverage.database'));
-
- $props = new Properties();
- $props->load($database);
+ 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 = "";
+
+ function setClasspath(Path $classpath)
+ {
+ if ($this->classpath === null)
+ {
+ $this->classpath = $classpath;
+ }
+ else
+ {
+ $this->classpath->append($classpath);
+ }
+ }
+
+ function createClasspath()
+ {
+ $this->classpath = new Path();
+ return $this->classpath;
+ }
+
+ function setGeshiPath($path)
+ {
+ $this->geshipath = $path;
+ }
+
+ function setGeshiLanguagesPath($path)
+ {
+ $this->geshilanguagespath = $path;
+ }
+
+ function __construct()
+ {
+ $this->doc = new DOMDocument();
+ $this->doc->encoding = 'UTF-8';
+ $this->doc->formatOutput = true;
+ $this->doc->appendChild($this->doc->createElement('snapshot'));
+ }
+
+ function setOutfile($outfile)
+ {
+ $this->outfile = $outfile;
+ }
+
+ /**
+ * Generate a report based on the XML created by this task
+ */
+ function createReport()
+ {
+ $transformer = new CoverageReportTransformer($this);
+ $this->transformers[] = $transformer;
+ return $transformer;
+ }
+
+ protected function getPackageElement($packageName)
+ {
+ $packages = $this->doc->documentElement->getElementsByTagName('package');
+
+ foreach ($packages as $package)
+ {
+ if ($package->getAttribute('name') == $packageName)
+ {
+ return $package;
+ }
+ }
+
+ return NULL;
+ }
+
+ protected function addClassToPackage($classname, $element)
+ {
+ $packageName = PHPUnitUtil::getPackageName($classname);
+
+ $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 <bschultz@proqrent.de>
+ * @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 <bschultz@proqrent.de>
+ * @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 <bschultz@proqrent.de>
+ * @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);
+ }
+
+ protected function stripDiv($source)
+ {
+ $openpos = strpos($source, "<div");
+ $closepos = strpos($source, ">", $openpos);
+
+ $line = substr($source, $closepos + 1);
+
+ $tagclosepos = strpos($line, "</div>");
+
+ $line = substr($line, 0, $tagclosepos);
+
+ return $line;
+ }
+
+ 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("#</?li>#", $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;
+ }
+ }
+
+ 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 <mrook@php.net>
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @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();
+
+ $classElement = $this->doc->createElement('class');
+ $classElement->setAttribute('name', $reflection->getName());
+
+ $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($reflection->getName(), $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);
+ }
+
+ 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);
- foreach ($props->keys() as $filename)
- {
- $file = unserialize($props->getProperty($filename));
+ $this->log("Transforming coverage report");
+
+ $props = new Properties();
+ $props->load($database);
- $this->transformCoverageInformation($file['fullname'], $file['coverage']);
- }
-
- $this->calculateStatistics();
-
- $this->doc->save($this->outfile);
+ foreach ($props->keys() as $filename)
+ {
+ $file = unserialize($props->getProperty($filename));
+
+ $this->transformCoverageInformation($file['fullname'], $file['coverage']);
+ }
+
+ $this->calculateStatistics();
- foreach ($this->transformers as $transformer)
- {
- $transformer->setXmlDocument($this->doc);
- $transformer->transform();
- }
- }
+ $this->doc->save($this->outfile);
+
+ foreach ($this->transformers as $transformer)
+ {
+ $transformer->setXmlDocument($this->doc);
+ $transformer->transform();
+ }
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php
index b7fee32f..cc37800f 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: CoverageReportTransformer.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: c1667521b5959687560a1bf015905d627785a3c6 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -28,94 +28,149 @@ 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 <michiel@trendserver.nl>
- * @version $Id: CoverageReportTransformer.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: c1667521b5959687560a1bf015905d627785a3c6 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageReportTransformer
{
- private $task = NULL;
- private $styleDir = "";
- private $toDir = "";
- private $document = NULL;
-
- function __construct(Task $task)
- {
- $this->task = $task;
- }
-
- function setStyleDir($styleDir)
- {
- $this->styleDir = $styleDir;
- }
-
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
-
- function setXmlDocument($document)
- {
- $this->document = $document;
- }
-
- function transform()
- {
- $dir = new PhingFile($this->toDir);
-
- if (!$dir->exists())
+ 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;
+
+ function __construct(Task $task)
+ {
+ $this->task = $task;
+ }
+
+ function setStyleDir($styleDir)
+ {
+ $this->styleDir = $styleDir;
+ }
+
+ function setToDir(PhingFile $toDir)
+ {
+ $this->toDir = $toDir;
+ }
+
+ function setXmlDocument($document)
+ {
+ $this->document = $document;
+ }
+
+ /**
+ * Setter for title parameter
+ */
+ 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;
+ }
+
+ 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();
- $proc->importStyleSheet($xsl);
-
- ExtendedFileStream::registerStream();
-
- // no output for the framed report
- // it's all done by extension...
- $proc->setParameter('', 'output.dir', $dir->getAbsolutePath());
- $proc->transformToXML($this->document);
- }
-
- 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;
- }
+ $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();
+ }
+
+ 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;
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php
index 058b891b..889a9042 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: CoverageSetupTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: da84ff4b224cdf3a8061e02d782320ccc492c253 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -28,136 +28,137 @@ require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
/**
* Initializes a code coverage database
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: CoverageSetupTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: da84ff4b224cdf3a8061e02d782320ccc492c253 $
* @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();
-
- /** 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
- */
- function addFileSet(FileSet $fileset)
- {
- $this->filesets[] = $fileset;
- }
-
- /**
- * Sets the filename of the coverage database to use
- *
- * @param string the filename of the database
- */
- function setDatabase($database)
- {
- $this->database = $database;
- }
-
- function setClasspath(Path $classpath)
- {
- if ($this->classpath === null)
- {
- $this->classpath = $classpath;
- }
- else
- {
- $this->classpath->append($classpath);
- }
- }
-
- function createClasspath()
- {
- $this->classpath = new Path();
- return $this->classpath;
- }
-
- /**
- * Iterate over all filesets and return the filename of all files
- * that end with .php. This is to avoid loading an xml file
- * for example.
- *
- * @return array an array of (basedir, filenames) pairs
- */
- private function getFilenames()
- {
- $files = array();
-
- foreach ($this->filesets as $fileset)
- {
- $ds = $fileset->getDirectoryScanner($this->project);
- $ds->scan();
-
- $includedFiles = $ds->getIncludedFiles();
-
- foreach ($includedFiles as $file)
- {
- if (strstr($file, ".php"))
- {
- $fs = new PhingFile(realpath($ds->getBaseDir()), $file);
-
- $files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath());
- }
- }
- }
-
- return $files;
- }
-
- function init()
- {
- include_once 'PHPUnit2/Framework/TestCase.php';
- if (!class_exists('PHPUnit2_Framework_TestCase')) {
- throw new Exception("PHPUnit2Task depends on PEAR PHPUnit2 package being installed.");
- }
- }
-
- 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());
-
- foreach ($files as $file)
- {
- $fullname = $file['fullname'];
-
- xdebug_start_code_coverage(XDEBUG_CC_UNUSED);
-
- Phing::__import($fullname, $this->classpath);
-
- $coverage = xdebug_get_code_coverage();
-
- xdebug_stop_code_coverage();
-
- CoverageMerger::merge($this->project, array($coverage));
- }
- }
+ /** 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
+ */
+ function addFileSet(FileSet $fileset)
+ {
+ $this->filesets[] = $fileset;
+ }
+
+ /**
+ * Supports embedded <filelist> element.
+ * @return FileList
+ */
+ 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
+ */
+ function setDatabase($database)
+ {
+ $this->database = $database;
+ }
+
+ function setClasspath(Path $classpath)
+ {
+ if ($this->classpath === null)
+ {
+ $this->classpath = $classpath;
+ }
+ else
+ {
+ $this->classpath->append($classpath);
+ }
+ }
+
+ 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;
+ }
+
+ function init()
+ {
+ }
+
+ 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());
+ }
}
-?>
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageThresholdTask.php b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageThresholdTask.php
new file mode 100644
index 00000000..d9afbb00
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/coverage/CoverageThresholdTask.php
@@ -0,0 +1,458 @@
+<?php
+/**
+ * $Id: ed00d6f1d05bb5dc7c9967c9ec67fa6f958682ec $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <bschultz@proqrent.de>
+ * @version $Id: ed00d6f1d05bb5dc7c9967c9ec67fa6f958682ec $
+ * @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
+ */
+ 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'
+ );
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/CreoleSQLExecTask.php b/buildscripts/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php
index d35e44f4..1ea3d5ba 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/CreoleSQLExecTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: CreoleSQLExecTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: f8f62d67a784faced2621d2ffc3b1c92e8703b05 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -19,7 +19,7 @@
* <http://phing.info>.
*/
-require_once 'phing/tasks/ext/CreoleTask.php';
+require_once 'phing/tasks/ext/creole/CreoleTask.php';
include_once 'phing/system/io/StringReader.php';
/**
@@ -48,8 +48,8 @@ include_once 'phing/system/io/StringReader.php';
* @author Jeff Martin <jeff@custommonkey.org> (Ant)
* @author Michael McCallum <gholam@xtra.co.nz> (Ant)
* @author Tim Stephenson <tim.stephenson@sybase.com> (Ant)
- * @package phing.tasks.ext
- * @version $Revision: 1.21 $
+ * @package phing.tasks.ext.creole
+ * @version $Id: f8f62d67a784faced2621d2ffc3b1c92e8703b05 $
*/
class CreoleSQLExecTask extends CreoleTask {
@@ -70,6 +70,11 @@ class CreoleSQLExecTask extends CreoleTask {
private $filesets = array();
/**
+ * all filterchains objects assigned to this task
+ */
+ private $filterChains = array();
+
+ /**
* SQL statement
*/
private $statement = null;
@@ -155,6 +160,17 @@ class CreoleSQLExecTask extends CreoleTask {
}
/**
+ * Creates a filterchain
+ *
+ * @access public
+ * @return object The created filterchain object
+ */
+ 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() {
@@ -303,7 +319,7 @@ class CreoleSQLExecTask extends CreoleTask {
try {
if ($this->output !== null) {
- $this->log("Opening output file " . $this->output, PROJECT_MSG_VERBOSE);
+ $this->log("Opening output file " . $this->output, Project::MSG_VERBOSE);
$out = new BufferedWriter(new FileWriter($this->output->getAbsolutePath(), $this->append));
}
@@ -311,7 +327,7 @@ class CreoleSQLExecTask extends CreoleTask {
for ($i=0,$size=count($this->transactions); $i < $size; $i++) {
$this->transactions[$i]->runTransaction($out);
if (!$this->isAutocommit()) {
- $this->log("Commiting transaction", PROJECT_MSG_VERBOSE);
+ $this->log("Commiting transaction", Project::MSG_VERBOSE);
$this->conn->commit();
}
}
@@ -357,9 +373,25 @@ class CreoleSQLExecTask extends CreoleTask {
public function runStatements(Reader $reader, $out = null) {
$sql = "";
$line = "";
- $in = new BufferedReader($reader);
- try {
+
+ $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());
@@ -389,8 +421,8 @@ class CreoleSQLExecTask extends CreoleTask {
&& 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)) - 1, $out);
+ $this->log("SQL: " . $sql, Project::MSG_VERBOSE);
+ $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter)), $out);
$sql = "";
}
}
@@ -418,7 +450,7 @@ class CreoleSQLExecTask extends CreoleTask {
try {
$this->totalSql++;
if (!$this->statement->execute($sql)) {
- $this->log($this->statement->getUpdateCount() . " rows affected", PROJECT_MSG_VERBOSE);
+ $this->log($this->statement->getUpdateCount() . " rows affected", Project::MSG_VERBOSE);
} else {
if ($this->print) {
$this->printResults($out);
@@ -428,27 +460,27 @@ class CreoleSQLExecTask extends CreoleTask {
$this->goodSql++;
} catch (SQLException $e) {
- $this->log("Failed to execute: " . $sql, PROJECT_MSG_ERR);
+ $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);
+ $this->log($e->getMessage(), Project::MSG_ERR);
}
}
/**
* print any results in the statement.
- * @throw SQLException
+ * @throws SQLException
*/
protected function printResults($out = null) {
- $lSep = Phing::getProperty('line.separator');
+
$rs = null;
do {
$rs = $this->statement->getResultSet();
if ($rs !== null) {
- $this->log("Processing new result set.", PROJECT_MSG_VERBOSE);
+ $this->log("Processing new result set.", Project::MSG_VERBOSE);
$line = "";
@@ -467,7 +499,7 @@ class CreoleSQLExecTask extends CreoleTask {
$out->write($line);
$out->newLine();
} else {
- print($line.$lSep);
+ print($line.PHP_EOL);
}
$line = "";
$colsprinted = true;
@@ -492,14 +524,14 @@ class CreoleSQLExecTask extends CreoleTask {
$out->write($line);
$out->newLine();
} else {
- print($line . $lSep);
+ print($line . PHP_EOL);
}
$line = "";
} // while rs->next()
}
} while ($this->statement->getMoreResults());
- print($lSep);
+ print(PHP_EOL);
if ($out !== null) $out->newLine();
}
}
@@ -510,6 +542,8 @@ class CreoleSQLExecTask extends CreoleTask {
* 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 {
@@ -539,14 +573,16 @@ class SQLExecTransaction {
public function runTransaction($out = null)
{
if (!empty($this->tSqlCommand)) {
- $this->parent->log("Executing commands", PROJECT_MSG_INFO);
+ $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);
+ Project::MSG_INFO);
+
$reader = new FileReader($this->tSrcFile);
+
$this->parent->runStatements($reader, $out);
$reader->close();
}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/CreoleTask.php b/buildscripts/phing/classes/phing/tasks/ext/creole/CreoleTask.php
index a1b439e5..6cff2033 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/CreoleTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/creole/CreoleTask.php
@@ -1,7 +1,7 @@
<?php
/*
- * $Id: CreoleTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 91a6dbbd682e6afa8befa95f01ae5fbaed11a72a $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -31,7 +31,7 @@ include_once 'phing/types/Reference.php';
* @author Jeff Martin <jeff@custommonkey.org> (Ant)
* @author Michael McCallum <gholam@xtra.co.nz> (Ant)
* @author Tim Stephenson <tim.stephenson@sybase.com> (Ant)
- * @version $Revision: 1.13 $
+ * @version $Id$
* @package phing.tasks.system
*/
abstract class CreoleTask extends Task {
@@ -164,7 +164,7 @@ abstract class CreoleTask extends Task {
try {
- $this->log("Connecting to " . $this->getUrl(), PROJECT_MSG_VERBOSE);
+ $this->log("Connecting to " . $this->getUrl(), Project::MSG_VERBOSE);
$info = new Properties();
$dsn = Creole::parseDSN($this->url);
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php
new file mode 100755
index 00000000..a5cc23ff
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php
@@ -0,0 +1,436 @@
+<?php
+/*
+ * $Id: 035d43c0c50ca9567e9c8a016fef6a3053164acb $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php';
+
+
+/**
+ * Generate SQL script for db using dbdeploy schema version table
+ * and delta scripts
+ *
+ * <dbdeploy url="mysql:host=localhost;dbname=test"
+ * userid="dbdeploy" password="dbdeploy" dir="db" outputfile="">
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+class DbDeployTask extends Task
+{
+ /**
+ * The tablename to use from the database for storing all changes
+ * This cannot be changed
+ *
+ * @var string
+ */
+ public static $TABLE_NAME = 'changelog';
+
+ /**
+ * Connection string for the database connection
+ *
+ * @var string
+ */
+ protected $url;
+
+ /**
+ * The userid for the database connection
+ *
+ * @var string
+ */
+ protected $userid;
+
+ /**
+ * The password of the database user
+ *
+ * @var string
+ */
+ protected $password;
+
+ /**
+ * Path to the directory that holds the database patch files
+ *
+ * @var string
+ */
+ protected $dir;
+
+ /**
+ * Output file for performing all database patches of this deployment
+ * Contains all the SQL statements that need to be executed
+ *
+ * @var string
+ */
+ protected $outputFile = 'dbdeploy_deploy.sql';
+
+ /**
+ * Outputfile for undoing the database patches of this deployment
+ * Contains all the SQL statements that need to be executed
+ *
+ * @var string
+ */
+ protected $undoOutputFile = 'dbdeploy_undo.sql';
+
+ /**
+ * The deltaset that's being used
+ *
+ * @var string
+ */
+ protected $deltaSet = 'Main';
+
+ /**
+ * The number of the last change to apply
+ *
+ * @var int
+ */
+ protected $lastChangeToApply = 999;
+
+ /**
+ * Contains the object for the DBMS that is used
+ *
+ * @var object
+ */
+ protected $dbmsSyntax = null;
+
+ /**
+ * Array with all change numbers that are applied already
+ *
+ * @var array
+ */
+ protected $appliedChangeNumbers = array();
+
+ /**
+ * Checkall attribute
+ * False means dbdeploy will only apply patches that have a higher number
+ * than the last patchnumber that was applied
+ * True means dbdeploy will apply all changes that aren't applied
+ * already (in ascending order)
+ *
+ * @var int
+ */
+ protected $checkall = false;
+
+ /**
+ * The main function for the task
+ *
+ * @throws BuildException
+ * @return void
+ */
+ public function main()
+ {
+ try {
+ // get correct DbmsSyntax object
+ $dbms = substr($this->url, 0, strpos($this->url, ':'));
+ $dbmsSyntaxFactory = new DbmsSyntaxFactory($dbms);
+ $this->dbmsSyntax = $dbmsSyntaxFactory->getDbmsSyntax();
+
+ // figure out which revisions are in the db already
+ $this->appliedChangeNumbers = $this->getAppliedChangeNumbers();
+ $this->log('Current db revision: '.$this->getLastChangeAppliedInDb());
+ $this->log('Checkall: ' . $this->checkall);
+
+ $this->deploy();
+
+ } catch (Exception $e) {
+ throw new BuildException($e);
+ }
+ }
+
+ /**
+ * Get the numbers of all the patches that are already applied according to
+ * the changelog table in the database
+ *
+ * @return array
+ */
+ protected function getAppliedChangeNumbers()
+ {
+ if (count($this->appliedChangeNumbers) == 0) {
+ $this->log('Getting applied changed numbers from DB: ' . $this->url);
+ $appliedChangeNumbers = array();
+ $dbh = new PDO($this->url, $this->userid, $this->password);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $sql = "SELECT *
+ FROM " . DbDeployTask::$TABLE_NAME . "
+ WHERE delta_set = '$this->deltaSet'
+ ORDER BY change_number";
+ foreach ($dbh->query($sql) as $change) {
+ $appliedChangeNumbers[] = $change['change_number'];
+ }
+ $this->appliedChangeNumbers = $appliedChangeNumbers;
+ }
+ return $this->appliedChangeNumbers;
+ }
+
+ /**
+ * Get the number of the last patch applied to the database
+ *
+ * @return int|mixed The highest patch number that is applied in the db
+ */
+ protected function getLastChangeAppliedInDb()
+ {
+ return (count($this->appliedChangeNumbers) > 0)
+ ? max($this->appliedChangeNumbers) : 0;
+ }
+
+ /**
+ * Create the deploy and undo deploy outputfiles
+ *
+ * @return void
+ */
+ protected function deploy()
+ {
+ // create deploy outputfile
+ $this->createOutputFile($this->outputFile, false);
+
+ // create undo deploy outputfile
+ $this->createOutputFile($this->undoOutputFile, true);
+ }
+
+ /**
+ * Generate the sql for doing/undoing the deployment and write it to a file
+ *
+ * @param string $file
+ * @param bool $undo
+ * @return void
+ */
+ protected function createOutputFile($file, $undo = false)
+ {
+ $fileHandle = fopen($file, "w+");
+ $sql = $this->generateSql($undo);
+ fwrite($fileHandle, $sql);
+ }
+
+ /**
+ * Generate the sql for doing/undoing this deployment
+ *
+ * @param bool $undo
+ * @return string The sql
+ */
+ protected function generateSql($undo = false)
+ {
+ $sql = '';
+ $lastChangeAppliedInDb = $this->getLastChangeAppliedInDb();
+ $files = $this->getDeltasFilesArray();
+ $this->sortFiles($files, $undo);
+
+ foreach ($files as $fileChangeNumber => $fileName) {
+ if ($this->fileNeedsToBeRead($fileChangeNumber, $lastChangeAppliedInDb)) {
+ $sql .= '-- Fragment begins: ' . $fileChangeNumber . ' --' . "\n";
+
+ if (!$undo) {
+ $sql .= 'INSERT INTO ' . DbDeployTask::$TABLE_NAME . '
+ (change_number, delta_set, start_dt, applied_by, description)' .
+ ' VALUES (' . $fileChangeNumber . ', \'' . $this->deltaSet . '\', ' .
+ $this->dbmsSyntax->generateTimestamp() .
+ ', \'dbdeploy\', \'' . $fileName . '\');' . "\n";
+ }
+
+ // read the file
+ $fullFileName = $this->dir . '/' . $fileName;
+ $fh = fopen($fullFileName, 'r');
+ $contents = fread($fh, filesize($fullFileName));
+ // allow construct with and without space added
+ $split = strpos($contents, '-- //@UNDO');
+ if ($split === false)
+ $split = strpos($contents, '--//@UNDO');
+
+ if ($undo) {
+ $sql .= substr($contents, $split + 10) . "\n";
+ $sql .= 'DELETE FROM ' . DbDeployTask::$TABLE_NAME . '
+ WHERE change_number = ' . $fileChangeNumber . '
+ AND delta_set = \'' . $this->deltaSet . '\';' . "\n";
+ } else {
+ $sql .= substr($contents, 0, $split);
+ $sql .= 'UPDATE ' . DbDeployTask::$TABLE_NAME . '
+ SET complete_dt = ' . $this->dbmsSyntax->generateTimestamp() . '
+ WHERE change_number = ' . $fileChangeNumber . '
+ AND delta_set = \'' . $this->deltaSet . '\';' . "\n";
+ }
+
+ $sql .= '-- Fragment ends: ' . $fileChangeNumber . ' --' . "\n";
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Get a list of all the patch files in the patch file directory
+ *
+ * @return array
+ */
+ protected function getDeltasFilesArray()
+ {
+ $files = array();
+ $baseDir = realpath($this->dir);
+ $dh = opendir($baseDir);
+ $fileChangeNumberPrefix = '';
+ while (($file = readdir($dh)) !== false) {
+ if (preg_match('[\d+]', $file, $fileChangeNumberPrefix)) {
+ $files[intval($fileChangeNumberPrefix[0])] = $file;
+ }
+ }
+ return $files;
+ }
+
+ /**
+ * Sort files in the patch files directory (ascending or descending depending on $undo boolean)
+ *
+ * @param array $files
+ * @param bool $undo
+ * @return void
+ */
+ protected function sortFiles(&$files, $undo)
+ {
+ if ($undo) {
+ krsort($files);
+ } else {
+ ksort($files);
+ }
+ }
+
+ /**
+ * Determine if this patch file need to be deployed
+ * (using fileChangeNumber, lastChangeAppliedInDb and $this->checkall)
+ *
+ * @param int $fileChangeNumber
+ * @param string $lastChangeAppliedInDb
+ * @return bool True or false if patch file needs to be deployed
+ */
+ protected function fileNeedsToBeRead($fileChangeNumber, $lastChangeAppliedInDb)
+ {
+ if ($this->checkall) {
+ return (!in_array($fileChangeNumber, $this->appliedChangeNumbers));
+ } else {
+ return ($fileChangeNumber > $lastChangeAppliedInDb && $fileChangeNumber <= $this->lastChangeToApply);
+ }
+ }
+
+ /**
+ * Set the url for the database connection
+ *
+ * @param string $url
+ * @return void
+ */
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ }
+
+ /**
+ * Set the userid for the database connection
+ *
+ * @param string $userid
+ * @return void
+ */
+ public function setUserId($userid)
+ {
+ $this->userid = $userid;
+ }
+
+ /**
+ * Set the password for the database connection
+ *
+ * @param string $password
+ * @return void
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+
+ /**
+ * Set the directory where to find the patchfiles
+ *
+ * @param string $dir
+ * @return void
+ */
+ public function setDir($dir)
+ {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Set the outputfile which contains all patch sql statements for this deployment
+ *
+ * @param string $outputFile
+ * @return void
+ */
+ public function setOutputFile($outputFile)
+ {
+ $this->outputFile = $outputFile;
+ }
+
+ /**
+ * Set the undo outputfile which contains all undo statements for this deployment
+ *
+ * @param string $undoOutputFile
+ * @return void
+ */
+ public function setUndoOutputFile($undoOutputFile)
+ {
+ $this->undoOutputFile = $undoOutputFile;
+ }
+
+ /**
+ * Set the lastchangetoapply property
+ *
+ * @param int $lastChangeToApply
+ * @return void
+ */
+ public function setLastChangeToApply($lastChangeToApply)
+ {
+ $this->lastChangeToApply = $lastChangeToApply;
+ }
+
+ /**
+ * Set the deltaset property
+ *
+ * @param string $deltaSet
+ * @return void
+ */
+ public function setDeltaSet($deltaSet)
+ {
+ $this->deltaSet = $deltaSet;
+ }
+
+ /**
+ * Set the checkall property
+ *
+ * @param bool $checkall
+ * @return void
+ */
+ public function setCheckAll($checkall)
+ {
+ $this->checkall = (int)$checkall;
+ }
+
+ /**
+ * Add a new fileset.
+ * @return FileSet
+ */
+ public function createFileSet()
+ {
+ $this->fileset = new FileSet();
+ $this->filesets[] = $this->fileset;
+ return $this->fileset;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php
new file mode 100755
index 00000000..f20d2df4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * $Id: 40826765e423da7500094b84f0025f75c8fdde87 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+abstract class DbmsSyntax
+{
+ public abstract function generateTimestamp();
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php
new file mode 100755
index 00000000..1cc163f5
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * $Id: 0efe41b73233dd4396055518a125e4ff642693c5 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/dbdeploy/DbmsSyntax.php';
+
+/**
+ * Factory for generating dbms-specific syntax-generating objects
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxFactory
+{
+ private $dbms;
+
+ public function __construct($dbms)
+ {
+ $this->dbms = $dbms;
+ }
+
+ public function getDbmsSyntax()
+ {
+ switch ($this->dbms){
+ case('sqlite') :
+ require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php';
+ return new DbmsSyntaxSQLite();
+ case('mysql'):
+ require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php';
+ return new DbmsSyntaxMysql();
+ case 'odbc':
+ case('mssql'):
+ case 'dblib':
+ require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php';
+ return new DbmsSyntaxMsSql();
+ case('pgsql'):
+ require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php';
+ return new DbmsSyntaxPgSQL();
+ case 'oci':
+ require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxOracle.php';
+ return new DbmsSyntaxOracle();
+ default:
+ throw new Exception($this->dbms . ' is not supported by dbdeploy task.');
+ }
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php
new file mode 100755
index 00000000..0b505d8e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * $Id: 10012c2626ef9befc8c18efa5898704e269d6164 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxMsSql extends DbmsSyntax
+{
+ public function generateTimestamp()
+ {
+ return "DATEDIFF(s, '19700101', GETDATE())";
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php
new file mode 100755
index 00000000..86bf8ae0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * $Id: 3a8bab5e99f20e29f5c7dfe7d02f7a91fb8ccecd $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxMysql extends DbmsSyntax
+{
+ public function generateTimestamp()
+ {
+ return "NOW()";
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxOracle.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxOracle.php
new file mode 100755
index 00000000..15b0b0a0
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxOracle.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * $Id: be6f99d787b94f7f2c1c8e359def3d465386bba9 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxOracle extends DbmsSyntax
+{
+ public function generateTimestamp()
+ {
+ return "(sysdate - to_date('01-JAN-1970','DD-MON-YYYY')) * (86400)";
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php
new file mode 100755
index 00000000..6c07931c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php
@@ -0,0 +1,36 @@
+<?php
+/*
+ * $Id: 17845f06b311dbe508e7cb1244cd849a1d3fcada $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author R�my BREUILS
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+class DbmsSyntaxPgSQL extends DbmsSyntax
+{
+ public function generateTimestamp()
+ {
+ return "NOW()";
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php
new file mode 100755
index 00000000..32aa023e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * $Id: a48723b4c3ef1e5c15417f5ea6e495960e5e018b $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Utility class for generating necessary server-specific SQL commands
+ *
+ * @author Luke Crouch at SourceForge (http://sourceforge.net)
+ * @version $Id$
+ * @package phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxSQLite extends DbmsSyntax
+{
+ public function generateTimestamp()
+ {
+ return "strftime('%s','now')";
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/docblox/DocBloxTask.php b/buildscripts/phing/classes/phing/tasks/ext/docblox/DocBloxTask.php
new file mode 100755
index 00000000..0c1556c8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/docblox/DocBloxTask.php
@@ -0,0 +1,221 @@
+<?php
+/*
+ * $Id: eaa494390770adc752097a412d63fb863482fd5d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/FileOutputStream.php';
+
+/**
+ * DocBlox Task (http://www.docblox-project.org)
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: eaa494390770adc752097a412d63fb863482fd5d $
+ * @since 2.4.6
+ * @package phing.tasks.ext.docblox
+ */
+class DocBloxTask 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 = "new_black";
+
+ /**
+ * Title of the project
+ * @var string
+ */
+ private $title = "";
+
+ /**
+ * Force DocBlox to be quiet
+ * @var boolean
+ */
+ private $quiet = true;
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ *
+ * @return FileSet
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Forces DocBlox to be quiet
+ * @param boolean $quiet
+ */
+ public function setQuiet($quiet)
+ {
+ $this->quiet = (boolean) $quiet;
+ }
+
+ /**
+ * Finds and initializes the DocBlox installation
+ */
+ private function initializeDocBlox()
+ {
+ $docbloxPath = null;
+
+ foreach (explode(PATH_SEPARATOR, get_include_path()) as $path) {
+ $testDocBloxPath = $path . DIRECTORY_SEPARATOR . 'DocBlox' . DIRECTORY_SEPARATOR . 'src';
+
+ if (file_exists($testDocBloxPath)) {
+ $docbloxPath = $testDocBloxPath;
+ }
+ }
+
+ if (empty($docbloxPath)) {
+ throw new BuildException("Please make sure DocBlox is installed and on the include_path.", $this->getLocation());
+ }
+
+ set_include_path($docbloxPath . PATH_SEPARATOR . get_include_path());
+
+ require_once $docbloxPath.'/DocBlox/Bootstrap.php';
+
+ $bootstrap = DocBlox_Bootstrap::createInstance();
+
+ $autoloader = $bootstrap->registerAutoloader();
+
+ if ($this->quiet) {
+ DocBlox_Core_Abstract::config()->logging->level = 'quiet';
+ } else {
+ DocBlox_Core_Abstract::config()->logging->level = 'debug';
+ }
+
+ $bootstrap->registerPlugins($autoloader);
+ }
+
+ /**
+ * Build a list of files (from the fileset elements) and call the DocBlox parser
+ * @return string
+ */
+ private function parseFiles()
+ {
+ $parser = new DocBlox_Parser();
+
+ //Only initialize the dispatcher when not already done
+ if (is_null(DocBlox_Parser_Abstract::$event_dispatcher)) {
+ DocBlox_Parser_Abstract::$event_dispatcher = new sfEventDispatcher();
+ }
+ $parser->setTitle($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->log("Will parse " . count($paths) . " file(s)", Project::MSG_VERBOSE);
+
+ $files = new DocBlox_Parser_Files();
+ $files->addFiles($paths);
+
+ $parser->setPath($files->getProjectRoot());
+
+ return $parser->parseFiles($files);
+ }
+
+ /**
+ * 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 (<fileset>)", $this->getLocation());
+ }
+
+ $this->initializeDocBlox();
+
+ $xml = $this->parseFiles();
+
+ $this->log("Transforming...", Project::MSG_VERBOSE);
+
+ $transformer = new DocBlox_Transformer();
+ $transformer->setTemplatesPath(DocBlox_Core_Abstract::config()->paths->templates);
+ $transformer->setTemplates($this->template);
+ $transformer->setSource($xml);
+ $transformer->setTarget($this->destDir->getAbsolutePath());
+ $transformer->execute();
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitBaseTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitBaseTask.php
new file mode 100644
index 00000000..8381cc64
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitBaseTask.php
@@ -0,0 +1,134 @@
+<?php
+/*
+ * $Id: 5ffc8c9c51dfa9bd0d691a88db670cdeb5f985c1 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/BuildException.php';
+
+/**
+ * Base class for Git tasks
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 5ffc8c9c51dfa9bd0d691a88db670cdeb5f985c1 $
+ * @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;
+ }
+
+ 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.');
+
+ }
+ }
+ $this->gitClient->setGitCommandPath($this->getGitPath());
+
+ return $this->gitClient;
+ }
+}
+
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitBranchTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitBranchTask.php
new file mode 100644
index 00000000..54a0eb20
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitBranchTask.php
@@ -0,0 +1,296 @@
+<?php
+/*
+ * $Id: 88a8737d783614bcd5acb103738fafc23c509225 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-branch
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 88a8737d783614bcd5acb103738fafc23c509225 $
+ * @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.');
+ }
+
+ $this->log(
+ sprintf('git-branch: branch "%s" repository', $this->getRepository()),
+ Project::MSG_INFO);
+ $this->log('git-branch output: ' . trim($output), Project::MSG_INFO);
+ }
+
+ public function setSetUpstream($flag)
+ {
+ $this->setUpstream = $flag;
+ }
+
+ public function getSetUpstream()
+ {
+ return $this->setUpstream;
+ }
+
+ public function isSetUpstream()
+ {
+ return $this->getSetUpstream();
+ }
+
+ public function setTrack($flag)
+ {
+ $this->track = $flag;
+ }
+
+ public function getTrack()
+ {
+ return $this->track;
+ }
+
+ public function isTrack()
+ {
+ return $this->getTrack();
+ }
+
+ public function setNoTrack($flag)
+ {
+ $this->noTrack = $flag;
+ }
+
+ public function getNoTrack()
+ {
+ return $this->noTrack;
+ }
+
+ public function isNoTrack()
+ {
+ return $this->getNoTrack();
+ }
+
+ public function setForce($flag)
+ {
+ $this->force = $flag;
+ }
+
+ public function getForce()
+ {
+ return $this->force;
+ }
+
+ public function isForce()
+ {
+ return $this->getForce();
+ }
+
+ public function setBranchname($branchname)
+ {
+ $this->branchname = $branchname;
+ }
+
+ public function getBranchname()
+ {
+ return $this->branchname;
+ }
+
+ public function setStartPoint($startPoint)
+ {
+ $this->startPoint = $startPoint;
+ }
+
+ public function getStartPoint()
+ {
+ return $this->startPoint;
+ }
+
+ public function setDelete($flag)
+ {
+ $this->extraOptions['d'] = $flag;
+ }
+
+ public function getDelete()
+ {
+ return $this->extraOptions['d'];
+ }
+
+ public function isDelete()
+ {
+ return $this->getDelete();
+ }
+
+ public function setForceDelete($flag)
+ {
+ $this->extraOptions['D'] = $flag;
+ }
+
+ public function getForceDelete()
+ {
+ return $this->extraOptions['D'];
+ }
+
+ public function setMove($flag)
+ {
+ $this->extraOptions['m'] = $flag;
+ }
+
+ public function getMove()
+ {
+ return $this->extraOptions['m'];
+ }
+
+ public function isMove()
+ {
+ return $this->getMove();
+ }
+
+ public function setForceMove($flag)
+ {
+ $this->extraOptions['M'] = $flag;
+ }
+
+ public function getForceMove()
+ {
+ return $this->extraOptions['M'];
+ }
+
+ public function isForceMove()
+ {
+ return $this->getForceMove();
+ }
+
+ public function setNewBranch($name)
+ {
+ $this->newbranch = $name;
+ }
+
+ public function getNewBranch()
+ {
+ return $this->newbranch;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitCheckoutTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitCheckoutTask.php
new file mode 100644
index 00000000..16a2bd9f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitCheckoutTask.php
@@ -0,0 +1,256 @@
+<?php
+/*
+ * $Id: a1dcb809b44bfd34c3af154683dd2200c814e5f0 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+/**
+ * Wrapper around git-checkout
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: a1dcb809b44bfd34c3af154683dd2200c814e5f0 $
+ * @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.');
+ }
+
+ $this->log(
+ sprintf('git-checkout: checkout "%s" repository', $this->getRepository()),
+ Project::MSG_INFO);
+ $this->log('git-checkout output: ' . trim($output), Project::MSG_INFO);
+ }
+
+ public function setBranchname($branchname)
+ {
+ $this->branchname = $branchname;
+ }
+
+ public function getBranchname()
+ {
+ return $this->branchname;
+ }
+
+ public function setStartPoint($startPoint)
+ {
+ $this->startPoint = $startPoint;
+ }
+
+ public function getStartPoint()
+ {
+ return $this->startPoint;
+ }
+
+ public function setForce($flag)
+ {
+ $this->force = $flag;
+ }
+
+ public function getForce()
+ {
+ return $this->force;
+ }
+
+ public function isForce()
+ {
+ return $this->getForce();
+ }
+
+ public function setQuiet($flag)
+ {
+ $this->quiet = $flag;
+ }
+
+ public function getQuiet()
+ {
+ return $this->quiet;
+ }
+
+ public function isQuiet()
+ {
+ return $this->getQuiet();
+ }
+
+ public function setTrack($flag)
+ {
+ $this->track = $flag;
+ }
+
+ public function getTrack()
+ {
+ return $this->track;
+ }
+
+ public function isTrack()
+ {
+ return $this->getTrack();
+ }
+
+ public function setNoTrack($flag)
+ {
+ $this->noTrack = $flag;
+ }
+
+ public function getNoTrack()
+ {
+ return $this->noTrack;
+ }
+
+ public function isNoTrack()
+ {
+ return $this->getNoTrack();
+ }
+
+ 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
+ public function setForceCreate($flag)
+ {
+ $this->setForce($flag);
+ }
+
+ public function getForceCreate()
+ {
+ return $this->extraOptions['B'];
+ }
+
+ public function isForceCreate()
+ {
+ return $this->getForceCreate();
+ }
+
+ public function setMerge($flag)
+ {
+ $this->extraOptions['m'] = $flag;
+ }
+
+ public function getMerge()
+ {
+ return $this->extraOptions['m'];
+ }
+
+ public function isMerge()
+ {
+ return $this->getMerge();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitCloneTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitCloneTask.php
new file mode 100644
index 00000000..3d1eb76f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitCloneTask.php
@@ -0,0 +1,128 @@
+<?php
+/*
+ * $Id: 0d9ce448c11e505885b9c5362f5c2d399e205f90 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+/**
+ * Wrapper around git-clone
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 0d9ce448c11e505885b9c5362f5c2d399e205f90 $
+ * @package phing.tasks.ext.git
+ * @see VersionControl_Git
+ * @since 2.4.3
+ */
+class GitCloneTask extends GitBaseTask
+{
+ /**
+ * Whether --bare key should be set for git-init
+ * @var string
+ */
+ private $isBare = false;
+
+ /**
+ * 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())
+ );
+ }
+
+ $client = $this->getGitClient(false, getcwd());
+
+ try {
+ $client->createClone(
+ $this->getRepository(),
+ $this->isBare(),
+ $this->getTargetPath());
+ } catch (Exception $e) {
+ throw new BuildException('The remote end hung up unexpectedly');
+ }
+
+ $msg = 'git-clone: cloning '
+ . ($this->isBare() ? '(bare) ' : '')
+ . '"' . $this->getRepository() .'" repository'
+ . ' to "' . $this->getTargetPath() .'" directory';
+ $this->log($msg, Project::MSG_INFO);
+ }
+
+ /**
+ * 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 string
+ */
+ public function isBare()
+ {
+ return $this->getBare();
+ }
+
+ public function getBare()
+ {
+ return $this->isBare;
+ }
+
+ public function setBare($flag)
+ {
+ $this->isBare = (bool)$flag;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitCommitTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitCommitTask.php
new file mode 100644
index 00000000..71b26ab9
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitCommitTask.php
@@ -0,0 +1,179 @@
+<?php
+/*
+ * $Id: 355a6d3cf8e182652b4acf3af0a6cd3eaa58fd02 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <jonathan.creasy@gmail.com>
+ * @see VersionControl_Git
+ * @since 2.4.3
+ */
+class GitCommitTask extends GitBaseTask
+{
+ /**
+ * Path to target directory
+ * @var string
+ */
+ private $targetPath;
+
+ private $allFiles;
+
+ private $message;
+
+ private $files;
+
+ /**
+ * 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');
+ }
+
+ if ($this->allFiles !== true && empty($this->files))
+ {
+ throw new BuildException('"allFiles" cannot be false if no files are specified.');
+ }
+
+ $client = $this->getGitClient(false, $this->getTargetPath());
+
+ $options = Array();
+
+ if ($this->allFiles === true)
+ {
+ $options['all'] = true;
+ }
+
+ $arguments = Array();
+ if ($this->allFiles !== true && is_array($this->files))
+ {
+ foreach($files as $file)
+ {
+ $arguments[] = $file;
+ }
+ }
+
+ if (!empty($this->message))
+ {
+ $arguments[] = $this->message;
+ } else {
+ $options['allow-empty-message'] = true;
+ }
+
+ try {
+ $command = $git->Command('commit');
+ $command->setArguments($arguments);
+ $command->setOptions($options);
+ $command->execute();
+ } catch (Exception $e) {
+ throw new BuildException('The remote end hung up unexpectedly');
+ }
+
+ $msg = 'git-commit: Executed git commit ';
+ foreach ($options as $option=>$value)
+ {
+
+ $msg .= ' --' . $options . '=' . $value;
+ }
+
+ foreach ($arguments as $argument)
+ {
+ $msg .= ' ' . $argument;
+ }
+
+ $this->log($msg, Project::MSG_INFO);
+ }
+
+ /**
+ * 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 getAllFiles()
+ *
+ * @return string
+ */
+ public function isallFiles()
+ {
+ return $this->getallFiles();
+ }
+
+ public function getallFiles()
+ {
+ return $this->allFiles;
+ }
+
+ public function setallFiles($flag)
+ {
+ $this->allFiles = (bool)$flag;
+ }
+
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ public function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+ public function getFiles()
+ {
+ return $this->files;
+ }
+
+ public function setFiles($files)
+ {
+ if (!$empty($files) && is_array($files))
+ {
+ $this->setallfiles(false);
+ $this->Files = $files;
+ } else {
+ $this->Files = null;
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitFetchTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitFetchTask.php
new file mode 100644
index 00000000..4b3e8a3d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitFetchTask.php
@@ -0,0 +1,284 @@
+<?php
+/*
+ * $Id: bcddbc1cd2e77003746b048568da8111b48da2fb $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-fetch
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: bcddbc1cd2e77003746b048568da8111b48da2fb $
+ * @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;
+
+ /**
+ * <group> argument to git-fetch
+ * @var string
+ */
+ private $group;
+
+ /**
+ * <repository> argument to git-fetch
+ * @var string
+ */
+ private $source = 'origin';
+
+ /**
+ * <refspec> 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()) { // <group>
+ $command->addArgument($this->getGroup());
+ } elseif ($this->getSource()) { // <repository> [<refspec>]
+ $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.');
+ }
+
+ $this->log(
+ sprintf('git-fetch: branch "%s" repository', $this->getRepository()),
+ Project::MSG_INFO);
+ $this->log('git-fetch output: ' . trim($output), Project::MSG_INFO);
+ }
+
+ public function setForce($flag)
+ {
+ $this->force = $flag;
+ }
+
+ public function getForce()
+ {
+ return $this->force;
+ }
+
+ public function isForce()
+ {
+ return $this->getForce();
+ }
+
+ public function setQuiet($flag)
+ {
+ $this->quiet = $flag;
+ }
+
+ public function getQuiet()
+ {
+ return $this->quiet;
+ }
+
+ public function isQuiet()
+ {
+ return $this->getQuiet();
+ }
+
+ public function setAll($flag)
+ {
+ $this->allRemotes = $flag;
+ }
+
+ public function getAll()
+ {
+ return $this->allRemotes;
+ }
+
+ public function isAllRemotes()
+ {
+ return $this->getAll();
+ }
+
+ public function setKeep($flag)
+ {
+ $this->keepFiles = $flag;
+ }
+
+ public function getKeep()
+ {
+ return $this->keepFiles;
+ }
+
+ public function isKeepFiles()
+ {
+ return $this->getKeep();
+ }
+
+ public function setPrune($flag)
+ {
+ $this->prune = $flag;
+ }
+
+ public function getPrune()
+ {
+ return $this->prune;
+ }
+
+ public function isPrune()
+ {
+ return $this->getPrune();
+ }
+
+ public function setNoTags($flag)
+ {
+ $this->noTags = $flag;
+ }
+
+ public function getNoTags()
+ {
+ return $this->noTags;
+ }
+
+ public function isNoTags()
+ {
+ return $this->getNoTags();
+ }
+
+ public function setTags($flag)
+ {
+ $this->tags = $flag;
+ }
+
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ public function isTags()
+ {
+ return $this->getTags();
+ }
+
+ public function setSource($source)
+ {
+ $this->source = $source;
+ }
+
+ public function getSource()
+ {
+ return $this->source;
+ }
+
+ public function setRefspec($spec)
+ {
+ $this->refspec = $spec;
+ }
+
+ public function getRefspec()
+ {
+ return $this->refspec;
+ }
+
+ public function setGroup($group)
+ {
+ $this->group = $group;
+ }
+
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitGcTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitGcTask.php
new file mode 100644
index 00000000..12de4119
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitGcTask.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * $Id: 13487520850c3a7ad71d85f02afbddfd408bfbba $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+/**
+ * Wrapper around git-gc
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 13487520850c3a7ad71d85f02afbddfd408bfbba $
+ * @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=<date>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');
+ }
+
+ $this->log(
+ sprintf('git-gc: cleaning up "%s" repository', $this->getRepository()),
+ Project::MSG_INFO);
+ }
+
+ /**
+ * @see getAggressive()
+ */
+ public function isAggressive()
+ {
+ return $this->getAggressive();
+ }
+
+ public function getAggressive()
+ {
+ return $this->isAggressive;
+ }
+
+ public function setAggressive($flag)
+ {
+ $this->isAggressive = (bool)$flag;
+ }
+
+ /**
+ * @see getAuto()
+ */
+ public function isAuto()
+ {
+ return $this->getAuto();
+ }
+
+ public function getAuto()
+ {
+ return $this->isAuto;
+ }
+
+ public function setAuto($flag)
+ {
+ $this->isAuto = (bool)$flag;
+ }
+
+ /**
+ * @see NoPrune()
+ */
+ public function isNoPrune()
+ {
+ return $this->getNoPrune();
+ }
+
+ public function getNoPrune()
+ {
+ return $this->noPrune;
+ }
+
+ public function setNoPrune($flag)
+ {
+ $this->noPrune = (bool)$flag;
+ }
+
+ public function getPrune()
+ {
+ return $this->prune;
+ }
+
+ public function setPrune($date)
+ {
+ $this->prune = $date;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitInitTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitInitTask.php
new file mode 100644
index 00000000..b4654cae
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitInitTask.php
@@ -0,0 +1,81 @@
+<?php
+/*
+ * $Id: 5e66bb51f299c733e4410258f40dcf61f6e96e2f $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/BuildException.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Repository initialization task
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 5e66bb51f299c733e4410258f40dcf61f6e96e2f $
+ * @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();
+ }
+
+ public function getBare()
+ {
+ return $this->isBare;
+ }
+
+ public function setBare($flag)
+ {
+ $this->isBare = (bool)$flag;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitLogTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitLogTask.php
new file mode 100644
index 00000000..c1d8058a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitLogTask.php
@@ -0,0 +1,270 @@
+<?php
+/*
+ * $Id: 27b94c44aa26823164ce02628de06ff8b44717f7 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-log
+ *
+ * @author Evan Kaufman <evan@digitalflophouse.com>
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 27b94c44aa26823164ce02628de06ff8b44717f7 $
+ * @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>|-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;
+
+ /**
+ * <since> argument to git-log
+ * @var string
+ */
+ private $sinceCommit;
+
+ /**
+ * <until> argument to git-log
+ * @var string
+ */
+ private $untilCommit = 'HEAD';
+
+ /**
+ * <path> 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());
+ }
+ $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');
+ }
+
+ 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);
+ }
+
+ public function setStat($stat)
+ {
+ $this->stat = $stat;
+ }
+
+ public function getStat()
+ {
+ return $this->stat;
+ }
+
+ public function setNameStatus($flag)
+ {
+ $this->nameStatus = (boolean)$flag;
+ }
+
+ public function getNameStatus()
+ {
+ return $this->nameStatus;
+ }
+
+ public function isNameStatus()
+ {
+ return $this->getNameStatus();
+ }
+
+ public function setMaxCount($count)
+ {
+ $this->maxCount = (int)$count;
+ }
+
+ public function getMaxCount()
+ {
+ return $this->maxCount;
+ }
+
+ public function setNoMerges($flag)
+ {
+ $this->noMerges = (bool)$flag;
+ }
+
+ public function getNoMerges()
+ {
+ return $this->noMerges;
+ }
+
+ public function isNoMerges()
+ {
+ return $this->getNoMerges();
+ }
+
+ public function setFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ public function getFormat()
+ {
+ return $this->format;
+ }
+
+ public function setDate($date)
+ {
+ $this->date = $date;
+ }
+
+ public function getDate()
+ {
+ return $this->date;
+ }
+
+ public function setSince($since)
+ {
+ $this->sinceCommit = $since;
+ }
+
+ public function getSince()
+ {
+ return $this->sinceCommit;
+ }
+
+ public function setAfter($after)
+ {
+ $this->setSince($after);
+ }
+
+ public function setUntil($until)
+ {
+ $this->untilCommit = $until;
+ }
+
+ public function getUntil()
+ {
+ return $this->untilCommit;
+ }
+
+ public function setBefore($before)
+ {
+ $this->setUntil($before);
+ }
+
+ public function setPaths($paths)
+ {
+ $this->paths = $paths;
+ }
+
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ public function setOutputProperty($prop)
+ {
+ $this->outputProperty = $prop;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitMergeTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitMergeTask.php
new file mode 100644
index 00000000..7a3e17fb
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitMergeTask.php
@@ -0,0 +1,258 @@
+<?php
+/*
+ * $Id: 82fabd65e9247cb37fa3fe16c122d525db4fc697 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-merge
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 82fabd65e9247cb37fa3fe16c122d525db4fc697 $
+ * @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
+{
+ /**
+ * <commit> of git-merge
+ * @var string
+ */
+ private $remote;
+
+ /**
+ * Commit message
+ * @var string
+ */
+ private $message;
+
+ /**
+ * Merge strategy. See -s <strategy> 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', '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.');
+ }
+
+ $this->log(
+ sprintf('git-merge: replaying "%s" commits', $this->getRemote()),
+ Project::MSG_INFO);
+ $this->log('git-merge output: ' . trim($output), Project::MSG_INFO);
+
+ }
+
+ public function setRemote($remote)
+ {
+ $this->remote = $remote;
+ }
+
+ public function getRemote()
+ {
+ return $this->remote;
+ }
+
+ public function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ public function setStrategy($strategy)
+ {
+ $this->strategy = $strategy;
+ }
+
+ public function getStrategy()
+ {
+ return $this->strategy;
+ }
+
+ public function setStrategyOption($strategyOption)
+ {
+ $this->strategyOption = $strategyOption;
+ }
+
+ public function getStrategyOption()
+ {
+ return $this->strategyOption;
+ }
+
+ public function setQuiet($flag)
+ {
+ $this->quiet = $flag;
+ }
+
+ public function getQuiet()
+ {
+ return $this->quiet;
+ }
+
+ public function isQuiet()
+ {
+ return $this->getQuiet();
+ }
+
+ public function setCommit($flag)
+ {
+ $this->commit = (boolean)$flag;
+ }
+
+ public function getCommit()
+ {
+ return $this->commit;
+ }
+
+ public function isCommit()
+ {
+ return $this->getCommit();
+ }
+
+ public function setNoCommit($flag)
+ {
+ $this->noCommit = (boolean)$flag;
+ }
+
+ public function getNoCommit()
+ {
+ return $this->noCommit;
+ }
+
+ public function isNoCommit()
+ {
+ return $this->getNoCommit();
+ }
+
+ public function setFastForwardCommit($flag)
+ {
+ $this->fastForwardCommit = $flag;
+ }
+
+ public function getFastForwardCommit()
+ {
+ return $this->fastForwardCommit;
+ }
+
+ public function isFastForwardCommit()
+ {
+ return $this->getFastForwardCommit();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitPullTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitPullTask.php
new file mode 100644
index 00000000..1f7cfcc1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitPullTask.php
@@ -0,0 +1,373 @@
+<?php
+/*
+ * $Id: f96a4faad59ab1b29abccd59d04269fe0c409084 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-pull
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: f96a4faad59ab1b29abccd59d04269fe0c409084 $
+ * @package phing.tasks.ext.git
+ * @see VersionControl_Git
+ * @since 2.4.3
+ */
+class GitPullTask extends GitBaseTask
+{
+ /**
+ * <repository> argument to git-pull
+ * @var string
+ */
+ private $source = 'origin';
+
+ /**
+ * <refspec> 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 <strategy> 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()) { // <repository> [<refspec>]
+ $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.');
+ }
+
+ $this->log('git-pull: complete', Project::MSG_INFO);
+ $this->log('git-pull output: ' . trim($output), Project::MSG_INFO);
+
+ }
+
+ public function setStrategy($strategy)
+ {
+ $this->strategy = $strategy;
+ }
+
+ public function getStrategy()
+ {
+ return $this->strategy;
+ }
+
+ public function setStrategyOption($strategyOption)
+ {
+ $this->strategyOption = $strategyOption;
+ }
+
+ public function getStrategyOption()
+ {
+ return $this->strategyOption;
+ }
+
+ public function setSource($source)
+ {
+ $this->source = $source;
+ }
+
+ public function getSource()
+ {
+ return $this->source;
+ }
+
+ public function setRefspec($spec)
+ {
+ $this->refspec = $spec;
+ }
+
+ public function getRefspec()
+ {
+ return $this->refspec;
+ }
+
+ public function setAll($flag)
+ {
+ $this->allRemotes = $flag;
+ }
+
+ public function getAll()
+ {
+ return $this->allRemotes;
+ }
+
+ public function isAllRemotes()
+ {
+ return $this->getAll();
+ }
+
+ public function setAppend($flag)
+ {
+ $this->append = (boolean)$flag;
+ }
+
+ public function getAppend()
+ {
+ return $this->append;
+ }
+
+ public function isAppend()
+ {
+ return $this->getAppend();
+ }
+
+ public function setKeep($flag)
+ {
+ $this->keepFiles = $flag;
+ }
+
+ public function getKeep()
+ {
+ return $this->keepFiles;
+ }
+
+ public function isKeepFiles()
+ {
+ return $this->getKeep();
+ }
+
+ public function setNoTags($flag)
+ {
+ $this->noTags = $flag;
+ }
+
+ public function getNoTags()
+ {
+ return $this->noTags;
+ }
+
+ public function isNoTags()
+ {
+ return $this->getNoTags();
+ }
+
+ public function setTags($flag)
+ {
+ $this->tags = $flag;
+ }
+
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ public function isTags()
+ {
+ return $this->getTags();
+ }
+
+ public function setQuiet($flag)
+ {
+ $this->quiet = $flag;
+ }
+
+ public function getQuiet()
+ {
+ return $this->quiet;
+ }
+
+ public function isQuiet()
+ {
+ return $this->getQuiet();
+ }
+
+ public function setRebase($flag)
+ {
+ $this->rebase = (boolean)$flag;
+ }
+
+ public function getRebase()
+ {
+ return $this->rebase;
+ }
+
+ public function isRebase()
+ {
+ return $this->getRebase();
+ }
+
+ public function setNoRebase($flag)
+ {
+ $this->noRebase = (boolean)$flag;
+ }
+
+ public function getNoRebase()
+ {
+ return $this->noRebase;
+ }
+
+ public function isNoRebase()
+ {
+ return $this->getNoRebase();
+ }
+
+ public function setForce($flag)
+ {
+ $this->force = $flag;
+ }
+
+ public function getForce()
+ {
+ return $this->force;
+ }
+
+ public function isForce()
+ {
+ return $this->getForce();
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitPushTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitPushTask.php
new file mode 100644
index 00000000..996fa57f
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitPushTask.php
@@ -0,0 +1,255 @@
+<?php
+/*
+ * $Id: a01e7e9f6cc92e419e82b4e99e4a45de6a61eba8 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper aroung git-push
+ *
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: a01e7e9f6cc92e419e82b4e99e4a45de6a61eba8 $
+ * @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;
+
+ /**
+ * <repository> argument to git-push
+ * @var string
+ */
+ private $destination = 'origin';
+
+ /**
+ * <refspec> 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()) { // <repository> [<refspec>]
+ $command->setOption('mirror', true);
+ $this->log('git-push: mirror all refs', Project::MSG_INFO);
+ } elseif ($this->getDestination()) { // <repository> [<refspec>]
+ $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.');
+ }
+
+ $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);
+ }
+
+ public function setAll($flag)
+ {
+ $this->allRemotes = $flag;
+ }
+
+ public function getAll()
+ {
+ return $this->allRemotes;
+ }
+
+ public function isAllRemotes()
+ {
+ return $this->getAll();
+ }
+
+ public function setMirror($flag)
+ {
+ $this->mirror = (boolean)$flag;
+ }
+
+ public function getMirror()
+ {
+ return $this->mirror;
+ }
+
+ public function isMirror()
+ {
+ return $this->getMirror();
+ }
+
+ public function setDelete($flag)
+ {
+ $this->delete = (boolean)$flag;
+ }
+
+ public function getDelete()
+ {
+ return $this->delete;
+ }
+
+ public function isDelete()
+ {
+ return $this->getDelete();
+ }
+
+ public function setTags($flag)
+ {
+ $this->tags = $flag;
+ }
+
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ public function isTags()
+ {
+ return $this->getTags();
+ }
+
+ public function setDestination($destination)
+ {
+ $this->destination = $destination;
+ }
+
+ public function getDestination()
+ {
+ return $this->destination;
+ }
+
+ public function setRefspec($spec)
+ {
+ $this->refspec = $spec;
+ }
+
+ public function getRefspec()
+ {
+ return $this->refspec;
+ }
+
+ public function setForce($flag)
+ {
+ $this->force = $flag;
+ }
+
+ public function getForce()
+ {
+ return $this->force;
+ }
+
+ public function isForce()
+ {
+ return $this->getForce();
+ }
+
+ public function setQuiet($flag)
+ {
+ $this->quiet = $flag;
+ }
+
+ public function getQuiet()
+ {
+ return $this->quiet;
+ }
+
+ public function isQuiet()
+ {
+ return $this->getQuiet();
+ }
+
+
+
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/git/GitTagTask.php b/buildscripts/phing/classes/phing/tasks/ext/git/GitTagTask.php
new file mode 100644
index 00000000..864e71ba
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/git/GitTagTask.php
@@ -0,0 +1,406 @@
+<?php
+/*
+ * $Id: 127d4af12e159083935466773d1af788e46acd4e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+/**
+ * Wrapper around git-tag
+ *
+ * @author Evan Kaufman <evan@digitalflophouse.com>
+ * @author Victor Farazdagi <simple.square@gmail.com>
+ * @version $Id: 127d4af12e159083935466773d1af788e46acd4e $
+ * @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;
+
+ /**
+ * <num> 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;
+
+ /**
+ * <tagname> argument to git-tag
+ * @var string
+ */
+ private $name;
+
+ /**
+ * <commit> argument to git-tag
+ * @var string
+ */
+ private $commit;
+
+ /**
+ * <object> argument to git-tag
+ * @var string
+ */
+ private $object;
+
+ /**
+ * <pattern> 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);
+ }
+
+ public function setAnnotate($flag)
+ {
+ $this->annotate = (bool)$flag;
+ }
+
+ public function getAnnotate()
+ {
+ return $this->annotate;
+ }
+
+ public function isAnnotate()
+ {
+ return $this->getAnnotate();
+ }
+
+ public function setSign($flag)
+ {
+ $this->sign = (bool)$flag;
+ }
+
+ public function getSign()
+ {
+ return $this->sign;
+ }
+
+ public function isSign()
+ {
+ return $this->getSign();
+ }
+
+ public function setKeySign($keyId)
+ {
+ $this->keySign = $keyId;
+ }
+
+ public function getKeySign()
+ {
+ return $this->keySign;
+ }
+
+ public function setReplace($flag)
+ {
+ $this->replace = (bool)$flag;
+ }
+
+ public function getReplace()
+ {
+ return $this->replace;
+ }
+
+ public function isReplace()
+ {
+ return $this->getReplace();
+ }
+
+ public function setForce($flag)
+ {
+ return $this->setReplace($flag);
+ }
+
+ public function setDelete($flag)
+ {
+ $this->delete = (bool)$flag;
+ }
+
+ public function getDelete()
+ {
+ return $this->delete;
+ }
+
+ public function isDelete()
+ {
+ return $this->getDelete();
+ }
+
+ public function setVerify($flag)
+ {
+ $this->verify = (bool)$flag;
+ }
+
+ public function getVerify()
+ {
+ return $this->verify;
+ }
+
+ public function isVerify()
+ {
+ return $this->getVerify();
+ }
+
+ public function setList($flag)
+ {
+ $this->list = (bool)$flag;
+ }
+
+ public function getList()
+ {
+ return $this->list;
+ }
+
+ public function isList()
+ {
+ return $this->getList();
+ }
+
+ public function setNum($num)
+ {
+ $this->num = (int)$num;
+ }
+
+ public function getNum()
+ {
+ return $this->num;
+ }
+
+ public function setContains($commit)
+ {
+ $this->contains = $commit;
+ }
+
+ public function getContains()
+ {
+ return $this->contains;
+ }
+
+ public function setMessage($msg)
+ {
+ $this->message = $msg;
+ }
+
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ public function setFile($file)
+ {
+ $this->file = $file;
+ }
+
+ public function getFile()
+ {
+ return $this->file;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setCommit($commit)
+ {
+ $this->commit = $commit;
+ }
+
+ public function getCommit()
+ {
+ return $this->commit;
+ }
+
+ public function setObject($object)
+ {
+ $this->object = $object;
+ }
+
+ public function getObject()
+ {
+ return $this->object;
+ }
+
+ public function setPattern($pattern)
+ {
+ $this->pattern = $pattern;
+ }
+
+ public function getPattern()
+ {
+ return $this->pattern;
+ }
+
+ public function setOutputProperty($prop)
+ {
+ $this->outputProperty = $prop;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php
index 76780fa6..38ec99d4 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: IoncubeComment.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: dbbc1b4830ba43116d5b5e5d20c749598eaf62b7 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -22,23 +22,22 @@
/**
* Wrapper for comments for ionCube tasks
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: IoncubeComment.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: dbbc1b4830ba43116d5b5e5d20c749598eaf62b7 $
* @package phing.tasks.ext.ioncube
* @since 2.2.0
*/
class IoncubeComment
{
- private $value = "";
-
- public function getValue()
- {
- return $this->value;
- }
-
- public function addText($txt)
- {
- $this->value = trim($txt);
- }
+ private $value = "";
+
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ public function addText($txt)
+ {
+ $this->value = trim($txt);
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php
index 9eecd5a0..5a31f355 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: IoncubeEncoderTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: a6ce870b3d14be7f365468e3a272e5ac16128e93 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -25,312 +25,618 @@ require_once 'phing/tasks/ext/ioncube/IoncubeComment.php';
/**
* Invokes the ionCube Encoder (PHP4 or PHP5)
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: IoncubeEncoderTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @author Domenico Sgarbossa <sbraaaa@yahoo.it>
+ * @version $Id: a6ce870b3d14be7f365468e3a272e5ac16128e93 $
* @package phing.tasks.ext.ioncube
* @since 2.2.0
*/
class IoncubeEncoderTask extends Task
{
- private $phpVersion = "5";
- private $ioncubePath = "/usr/local/ioncube";
- private $encoderName = "ioncube_encoder";
-
- private $fromDir = "";
- private $toDir = "";
-
- private $encrypt = "";
-
- private $targetOption = "";
- private $binary = false;
- private $optimize = "";
- private $withoutRuntimeLoaderSupport = false;
-
- private $licensePath = "";
- private $passPhrase = "";
-
- private $comments = array();
-
- /**
- * Sets the path to the ionCube encoder
- */
- function setIoncubePath($ioncubePath)
- {
- $this->ioncubePath = $ioncubePath;
- }
-
- /**
- * Returns the path to the ionCube encoder
- */
- function getIoncubePath()
- {
- return $this->ioncubePath;
- }
-
- /**
- * Sets the version of PHP to use (defaults to 5)
- */
- function setPhpVersion($phpVersion)
- {
- $this->phpVersion = $phpVersion;
- }
-
- /**
- * Returns the version of PHP to use (defaults to 5)
- */
- function getPhpVersion()
- {
- return $this->phpVersion;
- }
-
- /**
- * Sets the source directory
- */
- function setFromDir($fromDir)
- {
- $this->fromDir = $fromDir;
- }
-
- /**
- * Returns the source directory
- */
- function getFromDir($fromDir)
- {
- return $this->fromDir;
- }
-
- /**
- * Sets the target directory
- */
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
-
- /**
- * Returns the target directory
- */
- function getToDir($toDir)
- {
- return $this->toDir;
- }
-
- /**
- * Sets regexps of additional files to encrypt (separated by space)
- */
- function setEncrypt($encrypt)
- {
- $this->encrypt = $encrypt;
- }
-
- /**
- * Returns regexps of additional files to encrypt (separated by space)
- */
- function getEncrypt()
- {
- return $this->encrypt;
- }
-
- /**
- * Sets the binary option
- */
- function setBinary($binary)
- {
- $this->binary = $binary;
- }
-
- /**
- * Returns the binary option
- */
- function getBinary()
- {
- return $this->binary;
- }
-
- /**
- * Sets the optimize option
- */
- function setOptimize($optimize)
- {
- $this->optimize = $optimize;
- }
-
- /**
- * Returns the optimize option
- */
- function getOptimize()
- {
- return $this->optimize;
- }
-
- /**
- * Sets the without-runtime-loader-support option
- */
- function setWithoutRuntimeLoaderSupport($withoutRuntimeLoaderSupport)
- {
- $this->withoutRuntimeLoaderSupport = $withoutRuntimeLoaderSupport;
- }
-
- /**
- * Returns the without-runtime-loader-support option
- */
- function getWithoutRuntimeLoaderSupport()
- {
- return $this->withoutRuntimeLoaderSupport;
- }
-
- /**
- * Sets the option to use when encoding target directory already exists (defaults to none)
- */
- function setTargetOption($targetOption)
- {
- $this->targetOption = $targetOption;
- }
-
- /**
- * Returns he option to use when encoding target directory already exists (defaults to none)
- */
- function getTargetOption()
- {
- return $this->targetOption;
- }
-
- /**
- * Sets the path to the license file to use
- */
- function setLicensePath($licensePath)
- {
- $this->licensePath = $licensePath;
- }
-
- /**
- * Returns the path to the license file to use
- */
- function getLicensePath()
- {
- return $this->licensePath;
- }
-
- /**
- * Sets the passphrase to use when encoding files
- */
- function setPassPhrase($passPhrase)
- {
- $this->passPhrase = $passPhrase;
- }
-
- /**
- * Returns the passphrase to use when encoding files
- */
- function getPassPhrase()
- {
- return $this->passPhrase;
- }
-
- /**
- * Adds a comment to be used in encoded files
- */
- function addComment(IoncubeComment $comment)
- {
- $this->comments[] = $comment;
- }
-
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $arguments = $this->constructArguments();
-
- $encoder = new PhingFile($this->ioncubePath, $this->encoderName . ($this->phpVersion == 5 ? '5' : ''));
-
- $this->log("Running ionCube Encoder...");
-
- exec($encoder->__toString() . " " . $arguments . " 2>&1", $output, $return);
-
+ private $ionSwitches = array();
+
+ private $ionOptions = array();
+
+ private $ionOptionsXS = array();
+
+ private $comments = array();
+
+ private $encoderName = 'ioncube_encoder';
+
+ private $fromDir = '';
+
+ private $ioncubePath = '/usr/local/ioncube';
+
+ private $phpVersion = '5';
+
+ private $targetOption = '';
+
+ private $toDir = '';
+
+ private $showCommandLine = false;
+
+ /**
+ * Sets whether to show command line before it is executed
+ */
+ function setShowCommandLine($value)
+ {
+ $this->showCommandLine = $value;
+ }
+
+ /**
+ * Adds a comment to be used in encoded files
+ */
+ function addComment(IoncubeComment $comment)
+ {
+ $this->comments[] = $comment;
+ }
+
+ /**
+ * Sets the allowed server
+ */
+ function setAllowedServer($value)
+ {
+ $this->ionOptionsXS['allowed-server'] = $value;
+ }
+
+ /**
+ * Returns the allowed server setting
+ */
+ function getAllowedServer()
+ {
+ return $this->ionOptionsXS['allowed-server'];
+ }
+
+ /**
+ * Sets the binary option
+ */
+ function setBinary($value)
+ {
+ $this->ionSwitches['binary'] = $value;
+ }
+
+ /**
+ * Returns the binary option
+ */
+ function getBinary()
+ {
+ return $this->ionSwitches['binary'];
+ }
+
+ /**
+ * Sets files or folders to copy (separated by space)
+ */
+ function setCopy($value)
+ {
+ $this->ionOptionsXS['copy'] = $value;
+ }
+
+ /**
+ * Returns the copy setting
+ */
+ function getCopy()
+ {
+ return $this->ionOptionsXS['copy'];
+ }
+
+ /**
+ * Sets additional file patterns, files or directories to encode,
+ * or to reverse the effect of copy (separated by space)
+ */
+ function setEncode($value)
+ {
+ $this->ionOptionsXS['encode'] = $value;
+ }
+
+ /**
+ * Returns the encode setting
+ */
+ function getEncode()
+ {
+ return $this->ionOptionsXS['encode'];
+ }
+
+ /**
+ * Sets regexps of additional files to encrypt (separated by space)
+ */
+ function setEncrypt($value)
+ {
+ $this->ionOptionsXS['encrypt'] = $value;
+ }
+
+ /**
+ * Returns regexps of additional files to encrypt (separated by space)
+ */
+ function getEncrypt()
+ {
+ return $this->ionOptionsXS['encrypt'];
+ }
+
+ /**
+ * Sets a period after which the files expire
+ */
+ function setExpirein($value)
+ {
+ $this->ionOptions['expire-in'] = $value;
+ }
+
+ /**
+ * Returns the expireIn setting
+ */
+ function getExpirein()
+ {
+ return $this->ionOptions['expire-in'];
+ }
+
+ /**
+ * Sets a YYYY-MM-DD date to expire the files
+ */
+ function setExpireon($value)
+ {
+ $this->ionOptions['expire-on'] = $value;
+ }
+
+ /**
+ * Returns the expireOn setting
+ */
+ function getExpireon()
+ {
+ return $this->ionOptions['expire-on'];
+ }
+
+ /**
+ * Sets the source directory
+ */
+ function setFromDir($value)
+ {
+ $this->fromDir = $value;
+ }
+
+ /**
+ * Returns the source directory
+ */
+ function getFromDir()
+ {
+ return $this->fromDir;
+ }
+
+ /**
+ * Set files and directories to ignore entirely and exclude from the target directory
+ * (separated by space).
+ */
+ function setIgnore($value)
+ {
+ $this->ionOptionsXS['ignore'] = $value;
+ }
+
+ /**
+ * Returns the ignore setting
+ */
+ function getIgnore()
+ {
+ return $this->ionOptionsXS['ignore'];
+ }
+
+ /**
+ * Sets the path to the ionCube encoder
+ */
+ function setIoncubePath($value)
+ {
+ $this->ioncubePath = $value;
+ }
+
+ /**
+ * Returns the path to the ionCube encoder
+ */
+ function getIoncubePath()
+ {
+ return $this->ioncubePath;
+ }
+
+ /**
+ * Set files and directories not to be ignored (separated by space).
+ */
+ function setKeep($value)
+ {
+ $this->ionOptionsXS['keep'] = $value;
+ }
+
+ /**
+ * Returns the ignore setting
+ */
+ function getKeep()
+ {
+ return $this->ionOptionsXS['keep'];
+ }
+
+ /**
+ * Sets the path to the license file to use
+ */
+ function setLicensePath($value)
+ {
+ $this->ionOptions['with-license'] = $value;
+ }
+
+ /**
+ * Returns the path to the license file to use
+ */
+ function getLicensePath()
+ {
+ return $this->ionOptions['with-license'];
+ }
+
+ /**
+ * Sets the no-doc-comments option
+ */
+ function setNoDocComments($value)
+ {
+ $this->ionSwitches['no-doc-comment'] = $value;
+ }
+
+ /**
+ * Returns the no-doc-comments option
+ */
+ function getNoDocComments()
+ {
+ return $this->ionSwitches['no-doc-comment'];
+ }
+
+ /**
+ * Sets the obfuscate option
+ */
+ function setObfuscate($value)
+ {
+ $this->ionOptionsXS['obfuscate'] = $value;
+ }
+
+ /**
+ * Returns the optimize option
+ */
+ function getObfuscate()
+ {
+ return $this->ionOptionsXS['obfuscate'];
+ }
+
+ /**
+ * Sets the obfuscation key (required if using the obfuscate option)
+ */
+ function setObfuscationKey($value)
+ {
+ $this->ionOptions['obfuscation-key'] = $value;
+ }
+
+ /**
+ * Returns the optimize option
+ */
+ function getObfuscationKey()
+ {
+ return $this->ionOptions['obfuscation-key'];
+ }
+
+ /**
+ * Sets the optimize option
+ */
+ function setOptimize($value)
+ {
+ $this->ionOptions['optimize'] = $value;
+ }
+
+ /**
+ * Returns the optimize option
+ */
+ function getOptimize()
+ {
+ return $this->ionOptions['optimize'];
+ }
+
+ /**
+ * Sets the passphrase to use when encoding files
+ */
+ function setPassPhrase($value)
+ {
+ $this->ionOptions['passphrase'] = $value;
+ }
+
+ /**
+ * Returns the passphrase to use when encoding files
+ */
+ function getPassPhrase()
+ {
+ return $this->ionOptions['passphrase'];
+ }
+
+ /**
+ * Sets the version of PHP to use (defaults to 5)
+ */
+ function setPhpVersion($value)
+ {
+ $this->phpVersion = $value;
+ }
+
+ /**
+ * Returns the version of PHP to use (defaults to 5)
+ */
+ function getPhpVersion()
+ {
+ return $this->phpVersion;
+ }
+
+ /**
+ * Sets the target directory
+ */
+ function setToDir($value)
+ {
+ $this->toDir = $value;
+ }
+
+ /**
+ * Returns the target directory
+ */
+ function getToDir()
+ {
+ return $this->toDir;
+ }
+
+ /**
+ * Sets the without-runtime-loader-support option
+ */
+ function setWithoutRuntimeLoaderSupport($value)
+ {
+ $this->ionSwitches['without-runtime-loader-support'] = $value;
+ }
+
+ /**
+ * Returns the without-runtime-loader-support option
+ */
+ function getWithoutRuntimeLoaderSupport()
+ {
+ return $this->ionSwitches['without-runtime-loader-support'];
+ }
+
+ /**
+ * Sets the no-short-open-tags option
+ */
+ function setNoShortOpenTags($value)
+ {
+ $this->ionSwitches['no-short-open-tags'] = $value;
+ }
+
+ /**
+ * Returns the no-short-open-tags option
+ */
+ function getNoShortOpenTags()
+ {
+ return $this->ionSwitches['no-short-open-tags'];
+ }
+
+ /**
+ * Sets the ignore-deprecated-warnings option
+ */
+ function setIgnoreDeprecatedWarnings($value)
+ {
+ $this->ionSwitches['ignore-deprecated-warnings'] = $value;
+ }
+
+ /**
+ * Returns the ignore-deprecated-warnings option
+ */
+ function getIgnoreDeprecatedWarnings()
+ {
+ return $this->ionSwitches['ignore-deprecated-warnings'];
+ }
+
+ /**
+ * Sets the ignore-strict-warnings option
+ */
+ function setIgnoreStrictWarnings($value)
+ {
+ $this->ionSwitches['ignore-strict-warnings'] = $value;
+ }
+
+ /**
+ * Returns the ignore-strict-warnings option
+ */
+ function getIgnoreStrictWarnings()
+ {
+ return $this->ionSwitches['ignore-strict-warnings'];
+ }
+
+ /**
+ * Sets the allow-encoding-into-source option
+ */
+ function setAllowEncodingIntoSource($value)
+ {
+ $this->ionSwitches['allow-encoding-into-source'] = $value;
+ }
+
+ /**
+ * Returns the allow-encoding-into-source option
+ */
+ function getAllowEncodingIntoSource()
+ {
+ return $this->ionSwitches['allow-encoding-into-source'];
+ }
+
+ /**
+ * Sets the message-if-no-loader option
+ */
+ function setMessageIfNoLoader($value)
+ {
+ $this->ionOptions['message-if-no-loader'] = $value;
+ }
+
+ /**
+ * Returns the message-if-no-loader option
+ */
+ function getMessageIfNoLoader()
+ {
+ return $this->ionOptions['message-if-no-loader'];
+ }
+
+ /**
+ * Sets the action-if-no-loader option
+ */
+ function setActionIfNoLoader($value)
+ {
+ $this->ionOptions['action-if-no-loader'] = $value;
+ }
+
+ /**
+ * Returns the action-if-no-loader option
+ */
+ function getActionIfNoLoader()
+ {
+ return $this->ionOptions['action-if-no-loader'];
+ }
+
+ /**
+ * Sets the option to use when encoding target directory already exists (defaults to none)
+ */
+ function setTargetOption($targetOption)
+ {
+ $this->targetOption = $targetOption;
+ }
+
+ /**
+ * Returns he option to use when encoding target directory already exists (defaults to none)
+ */
+ function getTargetOption()
+ {
+ return $this->targetOption;
+ }
+
+ /**
+ * Sets the callback-file option
+ */
+ function setCallbackFile($value)
+ {
+ $this->ionOptions['callback-file'] = $value;
+ }
+
+ /**
+ * Returns the callback-file option
+ */
+ function getCallbackFile()
+ {
+ return $this->ionOptions['callback-file'];
+ }
+
+ /**
+ * Sets the obfuscation-exclusions-file option
+ */
+ function setObfuscationExclusionFile($value)
+ {
+ $this->ionOptions['obfuscation-exclusion-file'] = $value;
+ }
+
+ /**
+ * Returns the obfuscation-exclusions-file option
+ */
+ function getObfuscationExclusionFile()
+ {
+ return $this->ionOptions['obfuscation-exclusion-file'];
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $arguments = $this->constructArguments();
+
+ $encoder = new PhingFile($this->ioncubePath, $this->encoderName . ($this->phpVersion == 5 ? '5' : ''));
+
+ $this->log("Running ionCube Encoder...");
+
+ if ($this->showCommandLine)
+ {
+ $this->log("Command line: ".$encoder->__toString() . ' ' . $arguments);
+ }
+
+ exec($encoder->__toString() . ' ' . $arguments . " 2>&1", $output, $return);
+
if ($return != 0)
{
- throw new BuildException("Could not execute ionCube Encoder: " . implode(' ', $output));
+ throw new BuildException("Could not execute ionCube Encoder: " . implode(' ', $output));
}
- }
-
- /**
- * Constructs an argument string for the ionCube encoder
- */
- private function constructArguments()
- {
- $arguments = "";
-
- if ($this->binary)
- {
- $arguments.= "--binary ";
- }
-
- if (!empty($this->optimize))
- {
- $arguments.= "--optimize " . $this->optimize . " ";
- }
-
- if ($this->withoutRuntimeLoaderSupport)
- {
- $arguments.= "--without-runtime-loader-support ";
- }
-
- if (!empty($this->targetOption))
- {
- switch ($this->targetOption)
- {
- case "replace":
- case "merge":
- case "update":
- case "rename":
- {
- $arguments.= "--" . $this->targetOption . "-target ";
- } break;
-
- default:
- {
- throw new BuildException("Unknown target option '" . $this->targetOption . "'");
- } break;
- }
- }
-
- if (!empty($this->encrypt))
- {
- foreach (explode(" ", $this->encrypt) as $encrypt)
- {
- $arguments.= "--encrypt '$encrypt' ";
- }
- }
-
- if (!empty($this->licensePath))
- {
- $arguments.= "--with-license '" . $this->licensePath . "' ";
- }
-
- if (!empty($this->passPhrase))
- {
- $arguments.= "--passphrase '" . $this->passPhrase . "' ";
- }
-
- foreach ($this->comments as $comment)
- {
- $arguments.= "--add-comment '" . $comment->getValue() . "' ";
- }
-
- if ($this->fromDir != "")
- {
- $arguments .= $this->fromDir . " ";
- }
-
- if ($this->toDir != "")
- {
- $arguments .= "-o " . $this->toDir . " ";
- }
-
- return $arguments;
- }
+ }
+
+ /**
+ * Constructs an argument string for the ionCube encoder
+ */
+ private function constructArguments()
+ {
+ $arguments = '';
+
+ foreach ($this->ionSwitches as $name => $value)
+ {
+ if ($value)
+ {
+ $arguments.= "--$name ";
+ }
+ }
+
+ foreach ($this->ionOptions as $name => $value)
+ {
+ /**
+ * action-if-no-loader value is a php source snippet so it is
+ * better to handle it this way to prevent quote problems!
+ */
+ if ($name == 'action-if-no-loader')
+ {
+ $arguments.= "--$name \"$value\" ";
+ }
+ else
+ {
+ $arguments.= "--$name '$value' ";
+ }
+ }
+
+ foreach ($this->ionOptionsXS as $name => $value)
+ {
+ foreach (explode(' ', $value) as $arg)
+ {
+ $arguments.= "--$name '$arg' ";
+ }
+ }
+
+ foreach ($this->comments as $comment)
+ {
+ $arguments.= "--add-comment '" . $comment->getValue() . "' ";
+ }
+
+ if (!empty($this->targetOption))
+ {
+ switch ($this->targetOption)
+ {
+ case "replace":
+ case "merge":
+ case "update":
+ case "rename":
+ {
+ $arguments.= "--" . $this->targetOption . "-target ";
+ } break;
+
+ default:
+ {
+ throw new BuildException("Unknown target option '" . $this->targetOption . "'");
+ } break;
+ }
+ }
+
+ if ($this->fromDir != '')
+ {
+ $arguments .= $this->fromDir . ' ';
+ }
+
+ if ($this->toDir != '')
+ {
+ $arguments .= "-o " . $this->toDir . ' ';
+ }
+
+ return $arguments;
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php
index 70abd544..6e7ab68a 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: IoncubeLicenseTask.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 555e4853cd742e4ef733e3df4051c49cda527b73 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -25,120 +25,184 @@ require_once 'phing/tasks/ext/ioncube/IoncubeComment.php';
/**
* Invokes the ionCube "make_license" program
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: IoncubeLicenseTask.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 555e4853cd742e4ef733e3df4051c49cda527b73 $
* @package phing.tasks.ext.ioncube
* @since 2.2.0
*/
class IoncubeLicenseTask extends Task
{
- private $ioncubePath = "/usr/local/ioncube";
-
- private $licensePath = "";
- private $passPhrase = "";
-
- private $comments = array();
-
- /**
- * Sets the path to the ionCube encoder
- */
- function setIoncubePath($ioncubePath)
- {
- $this->ioncubePath = $ioncubePath;
- }
+ private $ioncubePath = "/usr/local/ioncube";
+
+ private $licensePath = "";
+ private $passPhrase = "";
+ private $allowedServer = "";
+ private $expireOn = "";
+ private $expireIn = "";
+ private $comments = array();
- /**
- * Returns the path to the ionCube encoder
- */
- function getIoncubePath()
- {
- return $this->ioncubePath;
- }
+ /**
+ * Sets the path to the ionCube encoder
+ */
+ function setIoncubePath($ioncubePath)
+ {
+ $this->ioncubePath = $ioncubePath;
+ }
- /**
- * Sets the path to the license file to use
- */
- function setLicensePath($licensePath)
- {
- $this->licensePath = $licensePath;
- }
+ /**
+ * Returns the path to the ionCube encoder
+ */
+ function getIoncubePath()
+ {
+ return $this->ioncubePath;
+ }
- /**
- * Returns the path to the license file to use
- */
- function getLicensePath()
- {
- return $this->licensePath;
- }
+ /**
+ * Sets the path to the license file to use
+ */
+ function setLicensePath($licensePath)
+ {
+ $this->licensePath = $licensePath;
+ }
- /**
- * Sets the passphrase to use when encoding files
- */
- function setPassPhrase($passPhrase)
- {
- $this->passPhrase = $passPhrase;
- }
+ /**
+ * Returns the path to the license file to use
+ */
+ function getLicensePath()
+ {
+ return $this->licensePath;
+ }
- /**
- * Returns the passphrase to use when encoding files
- */
- function getPassPhrase()
- {
- return $this->passPhrase;
- }
+ /**
+ * Sets the passphrase to use when encoding files
+ */
+ function setPassPhrase($passPhrase)
+ {
+ $this->passPhrase = $passPhrase;
+ }
- /**
- * Adds a comment to be used in encoded files
- */
- function addComment(IoncubeComment $comment)
- {
- $this->comments[] = $comment;
- }
+ /**
+ * Returns the passphrase to use when encoding files
+ */
+ function getPassPhrase()
+ {
+ return $this->passPhrase;
+ }
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $arguments = $this->constructArguments();
-
- $makelicense = new PhingFile($this->ioncubePath, 'make_license');
-
- $this->log("Running ionCube make_license...");
-
- exec($makelicense->__toString() . " " . $arguments . " 2>&1", $output, $return);
-
+ /**
+ * Adds a comment to be used in encoded files
+ */
+ function addComment(IoncubeComment $comment)
+ {
+ $this->comments[] = $comment;
+ }
+
+ /**
+ * Sets the --allowed-server option to use when generating the license
+ */
+ function setAllowedServer($allowedServer)
+ {
+ $this->allowedServer = $allowedServer;
+ }
+
+ /**
+ * Returns the --allowed-server option
+ */
+ function getAllowedServer()
+ {
+ return $this->allowedServer;
+ }
+
+ /**
+ * Sets the --expire-on option to use when generating the license
+ */
+ function setExpireOn($expireOn)
+ {
+ $this->expireOn = $expireOn;
+ }
+
+ /**
+ * Returns the --expire-on option
+ */
+ function getExpireOn()
+ {
+ return $this->expireOn;
+ }
+
+ /**
+ * Sets the --expire-in option to use when generating the license
+ */
+ function setExpireIn($expireIn)
+ {
+ $this->expireIn = $expireIn;
+ }
+
+ /**
+ * Returns the --expire-in option
+ */
+ function getExpireIn()
+ {
+ return $this->expireIn;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $arguments = $this->constructArguments();
+
+ $makelicense = new PhingFile($this->ioncubePath, 'make_license');
+
+ $this->log("Running ionCube make_license...");
+
+ exec($makelicense->__toString() . " " . $arguments . " 2>&1", $output, $return);
+
if ($return != 0)
{
- throw new BuildException("Could not execute ionCube make_license: " . implode(' ', $output));
+ throw new BuildException("Could not execute ionCube make_license: " . implode(' ', $output));
}
- }
+ }
+
+ /**
+ * Constructs an argument string for the ionCube make_license
+ */
+ private function constructArguments()
+ {
+ $arguments = "";
+
+ if (!empty($this->passPhrase))
+ {
+ $arguments.= "--passphrase '" . $this->passPhrase . "' ";
+ }
+
+ foreach ($this->comments as $comment)
+ {
+ $arguments.= "--header-line '" . $comment->getValue() . "' ";
+ }
+
+ if (!empty($this->licensePath))
+ {
+ $arguments.= "--o '" . $this->licensePath . "' ";
+ }
- /**
- * Constructs an argument string for the ionCube make_license
- */
- private function constructArguments()
+ if (!empty($this->allowedServer))
{
- $arguments = "";
-
- if (!empty($this->passPhrase))
- {
- $arguments.= "--passphrase '" . $this->passPhrase . "' ";
- }
-
- foreach ($this->comments as $comment)
- {
- $arguments.= "--header-line '" . $comment->getValue() . "' ";
- }
-
- if (!empty($this->licensePath))
- {
- $arguments.= "--o '" . $this->licensePath . "' ";
- }
-
- return $arguments;
+ $arguments.= "--allowed-server {" . $this->allowedServer . "} ";
}
+
+ if (!empty($this->expireOn))
+ {
+ $arguments.= "--expire-on " . $this->expireOn . " ";
+ }
+
+ if (!empty($this->expireIn))
+ {
+ $arguments.= "--expire-in " . $this->expireIn . " ";
+ }
+
+ return $arguments;
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMin.php b/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMin.php
new file mode 100644
index 00000000..44766fc1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMin.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ * jsmin.php - PHP implementation of Douglas Crockford's JSMin.
+ *
+ * This is pretty much a direct port of jsmin.c to PHP with just a few
+ * PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and
+ * outputs to stdout, this library accepts a string as input and returns another
+ * string as output.
+ *
+ * PHP 5 or higher is required.
+ *
+ * Permission is hereby granted to use this version of the library under the
+ * same terms as jsmin.c, which has the following license:
+ *
+ * --
+ * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * --
+ *
+ * @package JSMin
+ * @author Ryan Grove <ryan@wonko.com>
+ * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
+ * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 1.1.1 (2008-03-02)
+ * @link http://code.google.com/p/jsmin-php/
+ */
+
+class JSMin {
+ const ORD_LF = 10;
+ const ORD_SPACE = 32;
+
+ protected $a = '';
+ protected $b = '';
+ protected $input = '';
+ protected $inputIndex = 0;
+ protected $inputLength = 0;
+ protected $lookAhead = null;
+ protected $output = '';
+
+ // -- Public Static Methods --------------------------------------------------
+
+ public static function minify($js) {
+ $jsmin = new JSMin($js);
+ return $jsmin->min();
+ }
+
+ // -- Public Instance Methods ------------------------------------------------
+
+ public function __construct($input) {
+ $this->input = str_replace("\r\n", "\n", $input);
+ $this->inputLength = strlen($this->input);
+ }
+
+ // -- Protected Instance Methods ---------------------------------------------
+
+ protected function action($d) {
+ switch($d) {
+ case 1:
+ $this->output .= $this->a;
+
+ case 2:
+ $this->a = $this->b;
+
+ if ($this->a === "'" || $this->a === '"') {
+ for (;;) {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+
+ if ($this->a === $this->b) {
+ break;
+ }
+
+ if (ord($this->a) <= self::ORD_LF) {
+ throw new JSMinException('Unterminated string literal.');
+ }
+
+ if ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ }
+ }
+ }
+
+ case 3:
+ $this->b = $this->next();
+
+ if ($this->b === '/' && (
+ $this->a === '(' || $this->a === ',' || $this->a === '=' ||
+ $this->a === ':' || $this->a === '[' || $this->a === '!' ||
+ $this->a === '&' || $this->a === '|' || $this->a === '?')) {
+
+ $this->output .= $this->a . $this->b;
+
+ for (;;) {
+ $this->a = $this->get();
+
+ if ($this->a === '/') {
+ break;
+ } elseif ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ } elseif (ord($this->a) <= self::ORD_LF) {
+ throw new JSMinException('Unterminated regular expression '.
+ 'literal.');
+ }
+
+ $this->output .= $this->a;
+ }
+
+ $this->b = $this->next();
+ }
+ }
+ }
+
+ protected function get() {
+ $c = $this->lookAhead;
+ $this->lookAhead = null;
+
+ if ($c === null) {
+ if ($this->inputIndex < $this->inputLength) {
+ $c = $this->input[$this->inputIndex];
+ $this->inputIndex += 1;
+ } else {
+ $c = null;
+ }
+ }
+
+ if ($c === "\r") {
+ return "\n";
+ }
+
+ if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {
+ return $c;
+ }
+
+ return ' ';
+ }
+
+ protected function isAlphaNum($c) {
+ return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
+ }
+
+ protected function min() {
+ $this->a = "\n";
+ $this->action(3);
+
+ while ($this->a !== null) {
+ switch ($this->a) {
+ case ' ':
+ if ($this->isAlphaNum($this->b)) {
+ $this->action(1);
+ } else {
+ $this->action(2);
+ }
+ break;
+
+ case "\n":
+ switch ($this->b) {
+ case '{':
+ case '[':
+ case '(':
+ case '+':
+ case '-':
+ $this->action(1);
+ break;
+
+ case ' ':
+ $this->action(3);
+ break;
+
+ default:
+ if ($this->isAlphaNum($this->b)) {
+ $this->action(1);
+ }
+ else {
+ $this->action(2);
+ }
+ }
+ break;
+
+ default:
+ switch ($this->b) {
+ case ' ':
+ if ($this->isAlphaNum($this->a)) {
+ $this->action(1);
+ break;
+ }
+
+ $this->action(3);
+ break;
+
+ case "\n":
+ switch ($this->a) {
+ case '}':
+ case ']':
+ case ')':
+ case '+':
+ case '-':
+ case '"':
+ case "'":
+ $this->action(1);
+ break;
+
+ default:
+ if ($this->isAlphaNum($this->a)) {
+ $this->action(1);
+ }
+ else {
+ $this->action(3);
+ }
+ }
+ break;
+
+ default:
+ $this->action(1);
+ break;
+ }
+ }
+ }
+
+ return $this->output;
+ }
+
+ protected function next() {
+ $c = $this->get();
+
+ if ($c === '/') {
+ switch($this->peek()) {
+ case '/':
+ for (;;) {
+ $c = $this->get();
+
+ if (ord($c) <= self::ORD_LF) {
+ return $c;
+ }
+ }
+
+ case '*':
+ $this->get();
+
+ for (;;) {
+ switch($this->get()) {
+ case '*':
+ if ($this->peek() === '/') {
+ $this->get();
+ return ' ';
+ }
+ break;
+
+ case null:
+ throw new JSMinException('Unterminated comment.');
+ }
+ }
+
+ default:
+ return $c;
+ }
+ }
+
+ return $c;
+ }
+
+ protected function peek() {
+ $this->lookAhead = $this->get();
+ return $this->lookAhead;
+ }
+}
+
+/**
+ * @package JSMin
+ */
+class JSMinException extends Exception {}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMinTask.php b/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMinTask.php
new file mode 100644
index 00000000..26202942
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/jsmin/JsMinTask.php
@@ -0,0 +1,145 @@
+<?php
+/*
+ * $Id: 4a9a75fcd969cfc4e26a7f2c78836389e8be7864 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/jsmin/JsMin.php';
+
+/**
+ * Task to minify javascript files.
+ *
+ * Requires JSMin which can be found at http://code.google.com/p/jsmin-php/ but
+ * is bundled with Phing so no additional install of JsMin is required.
+ *
+ * @author Frank Kleine <mikey@stubbles.net>
+ * @version $Id: 4a9a75fcd969cfc4e26a7f2c78836389e8be7864 $
+ * @package phing.tasks.ext
+ * @since 2.3.0
+ */
+class JsMinTask extends Task
+{
+ /**
+ * the source files
+ *
+ * @var FileSet
+ */
+ protected $filesets = array();
+ /**
+ * Whether the build should fail, if
+ * errors occured
+ *
+ * @var boolean
+ */
+ protected $failonerror = false;
+
+ /**
+ * Define if the target should use or not a suffix -min
+ *
+ * @var boolean
+ */
+ protected $suffix = '-min';
+
+ /**
+ * directory to put minified javascript files into
+ *
+ * @var string
+ */
+ protected $targetDir;
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num - 1];
+ }
+
+ /**
+ * Whether the build should fail, if an error occured.
+ *
+ * @param boolean $value
+ */
+ public function setFailonerror($value)
+ {
+ $this->failonerror = $value;
+ }
+
+ /**
+ * Define if the task should or not use a suffix (-min is the default)
+ *
+ * @param string $value
+ */
+ public function setSuffix($value)
+ {
+ $this->suffix = $value;
+ }
+
+ /**
+ * sets the directory where minified javascript files should be put inot
+ *
+ * @param string $targetDir
+ */
+ public function setTargetDir($targetDir)
+ {
+ $this->targetDir = $targetDir;
+ }
+
+ /**
+ * The init method: Do init steps.
+ */
+ public function init()
+ {
+ return true;
+ }
+
+ /**
+ * The main entry point method.
+ */
+ public function main()
+ {
+ foreach ($this->filesets as $fs) {
+ try {
+ $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+ $fullPath = realpath($fs->getDir($this->project));
+ foreach ($files as $file) {
+ $this->log('Minifying file ' . $file);
+ try {
+ $target = $this->targetDir . '/' . str_replace($fullPath, '', str_replace('.js', $this->suffix . '.js', $file));
+ if (file_exists(dirname($target)) === false) {
+ mkdir(dirname($target), 0700, true);
+ }
+
+ file_put_contents($target, JSMin::minify(file_get_contents($fullPath . '/' . $file)));
+ } catch (JSMinException $jsme) {
+ $this->log("Could not minify file $file: " . $jsme->getMessage(), Project::MSG_ERR);
+ }
+ }
+ } catch (BuildException $be) {
+ // directory doesn't exist or is not readable
+ if ($this->failonerror) {
+ throw $be;
+ } else {
+ $this->log($be->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+ }
+ }
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/AbstractLiquibaseTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/AbstractLiquibaseTask.php
new file mode 100755
index 00000000..fbda3ecc
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/AbstractLiquibaseTask.php
@@ -0,0 +1,184 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/system/ExecTask.php';
+
+/**
+ * Abstract Liquibase task. Base class for all Liquibase Phing tasks.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+abstract class AbstractLiquibaseTask extends Task
+{
+ protected $jar;
+ protected $changeLogFile;
+ protected $username;
+ protected $password;
+ protected $url;
+ protected $classpathref;
+
+
+ /**
+ * Sets the absolute path to liquibase jar.
+ *
+ * @param string the absolute path to the liquibase jar.
+ */
+ public function setJar($jar)
+ {
+ $this->jar = $jar;
+ }
+
+
+ /**
+ * Sets the absolute path to the changelog file to use.
+ *
+ * @param string the absolute path to the changelog file
+ */
+ public function setChangeLogFile($changelogFile)
+ {
+ $this->changeLogFile = $changelogFile;
+ }
+
+
+ /**
+ * Sets the username to connect to the database.
+ *
+ * @param string the username
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+
+
+ /**
+ * Sets the password to connect to the database.
+ *
+ * @param string the password
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+
+
+ /**
+ * Sets the url to connect to the database in jdbc style, e.g.
+ * <code>
+ * jdbc:postgresql://psqlhost/mydatabase
+ * </code>
+ *
+ * @param string jdbc connection string
+ */
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ }
+
+
+ /**
+ * Sets the Java classpathref.
+ *
+ * @param string A reference to the classpath that contains the database
+ * driver, liquibase.jar, and the changelog.xml file
+ */
+ public function setclasspathref($classpathref)
+ {
+ $this->classpathref = $classpathref;
+ }
+
+
+ /**
+ * Ensure that correct parameters were passed in.
+ *
+ * @return void
+ */
+ protected function checkParams()
+ {
+ if((null === $this->jar) or !file_exists($this->jar))
+ {
+ throw new BuildException(
+ sprintf(
+ 'Specify the name of the LiquiBase.jar. "%s" does not exist!',
+ $this->jar
+ )
+ );
+ }
+
+ if((null === $this->changeLogFile) or !file_exists($this->changeLogFile))
+ {
+ throw new BuildException(
+ sprintf(
+ 'Specify the name of the Changelog file. "%s" does not exist!',
+ $this->changeLogFile
+ )
+ );
+ }
+
+ if(null === $this->classpathref)
+ {
+ throw new BuildException('Please provide a classpath!');
+ }
+
+ if(null === $this->username)
+ {
+ throw new BuildException('Please provide a username for database acccess!');
+ }
+
+ if(null === $this->password)
+ {
+ throw new BuildException('Please provide a password for database acccess!');
+ }
+
+ if(null === $this->url)
+ {
+ throw new BuildException('Please provide a url for database acccess!');
+ }
+ }
+
+
+ /**
+ * Executes the given command and returns the output.
+ *
+ * @param string the command to execute
+ * @param string additional parameters
+ * @return string the output of the executed command
+ */
+ protected function execute($lbcommand, $lbparams = '')
+ {
+ $command = sprintf(
+ 'java -jar %s --changeLogFile=%s --url=%s --username=%s --password=%s --classpath=%s %s %s',
+ escapeshellarg($this->jar),
+ escapeshellarg($this->changeLogFile),
+ escapeshellarg($this->url),
+ escapeshellarg($this->username),
+ escapeshellarg($this->password),
+ escapeshellarg($this->classpathref),
+ escapeshellarg($lbcommand),
+ $lbparams
+ );
+
+ passthru($command);
+
+ return;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseChangeLogTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseChangeLogTask.php
new file mode 100755
index 00000000..77fb97d2
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseChangeLogTask.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Task to create a changelog file.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseChangeLogTask extends AbstractLiquibaseTask
+{
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+ $this->execute('generateChangeLog');
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDbDocTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDbDocTask.php
new file mode 100755
index 00000000..e79fae92
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDbDocTask.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Task to create a javadoc-like documentation based on current database and
+ * changelog.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseDbDocTask extends AbstractLiquibaseTask
+{
+ protected $outputDir;
+
+
+ /**
+ * Sets the output directory where the documentation gets generated to.
+ *
+ * @param string the output directory
+ */
+ public function setOutputDir($outputDir)
+ {
+ $this->outputDir = $outputDir;
+ }
+
+
+ /**
+ * @see AbstractTask::checkParams()
+ */
+ protected function checkParams()
+ {
+ parent::checkParams();
+
+ if((null === $this->outputDir) or !is_dir($this->outputDir))
+ {
+ if(!mkdir($this->outputDir, 0777, true))
+ {
+ throw new BuildException(
+ sprintf(
+ 'The directory "%s" does not exist and could not be created!',
+ $this->outputDir
+ )
+ );
+ }
+ }
+
+ if(!is_writable($this->outputDir))
+ {
+ throw new BuildException(
+ sprintf(
+ 'The directory "%s" is not writable!',
+ $this->outputDir
+ )
+ );
+ }
+ }
+
+
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+ $this->execute('dbdoc', escapeshellarg($this->outputDir));
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDiffTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDiffTask.php
new file mode 100755
index 00000000..847f1401
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseDiffTask.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Task to create the diff between two databases. Will output the changes needed
+ * to convert the reference database to the database.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseDiffTask extends AbstractLiquibaseTask
+{
+ protected $referenceUsername;
+ protected $referencePassword;
+ protected $referenceUrl;
+
+
+ /**
+ * Sets the username to connect to the reference database.
+ *
+ * @param string the username
+ */
+ public function setReferenceUsername($username)
+ {
+ $this->referenceUsername = $username;
+ }
+
+
+ /**
+ * Sets the password to connect to the refernce database.
+ *
+ * @param string the password
+ */
+ public function setReferencePassword($password)
+ {
+ $this->referencePassword = $password;
+ }
+
+
+ /**
+ * Sets the url to connect to the reference database in jdbc style, e.g.
+ * <code>
+ * jdbc:postgresql://psqlhost/myrefdatabase
+ * </code>
+ *
+ * @param string jdbc connection string
+ */
+ public function setReferenceUrl($url)
+ {
+ $this->referenceUrl = $url;
+ }
+
+
+ /**
+ * @see AbstractTask::checkParams()
+ */
+ protected function checkParams()
+ {
+ parent::checkParams();
+
+ if(null === $this->referenceUsername)
+ {
+ throw new BuildException('Please provide a username for the reference database acccess!');
+ }
+
+ if(null === $this->referencePassword)
+ {
+ throw new BuildException('Please provide a password for the reference database acccess!');
+ }
+
+ if(null === $this->referenceUrl)
+ {
+ throw new BuildException('Please provide a url for the reference database acccess!');
+ }
+ }
+
+
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+
+ $refparams = sprintf(
+ '--referenceUsername=%s --referencePassword=%s --referenceUrl=%s',
+ escapeshellarg($this->referenceUsername),
+ escapeshellarg($this->referencePassword),
+ escapeshellarg($this->referenceUrl)
+ );
+
+ // save main changelog file
+ $changelogFile = $this->changeLogFile;
+
+ // set the name of the new generated changelog file
+ $this->setChangeLogFile(dirname($changelogFile).'/diffs/'.date('YmdHis').'.xml');
+ if(!is_dir(dirname($changelogFile).'/diffs/'))
+ {
+ mkdir(dirname($changelogFile).'/diffs/', 0777, true);
+ }
+ $this->execute('diffChangeLog', $refparams);
+
+ $xmlFile = new DOMDocument();
+ $xmlFile->load($changelogFile);
+
+ // create the new node
+ $rootNode = $xmlFile->getElementsByTagName('databaseChangeLog')->item(0);
+ $includeNode = $rootNode->appendChild($xmlFile->createElement('include'));
+
+ // set the attributes for the new node
+ $includeNode->setAttribute('file', str_replace(dirname($changelogFile).'/', '', $this->changeLogFile));
+ $includeNode->setAttribute('relativeToChangelogFile', 'true');
+ file_put_contents($changelogFile, $xmlFile->saveXML());
+
+ $this->setChangeLogFile($changelogFile);
+ $this->execute('markNextChangeSetRan');
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseRollbackTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseRollbackTask.php
new file mode 100755
index 00000000..ec5584e6
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseRollbackTask.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Rollbacks the database changes.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseRollbackTask extends AbstractLiquibaseTask
+{
+ protected $rollbackTag;
+
+
+ /**
+ * Sets the name of the tag to roll back to.
+ *
+ * @param string the name to roll back to
+ */
+ public function setRollbackTag($rollbackTag)
+ {
+ $this->rollbackTag = $rollbackTag;
+ }
+
+
+ /**
+ * @see AbstractTask::checkParams()
+ */
+ protected function checkParams()
+ {
+ parent::checkParams();
+
+ if(null === $this->rollbackTag)
+ {
+ throw new BuildException(
+ sprintf(
+ 'Please specify the tag to rollback to!',
+ $this->rollbackTag
+ )
+ );
+ }
+ }
+
+
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+ $this->execute('rollback', escapeshellarg($this->rollbackTag));
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseTagTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseTagTask.php
new file mode 100755
index 00000000..07b0e72e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseTagTask.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Task to tag the current database state. In case you tag the database multiple
+ * times without applying a new changelog before, the tags will overwrite each
+ * other!
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseTagTask extends AbstractLiquibaseTask
+{
+ protected $tag;
+
+
+ /**
+ * Sets the name of tag which is used to mark the database state for
+ * possible future rollback.
+ *
+ * @param string the name to tag the database with
+ */
+ public function setTag($tag)
+ {
+ $this->tag = $tag;
+ }
+
+
+ /**
+ * @see AbstractTask::checkParams()
+ */
+ protected function checkParams()
+ {
+ parent::checkParams();
+
+ if(null === $this->tag)
+ {
+ throw new BuildException(
+ sprintf(
+ 'Please specify the tag!',
+ $this->tag
+ )
+ );
+ }
+ }
+
+
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+ $this->execute('tag', escapeshellarg($this->tag));
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseUpdateTask.php b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseUpdateTask.php
new file mode 100755
index 00000000..35162e4d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/liquibase/LiquibaseUpdateTask.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * Copyright (c) 2007-2011 bitExpert AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
+
+/**
+ * Task to update the database to latest version of the changelog file.
+ *
+ * @author Stephan Hochdoerfer <S.Hochdoerfer@bitExpert.de>
+ * @version $Id$
+ * @since 2.4.10
+ * @package phing.tasks.ext.liquibase
+ */
+class LiquibaseUpdateTask extends AbstractLiquibaseTask
+{
+ /**
+ * @see Task::main()
+ */
+ public function main()
+ {
+ $this->checkParams();
+ $this->execute('update');
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php
new file mode 100644
index 00000000..53286f46
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * $Id: f3a492fa25b203d3263e3463c1ab522c61bd0a9c $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Analyzer element for the PhpDependTask
+ *
+ * @package phing.tasks.ext.pdepend
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: f3a492fa25b203d3263e3463c1ab522c61bd0a9c $
+ * @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
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ 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;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependLoggerElement.php b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependLoggerElement.php
new file mode 100644
index 00000000..619f7377
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependLoggerElement.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * $Id: 6aa728f12c6a9b89fb93cfd39908918937a6d5f9 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Logger element for the PhpDependTask.
+ *
+ * @package phing.tasks.ext.pdepend
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: 6aa728f12c6a9b89fb93cfd39908918937a6d5f9 $
+ * @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
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ public function setOutfile(PhingFile $outfile)
+ {
+ $this->_outfile = $outfile;
+ }
+
+ /**
+ * Get the output file.
+ *
+ * @return PhingFile
+ */
+ public function getOutfile()
+ {
+ return $this->_outfile;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependTask.php b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependTask.php
new file mode 100644
index 00000000..c42575b7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdepend/PhpDependTask.php
@@ -0,0 +1,506 @@
+<?php
+/**
+ * $Id: 572bbfe2e542b864211a85de9990f5cbfe31a4cd $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.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 <bschultz@proqrent.de>
+ * @version $Id: 572bbfe2e542b864211a85de9990f5cbfe31a4cd $
+ * @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 array<FileSet>
+ */
+ protected $_filesets = array();
+
+ /**
+ * List of allowed file extensions. Default file extensions are <b>php</b>
+ * and <p>php5</b>.
+ *
+ * @var array<string>
+ */
+ protected $_allowedFileExtensions = array('php', 'php5');
+
+ /**
+ * List of exclude directories. Default exclude dirs are <b>.git</b>,
+ * <b>.svn</b> and <b>CVS</b>.
+ *
+ * @var array<string>
+ */
+ protected $_excludeDirectories = array('.git', '.svn', 'CVS');
+
+ /**
+ * List of exclude packages
+ *
+ * @var array<string>
+ */
+ protected $_excludePackages = array();
+
+ /**
+ * Should the parse ignore doc comment annotations?
+ *
+ * @var boolean
+ */
+ protected $_withoutAnnotations = false;
+
+ /**
+ * Should PHP_Depend treat <b>+global</b> 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 array<PhpDependLoggerElement>
+ */
+ protected $_loggers = array();
+
+ /**
+ * Analyzer elements
+ *
+ * @var array<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;
+
+ /**
+ * Load the necessary environment for running PHP_Depend
+ *
+ * @return void
+ * @throws BuildException
+ */
+ public function init()
+ {
+ /**
+ * Determine PHP_Depend installation
+ */
+ @include_once 'PHP/Depend/TextUI/Runner.php';
+
+ if (! class_exists('PHP_Depend_TextUI_Runner')) {
+ throw new BuildException(
+ 'PhpDependTask depends on PHP_Depend being installed '
+ . 'and on include_path',
+ $this->getLocation()
+ );
+ }
+
+ /**
+ * Other dependencies that should only be loaded
+ * when class is actually used
+ */
+ require_once 'phing/tasks/ext/pdepend/PhpDependLoggerElement.php';
+ require_once 'phing/tasks/ext/pdepend/PhpDependAnalyzerElement.php';
+ require_once 'PHP/Depend/Autoload.php';
+ }
+
+ /**
+ * Set the input source file or directory
+ *
+ * @param PhingFile $file The input source file or directory
+ *
+ * @return void
+ */
+ public function setFile(PhingFile $file)
+ {
+ $this->_file = $file;
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute)
+ *
+ * @return FileSet The created fileset object
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->_filesets, new FileSet());
+ return $this->_filesets[$num-1];
+ }
+
+ /**
+ * Sets a list of filename extensions for valid php source code files
+ *
+ * @param string $fileExtensions List of valid file extensions
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ public function setWithoutAnnotations($withoutAnnotations)
+ {
+ $this->_withoutAnnotations = StringHelper::booleanValue(
+ $withoutAnnotations
+ );
+ }
+
+ /**
+ * Should PHP_Depend support projects with a bad documentation. If this
+ * option is set to <b>true</b>, PHP_Depend will treat the default package
+ * <b>+global</b> as a regular project package.
+ *
+ * @param boolean $supportBadDocumentation
+ *
+ * @return void
+ */
+ public function setSupportBadDocumentation($supportBadDocumentation)
+ {
+ $this->_supportBadDocumentation = StringHelper::booleanValue(
+ $supportBadDocumentation
+ );
+ }
+
+ /**
+ * Set debugging On/Off
+ *
+ * @param boolean $debug
+ *
+ * @return void
+ */
+ public function setDebug($debug)
+ {
+ $this->_debug = StringHelper::booleanValue($debug);
+ }
+
+ /**
+ * Set halt on error
+ *
+ * @param boolean $haltonerror
+ *
+ * @return void
+ */
+ public function setHaltonerror($haltonerror)
+ {
+ $this->_haltonerror = StringHelper::booleanValue($haltonerror);
+ }
+
+ /**
+ * Set the configuration file
+ *
+ * @param PhingFile $configFile The configuration file
+ *
+ * @return void
+ */
+ 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];
+ }
+
+ /**
+ * Executes PHP_Depend_TextUI_Runner against PhingFile or a FileSet
+ *
+ * @return void
+ * @throws BuildException
+ */
+ public function main()
+ {
+ $autoload = new PHP_Depend_Autoload();
+ $autoload->register();
+
+ 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 = array();
+
+ if ($this->_file instanceof PhingFile) {
+ $filesToParse[] = $this->_file->__toString();
+ } 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();
+ }
+ }
+ }
+
+ $this->_runner = new PHP_Depend_TextUI_Runner();
+ $this->_runner->addProcessListener(new PHP_Depend_TextUI_ResultPrinter());
+
+ $configurationFactory = new PHP_Depend_Util_Configuration_Factory();
+ $configuration = $configurationFactory->createDefault();
+ $this->_runner->setConfiguration($configuration);
+
+ $this->_runner->setSourceArguments($filesToParse);
+
+ foreach ($this->_loggers as $logger) {
+ // Register logger
+ $this->_runner->addLogger(
+ $logger->getType(),
+ $logger->getOutfile()->__toString()
+ );
+ }
+
+ foreach ($this->_analyzers as $analyzer) {
+ // Register additional analyzer
+ $this->_runner->addOption(
+ $analyzer->getType(),
+ $analyzer->getValue()
+ );
+ }
+
+ // Disable annotation parsing
+ if ($this->_withoutAnnotations) {
+ $this->_runner->setWithoutAnnotations();
+ }
+
+ // Enable bad documentation support
+ if ($this->_supportBadDocumentation) {
+ $this->_runner->setSupportBadDocumentation();
+ }
+
+ // Check for suffix
+ if (count($this->_allowedFileExtensions) > 0) {
+ $this->_runner->setFileExtensions($this->_allowedFileExtensions);
+ }
+
+ // Check for ignore directories
+ if (count($this->_excludeDirectories) > 0) {
+ $this->_runner->setExcludeDirectories($this->_excludeDirectories);
+ }
+
+ // Check for exclude packages
+ if (count($this->_excludePackages) > 0) {
+ $this->_runner->setExcludePackages($this->_excludePackages);
+ }
+
+ // Check for configuration option
+ if ($this->_configFile instanceof PhingFile) {
+ if (file_exists($this->_configFile->__toString()) === false) {
+ throw new BuildException(
+ 'The configuration file "'
+ . $this->_configFile->__toString() . '" doesn\'t exist.'
+ );
+ }
+
+ // Load configuration file
+ $config = new PHP_Depend_Util_Configuration(
+ $this->_configFile->__toString(),
+ null,
+ true
+ );
+
+ // Store in config registry
+ PHP_Depend_Util_ConfigurationInstance::set($config);
+ }
+
+ if ($this->_debug) {
+ require_once 'PHP/Depend/Util/Log.php';
+ // Enable debug logging
+ PHP_Depend_Util_Log::setSeverity(PHP_Depend_Util_Log::DEBUG);
+ }
+
+ $this->_runner->run();
+
+ if ($this->_runner->hasParseErrors() === true) {
+ $this->log('Following errors occurred:');
+
+ foreach ($this->_runner->getParseErrors() as $error) {
+ $this->log($error);
+ }
+
+ if ($this->_haltonerror === true) {
+ throw new BuildException('Errors occurred during parse process');
+ }
+ }
+ }
+
+ /**
+ * Validates the available loggers
+ *
+ * @return void
+ * @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
+ *
+ * @return void
+ * @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"
+ );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/DefaultPDOQuerySplitter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/DefaultPDOQuerySplitter.php
new file mode 100755
index 00000000..41f296f7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/DefaultPDOQuerySplitter.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ *
+ * @version SVN: $Id: dacfd46938db28930888f57a6924be642ec1b3d7 $
+ * @package phing.tasks.ext.pdo
+ */
+
+require_once 'phing/tasks/ext/pdo/PDOQuerySplitter.php';
+
+/**
+ * Splits SQL source into queries using simple regular expressions
+ *
+ * Extracted from PDOSQLExecTask::runStatements()
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Alexey Borzov <avb@php.net>
+ * @package phing.tasks.ext.pdo
+ * @version $Id$
+ */
+class DefaultPDOQuerySplitter extends PDOQuerySplitter
+{
+ /**
+ * Delimiter type, one of PDOSQLExecTask::DELIM_ROW or PDOSQLExecTask::DELIM_NORMAL
+ * @var string
+ */
+ private $delimiterType;
+
+ /**
+ * Leftover SQL from previous line
+ * @var string
+ */
+ private $sqlBacklog = '';
+
+ /**
+ * Constructor, sets the parent task, reader with SQL source and delimiter type
+ *
+ * @param PDOSQLExecTask $parent
+ * @param Reader $reader
+ * @param string $delimiterType
+ */
+ public function __construct(PDOSQLExecTask $parent, Reader $reader, $delimiterType = PDOSQLExecTask::DELIM_NORMAL)
+ {
+ parent::__construct($parent, $reader);
+ $this->delimiterType = $delimiterType;
+ }
+
+ /**
+ * Returns next query from SQL source, null if no more queries left
+ *
+ * In case of "row" delimiter type this searches for strings containing only
+ * delimiters. In case of "normal" delimiter type, this uses simple regular
+ * expression logic to search for delimiters.
+ *
+ * @return string|null
+ */
+ public function nextQuery()
+ {
+ $sql = "";
+ $hasQuery = false;
+
+ while (($line = $this->sqlReader->readLine()) !== null) {
+ $delimiter = $this->parent->getDelimiter();
+ $project = $this->parent->getOwningTarget()->getProject();
+ $line = ProjectConfigurator::replaceProperties(
+ $project, trim($line), $project->getProperties()
+ );
+
+ if (($line != $delimiter) && (
+ StringHelper::startsWith("//", $line) ||
+ StringHelper::startsWith("--", $line) ||
+ StringHelper::startsWith("#", $line))) {
+ continue;
+ }
+
+ if (strlen($line) > 4
+ && strtoupper(substr($line,0, 4)) == "REM ") {
+ continue;
+ }
+
+ // MySQL supports defining new delimiters
+ if (preg_match('/DELIMITER [\'"]?([^\'" $]+)[\'"]?/i', $line, $matches)) {
+ $this->parent->setDelimiter($matches[1]);
+ continue;
+ }
+
+ if ($this->sqlBacklog !== "") {
+ $sql = $this->sqlBacklog;
+ $this->sqlBacklog = "";
+ }
+
+ $sql .= " " . $line . "\n";
+
+ // 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";
+ }
+
+ // DELIM_ROW doesn't need this (as far as i can tell)
+ if ($this->delimiterType == PDOSQLExecTask::DELIM_NORMAL) {
+
+ $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter) . ")#";
+
+ $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
+ $this->sqlBacklog = "";
+ foreach ($sqlParts as $sqlPart) {
+ // we always want to append, even if it's a delim (which will be stripped off later)
+ $this->sqlBacklog .= $sqlPart;
+
+ // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query
+ if ($sqlPart === $delimiter) {
+ $sql = $this->sqlBacklog;
+ $this->sqlBacklog = "";
+ $hasQuery = true;
+ }
+ }
+ }
+
+ if ($hasQuery || ($this->delimiterType == PDOSQLExecTask::DELIM_ROW && $line == $delimiter)) {
+ // this assumes there is always a delimter on the end of the SQL statement.
+ $sql = StringHelper::substring($sql, 0, strlen($sql) - strlen($delimiter)
+ - ($this->delimiterType == PDOSQLExecTask::DELIM_ROW ? 2 : 1));
+ return $sql;
+ }
+ }
+
+ // Catch any statements not followed by ;
+ if ($sql !== "") {
+ return $sql;
+ }
+
+ return null;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOQuerySplitter.php
index df17d2d4..60a9d436 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOQuerySplitter.php
@@ -1,7 +1,6 @@
<?php
+
/**
- * $Id: SummaryPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- *
* 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
@@ -17,42 +16,48 @@
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
+ *
+ * @version $Id: e84ada3cdb7a04da60158c7a352fbb06f17f2ca7 $
+ * @package phing.tasks.ext.pdo
*/
-
-require_once 'PHPUnit2/Framework/Test.php';
-
-require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php';
/**
- * Prints short summary output of the test to Phing's logging system.
+ * Base class for classes that split SQL source into separate queries
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SummaryPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class SummaryPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
+ * @author Alexey Borzov <avb@php.net>
+ * @package phing.tasks.ext.pdo
+ * @version $Id$
+ */
+abstract class PDOQuerySplitter
{
- function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- parent::endTestSuite($suite);
-
- $sb = "Tests run: " . $this->getRunCount();
- $sb.= ", Failures: " . $this->getFailureCount();
- $sb.= ", Errors: " . $this->getErrorCount();
- $sb.= ", Time elapsed: " . $this->getElapsedTime();
- $sb.= " sec\n";
-
- if ($this->out != NULL)
- {
- $this->out->write($sb);
- $this->out->close();
- }
- }
-
- function getExtension()
- {
- return NULL;
- }
+ /**
+ * Task that uses the splitter
+ * @var PDOSQLExecTask
+ */
+ protected $parent;
+
+ /**
+ * Reader with SQL source
+ * @var BufferedReader
+ */
+ protected $sqlReader;
+
+ /**
+ * Constructor, sets the parent task and reader with SQL source
+ *
+ * @param PDOSQLExecTask $parent
+ * @param Reader $reader
+ */
+ public function __construct(PDOSQLExecTask $parent, Reader $reader)
+ {
+ $this->parent = $parent;
+ $this->sqlReader = new BufferedReader($reader);
+ }
+
+ /**
+ * Returns next query from SQL source, null if no more queries left
+ *
+ * @return string|null
+ */
+ abstract public function nextQuery();
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php
new file mode 100644
index 00000000..82a90ca4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * $Id: a3237522d22494bbfaf0521ebb8f091d448f3614 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Abstract
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+abstract class PDOResultFormatter
+{
+ /**
+ * Output writer.
+ *
+ * @var Writer
+ */
+ protected $out;
+
+ /**
+ * Sets the output writer.
+ *
+ * @param Writer $out
+ */
+ public function setOutput(Writer $out) {
+ $this->out = $out;
+ }
+
+ /**
+ * Gets the output writer.
+ *
+ * @return Writer
+ */
+ public function getOutput() {
+ return $this->out;
+ }
+
+ /**
+ * Gets the preferred output filename for this formatter.
+ * @return string
+ */
+ abstract public function getPreferredOutfile();
+
+ /**
+ * Perform any initialization.
+ */
+ public function initialize() {
+
+ }
+
+ /**
+ * Processes a specific row from PDO result set.
+ *
+ * @param array $row Row of PDO result set.
+ */
+ abstract public function processRow($row);
+
+ /**
+ * Perform any final tasks and Close the writer.
+ */
+ public function close() {
+ $this->out->close();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php
new file mode 100644
index 00000000..bc657604
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php
@@ -0,0 +1,313 @@
+<?php
+/**
+ * $Id: a3ca52c2b277a8cbc0d2802b75f2bea18701b636 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PlainPDOResultFormatter.php';
+require_once 'phing/tasks/ext/pdo/XMLPDOResultFormatter.php';
+require_once 'phing/util/LogWriter.php';
+
+/**
+ * A class to represent the nested <formatter> element for PDO SQL results.
+ *
+ * This class is inspired by the similarly-named class in the PHPUnit tasks.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class PDOSQLExecFormatterElement
+{
+ /**
+ * @var PDOResultFormatter
+ */
+ private $formatter;
+
+ /**
+ * The type of the formatter (used for built-in formatter classes).
+ * @var string
+ */
+ private $type = "";
+
+ /**
+ * Whether to use file (or write output to phing log).
+ * @var boolean
+ */
+ private $useFile = true;
+
+ /**
+ * Output file for formatter.
+ * @var PhingFile
+ */
+ private $outfile;
+
+ /**
+ * Print header columns.
+ * @var boolean
+ */
+ private $showheaders = true;
+
+ /**
+ * Whether to format XML output.
+ * @var boolean
+ */
+ private $formatoutput = true;
+
+ /**
+ * Encoding for XML output.
+ * @var string
+ */
+ private $encoding;
+
+ /**
+ * Column delimiter.
+ * Defaults to ','
+ * @var string
+ */
+ private $coldelimiter = ",";
+
+ /**
+ * Row delimiter.
+ * Defaults to PHP_EOL.
+ * @var string
+ */
+ private $rowdelimiter = PHP_EOL;
+
+ /**
+ * Append to an existing file or overwrite it?
+ * @var boolean
+ */
+ private $append = false;
+
+ /**
+ * Parameters for a custom formatter.
+ * @var array Parameter[]
+ */
+ private $formatterParams = array();
+
+ /**
+ * @var PDOSQLExecTask
+ */
+ private $parentTask;
+
+ /**
+ * Construct a new PDOSQLExecFormatterElement with parent task.
+ * @param PDOSQLExecTask $parentTask
+ */
+ public function __construct(PDOSQLExecTask $parentTask)
+ {
+ $this->parentTask = $parentTask;
+ }
+
+ /**
+ * Supports nested <param> element (for custom formatter classes).
+ * @return Parameter
+ */
+ public function createParam() {
+ $num = array_push($this->parameters, new Parameter());
+ return $this->parameters[$num-1];
+ }
+
+ /**
+ * Gets a configured output writer.
+ * @return Writer
+ */
+ private function getOutputWriter()
+ {
+ if ($this->useFile) {
+ $of = $this->getOutfile();
+ if (!$of) {
+ $of = new PhingFile($this->formatter->getPreferredOutfile());
+ }
+ return new FileWriter($of, $this->append);
+ } else {
+ return $this->getDefaultOutput();
+ }
+ }
+
+ /**
+ * Configures wrapped formatter class with any attributes on this element.
+ */
+ public function prepare() {
+
+ if (!$this->formatter) {
+ throw new BuildException("No formatter specified (use type or classname attribute)", $this->getLocation());
+ }
+
+ $out = $this->getOutputWriter();
+
+ $this->parentTask->log("Setting output writer to: " . get_class($out), Project::MSG_VERBOSE);
+ $this->formatter->setOutput($out);
+
+ if ($this->formatter instanceof PlainPDOResultFormatter) {
+ // set any options that apply to the plain formatter
+ $this->formatter->setShowheaders($this->showheaders);
+ $this->formatter->setRowdelim($this->rowdelimiter);
+ $this->formatter->setColdelim($this->coldelimiter);
+ } elseif ($this->formatter instanceof XMLPDOResultFormatter) {
+ // set any options that apply to the xml formatter
+ $this->formatter->setEncoding($this->encoding);
+ $this->formatter->setFormatOutput($this->formatoutput);
+ }
+
+ foreach($this->formatterParams as $param) {
+ $param = new Parameter();
+ $method = 'set' . $param->getName();
+ if (!method_exists($this->formatter, $param->getName())) {
+ throw new BuildException("Formatter " . get_class($this->formatter) . " does not have a $method method.", $this->getLocation());
+ }
+ call_user_func(array($this->formatter, $method), $param->getValue());
+ }
+ }
+
+ /**
+ * Sets the formatter type.
+ * @param string $type
+ */
+ function setType($type) {
+ $this->type = $type;
+ if ($this->type == "xml") {
+ $this->formatter = new XMLPDOResultFormatter();
+ } elseif ($this->type == "plain") {
+ $this->formatter = new PlainPDOResultFormatter();
+ } else {
+ throw new BuildException("Formatter '" . $this->type . "' not implemented");
+ }
+ }
+
+ /**
+ * Set classname for a custom formatter (must extend PDOResultFormatter).
+ * @param string $className
+ */
+ function setClassName($className) {
+ $classNameNoDot = Phing::import($className);
+ $this->formatter = new $classNameNoDot();
+ }
+
+ /**
+ * Set whether to write formatter results to file.
+ * @param boolean $useFile
+ */
+ function setUseFile($useFile) {
+ $this->useFile = (boolean) $useFile;
+ }
+
+ /**
+ * Return whether to write formatter results to file.
+ * @return boolean
+ */
+ function getUseFile() {
+ return $this->useFile;
+ }
+
+ /**
+ * Sets the output file for the formatter results.
+ * @param PhingFile $outFile
+ */
+ function setOutfile(PhingFile $outfile) {
+ $this->outfile = $outfile;
+ }
+
+ /**
+ * Get the output file.
+ * @return PhingFile
+ */
+ function getOutfile() {
+ return $this->outfile;
+ /*
+ } else {
+ return new PhingFile($this->formatter->getPreferredOutfile());
+ }*/
+ }
+
+ /**
+ * whether output should be appended to or overwrite
+ * an existing file. Defaults to false.
+ * @param boolean $append
+ */
+ public function setAppend($append) {
+ $this->append = (boolean) $append;
+ }
+
+ /**
+ * Whether output should be appended to file.
+ * @return boolean
+ */
+ public function getAppend() {
+ return $this->append;
+ }
+
+ /**
+ * Print headers for result sets from the
+ * statements; optional, default true.
+ * @param boolean $showheaders
+ */
+ public function setShowheaders($showheaders) {
+ $this->showheaders = (boolean) $showheaders;
+ }
+
+ /**
+ * Sets the column delimiter.
+ * @param string $v
+ */
+ public function setColdelim($v) {
+ $this->coldelimiter = $v;
+ }
+
+ /**
+ * Sets the row delimiter.
+ * @param string $v
+ */
+ public function setRowdelim($v) {
+ $this->rowdelimiter = $v;
+ }
+
+ /**
+ * Set the DOM document encoding.
+ * @param string $v
+ */
+ public function setEncoding($v) {
+ $this->encoding = $v;
+ }
+
+ /**
+ * @param boolean $v
+ */
+ public function setFormatOutput($v) {
+ $this->formatOutput = (boolean) $v;
+ }
+
+ /**
+ * Gets a default output writer for this task.
+ * @return Writer
+ */
+ private function getDefaultOutput()
+ {
+ return new LogWriter($this->parentTask);
+ }
+
+ /**
+ * Gets the formatter that has been configured based on this element.
+ * @return PDOResultFormatter
+ */
+ function getFormatter() {
+ return $this->formatter;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php
new file mode 100755
index 00000000..3837d7ff
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php
@@ -0,0 +1,606 @@
+<?php
+/*
+ * $Id: 8b5a8e4f80b46f8a797b058dbb9a240a1185c12b $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/pdo/PDOTask.php';
+include_once 'phing/system/io/StringReader.php';
+include_once 'phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php';
+
+/**
+ * Executes a series of SQL statements on a database using PDO.
+ *
+ * <p>Statements can
+ * either be read in from a text file using the <i>src</i> attribute or from
+ * between the enclosing SQL tags.</p>
+ *
+ * <p>Multiple statements can be provided, separated by semicolons (or the
+ * defined <i>delimiter</i>). Individual lines within the statements can be
+ * commented using either --, // or REM at the start of the line.</p>
+ *
+ * <p>The <i>autocommit</i> 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.</p>
+ *
+ * <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs
+ * during the execution of one of the statements.
+ * The possible values are: <b>continue</b> execution, only show the error;
+ * <b>stop</b> execution and commit transaction;
+ * and <b>abort</b> execution and transaction and fail task.</p>
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @package phing.tasks.ext.pdo
+ * @version $Id: 8b5a8e4f80b46f8a797b058dbb9a240a1185c12b $
+ */
+class PDOSQLExecTask extends PDOTask {
+
+ /**
+ * Count of how many statements were executed successfully.
+ * @var int
+ */
+ private $goodSql = 0;
+
+ /**
+ * Count of total number of SQL statements.
+ * @var int
+ */
+ private $totalSql = 0;
+
+ const DELIM_ROW = "row";
+ const DELIM_NORMAL = "normal";
+
+ /**
+ * Database connection
+ * @var PDO
+ */
+ private $conn = null;
+
+ /**
+ * Files to load
+ * @var array FileSet[]
+ */
+ private $filesets = array();
+
+ /**
+ * Files to load
+ * @var array FileList[]
+ */
+ private $filelists = array();
+
+ /**
+ * Formatter elements.
+ * @var array PDOSQLExecFormatterElement[]
+ */
+ private $formatters = array();
+
+ /**
+ * SQL statement
+ * @var PDOStatement
+ */
+ private $statement;
+
+ /**
+ * SQL input file
+ * @var PhingFile
+ */
+ private $srcFile;
+
+ /**
+ * SQL input command
+ * @var string
+ */
+ private $sqlCommand = "";
+
+ /**
+ * SQL transactions to perform
+ */
+ private $transactions = array();
+
+ /**
+ * SQL Statement delimiter (for parsing files)
+ * @var string
+ */
+ 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
+
+ /**
+ * Action to perform if an error is found
+ **/
+ private $onError = "abort";
+
+ /**
+ * Encoding to use when reading SQL statements from a file
+ */
+ private $encoding = null;
+
+ /**
+ * Fetch mode for PDO select queries.
+ * @var int
+ */
+ private $fetchMode;
+
+ /**
+ * Set the name of the SQL file to be run.
+ * Required unless statements are enclosed in the build file
+ */
+ public function setSrc(PhingFile $srcFile) {
+ $this->srcFile = $srcFile;
+ }
+
+ /**
+ * Set an inline SQL command to execute.
+ * NB: Properties are not expanded in this text.
+ */
+ public function addText($sql) {
+ $this->sqlCommand .= $sql;
+ }
+
+ /**
+ * Adds a set of files (nested fileset attribute).
+ */
+ public function addFileset(FileSet $set) {
+ $this->filesets[] = $set;
+ }
+
+ /**
+ * Adds a set of files (nested filelist attribute).
+ */
+ public function addFilelist(FileList $list) {
+ $this->filelists[] = $list;
+ }
+
+ /**
+ * Creates a new PDOSQLExecFormatterElement for <formatter> element.
+ * @return PDOSQLExecFormatterElement
+ */
+ public function createFormatter()
+ {
+ $fe = new PDOSQLExecFormatterElement($this);
+ $this->formatters[] = $fe;
+ return $fe;
+ }
+
+ /**
+ * Add a SQL transaction to execute
+ */
+ public function createTransaction() {
+ $t = new PDOSQLExecTransaction($this);
+ $this->transactions[] = $t;
+ return $t;
+ }
+
+ /**
+ * Set the file encoding to use on the SQL files read in
+ *
+ * @param encoding the encoding to use on the files
+ */
+ public function setEncoding($encoding) {
+ $this->encoding = $encoding;
+ }
+
+ /**
+ * Set the statement delimiter.
+ *
+ * <p>For example, set this to "go" and delimitertype to "ROW" for
+ * Sybase ASE or MS SQL Server.</p>
+ *
+ * @param delimiter
+ */
+ public function setDelimiter($delimiter)
+ {
+ $this->delimiter = $delimiter;
+ }
+
+ /**
+ * Get the statement delimiter.
+ *
+ * @return string
+ */
+ public function getDelimiter()
+ {
+ return $this->delimiter;
+ }
+
+ /**
+ * Set the Delimiter type for this sql task. The delimiter type takes two
+ * values - normal and row. Normal means that any occurence 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;
+ }
+
+ /**
+ * Action to perform when statement fails: continue, stop, or abort
+ * optional; default &quot;abort&quot;
+ */
+ public function setOnerror($action) {
+ $this->onError = $action;
+ }
+
+ /**
+ * Sets the fetch mode to use for the PDO resultset.
+ * @param mixed $mode The PDO fetchmode integer or constant name.
+ */
+ public function setFetchmode($mode) {
+ if (is_numeric($mode)) {
+ $this->fetchMode = (int) $mode;
+ } else {
+ if (defined($mode)) {
+ $this->fetchMode = constant($mode);
+ } else {
+ throw new BuildException("Invalid PDO fetch mode specified: " . $mode, $this->getLocation());
+ }
+ }
+ }
+
+ /**
+ * Gets a default output writer for this task.
+ * @return Writer
+ */
+ private function getDefaultOutput()
+ {
+ return new LogWriter($this);
+ }
+
+ /**
+ * Load the sql file and then execute it
+ * @throws BuildException
+ */
+ public function main() {
+
+ // Set a default fetchmode if none was specified
+ // (We're doing that here to prevent errors loading the class is PDO is not available.)
+ if ($this->fetchMode === null) {
+ $this->fetchMode = PDO::FETCH_ASSOC;
+ }
+
+ // Initialize the formatters here. This ensures that any parameters passed to the formatter
+ // element get passed along to the actual formatter object
+ foreach($this->formatters as $fe) {
+ $fe->prepare();
+ }
+
+ $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) && empty($this->filelists)
+ && count($this->transactions) === 0) {
+ throw new BuildException("Source file or fileset/filelist, "
+ . "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
+ foreach($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($this->project);
+ $srcDir = $fs->getDir($this->project);
+ $srcFiles = $ds->getIncludedFiles();
+ // Make a transaction for each file
+ foreach($srcFiles as $srcFile) {
+ $t = $this->createTransaction();
+ $t->setSrc(new PhingFile($srcDir, $srcFile));
+ }
+ }
+
+ // process filelists
+ foreach($this->filelists as $fl) {
+ $srcDir = $fl->getDir($this->project);
+ $srcFiles = $fl->getFiles($this->project);
+ // Make a transaction for each file
+ foreach($srcFiles as $srcFile) {
+ $t = $this->createTransaction();
+ $t->setSrc(new PhingFile($srcDir, $srcFile));
+ }
+ }
+
+ // 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 = null;
+
+ // Initialize the formatters.
+ $this->initFormatters();
+
+ try {
+
+ // Process all transactions
+ for ($i=0,$size=count($this->transactions); $i < $size; $i++) {
+ if (!$this->isAutocommit()) {
+ $this->log("Beginning transaction", Project::MSG_VERBOSE);
+ $this->conn->beginTransaction();
+ }
+ $this->transactions[$i]->runTransaction();
+ if (!$this->isAutocommit()) {
+ $this->log("Commiting transaction", Project::MSG_VERBOSE);
+ $this->conn->commit();
+ }
+ }
+ } catch (Exception $e) {
+ $this->closeConnection();
+ throw $e;
+ }
+ } catch (IOException $e) {
+ if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+ try {
+ $this->conn->rollback();
+ } catch (PDOException $ex) {}
+ }
+ $this->closeConnection();
+ throw new BuildException($e->getMessage(), $this->location);
+ } catch (PDOException $e){
+ if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+ try {
+ $this->conn->rollback();
+ } catch (PDOException $ex) {}
+ }
+ $this->closeConnection();
+ throw new BuildException($e->getMessage(), $this->location);
+ }
+
+ // Close the formatters.
+ $this->closeFormatters();
+
+ $this->log($this->goodSql . " of " . $this->totalSql .
+ " SQL statements executed successfully");
+
+ } catch (Exception $e) {
+ $this->transactions = $savedTransaction;
+ $this->sqlCommand = $savedSqlCommand;
+ $this->closeConnection();
+ throw $e;
+ }
+ // finally {
+ $this->transactions = $savedTransaction;
+ $this->sqlCommand = $savedSqlCommand;
+ $this->closeConnection();
+ }
+
+
+ /**
+ * read in lines and execute them
+ * @throws PDOException, IOException
+ */
+ public function runStatements(Reader $reader) {
+
+ if (self::DELIM_NORMAL == $this->delimiterType && 0 === strpos($this->getUrl(), 'pgsql:')) {
+ require_once 'phing/tasks/ext/pdo/PgsqlPDOQuerySplitter.php';
+ $splitter = new PgsqlPDOQuerySplitter($this, $reader);
+ } else {
+ require_once 'phing/tasks/ext/pdo/DefaultPDOQuerySplitter.php';
+ $splitter = new DefaultPDOQuerySplitter($this, $reader, $this->delimiterType);
+ }
+
+ try {
+ while (null !== ($query = $splitter->nextQuery())) {
+ $this->log("SQL: " . $query, Project::MSG_VERBOSE);
+ $this->execSQL($query);
+ }
+
+ } catch (PDOException $e) {
+ throw $e;
+ }
+ }
+
+ /**
+ * Whether the passed-in SQL statement is a SELECT statement.
+ * This does a pretty simple match, checking to see if statement starts with
+ * 'select' (but not 'select into').
+ *
+ * @param string $sql
+ * @return boolean Whether specified SQL looks like a SELECT query.
+ */
+ protected function isSelectSql($sql)
+ {
+ $sql = trim($sql);
+ return (stripos($sql, 'select') === 0 && stripos($sql, 'select into ') !== 0);
+ }
+
+ /**
+ * Exec the sql statement.
+ * @throws PDOException
+ */
+ protected function execSQL($sql) {
+
+ // Check and ignore empty statements
+ if (trim($sql) == "") {
+ return;
+ }
+
+ try {
+ $this->totalSql++;
+
+ $this->statement = $this->conn->prepare($sql);
+ $this->statement->execute();
+ $this->log($this->statement->rowCount() . " rows affected", Project::MSG_VERBOSE);
+
+ // only call processResults() for statements that return actual data (such as 'select')
+ if ($this->statement->columnCount() > 0)
+ {
+ $this->processResults();
+ }
+
+ $this->statement->closeCursor();
+ $this->statement = null;
+
+ $this->goodSql++;
+
+ } catch (PDOException $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);
+ }
+ }
+
+ /**
+ * Returns configured PDOResultFormatter objects (which were created from PDOSQLExecFormatterElement objects).
+ * @return array PDOResultFormatter[]
+ */
+ protected function getConfiguredFormatters()
+ {
+ $formatters = array();
+ foreach ($this->formatters as $fe) {
+ $formatters[] = $fe->getFormatter();
+ }
+ return $formatters;
+ }
+
+ /**
+ * Initialize the formatters.
+ */
+ protected function initFormatters() {
+ $formatters = $this->getConfiguredFormatters();
+ foreach ($formatters as $formatter) {
+ $formatter->initialize();
+ }
+
+ }
+
+ /**
+ * Run cleanup and close formatters.
+ */
+ protected function closeFormatters() {
+ $formatters = $this->getConfiguredFormatters();
+ foreach ($formatters as $formatter) {
+ $formatter->close();
+ }
+ }
+
+ /**
+ * Passes results from query to any formatters.
+ * @throws PDOException
+ */
+ protected function processResults() {
+
+ try {
+
+ $this->log("Processing new result set.", Project::MSG_VERBOSE);
+
+ $formatters = $this->getConfiguredFormatters();
+
+ while ($row = $this->statement->fetch($this->fetchMode)) {
+ foreach ($formatters as $formatter) {
+ $formatter->processRow($row);
+ }
+ }
+
+ } catch (Exception $x) {
+ $this->log("Error processing reults: " . $x->getMessage(), Project::MSG_ERR);
+ foreach ($formatters as $formatter) {
+ $formatter->close();
+ }
+ throw $x;
+ }
+
+ }
+
+ /**
+ * Closes current connection
+ */
+ protected function closeConnection()
+ {
+ if ($this->conn) {
+ unset($this->conn);
+ }
+ }
+}
+
+/**
+ * "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.pdo
+ */
+class PDOSQLExecTransaction {
+
+ private $tSrcFile = null;
+ private $tSqlCommand = "";
+ private $parent;
+
+ function __construct($parent)
+ {
+ // Parent is required so that we can log things ...
+ $this->parent = $parent;
+ }
+
+ public function setSrc(PhingFile $src)
+ {
+ $this->tSrcFile = $src;
+ }
+
+ public function addText($sql)
+ {
+ $this->tSqlCommand .= $sql;
+ }
+
+ /**
+ * @throws IOException, PDOException
+ */
+ public function runTransaction()
+ {
+ if (!empty($this->tSqlCommand)) {
+ $this->parent->log("Executing commands", Project::MSG_INFO);
+ $this->parent->runStatements(new StringReader($this->tSqlCommand));
+ }
+
+ if ($this->tSrcFile !== null) {
+ $this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(),
+ Project::MSG_INFO);
+ $reader = new FileReader($this->tSrcFile);
+ $this->parent->runStatements($reader);
+ $reader->close();
+ }
+ }
+}
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOTask.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOTask.php
new file mode 100755
index 00000000..93feaa6d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PDOTask.php
@@ -0,0 +1,215 @@
+<?php
+
+/*
+ * $Id: de478f3e51714db7d9163b6bbc3fa64de27549cb $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/Reference.php';
+
+/**
+ * Handles PDO configuration needed by SQL type tasks.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Nick Chalko <nick@chalko.com> (Ant)
+ * @author Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @version $Id$
+ * @package phing.tasks.system
+ */
+abstract class PDOTask extends Task {
+
+ private $caching = true;
+
+ /**
+ * Autocommit flag. Default value is false
+ */
+ private $autocommit = false;
+
+ /**
+ * 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.
+ */
+ function init() {
+ if (!class_exists('PDO')) {
+ throw new Exception("PDOTask depends on PDO feature being included in PHP.");
+ }
+ }
+
+ /**
+ * Caching loaders / driver. This is to avoid
+ * getting an OutOfMemoryError when calling this task
+ * multiple times in a row; default: true
+ * @param $enable
+ */
+ public function setCaching($enable) {
+ $this->caching = $enable;
+ }
+
+ /**
+ * Sets the database connection URL; required.
+ * @param url The url to set
+ */
+ public function setUrl($url) {
+ $this->url = $url;
+ }
+
+ /**
+ * Sets the password; required.
+ * @param password The password to set
+ */
+ public function setPassword($password) {
+ $this->password = $password;
+ }
+
+ /**
+ * Auto commit flag for database connection;
+ * optional, default false.
+ * @param 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 version The version to set
+ */
+ public function setVersion($version) {
+ $this->version = $version;
+ }
+
+ 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);
+
+ $user = null;
+ $pass = null;
+
+ if ($this->userId) {
+ $user = $this->getUserId();
+ }
+
+ if ($this->password) {
+ $pass = $this->getPassword();
+ }
+
+ $conn = new PDO($this->getUrl(), $user, $pass);
+ $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ try {
+ $conn->setAttribute(PDO::ATTR_AUTOCOMMIT, $this->autocommit);
+ } catch (PDOException $pe) {
+ $this->log("Unable to enable auto-commit for this database: " . $pe->getMessage(), Project::MSG_VERBOSE);
+ }
+
+ return $conn;
+
+ } catch (SQLException $e) {
+ throw new BuildException($e->getMessage(), $this->location);
+ }
+
+ }
+
+ public function isCaching($value) {
+ $this->caching = $value;
+ }
+
+ /**
+ * Gets the autocommit.
+ * @return Returns a boolean
+ */
+ public function isAutocommit() {
+ return $this->autocommit;
+ }
+
+ /**
+ * Gets the url.
+ * @return Returns a String
+ */
+ public function getUrl() {
+ return $this->url;
+ }
+
+ /**
+ * Gets the userId.
+ * @return Returns a String
+ */
+ public function getUserId() {
+ return $this->userId;
+ }
+
+ /**
+ * Set the user name for the connection; required.
+ * @param userId The userId to set
+ */
+ public function setUserid($userId) {
+ $this->userId = $userId;
+ }
+
+ /**
+ * Gets the password.
+ * @return Returns a String
+ */
+ public function getPassword() {
+ return $this->password;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PgsqlPDOQuerySplitter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PgsqlPDOQuerySplitter.php
new file mode 100755
index 00000000..b99ac624
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PgsqlPDOQuerySplitter.php
@@ -0,0 +1,291 @@
+<?php
+
+/**
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ *
+ * @version SVN: $Id: 0e3570c0e594f4396d833d77e841294855b297d9 $
+ * @package phing.tasks.ext.pdo
+ */
+
+require_once 'phing/tasks/ext/pdo/PDOQuerySplitter.php';
+
+/**
+ * Splits PostgreSQL's dialect of SQL into separate queries
+ *
+ * Unlike DefaultPDOQuerySplitter this uses a lexer instead of regular
+ * expressions. This allows handling complex constructs like C-style comments
+ * (including nested ones) and dollar-quoted strings.
+ *
+ * @author Alexey Borzov <avb@php.net>
+ * @package phing.tasks.ext.pdo
+ * @version $Id: 0e3570c0e594f4396d833d77e841294855b297d9 $
+ * @link http://www.phing.info/trac/ticket/499
+ * @link http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
+ */
+class PgsqlPDOQuerySplitter extends PDOQuerySplitter
+{
+ /**#@+
+ * Lexer states
+ */
+ const STATE_NORMAL = 0;
+ const STATE_SINGLE_QUOTED = 1;
+ const STATE_DOUBLE_QUOTED = 2;
+ const STATE_DOLLAR_QUOTED = 3;
+ const STATE_COMMENT_LINEEND = 4;
+ const STATE_COMMENT_MULTILINE = 5;
+ const STATE_BACKSLASH = 6;
+ /**#@-*/
+
+ /**
+ * Nesting depth of current multiline comment
+ * @var int
+ */
+ protected $commentDepth = 0;
+
+ /**
+ * Current dollar-quoting "tag"
+ * @var string
+ */
+ protected $quotingTag = '';
+
+ /**
+ * Current lexer state, one of STATE_* constants
+ * @var int
+ */
+ protected $state = self::STATE_NORMAL;
+
+ /**
+ * Whether a backslash was just encountered in quoted string
+ * @var bool
+ */
+ protected $escape = false;
+
+ /**
+ * Current source line being examined
+ * @var string
+ */
+ protected $line = '';
+
+ /**
+ * Position in current source line
+ * @var int
+ */
+ protected $inputIndex;
+
+ /**
+ * Gets next symbol from the input, false if at end
+ *
+ * @return string|bool
+ */
+ public function getc()
+ {
+ if (!strlen($this->line) || $this->inputIndex >= strlen($this->line)) {
+ if (null === ($line = $this->sqlReader->readLine())) {
+ return false;
+ }
+ $project = $this->parent->getOwningTarget()->getProject();
+ $this->line = ProjectConfigurator::replaceProperties(
+ $project, $line, $project->getProperties()
+ ) . "\n";
+ $this->inputIndex = 0;
+ }
+ return $this->line[$this->inputIndex++];
+ }
+
+ /**
+ * Bactracks one symbol on the input
+ *
+ * NB: we don't need ungetc() at the start of the line, so this case is
+ * not handled.
+ */
+ public function ungetc()
+ {
+ $this->inputIndex--;
+ }
+
+ /**
+ * Checks whether symbols after $ are a valid dollar-quoting tag
+ *
+ * @return string|bool Dollar-quoting "tag" if it is present, false otherwise
+ */
+ protected function checkDollarQuote()
+ {
+ $ch = $this->getc();
+ if ('$' == $ch) {
+ // empty tag
+ return '';
+
+ } elseif (!ctype_alpha($ch) && '_' != $ch) {
+ // not a delimiter
+ $this->ungetc();
+ return false;
+
+ } else {
+ $tag = $ch;
+ while (false !== ($ch = $this->getc())) {
+ if ('$' == $ch) {
+ return $tag;
+
+ } elseif (ctype_alnum($ch) || '_' == $ch) {
+ $tag .= $ch;
+
+ } else {
+ for ($i = 0; $i < strlen($tag); $i++) {
+ $this->ungetc();
+ }
+ return false;
+ }
+ }
+ }
+ }
+
+ public function nextQuery()
+ {
+ $sql = '';
+ $delimiter = $this->parent->getDelimiter();
+ $openParens = 0;
+
+ while (false !== ($ch = $this->getc())) {
+ switch ($this->state) {
+ case self::STATE_NORMAL:
+ switch ($ch) {
+ case '-':
+ if ('-' == $this->getc()) {
+ $this->state = self::STATE_COMMENT_LINEEND;
+ } else {
+ $this->ungetc();
+ }
+ break;
+ case '"':
+ $this->state = self::STATE_DOUBLE_QUOTED;
+ break;
+ case "'":
+ $this->state = self::STATE_SINGLE_QUOTED;
+ break;
+ case '/':
+ if ('*' == $this->getc()) {
+ $this->state = self::STATE_COMMENT_MULTILINE;
+ $this->commentDepth = 1;
+ } else {
+ $this->ungetc();
+ }
+ break;
+ case '$':
+ if (false !== ($tag = $this->checkDollarQuote())) {
+ $this->state = self::STATE_DOLLAR_QUOTED;
+ $this->quotingTag = $tag;
+ $sql .= '$' . $tag . '$';
+ continue 3;
+ }
+ break;
+ case '(':
+ $openParens++;
+ break;
+ case ')':
+ $openParens--;
+ break;
+ // technically we can use e.g. psql's \g command as delimiter
+ case $delimiter[0]:
+ // special case to allow "create rule" statements
+ // http://www.postgresql.org/docs/current/interactive/sql-createrule.html
+ if (';' == $delimiter && 0 < $openParens) {
+ break;
+ }
+ $hasQuery = true;
+ for ($i = 1; $i < strlen($delimiter); $i++) {
+ if ($delimiter[$i] != $this->getc()) {
+ $hasQuery = false;
+ }
+ }
+ if ($hasQuery) {
+ return $sql;
+ } else {
+ for ($j = 1; $j < $i; $j++) {
+ $this->ungetc();
+ }
+ }
+ }
+ break;
+
+ case self::STATE_COMMENT_LINEEND:
+ if ("\n" == $ch) {
+ $this->state = self::STATE_NORMAL;
+ }
+ break;
+
+ case self::STATE_COMMENT_MULTILINE:
+ switch ($ch) {
+ case '/':
+ if ('*' != $this->getc()) {
+ $this->ungetc();
+ } else {
+ $this->commentDepth++;
+ }
+ break;
+
+ case '*':
+ if ('/' != $this->getc()) {
+ $this->ungetc();
+ } else {
+ $this->commentDepth--;
+ if (0 == $this->commentDepth) {
+ $this->state = self::STATE_NORMAL;
+ continue 3;
+ }
+ }
+ }
+
+ case self::STATE_SINGLE_QUOTED:
+ case self::STATE_DOUBLE_QUOTED:
+ if ($this->escape) {
+ $this->escape = false;
+ break;
+ }
+ $quote = $this->state == self::STATE_SINGLE_QUOTED ? "'" : '"';
+ switch ($ch) {
+ case '\\':
+ $this->escape = true;
+ break;
+ case $quote:
+ if ($quote == $this->getc()) {
+ $sql .= $quote;
+ } else {
+ $this->ungetc();
+ $this->state = self::STATE_NORMAL;
+ }
+ }
+
+ case self::STATE_DOLLAR_QUOTED:
+ if ('$' == $ch && false !== ($tag = $this->checkDollarQuote())) {
+ if ($tag == $this->quotingTag) {
+ $this->state = self::STATE_NORMAL;
+ }
+ $sql .= '$' . $tag . '$';
+ continue 2;
+ }
+ }
+
+ if ($this->state != self::STATE_COMMENT_LINEEND && $this->state != self::STATE_COMMENT_MULTILINE) {
+ $sql .= $ch;
+ }
+ }
+ if ('' !== $sql) {
+ return $sql;
+ }
+ return null;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php
new file mode 100644
index 00000000..3aad8ec8
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * $Id: 0b899576769e68651a8847db8db8941aa4d784a2 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PDOResultFormatter.php';
+
+/**
+ * Plain text formatter for PDO results.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class PlainPDOResultFormatter extends PDOResultFormatter
+{
+ /**
+ * Have column headers been printed?
+ * @var boolean
+ */
+ private $colsprinted = false;
+
+ /**
+ * Whether to show headers.
+ * @var boolean
+ */
+ private $showheaders = true;
+
+ /**
+ * Column delimiter.
+ * Defaults to ','
+ * @var string
+ */
+ private $coldelimiter = ",";
+
+ /**
+ * Row delimiter.
+ * Defaults to PHP_EOL.
+ * @var string
+ */
+ private $rowdelimiter = PHP_EOL;
+
+ /**
+ * Set the showheaders attribute.
+ * @param boolean $v
+ */
+ public function setShowheaders($v) {
+ $this->showheaders = StringHelper::booleanValue($v);
+ }
+
+ /**
+ * Sets the column delimiter.
+ * @param string $v
+ */
+ public function setColdelim($v) {
+ $this->coldelimiter = $v;
+ }
+
+ /**
+ * Sets the row delimiter.
+ * @param string $v
+ */
+ public function setRowdelim($v) {
+ $this->rowdelimiter = $v;
+ }
+
+ /**
+ * Processes a specific row from PDO result set.
+ *
+ * @param array $row Row of PDO result set.
+ */
+ public function processRow($row) {
+
+ if (!$this->colsprinted && $this->showheaders) {
+ $first = true;
+ foreach($row as $fieldName => $ignore) {
+ if ($first) $first = false; else $line .= ",";
+ $line .= $fieldName;
+ }
+
+ $this->out->write($line);
+ $this->out->write(PHP_EOL);
+
+ $line = "";
+ $colsprinted = true;
+ } // if show headers
+
+ $first = true;
+ foreach($row as $columnValue) {
+
+ if ($columnValue != null) {
+ $columnValue = trim($columnValue);
+ }
+
+ if ($first) {
+ $first = false;
+ } else {
+ $line .= $this->coldelimiter;
+ }
+ $line .= $columnValue;
+ }
+
+ $this->out->write($line);
+ $this->out->write($this->rowdelimiter);
+
+ }
+
+ public function getPreferredOutfile()
+ {
+ return new PhingFile('results.txt');
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php
new file mode 100644
index 00000000..435ae6e7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * $Id: e5c24c7ac3cd665f7877d66f64218be584429581 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PDOResultFormatter.php';
+
+/**
+ * XML formatter for PDO results.
+ *
+ * This class reprsents the output of a query using a simple XML schema.
+ *
+ * <results>
+ * <row>
+ * <col name="id">value</col>
+ * <col name="name">value2</col>
+ * </row>
+ * <row>
+ * <col name="id">value</col>
+ * <col name="name">value2</col>
+ * </row>
+ * </results>
+ *
+ * The actual names of the colums will depend on the fetchmode that was used
+ * with PDO.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class XMLPDOResultFormatter extends PDOResultFormatter {
+
+ /**
+ * The XML document being created.
+ * @var DOMDocument
+ */
+ private $doc;
+
+ /**
+ * @var DOMElement
+ */
+ private $rootNode;
+
+ /**
+ * XML document encoding
+ *
+ * @var string
+ */
+ private $encoding;
+
+ /**
+ * @var boolean
+ */
+ private $formatOutput = true;
+
+ /**
+ * Set the DOM document encoding.
+ * @param string $v
+ */
+ public function setEncoding($v) {
+ $this->encoding = $v;
+ }
+
+ /**
+ * @param boolean $v
+ */
+ public function setFormatOutput($v) {
+ $this->formatOutput = (boolean) $v;
+ }
+
+ public function initialize() {
+ $this->doc = new DOMDocument("1.0", $this->encoding);
+ $this->rootNode = $this->doc->createElement('results');
+ $this->doc->appendChild($this->rootNode);
+ $this->doc->formatOutput = $this->formatOutput;
+ }
+
+ /**
+ * Processes a specific row from PDO result set.
+ *
+ * @param array $row Row of PDO result set.
+ */
+ public function processRow($row) {
+
+ $rowNode = $this->doc->createElement('row');
+ $this->rootNode->appendChild($rowNode);
+
+ foreach($row as $columnName => $columnValue) {
+
+ $colNode = $this->doc->createElement('column');
+ $colNode->setAttribute('name', $columnName);
+
+ if ($columnValue != null) {
+ $columnValue = trim($columnValue);
+ $colNode->nodeValue = $columnValue;
+ }
+ $rowNode->appendChild($colNode);
+ }
+
+ }
+
+ /**
+ * Gets a preferred filename for an output file.
+ *
+ * If no filename is specified, this is where the results will be placed
+ * (unless usefile=false).
+ *
+ * @return string
+ */
+ public function getPreferredOutfile()
+ {
+ return new PhingFile('results.xml');
+ }
+
+ /**
+ * Write XML to file and free the DOM objects.
+ */
+ public function close() {
+ $this->out->write($this->doc->saveXML());
+ $this->rootNode = null;
+ $this->doc = null;
+ parent::close();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/pearpackage/Fileset.php b/buildscripts/phing/classes/phing/tasks/ext/pearpackage/Fileset.php
index 12bd4e55..23a0e4c6 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/pearpackage/Fileset.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/pearpackage/Fileset.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: Fileset.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 7016dea93483cc99ad17a638e30f5ff57c37c78b $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -30,17 +30,11 @@ include_once 'phing/system/io/PhingFile.php';
* @author Greg Beaver
* @author Hans Lellelid <hans@xmpl.org>
* @package phing.tasks.ext.pearpackage
- * @version $Revision: 1.7 $
+ * @version $Id$
*/
class PEAR_PackageFileManager_Fileset {
/**
- * @access private
- * @var PEAR_PackageFileManager
- */
- private $parent;
-
- /**
* Curent Phing Project.
* @var Project
*/
@@ -60,9 +54,12 @@ class PEAR_PackageFileManager_Fileset {
* @param PEAR_PackageFileManager
* @param array
*/
- function __construct($parent, $options)
+ function __construct($options)
{
- $this->parent = $parent;
+ if (!is_array($options)) {
+ $options = $options->getOptions();
+ }
+
$this->project = $options['phing_project'];
$this->filesets = $options['phing_filesets'];
}
@@ -109,7 +106,7 @@ class PEAR_PackageFileManager_Fileset {
$path = '/'; // for array index
}
- $parts = explode('.', basename($file));
+ $parts = explode('.', basename($file));
$ext = array_pop($parts);
if (strlen($ext) == strlen($file)) {
$ext = '';
@@ -228,4 +225,4 @@ class PEAR_PackageFileManager_Fileset {
return strnatcasecmp($a,$b);
}
}
-?>
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadata.php b/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadata.php
new file mode 100644
index 00000000..1f7a263c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadata.php
@@ -0,0 +1,55 @@
+<?php
+/*
+ * $Id: fae81ee47ae75fc98d7848a22da93bfd4afb7a1b $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phar/PharMetadataElement.php';
+
+/**
+ * @package phing.tasks.ext.phar
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @since 2.4.0
+ */
+class PharMetadata
+{
+ /**
+ * @var array
+ */
+ protected $elements = array();
+ /**
+ * @return PharMetadataElement
+ */
+ public function createElement()
+ {
+ return ($this->elements[] = new PharMetadataElement());
+ }
+ /**
+ * @return array
+ */
+ public function toArray()
+ {
+ $metadata = array();
+
+ foreach ($this->elements as $element) {
+ $metadata[$element->getName()] = $element->toArray();
+ }
+
+ return $metadata;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadataElement.php b/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadataElement.php
new file mode 100644
index 00000000..c40f68f1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phar/PharMetadataElement.php
@@ -0,0 +1,80 @@
+<?php
+/*
+ * $Id: 4c70deae6a6f273d55f504077a3941ad926ad325 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phar/PharMetadata.php';
+
+/**
+ * @package phing.tasks.ext.phar
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @since 2.4.0
+ */
+class PharMetadataElement
+ extends PharMetadata
+{
+ /**
+ * @var string
+ */
+ private $name;
+ /**
+ * @var string
+ */
+ private $value;
+ /**
+ * @param string $value
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ }
+ /**
+ * @param string $name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+ /**
+ * Return array of
+ *
+ * @return string|array
+ */
+ public function getValue()
+ {
+ /*
+ * Elements first!
+ */
+ return (empty($this->elements) ? $this->value : $this->elements);
+ }
+ /**
+ * @return string|array
+ */
+ public function toArray()
+ {
+ return (empty($this->elements) ? $this->value : parent::toArray());
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phar/PharPackageTask.php b/buildscripts/phing/classes/phing/tasks/ext/phar/PharPackageTask.php
new file mode 100644
index 00000000..76a4215a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phar/PharPackageTask.php
@@ -0,0 +1,362 @@
+<?php
+/*
+ * $Id: 0396ab9c461e7d7655f12c9ed3a613fe6e69f973 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+require_once 'phing/types/IterableFileSet.php';
+require_once 'phing/tasks/ext/phar/PharMetadata.php';
+
+/**
+ * Package task for {@link http://ru.php.net/manual/en/book.phar.php Phar technology}.
+ *
+ * @package phing.tasks.ext
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @since 2.4.0
+ */
+class PharPackageTask
+ extends MatchingTask
+{
+ /**
+ * @var PhingFile
+ */
+ private $destinationFile;
+ /**
+ * @var int
+ */
+ private $compression = Phar::NONE;
+ /**
+ * Base directory, from where local package paths will be calculated.
+ *
+ * @var PhingFile
+ */
+ private $baseDirectory;
+ /**
+ * @var PhingFile
+ */
+ private $cliStubFile;
+ /**
+ * @var PhingFile
+ */
+ private $webStubFile;
+ /**
+ * @var string
+ */
+ private $stubPath;
+ /**
+ * Private key the Phar will be signed with.
+ *
+ * @var PhingFile
+ */
+ private $key;
+ /**
+ * Password for the private key.
+ *
+ * @var string
+ */
+ private $keyPassword = '';
+ /**
+ * @var int
+ */
+ private $signatureAlgorithm = Phar::SHA1;
+ /**
+ * @var array
+ */
+ private $filesets = array();
+ /**
+ * @var PharMetadata
+ */
+ private $metadata = null;
+ /**
+ * @var string
+ */
+ private $alias;
+ /**
+ * @return PharMetadata
+ */
+ public function createMetadata()
+ {
+ return ($this->metadata = new PharMetadata());
+ }
+ /**
+ * @return FileSet
+ */
+ public function createFileSet()
+ {
+ $this->fileset = new IterableFileSet();
+ $this->filesets[] = $this->fileset;
+ return $this->fileset;
+ }
+ /**
+ * @param string $algorithm
+ */
+ public function setSignature($algorithm)
+ {
+ /*
+ * If we don't support passed algprithm, leave old one.
+ */
+ switch ($algorithm) {
+ case 'md5':
+ $this->signatureAlgorithm = Phar::MD5;
+ break;
+ case 'sha1':
+ $this->signatureAlgorithm = Phar::SHA1;
+ break;
+ case 'sha256':
+ $this->signatureAlgorithm = Phar::SHA256;
+ break;
+ case 'sha512':
+ $this->signatureAlgorithm = Phar::SHA512;
+ break;
+ case 'openssl':
+ $this->signatureAlgorithm = Phar::OPENSSL;
+ break;
+ default:
+ break;
+ }
+ }
+ /**
+ * @param string $compression
+ */
+ public function setCompression($compression)
+ {
+ /*
+ * If we don't support passed compression, leave old one.
+ */
+ switch ($compression) {
+ case 'gzip':
+ $this->compression = Phar::GZ;
+ break;
+ case 'bzip2':
+ $this->compression = Phar::BZ2;
+ break;
+ default:
+ break;
+ }
+ }
+ /**
+ * @param PhingFile $destinationFile
+ */
+ public function setDestFile(PhingFile $destinationFile)
+ {
+ $this->destinationFile = $destinationFile;
+ }
+ /**
+ * @param PhingFile $baseDirectory
+ */
+ public function setBaseDir(PhingFile $baseDirectory)
+ {
+ $this->baseDirectory = $baseDirectory;
+ }
+ /**
+ * @param PhingFile $stubFile
+ */
+ public function setCliStub(PhingFile $stubFile)
+ {
+ $this->cliStubFile = $stubFile;
+ }
+ /**
+ * @param PhingFile $stubFile
+ */
+ public function setWebStub(PhingFile $stubFile)
+ {
+ $this->webStubFile = $stubFile;
+ }
+ /**
+ * @param string $stubPath
+ */
+ public function setStub($stubPath)
+ {
+ $this->stubPath = $stubPath;
+ }
+ /**
+ * @param $alias
+ */
+ public function setAlias($alias)
+ {
+ $this->alias = $alias;
+ }
+ /**
+ * Sets the private key to use to sign the Phar with.
+ *
+ * @param PhingFile $key Private key to sign the Phar with.
+ */
+ public function setKey(PhingFile $key)
+ {
+ $this->key = $key;
+ }
+ /**
+ * Password for the private key.
+ *
+ * @param string $keyPassword
+ */
+ public function setKeyPassword($keyPassword)
+ {
+ $this->keyPassword = $keyPassword;
+ }
+ /**
+ * @throws BuildException
+ */
+ public function main()
+ {
+ $this->checkPreconditions();
+
+ try {
+ $this->log(
+ 'Building package: '.$this->destinationFile->__toString(),
+ Project::MSG_INFO
+ );
+
+ /*
+ * Delete old package, if exists.
+ */
+ if ($this->destinationFile->exists()) {
+ /*
+ * TODO Check operation for errors...
+ */
+ $this->destinationFile->delete();
+ }
+
+ $phar = $this->buildPhar();
+ $phar->startBuffering();
+
+ $baseDirectory = realpath($this->baseDirectory->getPath());
+
+ foreach ($this->filesets as $fileset) {
+ $this->log(
+ 'Adding specified files in ' . $fileset->getDir($this->project) . ' to package',
+ Project::MSG_VERBOSE
+ );
+
+ $phar->buildFromIterator($fileset, $baseDirectory);
+ }
+
+ $phar->stopBuffering();
+
+ /*
+ * File compression, if needed.
+ */
+ if (Phar::NONE != $this->compression) {
+ $phar->compressFiles($this->compression);
+ }
+ } catch (Exception $e) {
+ throw new BuildException(
+ 'Problem creating package: '.$e->getMessage(),
+ $e,
+ $this->getLocation()
+ );
+ }
+ }
+ /**
+ * @throws BuildException
+ */
+ private function checkPreconditions()
+ {
+ if (is_null($this->destinationFile)) {
+ throw new BuildException("destfile attribute must be set!", $this->getLocation());
+ }
+
+ if ($this->destinationFile->exists() && $this->destinationFile->isDirectory()) {
+ throw new BuildException("destfile is a directory!", $this->getLocation());
+ }
+
+ if (!$this->destinationFile->canWrite()) {
+ throw new BuildException("Can not write to the specified destfile!", $this->getLocation());
+ }
+ if (!is_null($this->baseDirectory)) {
+ if (!$this->baseDirectory->exists()) {
+ throw new BuildException("basedir '" . (string) $this->baseDirectory . "' does not exist!", $this->getLocation());
+ }
+ }
+ if ($this->signatureAlgorithm == Phar::OPENSSL) {
+
+ if (!extension_loaded('openssl')) {
+ throw new BuildException("PHP OpenSSL extension is required for OpenSSL signing of Phars!", $this->getLocation());
+ }
+
+ if (is_null($this->key)) {
+ throw new BuildException("key attribute must be set for OpenSSL signing!", $this->getLocation());
+ }
+
+ if (!$this->key->exists()) {
+ throw new BuildException("key '" . (string) $this->key . "' does not exist!", $this->getLocation());
+ }
+
+ if (!$this->key->canRead()) {
+ throw new BuildException("key '" . (string) $this->key . "' cannot be read!", $this->getLocation());
+ }
+ }
+ }
+ /**
+ * Build and configure Phar object.
+ *
+ * @return Phar
+ */
+ private function buildPhar()
+ {
+ $phar = new Phar($this->destinationFile);
+
+ if ($this->signatureAlgorithm == Phar::OPENSSL) {
+
+ // Load up the contents of the key
+ $keyContents = file_get_contents($this->key);
+
+ // Setup an OpenSSL resource using the private key and tell the Phar
+ // to sign it using that key.
+ $private = openssl_pkey_get_private($keyContents, $this->keyPassword);
+ $phar->setSignatureAlgorithm(Phar::OPENSSL, $private);
+
+ // Get the details so we can get the public key and write that out
+ // alongside the phar.
+ $details = openssl_pkey_get_details($private);
+ file_put_contents($this->destinationFile . '.pubkey', $details['key']);
+
+ } else {
+ $phar->setSignatureAlgorithm($this->signatureAlgorithm);
+ }
+
+ if (isset($this->stubPath)) {
+ $phar->setStub(file_get_contents($this->stubPath));
+ } else {
+ if (!empty($this->cliStubFile)) {
+ $cliStubFile = $this->cliStubFile->getPathWithoutBase($this->baseDirectory);
+ } else {
+ $cliStubFile = null;
+ }
+
+ if (!empty($this->webStubFile)) {
+ $webStubFile = $this->webStubFile->getPathWithoutBase($this->baseDirectory);
+ } else {
+ $webStubFile = null;
+ }
+
+ $phar->setDefaultStub($cliStubFile, $webStubFile);
+ }
+
+ if ($metadata = $this->metadata->toArray()) {
+ $phar->setMetadata($metadata);
+ }
+
+ if(!empty($this->alias)){
+ $phar->setAlias($this->alias);
+ }
+
+ return $phar;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageTask.php b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageTask.php
new file mode 100644
index 00000000..80da93fa
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageTask.php
@@ -0,0 +1,248 @@
+<?php
+/**
+ * $Id: 5029881915d6a9e95320ba6e7f463f38af66cd93 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <alexey@shockov.com>
+ * @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);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccess.php b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccess.php
new file mode 100644
index 00000000..9634d899
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccess.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * $Id: b6ea3e7df3c43498e8c6e105bedfd0b6e99e055a $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phk/PhkPackageWebAccessPath.php';
+
+/**
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @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;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccessPath.php b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccessPath.php
new file mode 100644
index 00000000..730a8929
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phk/PhkPackageWebAccessPath.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * $Id: 755aeaf34726af2eb30c989914faad8d7aebd126 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * @author Alexey Shockov <alexey@shockov.com>
+ * @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;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php
new file mode 100644
index 00000000..e650ca72
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * $Id: dece05e79e883b4d5e95f2215e36ce4f2f72ed2e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * A wrapper for the implementations of PHPCPDResultFormatter.
+ *
+ * @package phing.tasks.ext.phpcpd
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: dece05e79e883b4d5e95f2215e36ce4f2f72ed2e $
+ */
+class PHPCPDFormatterElement
+{
+ /**
+ * The report result formatter.
+ *
+ * @var PHPCPDResultFormatter
+ */
+ protected $_formatter = null;
+
+ /**
+ * The type of the formatter.
+ *
+ * @var string
+ */
+ protected $_type = '';
+
+ /**
+ * Whether to use file (or write output to phing log).
+ *
+ * @var boolean
+ */
+ protected $_useFile = true;
+
+ /**
+ * Output file for formatter.
+ *
+ * @var PhingFile
+ */
+ protected $_outfile = null;
+
+ /**
+ * The parent task
+ *
+ * @var PHPCPDTask
+ */
+ private $_parentTask;
+
+ /**
+ * Construct a new PHPCPDFormatterElement with parent task.
+ * @param PHPCPDTask $parentTask
+ */
+ public function __construct(PHPCPDTask $parentTask)
+ {
+ $this->_parentTask = $parentTask;
+ }
+
+ /**
+ * Sets the formatter type.
+ *
+ * @param string $type Type of the formatter
+ *
+ * @return void
+ */
+ public function setType($type)
+ {
+ $this->_type = $type;
+
+ switch ($this->_type) {
+ case 'pmd':
+ if ($this->_useFile === false) {
+ throw new BuildException(
+ "Formatter '" . $this->_type
+ . "' can only print the result to an file"
+ );
+ }
+
+ include_once 'phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php';
+ $this->_formatter = new PMDPHPCPDResultFormatter();
+ break;
+
+ case 'default':
+ include_once 'phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php';
+ $this->_formatter = new DefaultPHPCPDResultFormatter();
+ 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.
+ *
+ * @return void
+ */
+ 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
+ *
+ * @return void
+ */
+ public function setOutfile(PhingFile $outfile)
+ {
+ $this->_outfile = $outfile;
+ }
+
+ /**
+ * Get the output file.
+ *
+ * @return PhingFile
+ */
+ public function getOutfile()
+ {
+ return $this->_outfile;
+ }
+
+ /**
+ * Returns the report formatter.
+ *
+ * @throws BuildException When the specified renderer does not exist.
+ * @return PHPCPDResultFormatter
+ */
+ public function getFormatter()
+ {
+ return $this->_formatter;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDTask.php
new file mode 100644
index 00000000..31f76154
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/PHPCPDTask.php
@@ -0,0 +1,312 @@
+<?php
+/**
+ * $Id: 8fbff39b2ca68e97afd59d5dc6d5a37c3678624e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Runs PHP Copy & Paste Detector. Checking PHP files for duplicated code.
+ * Refactored original PhpCpdTask provided by
+ * Timo Haberkern <timo.haberkern@fantastic-bits.de>
+ *
+ * @package phing.tasks.ext.phpcpd
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: 8fbff39b2ca68e97afd59d5dc6d5a37c3678624e $
+ */
+class PHPCPDTask extends Task
+{
+ /**
+ * A php source code filename or directory
+ *
+ * @var PhingFile
+ */
+ protected $_file = null;
+
+ /**
+ * All fileset objects assigned to this task
+ *
+ * @var array<FileSet>
+ */
+ protected $_filesets = array();
+
+ /**
+ * Minimum number of identical lines.
+ *
+ * @var integer
+ */
+ protected $_minLines = 5;
+
+ /**
+ * Minimum number of identical tokens.
+ *
+ * @var integer
+ */
+ protected $_minTokens = 70;
+
+ /**
+ * 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 = 'default';
+
+ /**
+ * Formatter elements.
+ *
+ * @var array<PHPCPDFormatterElement>
+ */
+ protected $_formatters = array();
+
+ /**
+ * Load the necessary environment for running PHPCPD.
+ *
+ * @throws BuildException - if the phpcpd classes can't be loaded.
+ */
+ public function init()
+ {
+ /**
+ * Determine PHPCPD installation
+ */
+ @include_once 'PHPCPD/Autoload.php';
+
+ if (! class_exists('PHPCPD_TextUI_Command')) {
+ throw new BuildException(
+ 'PHPCPDTask depends on PHPCPD being installed '
+ . 'and on include_path.',
+ $this->getLocation()
+ );
+ }
+
+ // Other dependencies that should only be loaded
+ // when class is actually used
+ require_once 'phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php';
+ }
+
+ /**
+ * Set the input source file or directory.
+ *
+ * @param PhingFile $file The input source file or directory.
+ *
+ * @return void
+ */
+ public function setFile(PhingFile $file)
+ {
+ $this->_file = $file;
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ *
+ * @param FileSet $fs List of files to scan
+ *
+ * @return void
+ */
+ public function addFileSet(FileSet $fs)
+ {
+ $this->_filesets[] = $fs;
+ }
+
+ /**
+ * Sets the minimum number of identical lines (default: 5).
+ *
+ * @param integer $minLines Minimum number of identical lines
+ *
+ * @return void
+ */
+ public function setMinLines($minLines)
+ {
+ $this->_minLines = $minLines;
+ }
+
+ /**
+ * Sets the minimum number of identical tokens (default: 70).
+ *
+ * @param integer $minTokens Minimum number of identical tokens
+ */
+ public function setMinTokens($minTokens)
+ {
+ $this->_minTokens = $minTokens;
+ }
+
+ /**
+ * Sets a list of filename extensions for valid php source code files.
+ *
+ * @param string $fileExtensions List of valid file extensions.
+ *
+ * @return void
+ */
+ 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.
+ *
+ * @return void
+ */
+ public function setIgnorePatterns($ignorePatterns)
+ {
+ $this->_ignorePatterns = array();
+
+ $token = ' ,;';
+ $pattern = strtok($ignorePatterns, $token);
+
+ while ($pattern !== false) {
+ $this->_ignorePatterns[] = $pattern;
+ $pattern = strtok($token);
+ }
+ }
+
+ /**
+ * Sets the output format
+ *
+ * @param string $format Format of the report
+ */
+ public function setFormat($format)
+ {
+ $this->_format = $format;
+ }
+
+ /**
+ * Create object for nested formatter element.
+ *
+ * @return PHPCPDFormatterElement
+ */
+ public function createFormatter()
+ {
+ $num = array_push(
+ $this->_formatters,
+ new PHPCPDFormatterElement($this)
+ );
+ return $this->_formatters[$num-1];
+ }
+
+ /**
+ * Executes PHPCPD against PhingFile or a FileSet
+ *
+ * @return void
+ */
+ 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 (count($this->_formatters) == 0) {
+ // turn legacy format attribute into formatter
+ $fmt = new PHPCPDFormatterElement($this);
+ $fmt->setType($this->_format);
+ $fmt->setUseFile(false);
+ $this->_formatters[] = $fmt;
+ }
+
+ $this->validateFormatters();
+
+ $filesToParse = array();
+
+ if ($this->_file instanceof PhingFile) {
+ $filesToParse[] = $this->_file->getPath();
+ } 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();
+ }
+ }
+ }
+
+ $this->log('Processing files...');
+
+ $detector = new PHPCPD_Detector(new PHPCPD_Detector_Strategy_Default());
+ $clones = $detector->copyPasteDetection(
+ $filesToParse,
+ $this->_minLines,
+ $this->_minTokens
+ );
+
+ $this->log('Finished copy/paste detection');
+
+ foreach ($this->_formatters as $fe) {
+ $formatter = $fe->getFormatter();
+ $formatter->processClones(
+ $clones,
+ $this->project,
+ $fe->getUseFile(),
+ $fe->getOutfile()
+ );
+ }
+ }
+
+ /**
+ * Validates the available formatters
+ *
+ * @throws BuildException
+ * @return void
+ */
+ protected function validateFormatters()
+ {
+ 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."
+ );
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php
new file mode 100644
index 00000000..b84da547
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * $Id: a4825de14746285d97af9d435215ec8400406fa7 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPCPD/TextUI/ResultPrinter.php';
+require_once 'phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php';
+
+/**
+ * Prints plain text output of phpcpd run
+ *
+ * @package phing.tasks.ext.phpcpd.formatter
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: a4825de14746285d97af9d435215ec8400406fa7 $
+ */
+class DefaultPHPCPDResultFormatter extends PHPCPDResultFormatter
+{
+
+ /**
+ * Processes a list of clones.
+ *
+ * @param PHPCPD_CloneMap $clones
+ * @param Project $project
+ * @param boolean $useFile
+ * @param PhingFile|null $outfile
+ */
+ public function processClones(PHPCPD_CloneMap $clones, Project $project, $useFile = false, $outFile = null)
+ {
+ $logger = new PHPCPD_TextUI_ResultPrinter();
+ // default format goes to logs, no buffering
+ ob_start();
+ $logger->printResult($clones, $project->getBaseDir(), true);
+ $output = ob_get_contents();
+ ob_end_clean();
+
+ if (!$useFile || empty($outFile)) {
+ echo $output;
+ } else {
+ file_put_contents($outFile->getPath(), $output);
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php
new file mode 100644
index 00000000..0cdab194
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * $Id: 478d7a823945aa4706befb0059b2fab28743fb07 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * This abstract class describes classes that format the results of a PHPCPD run.
+ *
+ * @package phing.tasks.ext.phpcpd.formatter
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: 478d7a823945aa4706befb0059b2fab28743fb07 $
+ */
+abstract class PHPCPDResultFormatter
+{
+ /**
+ * Processes a list of clones.
+ *
+ * @param PHPCPD_CloneMap $clones
+ * @param Project $project
+ * @param boolean $useFile
+ * @param PhingFile|null $outfile
+ */
+ abstract public function processClones(PHPCPD_CloneMap $clones, Project $project, $useFile = false, $outFile = null);
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php
new file mode 100644
index 00000000..33c24407
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * $Id: a336822b8c54702ba2b0590e5a812c779e5c221b $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPCPD/Log/XML/PMD.php';
+require_once 'phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php';
+
+/**
+ * Prints PMD-XML output of phpcpd run
+ *
+ * @package phing.tasks.ext.phpcpd.formatter
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: a336822b8c54702ba2b0590e5a812c779e5c221b $
+ */
+class PMDPHPCPDResultFormatter extends PHPCPDResultFormatter
+{
+ /**
+ * Processes a list of clones.
+ *
+ * @param PHPCPD_CloneMap $clones
+ * @param Project $project
+ * @param boolean $useFile
+ * @param PhingFile|null $outfile
+ */
+ public function processClones(PHPCPD_CloneMap $clones, Project $project, $useFile = false, $outFile = null)
+ {
+ if (!$useFile || empty($outFile)) {
+ throw new BuildException("Output filename required for this formatter");
+ }
+
+ $logger = new PHPCPD_Log_XML_PMD($outFile);
+ $logger->processClones($clones);
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PHPDocumentorTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PHPDocumentorTask.php
deleted file mode 100644
index 2fefc4e5..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PHPDocumentorTask.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
- /**
- * $Id: PHPDocumentorTask.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
- require_once 'phing/Task.php';
-
- /**
- * Task to run phpDocumentor.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPDocumentorTask.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpdoc
- */
- class PHPDocumentorTask extends Task
- {
- /**
- * The name of the executable for phpDocumentor
- */
- const PHPDOC = 'phpdoc';
-
- private $title = "Default Title";
-
- private $destdir = ".";
-
- private $sourcepath = NULL;
-
- private $output = "";
-
- private $linksource = false;
-
- private $parseprivate = false;
-
- /**
- * Set the title for the generated documentation
- */
- function setTitle($title)
- {
- $this->title = $title;
- }
-
- /**
- * Set the destination directory for the generated documentation
- */
- function setDestdir($destdir)
- {
- $this->destdir = $destdir;
- }
-
- /**
- * Set the source path
- */
- function setSourcepath(Path $sourcepath)
- {
- if ($this->sourcepath === NULL)
- {
- $this->sourcepath = $sourcepath;
- }
- else
- {
- $this->sourcepath->append($sourcepath);
- }
- }
-
- /**
- * Set the output type
- */
- function setOutput($output)
- {
- $this->output = $output;
- }
-
- /**
- * Should sources be linked in the generated documentation
- */
- function setLinksource($linksource)
- {
- $this->linksource = $linksource;
- }
-
- /**
- * Should private members/classes be documented
- */
- function setParseprivate($parseprivate)
- {
- $this->parseprivate = $parseprivate;
- }
-
- /**
- * Main entrypoint of the task
- */
- function main()
- {
- $arguments = $this->constructArguments();
-
- exec(self::PHPDOC . " " . $arguments, $output, $retval);
- }
-
- /**
- * Constructs an argument string for phpDocumentor
- */
- private function constructArguments()
- {
- $arguments = "-q ";
-
- if ($this->title)
- {
- $arguments.= "-ti \"" . $this->title . "\" ";
- }
-
- if ($this->destdir)
- {
- $arguments.= "-t " . $this->destdir . " ";
- }
-
- if ($this->sourcepath !== NULL)
- {
- $arguments.= "-d " . $this->sourcepath->__toString() . " ";
- }
-
- if ($this->output)
- {
- $arguments.= "-o " . $this->output . " ";
- }
-
- if ($this->linksource)
- {
- $arguments.= "-s ";
- }
-
- if ($this->parseprivate)
- {
- $arguments.= "-pp ";
- }
-
- return $arguments;
- }
- };
-
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php
new file mode 100644
index 00000000..462b1d99
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorErrorTracker.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * $Id: 73c919ab2044bf6582f52bd7ccb0184019d52f53 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 occured 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 <privat@timohummel.com> @author felicitus
+ * @version $Id: 73c919ab2044bf6582f52bd7ccb0184019d52f53 $
+ * @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
+ */
+ 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
+ */
+
+ 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;
+ }
+
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php
new file mode 100644
index 00000000..62662b0b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php
@@ -0,0 +1,230 @@
+<?php
+/**
+ * $Id: cde99d501839daf8c9dd9df61ee6cce7caad6b3e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <hans@xmpl.org>@author hans
+ * @version $Id: cde99d501839daf8c9dd9df61ee6cce7caad6b3e $
+ * @package phing.tasks.ext.phpdoc
+ */
+class PhingPhpDocumentorSetup extends phpDocumentor_setup {
+
+ /**
+ * Constructs a new PhingPhpDocumentorSetup.
+ *
+ * @param string $configDir Directory in which to look for configuration files.
+ * @param object $task The task we're working with, so we can pass it on to the ErrorTracker
+ */
+ 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;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentor2Task.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentor2Task.php
new file mode 100755
index 00000000..70fcc9e2
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentor2Task.php
@@ -0,0 +1,224 @@
+<?php
+/*
+ * $Id: eaa494390770adc752097a412d63fb863482fd5d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/FileOutputStream.php';
+
+/**
+ * PhpDocumentor2 Task (http://www.phpdoc.org)
+ * Based on the DocBlox Task
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: eaa494390770adc752097a412d63fb863482fd5d $
+ * @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";
+
+ /**
+ * Title of the project
+ * @var string
+ */
+ private $title = "";
+
+ /**
+ * Force phpDocumentor to be quiet
+ * @var boolean
+ */
+ private $quiet = true;
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ *
+ * @return FileSet
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Forces phpDocumentor to be quiet
+ * @param boolean $quiet
+ */
+ public function setQuiet($quiet)
+ {
+ $this->quiet = (boolean) $quiet;
+ }
+
+ /**
+ * Finds and initializes the phpDocumentor installation
+ */
+ private function initializePhpDocumentor()
+ {
+ $phpDocumentorPath = null;
+
+ foreach (explode(PATH_SEPARATOR, get_include_path()) as $path) {
+ $testPhpDocumentorPath = $path . DIRECTORY_SEPARATOR . 'phpDocumentor' . DIRECTORY_SEPARATOR . 'src';
+
+ if (file_exists($testPhpDocumentorPath)) {
+ $phpDocumentorPath = $testPhpDocumentorPath;
+ }
+ }
+
+ if (empty($phpDocumentorPath)) {
+ throw new BuildException("Please make sure PhpDocumentor 2 is installed and on the include_path.", $this->getLocation());
+ }
+
+ set_include_path($phpDocumentorPath . PATH_SEPARATOR . get_include_path());
+
+ require_once $phpDocumentorPath . '/phpDocumentor/Bootstrap.php';
+
+ $bootstrap = phpDocumentor_Bootstrap::createInstance();
+
+ $autoloader = $bootstrap->registerAutoloader();
+
+ if ($this->quiet) {
+ phpDocumentor_Core_Abstract::config()->logging->level = 'quiet';
+ } else {
+ phpDocumentor_Core_Abstract::config()->logging->level = 'debug';
+ }
+
+ $bootstrap->registerPlugins($autoloader);
+ }
+
+ /**
+ * Build a list of files (from the fileset elements)
+ * and call the phpDocumentor parser
+ *
+ * @return string
+ */
+ private function parseFiles()
+ {
+ $parser = new phpDocumentor_Parser();
+
+ //Only initialize the dispatcher when not already done
+ if (is_null(phpDocumentor_Parser_Abstract::$event_dispatcher)) {
+ phpDocumentor_Parser_Abstract::$event_dispatcher = new sfEventDispatcher();
+ }
+ $parser->setTitle($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->log("Will parse " . count($paths) . " file(s)", Project::MSG_VERBOSE);
+
+ $files = new phpDocumentor_Parser_Files();
+ $files->addFiles($paths);
+
+ $parser->setPath($files->getProjectRoot());
+
+ return $parser->parseFiles($files);
+ }
+
+ /**
+ * 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 (<fileset>)", $this->getLocation());
+ }
+
+ $this->initializePhpDocumentor();
+
+ $xml = $this->parseFiles();
+
+ $this->log("Transforming...", Project::MSG_VERBOSE);
+
+ $transformer = new phpDocumentor_Transformer();
+ $transformer->setTemplatesPath(phpDocumentor_Core_Abstract::config()->paths->templates);
+ $transformer->setTemplates($this->template);
+ $transformer->setSource($xml);
+ $transformer->setTarget($this->destDir->getAbsolutePath());
+ $transformer->execute();
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php
new file mode 100755
index 00000000..fb2a0b2b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php
@@ -0,0 +1,265 @@
+<?php
+
+/**
+ * $Id: 6a6c740651bb91c9854fcdf0cb1d7e768b84f805 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <mrook@php.net>
+ * @author Markus Fischer <markus@fischer.name>
+ * @version $Id: 6a6c740651bb91c9854fcdf0cb1d7e768b84f805 $
+ * @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
+ */
+ 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.
+ */
+ 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 (<fileset> or sourcepath attribute) for phpdoc.",
+ $this->getLocation());
+ }
+ if ($this->configdir) {
+ $this->log('Ignoring unsupported configdir-Attribute',
+ Project::MSG_VERBOSE);
+ }
+ }
+};
+
+
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php
new file mode 100755
index 00000000..e4ae363a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php
@@ -0,0 +1,480 @@
+<?php
+
+/**
+ * $Id: 23a04ddae9cad46198e15081a0fb44354135b1c8 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Task to run PhpDocumentor.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 23a04ddae9cad46198e15081a0fb44354135b1c8 $
+ * @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
+ */
+ public function setTitle($title) {
+ $this->title = $title;
+ }
+
+ /**
+ * Set the destination directory for the generated documentation
+ */
+ public function setDestdir(PhingFile $destdir) {
+ $this->destdir = $destdir;
+ }
+
+ /**
+ * Alias for {@link setDestdir()}.
+ * @see setDestdir()
+ */
+ 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 $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(explode(PATH_SEPARATOR, get_include_path()) 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.
+ */
+ 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 (<fileset>) 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);
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDFormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDFormatterElement.php
new file mode 100644
index 00000000..c327e331
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDFormatterElement.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * $Id: 69fc758899446b96312ac12f26b461969eb41b6e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * A wrapper for the implementations of PHPMDResultFormatter.
+ *
+ * @package phing.tasks.ext.phpmd
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @version $Id: 69fc758899446b96312ac12f26b461969eb41b6e $
+ * @since 2.4.1
+ */
+class PHPMDFormatterElement
+{
+ /**
+ * @var PHPMDResultFormatter
+ */
+ protected $formatter = null;
+
+ /**
+ * The type of the formatter.
+ *
+ * @var string
+ */
+ protected $type = "";
+
+ /**
+ * 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
+ *
+ * @return void
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+
+ switch ($this->type) {
+ case 'xml':
+ include_once 'PHP/PMD/Renderer/XMLRenderer.php';
+ break;
+
+ case 'html':
+ include_once 'PHP/PMD/Renderer/HTMLRenderer.php';
+ break;
+
+ case 'text':
+ include_once 'PHP/PMD/Renderer/TextRenderer.php';
+ 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.
+ *
+ * @return void
+ */
+ public function setUseFile($useFile)
+ {
+ $this->useFile = (boolean) $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
+ *
+ * @return void
+ */
+ 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()
+ {
+ switch ($this->type) {
+ case 'xml':
+ $renderer = new PHP_PMD_Renderer_XMLRenderer();
+ break;
+
+ case 'html':
+ $renderer = new PHP_PMD_Renderer_HTMLRenderer();
+ break;
+
+ case 'text':
+ $renderer = new PHP_PMD_Renderer_TextRenderer();
+ break;
+
+ default:
+ throw new BuildException("PHP_MD renderer '" . $this->type . "' not implemented");
+ }
+
+ // Create a report stream
+ if ($this->getUseFile() === false || $this->getOutfile() === null) {
+ $stream = STDOUT;
+ } else {
+ $stream = fopen($this->getOutfile()->getAbsoluteFile(), 'wb');
+ }
+
+ require_once 'PHP/PMD/Writer/Stream.php';
+
+ $renderer->setWriter(new PHP_PMD_Writer_Stream($stream));
+
+ return $renderer;
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDTask.php
new file mode 100644
index 00000000..1c4d34bf
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpmd/PHPMDTask.php
@@ -0,0 +1,284 @@
+<?php
+/**
+ * $Id: 35668c2c6fbf1ca87fab21c26fd55ef630458fc7 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <bschultz@proqrent.de>
+ * @version $Id: 35668c2c6fbf1ca87fab21c26fd55ef630458fc7 $
+ * @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 array<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 array<PHPMDFormatterElement>
+ */
+ protected $formatters = array();
+
+ /**
+ * Set the input source file or directory.
+ *
+ * @param PhingFile $file The input source file or directory.
+ *
+ * @return void
+ */
+ public function setFile(PhingFile $file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Nested creator, adds a set of files (nested fileset attribute).
+ *
+ * @return FileSet The created fileset object
+ */
+ public function createFileSet()
+ {
+ $num = array_push($this->filesets, new FileSet());
+ return $this->filesets[$num-1];
+ }
+
+ /**
+ * Sets the minimum rule priority.
+ *
+ * @param integer $minimumPriority Minimum rule priority.
+ *
+ * @return void
+ */
+ public function setMinimumPriority($minimumPriority)
+ {
+ $this->minimumPriority = $minimumPriority;
+ }
+
+ /**
+ * Sets the rule-sets.
+ *
+ * @param string $ruleSetFileNames Comma-separated string of rule-set filenames
+ * or identifier.
+ *
+ * @return void
+ */
+ 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.
+ *
+ * @return void
+ */
+ 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.
+ *
+ * @return void
+ */
+ 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];
+ }
+
+ /**
+ * Executes PHPMD against PhingFile or a FileSet
+ *
+ * @throws BuildException - if the phpmd classes can't be loaded.
+ * @return void
+ */
+ public function main()
+ {
+ /**
+ * Find PHPMD
+ */
+ @include_once 'PHP/PMD.php';
+
+ if (! class_exists('PHP_PMD')) {
+ throw new BuildException(
+ 'PHPMDTask depends on PHPMD being installed and on include_path.',
+ $this->getLocation()
+ );
+ }
+
+ require_once 'PHP/PMD/AbstractRule.php';
+
+ if (!$this->minimumPriority) {
+ $this->minimumPriority = PHP_PMD_AbstractRule::LOWEST_PRIORITY;
+ }
+
+ 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();
+ }
+
+ // Create a rule set factory
+ $ruleSetFactory = new PHP_PMD_RuleSetFactory();
+ $ruleSetFactory->setMinimumPriority($this->minimumPriority);
+
+ $phpmd = new PHP_PMD();
+
+ $phpmd->setFileExtensions($this->allowedFileExtensions);
+ $phpmd->setIgnorePattern($this->ignorePatterns);
+
+ $filesToParse = array();
+
+ if ($this->file instanceof PhingFile) {
+ $filesToParse[] = $this->file->getPath();
+ } 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();
+ }
+ }
+ }
+
+ if (count($filesToParse) > 0) {
+ $inputPath = implode(',', $filesToParse);
+
+ $this->log('Processing files...');
+
+ $phpmd->processFiles(
+ $inputPath,
+ $this->rulesets,
+ $reportRenderers,
+ $ruleSetFactory
+ );
+
+ $this->log('Finished processing files');
+ } else {
+ $this->log('No files to process');
+ }
+ }
+} \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/BatchTest.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/BatchTest.php
new file mode 100755
index 00000000..6a6cec24
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/BatchTest.php
@@ -0,0 +1,230 @@
+<?php
+/**
+ * $Id: 4067d915614ff7a864c31f19549bcf6a96c0f92d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpunit/PHPUnitUtil.php';
+require_once 'phing/types/FileSet.php';
+
+/**
+ * Scans a list of files given by the fileset attribute, extracts valid test cases
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 4067d915614ff7a864c31f19549bcf6a96c0f92d $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class BatchTest
+{
+ /** the list of filesets containing the testcase filename rules */
+ private $filesets = array();
+
+ /** the reference to the project */
+ private $project = NULL;
+
+ /** the classpath to use with Phing::__import() calls */
+ private $classpath = NULL;
+
+ /** names of classes to exclude */
+ private $excludeClasses = array();
+
+ /** name of the batchtest/suite */
+ protected $name = "Phing Batchtest";
+
+ /**
+ * Create a new batchtest instance
+ *
+ * @param Project the project it depends on.
+ */
+ public function __construct(Project $project)
+ {
+ $this->project = $project;
+ }
+
+ /**
+ * Sets the name of the batchtest/suite
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the classes to exclude
+ */
+ public function setExclude($exclude)
+ {
+ $this->excludeClasses = explode(" ", $exclude);
+ }
+
+ /**
+ * Sets the classpath
+ */
+ public function setClasspath(Path $classpath)
+ {
+ if ($this->classpath === null)
+ {
+ $this->classpath = $classpath;
+ }
+ else
+ {
+ $this->classpath->append($classpath);
+ }
+ }
+
+ /**
+ * Creates a new Path object
+ */
+ public function createClasspath()
+ {
+ $this->classpath = new Path();
+ return $this->classpath;
+ }
+
+ /**
+ * Returns the classpath
+ */
+ public function getClasspath()
+ {
+ return $this->classpath;
+ }
+
+ /**
+ * Add a new fileset containing the XML results to aggregate
+ *
+ * @param FileSet the new fileset containing XML results.
+ */
+ public function addFileSet(FileSet $fileset)
+ {
+ $this->filesets[] = $fileset;
+ }
+
+ /**
+ * Iterate over all filesets and return the filename of all files.
+ *
+ * @return array an array of filenames
+ */
+ private function getFilenames()
+ {
+ $filenames = array();
+
+ foreach ($this->filesets as $fileset)
+ {
+ $ds = $fileset->getDirectoryScanner($this->project);
+ $ds->scan();
+
+ $files = $ds->getIncludedFiles();
+
+ foreach ($files as $file)
+ {
+ $filenames[] = $ds->getBaseDir() . "/" . $file;
+ }
+ }
+
+ return $filenames;
+ }
+
+ /**
+ * Checks wheter $input is a PHPUnit Test
+ */
+ private function isTestCase($input)
+ {
+ return is_subclass_of($input, 'PHPUnit_Framework_TestCase') || is_subclass_of($input, 'PHPUnit_Framework_TestSuite');
+ }
+
+ /**
+ * Filters an array of classes, removes all classes that are not test cases or test suites,
+ * or classes that are declared abstract
+ */
+ private function filterTests($input)
+ {
+ $reflect = new ReflectionClass($input);
+
+ return $this->isTestCase($input) && (!$reflect->isAbstract());
+ }
+
+ /**
+ * Returns an array of test cases and test suites that are declared
+ * by the files included by the filesets
+ *
+ * @return array an array of tests.
+ */
+ protected function elements()
+ {
+ $filenames = $this->getFilenames();
+
+ $declaredClasses = array();
+
+ foreach ($filenames as $filename)
+ {
+ $definedClasses = PHPUnitUtil::getDefinedClasses($filename, $this->classpath);
+
+ foreach($definedClasses as $definedClass) {
+ $this->project->log("(PHPUnit) Adding $definedClass (from $filename) to tests.", Project::MSG_DEBUG);
+ }
+
+ $declaredClasses = array_merge($declaredClasses, $definedClasses);
+ }
+
+ $elements = array_filter($declaredClasses, array($this, "filterTests"));
+
+ return $elements;
+ }
+
+ /**
+ * Returns a testsuite containing all the tests in this batch
+ *
+ * @deprecated
+ * @return PHPUnit_Framework_TestSuite
+ */
+ public function getTestSuite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite($this->name);
+
+ foreach ($this->elements() as $test)
+ {
+ $testClass = new $test();
+ if (!($testClass instanceof PHPUnit_Framework_TestSuite))
+ {
+ $testClass = new ReflectionClass($test);
+ }
+
+ $suite->addTestSuite($testClass);
+ }
+
+ return $suite;
+ }
+
+ /**
+ * Add the tests in this batchtest to a test suite
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function addToTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ foreach ($this->elements() as $element) {
+ $testClass = new $element();
+ if (!($testClass instanceof PHPUnit_Framework_TestSuite))
+ {
+ $testClass = new ReflectionClass($element);
+ }
+ $suite->addTestSuite($testClass);
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php
new file mode 100755
index 00000000..c220b79d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * $Id: 296214ebac3a12e51bffed3dcc2c0bb93fb0754e $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * A wrapper for the implementations of PHPUnit2ResultFormatter.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 296214ebac3a12e51bffed3dcc2c0bb93fb0754e $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class FormatterElement
+{
+ protected $formatter = NULL;
+
+ protected $type = "";
+
+ protected $useFile = true;
+
+ protected $toDir = ".";
+
+ protected $outfile = "";
+
+ protected $parent = NULL;
+
+ /**
+ * Sets parent task
+ * @param Task $parent Calling Task
+ */
+ public function setParent($parent)
+ {
+ $this->parent = $parent;
+ }
+
+ /**
+ * Loads a specific formatter type
+ * @param string $type
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+
+ if ($this->type == "summary")
+ {
+ require_once 'phing/tasks/ext/phpunit/formatter/SummaryPHPUnitResultFormatter.php';
+ $this->formatter = new SummaryPHPUnitResultFormatter($this->parent);
+ }
+ else
+ if ($this->type == "clover")
+ {
+ require_once 'phing/tasks/ext/phpunit/formatter/CloverPHPUnitResultFormatter.php';
+ $this->formatter = new CloverPHPUnitResultFormatter($this->parent);
+ }
+ else
+ if ($this->type == "xml")
+ {
+ require_once 'phing/tasks/ext/phpunit/formatter/XMLPHPUnitResultFormatter.php';
+ $this->formatter = new XMLPHPUnitResultFormatter($this->parent);
+ }
+ else
+ if ($this->type == "plain")
+ {
+ require_once 'phing/tasks/ext/phpunit/formatter/PlainPHPUnitResultFormatter.php';
+ $this->formatter = new PlainPHPUnitResultFormatter($this->parent);
+ }
+ else
+ {
+ throw new BuildException("Formatter '" . $this->type . "' not implemented");
+ }
+ }
+
+ /**
+ * Loads a specific formatter class
+ */
+ public function setClassName($className)
+ {
+ $classNameNoDot = Phing::import($className);
+
+ $this->formatter = new $classNameNoDot();
+ }
+
+ /**
+ * Sets whether to store formatting results in a file
+ */
+ public function setUseFile($useFile)
+ {
+ $this->useFile = $useFile;
+ }
+
+ /**
+ * Returns whether to store formatting results in a file
+ */
+ public function getUseFile()
+ {
+ return $this->useFile;
+ }
+
+ /**
+ * Sets output directory
+ * @param string $toDir
+ */
+ public function setToDir($toDir)
+ {
+ $this->toDir = $toDir;
+ }
+
+ /**
+ * Returns output directory
+ * @return string
+ */
+ public function getToDir()
+ {
+ return $this->toDir;
+ }
+
+ /**
+ * Sets output filename
+ * @param string $outfile
+ */
+ public function setOutfile($outfile)
+ {
+ $this->outfile = $outfile;
+ }
+
+ /**
+ * Returns output filename
+ * @return string
+ */
+ public function getOutfile()
+ {
+ if ($this->outfile)
+ {
+ return $this->outfile;
+ }
+ else
+ {
+ return $this->formatter->getPreferredOutfile() . $this->getExtension();
+ }
+ }
+
+ /**
+ * Returns extension
+ * @return string
+ */
+ public function getExtension()
+ {
+ return $this->formatter->getExtension();
+ }
+
+ /**
+ * Returns formatter object
+ * @return PHPUnitResultFormatter
+ */
+ public function getFormatter()
+ {
+ return $this->formatter;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php
new file mode 100755
index 00000000..87338da7
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php
@@ -0,0 +1,248 @@
+<?php
+/**
+ * $Id: b88d6fa4ca4717177b562a0475c81d92c161d9b4 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 PHPUnit xml report using XSLT.
+ * This transformation generates an html report in either framed or non-framed
+ * style. The non-framed style is convenient to have a concise report via mail,
+ * the framed report is much more convenient if you want to browse into
+ * different packages or testcases since it is a Javadoc like report.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: b88d6fa4ca4717177b562a0475c81d92c161d9b4 $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitReportTask extends Task
+{
+ private $format = "noframes";
+ private $styleDir = "";
+ private $toDir = "";
+
+ /**
+ * Whether to use the sorttable JavaScript library, defaults to false
+ * See {@link http://www.kryogenix.org/code/browser/sorttable/)}
+ *
+ * @var boolean
+ */
+ private $useSortTable = false;
+
+ /** the directory where the results XML can be found */
+ private $inFile = "testsuites.xml";
+
+ /**
+ * Set the filename of the XML results file to use.
+ */
+ public function setInFile(PhingFile $inFile)
+ {
+ $this->inFile = $inFile;
+ }
+
+ /**
+ * Set the format of the generated report. Must be noframes or frames.
+ */
+ public function setFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ /**
+ * Set the directory where the stylesheets are located.
+ */
+ public function setStyleDir($styleDir)
+ {
+ $this->styleDir = $styleDir;
+ }
+
+ /**
+ * Set the directory where the files resulting from the
+ * transformation should be written to.
+ */
+ public function setToDir(PhingFile $toDir)
+ {
+ $this->toDir = $toDir;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns the path to the XSL stylesheet
+ */
+ protected function getStyleSheet()
+ {
+ $xslname = "phpunit-" . $this->format . ".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;
+ }
+
+ /**
+ * Transforms the DOM document
+ */
+ protected function transform(DOMDocument $document)
+ {
+ 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);
+ $proc->setParameter('', 'output.sorttable', $this->useSortTable);
+
+ if ($this->format == "noframes")
+ {
+ $writer = new FileWriter(new PhingFile($this->toDir, "phpunit-noframes.html"));
+ $writer->write($proc->transformToXML($document));
+ $writer->close();
+ }
+ else
+ {
+ 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->transformToXML($document);
+
+ ExtendedFileStream::unregisterStream();
+ }
+ }
+
+ /**
+ * Fixes DOM document tree:
+ * - adds package="default" to 'testsuite' elements without
+ * package attribute
+ * - removes outer 'testsuite' container(s)
+ */
+ protected function fixDocument(DOMDocument $document)
+ {
+ $rootElement = $document->firstChild;
+
+ $xp = new DOMXPath($document);
+
+ $nodes = $xp->query("/testsuites/testsuite");
+
+ foreach ($nodes as $node) {
+ $children = $xp->query("./testsuite", $node);
+
+ if ($children->length) {
+ foreach ($children as $child) {
+ if (!$child->hasAttribute('package'))
+ {
+ $child->setAttribute('package', 'default');
+ }
+ $rootElement->appendChild($child);
+ }
+
+ $rootElement->removeChild($node);
+ }
+ }
+ }
+
+ /**
+ * Initialize the task
+ */
+ public function init()
+ {
+ if (!class_exists('XSLTProcessor')) {
+ throw new BuildException("PHPUnitReportTask requires the XSL extension");
+ }
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ public function main()
+ {
+ $testSuitesDoc = new DOMDocument();
+ $testSuitesDoc->load((string) $this->inFile);
+
+ $this->fixDocument($testSuitesDoc);
+
+ $this->transform($testSuitesDoc);
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php
new file mode 100755
index 00000000..5b842b95
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php
@@ -0,0 +1,378 @@
+<?php
+/**
+ * $Id: 4554fdd642b6ef7774cbb89c537ccba90f3ca972 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/util/LogWriter.php';
+
+/**
+ * Runs PHPUnit tests.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 4554fdd642b6ef7774cbb89c537ccba90f3ca972 $
+ * @package phing.tasks.ext.phpunit
+ * @see BatchTest
+ * @since 2.1.0
+ */
+class PHPUnitTask extends Task
+{
+ private $batchtests = array();
+ private $formatters = array();
+ private $bootstrap = "";
+ private $haltonerror = false;
+ private $haltonfailure = false;
+ private $haltonincomplete = false;
+ private $haltonskipped = false;
+ private $errorproperty;
+ private $failureproperty;
+ private $incompleteproperty;
+ private $skippedproperty;
+ private $printsummary = false;
+ private $testfailed = false;
+ private $testfailuremessage = "";
+ private $codecoverage = null;
+ private $groups = array();
+ private $excludeGroups = array();
+ private $processIsolation = false;
+ private $usecustomerrorhandler = true;
+
+ /**
+ * Initialize Task.
+ * This method includes any necessary PHPUnit 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() {
+ /**
+ * Determine PHPUnit version number
+ */
+ @include_once 'PHPUnit/Runner/Version.php';
+
+ if (!class_exists('PHPUnit_Runner_Version')) {
+ throw new BuildException("PHPUnitTask requires PHPUnit to be installed", $this->getLocation());
+ }
+
+ $version = PHPUnit_Runner_Version::id();
+
+ if (version_compare($version, '3.6.0') < 0)
+ {
+ throw new BuildException("PHPUnitTask requires PHPUnit version >= 3.6.0", $this->getLocation());
+ }
+
+ /**
+ * Other dependencies that should only be loaded when class is actually used.
+ */
+ require_once 'phing/tasks/ext/phpunit/PHPUnitTestRunner.php';
+ require_once 'phing/tasks/ext/phpunit/BatchTest.php';
+ require_once 'phing/tasks/ext/phpunit/FormatterElement.php';
+
+ /**
+ * point PHPUnit_MAIN_METHOD define to non-existing method
+ */
+ if (!defined('PHPUnit_MAIN_METHOD'))
+ {
+ define('PHPUnit_MAIN_METHOD', 'PHPUnitTask::undefined');
+ }
+ }
+
+ /**
+ * Sets the name of a bootstrap file that is run before
+ * executing the tests
+ *
+ * @param string $bootstrap the name of the bootstrap file
+ */
+ public function setBootstrap($bootstrap)
+ {
+ $this->bootstrap = $bootstrap;
+ }
+
+ public function setErrorproperty($value)
+ {
+ $this->errorproperty = $value;
+ }
+
+ public function setFailureproperty($value)
+ {
+ $this->failureproperty = $value;
+ }
+
+ public function setIncompleteproperty($value)
+ {
+ $this->incompleteproperty = $value;
+ }
+
+ public function setSkippedproperty($value)
+ {
+ $this->skippedproperty = $value;
+ }
+
+ public function setHaltonerror($value)
+ {
+ $this->haltonerror = $value;
+ }
+
+ public function setHaltonfailure($value)
+ {
+ $this->haltonfailure = $value;
+ }
+
+ public function getHaltonfailure()
+ {
+ return $this->haltonfailure;
+ }
+
+ public function setHaltonincomplete($value)
+ {
+ $this->haltonincomplete = $value;
+ }
+
+ public function getHaltonincomplete()
+ {
+ return $this->haltonincomplete;
+ }
+
+ public function setHaltonskipped($value)
+ {
+ $this->haltonskipped = $value;
+ }
+
+ public function getHaltonskipped()
+ {
+ return $this->haltonskipped;
+ }
+
+ public function setPrintsummary($printsummary)
+ {
+ $this->printsummary = $printsummary;
+ }
+
+ public function setCodecoverage($codecoverage)
+ {
+ $this->codecoverage = $codecoverage;
+ }
+
+ public function setProcessIsolation($processIsolation)
+ {
+ $this->processIsolation = $processIsolation;
+ }
+
+ public function setUseCustomErrorHandler($usecustomerrorhandler)
+ {
+ $this->usecustomerrorhandler = $usecustomerrorhandler;
+ }
+
+ public function setGroups($groups)
+ {
+ $token = ' ,;';
+ $this->groups = array();
+ $tok = strtok($groups, $token);
+ while ($tok !== false) {
+ $this->groups[] = $tok;
+ $tok = strtok($token);
+ }
+ }
+
+ public function setExcludeGroups($excludeGroups)
+ {
+ $token = ' ,;';
+ $this->excludeGroups = array();
+ $tok = strtok($excludeGroups, $token);
+ while ($tok !== false) {
+ $this->excludeGroups[] = $tok;
+ $tok = strtok($token);
+ }
+ }
+
+ /**
+ * Add a new formatter to all tests of this task.
+ *
+ * @param FormatterElement formatter element
+ */
+ public function addFormatter(FormatterElement $fe)
+ {
+ $fe->setParent($this);
+ $this->formatters[] = $fe;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ public function main()
+ {
+ if ($this->codecoverage && !extension_loaded('xdebug'))
+ {
+ throw new Exception("PHPUnitTask depends on Xdebug being installed to gather code coverage information.");
+ }
+
+ if ($this->printsummary)
+ {
+ $fe = new FormatterElement();
+ $fe->setParent($this);
+ $fe->setType("summary");
+ $fe->setUseFile(false);
+ $this->formatters[] = $fe;
+ }
+
+ $autoloadSave = spl_autoload_functions();
+
+ if ($this->bootstrap)
+ {
+ require_once $this->bootstrap;
+ }
+
+ $suite = new PHPUnit_Framework_TestSuite('AllTests');
+
+ foreach ($this->batchtests as $batchtest)
+ {
+ $batchtest->addToTestSuite($suite);
+ }
+
+ $this->execute($suite);
+
+ if ($this->testfailed)
+ {
+ throw new BuildException($this->testfailuremessage);
+ }
+
+ $autoloadNew = spl_autoload_functions();
+ foreach ($autoloadNew as $autoload) {
+ spl_autoload_unregister($autoload);
+ }
+
+ foreach ($autoloadSave as $autoload) {
+ spl_autoload_register($autoload);
+ }
+ }
+
+ /**
+ * @throws BuildException
+ */
+ protected function execute($suite)
+ {
+ $runner = new PHPUnitTestRunner($this->project, $this->groups, $this->excludeGroups, $this->processIsolation);
+
+ if ($this->codecoverage) {
+ /**
+ * Add some defaults to the PHPUnit filter
+ */
+ $pwd = dirname(__FILE__);
+ $path = realpath($pwd . '/../../../');
+
+ $filter = new PHP_CodeCoverage_Filter();
+ $filter->addDirectoryToBlacklist($path);
+ $runner->setCodecoverage(new PHP_CodeCoverage(null, $filter));
+ }
+
+ $runner->setUseCustomErrorHandler($this->usecustomerrorhandler);
+
+ foreach ($this->formatters as $fe)
+ {
+ $formatter = $fe->getFormatter();
+
+ if ($fe->getUseFile())
+ {
+ $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
+
+ $writer = new FileWriter($destFile->getAbsolutePath());
+
+ $formatter->setOutput($writer);
+ }
+ else
+ {
+ $formatter->setOutput($this->getDefaultOutput());
+ }
+
+ $runner->addFormatter($formatter);
+
+ $formatter->startTestRun();
+ }
+
+ $runner->run($suite);
+
+ foreach ($this->formatters as $fe)
+ {
+ $formatter = $fe->getFormatter();
+ $formatter->endTestRun();
+ }
+
+ $retcode = $runner->getRetCode();
+
+ if ($retcode == PHPUnitTestRunner::ERRORS) {
+ if ($this->errorproperty) {
+ $this->project->setNewProperty($this->errorproperty, true);
+ }
+ if ($this->haltonerror) {
+ $this->testfailed = true;
+ $this->testfailuremessage = $runner->getLastErrorMessage();
+ }
+ } elseif ($retcode == PHPUnitTestRunner::FAILURES) {
+ if ($this->failureproperty) {
+ $this->project->setNewProperty($this->failureproperty, true);
+ }
+
+ if ($this->haltonfailure) {
+ $this->testfailed = true;
+ $this->testfailuremessage = $runner->getLastFailureMessage();
+ }
+ } elseif ($retcode == PHPUnitTestRunner::INCOMPLETES) {
+ if ($this->incompleteproperty) {
+ $this->project->setNewProperty($this->incompleteproperty, true);
+ }
+
+ if ($this->haltonincomplete) {
+ $this->testfailed = true;
+ $this->testfailuremessage = $runner->getLastIncompleteMessage();
+ }
+ } elseif ($retcode == PHPUnitTestRunner::SKIPPED) {
+ if ($this->skippedproperty) {
+ $this->project->setNewProperty($this->skippedproperty, true);
+ }
+
+ if ($this->haltonskipped) {
+ $this->testfailed = true;
+ $this->testfailuremessage = $runner->getLastSkippedMessage();
+ }
+ }
+ }
+
+ protected function getDefaultOutput()
+ {
+ return new LogWriter($this);
+ }
+
+ /**
+ * Adds a set of tests based on pattern matching.
+ *
+ * @return BatchTest a new instance of a batch test.
+ */
+ public function createBatchTest()
+ {
+ $batchtest = new BatchTest($this->getProject());
+
+ $this->batchtests[] = $batchtest;
+
+ return $batchtest;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php
new file mode 100755
index 00000000..6c7e5e68
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php
@@ -0,0 +1,312 @@
+<?php
+/**
+ * $Id: 5926dfc1177ec0c52ec275a8e542979c8deb6e6f $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit/Autoload.php';
+require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
+require_once 'phing/system/util/Timer.php';
+
+/**
+ * Simple Testrunner for PHPUnit that runs all tests of a testsuite.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 5926dfc1177ec0c52ec275a8e542979c8deb6e6f $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitTestRunner extends PHPUnit_Runner_BaseTestRunner implements PHPUnit_Framework_TestListener
+{
+ const SUCCESS = 0;
+ const FAILURES = 1;
+ const ERRORS = 2;
+ const INCOMPLETES = 3;
+ const SKIPPED = 4;
+
+ private $retCode = 0;
+ private $lastErrorMessage = '';
+ private $lastFailureMessage = '';
+ private $lastIncompleteMessage = '';
+ private $lastSkippedMessage = '';
+ private $formatters = array();
+
+ private $codecoverage = null;
+
+ private $project = NULL;
+
+ private $groups = array();
+ private $excludeGroups = array();
+
+ private $processIsolation = false;
+
+ private $useCustomErrorHandler = true;
+
+ public function __construct(Project $project, $groups = array(), $excludeGroups = array(), $processIsolation = false)
+ {
+ $this->project = $project;
+ $this->groups = $groups;
+ $this->excludeGroups = $excludeGroups;
+ $this->processIsolation = $processIsolation;
+ $this->retCode = self::SUCCESS;
+ }
+
+ public function setCodecoverage($codecoverage)
+ {
+ $this->codecoverage = $codecoverage;
+ }
+
+ public function setUseCustomErrorHandler($useCustomErrorHandler)
+ {
+ $this->useCustomErrorHandler = $useCustomErrorHandler;
+ }
+
+ public function addFormatter($formatter)
+ {
+ $this->formatters[] = $formatter;
+ }
+
+ public function handleError($level, $message, $file, $line)
+ {
+ return PHPUnit_Util_ErrorHandler::handleError($level, $message, $file, $line);
+ }
+
+ /**
+ * Run a test
+ */
+ public function run(PHPUnit_Framework_TestSuite $suite)
+ {
+ $res = new PHPUnit_Framework_TestResult();
+
+ if ($this->codecoverage)
+ {
+ $whitelist = CoverageMerger::getWhiteList($this->project);
+
+ $this->codecoverage->filter()->addFilesToWhiteList($whitelist);
+
+ $res->setCodeCoverage($this->codecoverage);
+ }
+
+ $res->addListener($this);
+
+ foreach ($this->formatters as $formatter)
+ {
+ $res->addListener($formatter);
+ }
+
+ /* Set PHPUnit error handler */
+ if ($this->useCustomErrorHandler)
+ {
+ $oldErrorHandler = set_error_handler(array($this, 'handleError'), E_ALL | E_STRICT);
+ }
+
+ $suite->run($res, false, $this->groups, $this->excludeGroups, $this->processIsolation);
+
+ foreach ($this->formatters as $formatter)
+ {
+ $formatter->processResult($res);
+ }
+
+ /* Restore Phing error handler */
+ if ($this->useCustomErrorHandler)
+ {
+ restore_error_handler();
+ }
+
+ if ($this->codecoverage)
+ {
+ CoverageMerger::merge($this->project, $this->codecoverage->getData());
+ }
+
+ if ($res->errorCount() != 0)
+ {
+ $this->retCode = self::ERRORS;
+ }
+ else if ($res->failureCount() != 0)
+ {
+ $this->retCode = self::FAILURES;
+ }
+ else if ($res->notImplementedCount() != 0)
+ {
+ $this->retCode = self::INCOMPLETES;
+ }
+ else if ($res->skippedCount() != 0)
+ {
+ $this->retCode = self::SKIPPED;
+ }
+ }
+
+ public function getRetCode()
+ {
+ return $this->retCode;
+ }
+
+ public function getLastErrorMessage()
+ {
+ return $this->lastErrorMessage;
+ }
+
+ public function getLastFailureMessage()
+ {
+ return $this->lastFailureMessage;
+ }
+
+ public function getLastIncompleteMessage()
+ {
+ return $this->lastIncompleteMessage;
+ }
+
+ public function getLastSkippedMessage()
+ {
+ return $this->lastSkippedMessage;
+ }
+
+ protected function composeMessage($message, PHPUnit_Framework_Test $test, Exception $e)
+ {
+ return "Test $message (" . $test->getName() . " in class " . get_class($test) . "): " . $e->getMessage();
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->lastErrorMessage = $this->composeMessage("ERROR", $test, $e);
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->lastFailureMessage = $this->composeMessage("FAILURE", $test, $e);
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->lastIncompleteMessage = $this->composeMessage("INCOMPLETE", $test, $e);
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ * @since Method available since Release 3.0.0
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->lastSkippedMessage = $this->composeMessage("SKIPPED", $test, $e);
+ }
+
+ /**
+ * A test started.
+ *
+ * @param string $testName
+ */
+ public function testStarted($testName)
+ {
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param string $testName
+ */
+ public function testEnded($testName)
+ {
+ }
+
+ /**
+ * A test failed.
+ *
+ * @param integer $status
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ */
+ public function testFailed($status, PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e)
+ {
+ }
+
+ /**
+ * Override to define how to handle a failed loading of
+ * a test suite.
+ *
+ * @param string $message
+ */
+ protected function runFailed($message)
+ {
+ throw new BuildException($message);
+ }
+
+ /**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ * @since Method available since Release 2.2.0
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test suite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ * @since Method available since Release 2.2.0
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php
new file mode 100755
index 00000000..25a85f4c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * $Id: c569f96e625ed8f9c6ae5add2b2f4a0a6c3e5a54 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Various utility functions
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: c569f96e625ed8f9c6ae5add2b2f4a0a6c3e5a54 $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitUtil
+{
+ protected static $definedClasses = array();
+
+ /**
+ * Returns the package of a class as defined in the docblock of the class using @package
+ *
+ * @param string the name of the class
+ * @return string the name of the package
+ */
+ static function getPackageName($classname)
+ {
+ $reflect = new ReflectionClass($classname);
+
+ if (preg_match('/@package[\s]+([\.\w]+)/', $reflect->getDocComment(), $matches))
+ {
+ return $matches[1];
+ }
+ else
+ {
+ return "default";
+ }
+ }
+
+ /**
+ * Returns the subpackage of a class as defined in the docblock of the class
+ * using @subpackage
+ *
+ * @param string $classname the name of the class
+ *
+ * @author Benjamin Schultz <bschultz@proqrent.de>
+ * @return string|null the name of the subpackage
+ */
+ public static function getSubpackageName($classname)
+ {
+ $reflect = new ReflectionClass($classname);
+
+ if (preg_match('/@subpackage[\s]+([\.\w]+)/', $reflect->getDocComment(), $matches)) {
+ return $matches[1];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Derives the classname from a filename.
+ * Assumes that there is only one class defined in that particular file, and that
+ * the naming follows the dot-path (Java) notation scheme.
+ *
+ * @param string the filename
+ * @return string the name fo the class
+ */
+ public static function getClassFromFileName($filename)
+ {
+ $filename = basename($filename);
+
+ $rpos = strrpos($filename, '.');
+
+ if ($rpos != -1)
+ {
+ $filename = substr($filename, 0, $rpos);
+ }
+
+ return $filename;
+ }
+
+ /**
+ * @param string the filename
+ * @param Path optional classpath
+ * @return array list of classes defined in the file
+ */
+ public static function getDefinedClasses($filename, $classpath = NULL)
+ {
+ $filename = realpath($filename);
+
+ if (!file_exists($filename))
+ {
+ throw new Exception("File '" . $filename . "' does not exist");
+ }
+
+ if (isset(self::$definedClasses[$filename]))
+ {
+ return self::$definedClasses[$filename];
+ }
+
+ Phing::__import($filename, $classpath);
+
+ $declaredClasses = get_declared_classes();
+
+ foreach ($declaredClasses as $classname)
+ {
+ $reflect = new ReflectionClass($classname);
+
+ self::$definedClasses[$reflect->getFilename()][] = $classname;
+
+ if (is_array(self::$definedClasses[$reflect->getFilename()]))
+ {
+ self::$definedClasses[$reflect->getFilename()] = array_unique(self::$definedClasses[$reflect->getFilename()]);
+ }
+ }
+
+ if (isset(self::$definedClasses[$filename]))
+ {
+ return self::$definedClasses[$filename];
+ }
+ else
+ {
+ return array();
+ }
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/CloverPHPUnitResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/CloverPHPUnitResultFormatter.php
new file mode 100755
index 00000000..4d03078d
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/CloverPHPUnitResultFormatter.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * $Id: 97f504caad678a6c7d231fe298c27d1281008e48 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php';
+
+/**
+ * Prints Clover XML output of the test
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 97f504caad678a6c7d231fe298c27d1281008e48 $
+ * @package phing.tasks.ext.formatter
+ * @since 2.4.0
+ */
+class CloverPHPUnitResultFormatter extends PHPUnitResultFormatter
+{
+ /**
+ * @var PHPUnit_Framework_TestResult
+ */
+ private $result = NULL;
+
+ /**
+ * PHPUnit version
+ * @var string
+ */
+ private $version = NULL;
+
+ public function __construct(PHPUnitTask $parentTask)
+ {
+ parent::__construct($parentTask);
+
+ $this->version = PHPUnit_Runner_Version::id();
+ }
+
+ public function getExtension()
+ {
+ return ".xml";
+ }
+
+ public function getPreferredOutfile()
+ {
+ return "clover-coverage";
+ }
+
+ public function processResult(PHPUnit_Framework_TestResult $result)
+ {
+ $this->result = $result;
+ }
+
+ public function endTestRun()
+ {
+ require_once 'PHP/CodeCoverage/Report/Clover.php';
+
+ $coverage = $this->result->getCodeCoverage();
+
+ if (!empty($coverage)) {
+ $clover = new PHP_CodeCoverage_Report_Clover();
+
+ $contents = $clover->process($coverage);
+
+ if ($this->out)
+ {
+ $this->out->write($contents);
+ $this->out->close();
+ }
+ }
+
+ parent::endTestRun();
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php
new file mode 100755
index 00000000..1b09dbc1
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * $Id: cbf356a8395e116cd6ecddb7f5a822d4b6edf01c $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit/Framework/TestListener.php';
+
+require_once 'phing/system/io/Writer.php';
+
+/**
+ * This abstract class describes classes that format the results of a PHPUnit testrun.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: cbf356a8395e116cd6ecddb7f5a822d4b6edf01c $
+ * @package phing.tasks.ext.phpunit.formatter
+ * @since 2.1.0
+ */
+abstract class PHPUnitResultFormatter implements PHPUnit_Framework_TestListener
+{
+ protected $out = NULL;
+
+ protected $project = NULL;
+
+ private $timers = false;
+
+ private $runCounts = false;
+
+ private $failureCounts = false;
+
+ private $errorCounts = false;
+
+ private $incompleteCounts = false;
+
+ private $skipCounts = false;
+
+ /**
+ * Constructor
+ * @param PHPUnitTask $parentTask Calling Task
+ */
+ public function __construct(PHPUnitTask $parentTask)
+ {
+ $this->project = $parentTask->getProject();
+ }
+
+ /**
+ * Sets the writer the formatter is supposed to write its results to.
+ */
+ public function setOutput(Writer $out)
+ {
+ $this->out = $out;
+ }
+
+ /**
+ * Returns the extension used for this formatter
+ *
+ * @return string the extension
+ */
+ public function getExtension()
+ {
+ return "";
+ }
+
+ public function getPreferredOutfile()
+ {
+ return "";
+ }
+
+ public function processResult(PHPUnit_Framework_TestResult $result)
+ {
+ }
+
+ public function startTestRun()
+ {
+ $this->timers = array($this->getMicrotime());
+ $this->runCounts = array(0);
+ $this->failureCounts = array(0);
+ $this->errorCounts = array(0);
+ $this->incompleteCounts = array(0);
+ $this->skipCounts = array(0);
+ }
+
+ public function endTestRun()
+ {
+ }
+
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->timers[] = $this->getMicrotime();
+ $this->runCounts[] = 0;
+ $this->failureCounts[] = 0;
+ $this->errorCounts[] = 0;
+ $this->incompleteCounts[] = 0;
+ $this->skipCounts[] = 0;
+ }
+
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $lastRunCount = array_pop($this->runCounts);
+ $this->runCounts[count($this->runCounts) - 1] += $lastRunCount;
+
+ $lastFailureCount = array_pop($this->failureCounts);
+ $this->failureCounts[count($this->failureCounts) - 1] += $lastFailureCount;
+
+ $lastErrorCount = array_pop($this->errorCounts);
+ $this->errorCounts[count($this->errorCounts) - 1] += $lastErrorCount;
+
+ $lastIncompleteCount = array_pop($this->incompleteCounts);
+ $this->incompleteCounts[count($this->incompleteCounts) - 1] += $lastIncompleteCount;
+
+ $lastSkipCount = array_pop($this->skipCounts);
+ $this->skipCounts[count($this->skipCounts) - 1] += $lastSkipCount;
+
+ array_pop($this->timers);
+ }
+
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->runCounts[count($this->runCounts) - 1]++;
+ }
+
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ }
+
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->errorCounts[count($this->errorCounts) - 1]++;
+ }
+
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->failureCounts[count($this->failureCounts) - 1]++;
+ }
+
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->incompleteCounts[count($this->incompleteCounts) - 1]++;
+ }
+
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->skipCounts[count($this->skipCounts) - 1]++;
+ }
+
+ public function getRunCount()
+ {
+ return end($this->runCounts);
+ }
+
+ public function getFailureCount()
+ {
+ return end($this->failureCounts);
+ }
+
+ public function getErrorCount()
+ {
+ return end($this->errorCounts);
+ }
+
+ public function getIncompleteCount()
+ {
+ return end($this->incompleteCounts);
+ }
+
+ public function getSkippedCount()
+ {
+ return end($this->skipCounts);
+ }
+
+ public function getElapsedTime()
+ {
+ if (end($this->timers))
+ {
+ return $this->getMicrotime() - end($this->timers);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private function getMicrotime() {
+ list($usec, $sec) = explode(' ', microtime());
+ return (float)$usec + (float)$sec;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PlainPHPUnitResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PlainPHPUnitResultFormatter.php
new file mode 100755
index 00000000..e67cfd2b
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/PlainPHPUnitResultFormatter.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * $Id: 529f9b6ab9ced7b78871e3612cd8afce58261a6f $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php';
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 529f9b6ab9ced7b78871e3612cd8afce58261a6f $
+ * @package phing.tasks.ext.phpunit.formatter
+ * @since 2.1.0
+ */
+class PlainPHPUnitResultFormatter extends PHPUnitResultFormatter
+{
+ private $inner = "";
+
+ public function getExtension()
+ {
+ return ".txt";
+ }
+
+ public function getPreferredOutfile()
+ {
+ return "testresults";
+ }
+
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ parent::startTestSuite($suite);
+
+ $this->inner = "";
+ }
+
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ if ($suite->getName() == 'AllTests')
+ {
+ return false;
+ }
+
+ $sb = "Testsuite: " . $suite->getName() . "\n";
+ $sb.= "Tests run: " . $this->getRunCount();
+ $sb.= ", Failures: " . $this->getFailureCount();
+ $sb.= ", Errors: " . $this->getErrorCount();
+ $sb.= ", Incomplete: " . $this->getIncompleteCount();
+ $sb.= ", Skipped: " . $this->getSkippedCount();
+ $sb.= ", Time elapsed: " . sprintf('%0.5f', $this->getElapsedTime()) . " s\n";
+
+ if ($this->out != NULL)
+ {
+ $this->out->write($sb);
+ $this->out->write($this->inner);
+ }
+
+ parent::endTestSuite($suite);
+ }
+
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ parent::addError($test, $e, $time);
+
+ $this->formatError("ERROR", $test, $e);
+ }
+
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ parent::addFailure($test, $e, $time);
+ $this->formatError("FAILED", $test, $e);
+ }
+
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ parent::addIncompleteTest($test, $e, $time);
+
+ $this->formatError("INCOMPLETE", $test);
+ }
+
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ parent::addSkippedTest($test, $e, $time);
+ $this->formatError("SKIPPED", $test);
+ }
+
+ private function formatError($type, PHPUnit_Framework_Test $test, Exception $e = null)
+ {
+ if ($test != null)
+ {
+ $this->endTest($test, time());
+ }
+
+ $this->inner.= $test->getName() . " " . $type . "\n";
+
+ if ($e !== null) {
+ $this->inner.= $e->getMessage() . "\n";
+ // $this->inner.= PHPUnit_Util_Filter::getFilteredStackTrace($e, true) . "\n";
+ }
+ }
+
+ public function endTestRun()
+ {
+ parent::endTestRun();
+
+ if ($this->out != NULL)
+ {
+ $this->out->close();
+ }
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/SummaryPHPUnitResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/SummaryPHPUnitResultFormatter.php
new file mode 100755
index 00000000..0007c235
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/SummaryPHPUnitResultFormatter.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * $Id: bd9c51fa75c9b856105fc810200028d855a3782d $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php';
+
+/**
+ * Prints short summary output of the test to Phing's logging system.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: bd9c51fa75c9b856105fc810200028d855a3782d $
+ * @package phing.tasks.ext.formatter
+ * @since 2.1.0
+ */
+class SummaryPHPUnitResultFormatter extends PHPUnitResultFormatter
+{
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ parent::endTestSuite($suite);
+ }
+
+ public function endTestRun()
+ {
+ parent::endTestRun();
+
+ $sb = "Total tests run: " . $this->getRunCount();
+ $sb.= ", Failures: " . $this->getFailureCount();
+ $sb.= ", Errors: " . $this->getErrorCount();
+ $sb.= ", Incomplete: " . $this->getIncompleteCount();
+ $sb.= ", Skipped: " . $this->getSkippedCount();
+ $sb.= ", Time elapsed: " . sprintf('%0.5f', $this->getElapsedTime()) . " s\n";
+
+ if ($this->out != NULL)
+ {
+ $this->out->write($sb);
+ $this->out->close();
+ }
+ }
+
+ public function getExtension()
+ {
+ return NULL;
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/XMLPHPUnitResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/XMLPHPUnitResultFormatter.php
new file mode 100755
index 00000000..7fef7454
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/phpunit/formatter/XMLPHPUnitResultFormatter.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * $Id: 3d9c47a29ded9b67b3a3e10c55602b0ab2a9ea38 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit/Util/Log/JUnit.php';
+
+require_once 'phing/tasks/ext/phpunit/formatter/PHPUnitResultFormatter.php';
+
+/**
+ * Prints XML output of the test to a specified Writer
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 3d9c47a29ded9b67b3a3e10c55602b0ab2a9ea38 $
+ * @package phing.tasks.ext.formatter
+ * @since 2.1.0
+ */
+class XMLPHPUnitResultFormatter extends PHPUnitResultFormatter
+{
+ /**
+ * @var PHPUnit_Util_Log_JUnit
+ */
+ private $logger = NULL;
+
+ public function __construct(PHPUnitTask $parentTask)
+ {
+ parent::__construct($parentTask);
+
+ $logIncompleteSkipped = $parentTask->getHaltonincomplete() || $parentTask->getHaltonskipped();
+
+ $this->logger = new PHPUnit_Util_Log_JUnit(null, $logIncompleteSkipped);
+ $this->logger->setWriteDocument(false);
+ }
+
+ public function getExtension()
+ {
+ return ".xml";
+ }
+
+ public function getPreferredOutfile()
+ {
+ return "testsuites";
+ }
+
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ parent::startTestSuite($suite);
+
+ $this->logger->startTestSuite($suite);
+ }
+
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ parent::endTestSuite($suite);
+
+ $this->logger->endTestSuite($suite);
+ }
+
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ parent::startTest($test);
+
+ $this->logger->startTest($test);
+ }
+
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ parent::endTest($test, $time);
+
+ $this->logger->endTest($test, $time);
+ }
+
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ parent::addError($test, $e, $time);
+
+ $this->logger->addError($test, $e, $time);
+ }
+
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ parent::addFailure($test, $e, $time);
+
+ $this->logger->addFailure($test, $e, $time);
+ }
+
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ parent::addIncompleteTest($test, $e, $time);
+
+ $this->logger->addIncompleteTest($test, $e, $time);
+ }
+
+ public function endTestRun()
+ {
+ parent::endTestRun();
+
+ if ($this->out)
+ {
+ $this->out->write($this->logger->getXML());
+ $this->out->close();
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/BatchTest.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/BatchTest.php
deleted file mode 100644
index 63f8911a..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/BatchTest.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-/**
- * $Id: BatchTest.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'phing/types/FileSet.php';
-
-/**
- * Scans a list of (.php) files given by the fileset attribute, extracts
- * all subclasses of PHPUnit2_Framework_TestCase.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: BatchTest.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class BatchTest
-{
- /** the list of filesets containing the testcase filename rules */
- private $filesets = array();
-
- /** the reference to the project */
- private $project = NULL;
-
- /** the classpath to use with Phing::__import() calls */
- private $classpath = NULL;
-
- /** names of classes to exclude */
- private $excludeClasses = array();
-
- /**
- * Create a new batchtest instance
- *
- * @param Project the project it depends on.
- */
- function __construct(Project $project)
- {
- $this->project = $project;
- }
-
- /**
- * Sets the classes to exclude
- */
- function setExclude($exclude)
- {
- $this->excludeClasses = explode(" ", $exclude);
- }
-
- /**
- * Sets the classpath
- */
- function setClasspath(Path $classpath)
- {
- if ($this->classpath === null)
- {
- $this->classpath = $classpath;
- }
- else
- {
- $this->classpath->append($classpath);
- }
- }
-
- /**
- * Creates a new Path object
- */
- function createClasspath()
- {
- $this->classpath = new Path();
- return $this->classpath;
- }
-
- /**
- * Returns the classpath
- */
- function getClasspath()
- {
- return $this->classpath;
- }
-
- /**
- * Add a new fileset containing the XML results to aggregate
- *
- * @param FileSet the new fileset containing XML results.
- */
- function addFileSet(FileSet $fileset)
- {
- $this->filesets[] = $fileset;
- }
-
- /**
- * Iterate over all filesets and return the filename of all files
- * that end with .php.
- *
- * @return array an array of filenames
- */
- private function getFilenames()
- {
- $filenames = array();
-
- foreach ($this->filesets as $fileset)
- {
- $ds = $fileset->getDirectoryScanner($this->project);
- $ds->scan();
-
- $files = $ds->getIncludedFiles();
-
- foreach ($files as $file)
- {
- if (strstr($file, ".php"))
- {
- $filenames[] = $ds->getBaseDir() . "/" . $file;
- }
- }
- }
-
- return $filenames;
- }
-
- /**
- * Filters an array of classes, removes all classes that are not subclasses of PHPUnit2_Framework_TestCase,
- * or classes that are declared abstract
- */
- private function filterTests($input)
- {
- $reflect = new ReflectionClass($input);
-
- return is_subclass_of($input, 'PHPUnit2_Framework_TestCase') && (!$reflect->isAbstract());
- }
-
- /**
- * Returns an array of PHPUnit2_Framework_TestCase classes that are declared
- * by the files included by the filesets
- *
- * @return array an array of PHPUnit2_Framework_TestCase classes.
- */
- function elements()
- {
- $filenames = $this->getFilenames();
-
- $declaredClasses = array();
-
- foreach ($filenames as $filename)
- {
- $definedClasses = PHPUnit2Util::getDefinedClasses($filename);
-
- $declaredClasses = array_merge($declaredClasses, $definedClasses);
- }
-
- $elements = array_filter($declaredClasses, array($this, "filterTests"));
-
- return $elements;
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/FormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/FormatterElement.php
deleted file mode 100644
index 9d2a4656..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/FormatterElement.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/**
- * $Id: FormatterElement.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php';
-require_once 'phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php';
-require_once 'phing/system/io/PhingFile.php';
-
-/**
- * A wrapper for the implementations of PHPUnit2ResultFormatter.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: FormatterElement.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class FormatterElement
-{
- protected $formatter = NULL;
-
- protected $type = "";
-
- protected $useFile = true;
-
- protected $toDir = ".";
-
- protected $outfile = "";
-
- function setType($type)
- {
- $this->type = $type;
-
- if ($this->type == "xml")
- {
- $destFile = new PhingFile($this->toDir, 'testsuites.xml');
- $this->formatter = new XMLPHPUnit2ResultFormatter();
- }
- else
- if ($this->type == "plain")
- {
- $this->formatter = new PlainPHPUnit2ResultFormatter();
- }
- else
- {
- throw new BuildException("Formatter '" . $this->type . "' not implemented");
- }
- }
-
- function setClassName($className)
- {
- $classNameNoDot = Phing::import($className);
-
- $this->formatter = new $classNameNoDot();
- }
-
- function setUseFile($useFile)
- {
- $this->useFile = $useFile;
- }
-
- function getUseFile()
- {
- return $this->useFile;
- }
-
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
-
- function getToDir()
- {
- return $this->toDir;
- }
-
- function setOutfile($outfile)
- {
- $this->outfile = $outfile;
- }
-
- function getOutfile()
- {
- if ($this->outfile)
- {
- return $this->outfile;
- }
- else
- {
- return $this->formatter->getPreferredOutfile() . $this->getExtension();
- }
- }
-
- function getExtension()
- {
- return $this->formatter->getExtension();
- }
-
- function getFormatter()
- {
- return $this->formatter;
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php
deleted file mode 100644
index 1e08e79c..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-/**
- * $Id: PHPUnit2ReportTask.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-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 PHPUnit2 xml report using XSLT.
- * This transformation generates an html report in either framed or non-framed
- * style. The non-framed style is convenient to have a concise report via mail,
- * the framed report is much more convenient if you want to browse into
- * different packages or testcases since it is a Javadoc like report.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPUnit2ReportTask.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class PHPUnit2ReportTask extends Task
-{
- private $format = "noframes";
- private $styleDir = "";
- private $toDir = "";
-
- /** the directory where the results XML can be found */
- private $inFile = "testsuites.xml";
-
- /**
- * Set the filename of the XML results file to use.
- */
- function setInFile($inFile)
- {
- $this->inFile = $inFile;
- }
-
- /**
- * Set the format of the generated report. Must be noframes or frames.
- */
- function setFormat($format)
- {
- $this->format = $format;
- }
-
- /**
- * Set the directory where the stylesheets are located.
- */
- function setStyleDir($styleDir)
- {
- $this->styleDir = $styleDir;
- }
-
- /**
- * Set the directory where the files resulting from the
- * transformation should be written to.
- */
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
-
- private function getStyleSheet()
- {
- $xslname = "phpunit2-" . $this->format . ".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;
- }
-
- function transform($document)
- {
- $dir = new PhingFile($this->toDir);
-
- if (!$dir->exists())
- {
- throw new BuildException("Directory '" . $this->toDir . "' does not exist");
- }
-
- $xslfile = $this->getStyleSheet();
-
- $xsl = new DOMDocument();
- $xsl->load($xslfile->getAbsolutePath());
-
- $proc = new XSLTProcessor();
- $proc->importStyleSheet($xsl);
-
- if ($this->format == "noframes")
- {
- $writer = new FileWriter(new PhingFile($this->toDir, "phpunit2-noframes.html"));
- $writer->write($proc->transformToXML($document));
- $writer->close();
- }
- else
- {
- ExtendedFileStream::registerStream();
-
- // no output for the framed report
- // it's all done by extension...
- $dir = new PhingFile($this->toDir);
- $proc->setParameter('', 'output.dir', $dir->getAbsolutePath());
- $proc->transformToXML($document);
- }
- }
-
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $testSuitesDoc = new DOMDocument();
- $testSuitesDoc->load($this->inFile);
-
- $this->transform($testSuitesDoc);
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php
deleted file mode 100644
index 5722c63e..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-/**
- * $Id: PHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'PHPUnit2/Framework/TestListener.php';
-
-require_once 'phing/system/io/Writer.php';
-
-/**
- * This abstract class describes classes that format the results of a PHPUnit2 testrun.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-abstract class PHPUnit2ResultFormatter implements PHPUnit2_Framework_TestListener
-{
- protected $out = NULL;
-
- protected $project = NULL;
-
- private $timer = NULL;
-
- private $runCount = 0;
-
- private $failureCount = 0;
-
- private $errorCount = 0;
-
- /**
- * Sets the writer the formatter is supposed to write its results to.
- */
- function setOutput(Writer $out)
- {
- $this->out = $out;
- }
-
- /**
- * Returns the extension used for this formatter
- *
- * @return string the extension
- */
- function getExtension()
- {
- return "";
- }
-
- /**
- * Sets the project
- *
- * @param Project the project
- */
- function setProject(Project $project)
- {
- $this->project = $project;
- }
-
- function getPreferredOutfile()
- {
- return "";
- }
-
- function startTestRun()
- {
- }
-
- function endTestRun()
- {
- }
-
- function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- $this->runCount = 0;
- $this->failureCount = 0;
- $this->errorCount = 0;
-
- $this->timer = new Timer();
- $this->timer->start();
- }
-
- function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- $this->timer->stop();
- }
-
- function startTest(PHPUnit2_Framework_Test $test)
- {
- $this->runCount++;
- }
-
- function endTest(PHPUnit2_Framework_Test $test)
- {
- }
-
- function addError(PHPUnit2_Framework_Test $test, Exception $e)
- {
- $this->errorCount++;
- }
-
- function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
- {
- $this->failureCount++;
- }
-
- function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
- {
- }
-
- function getRunCount()
- {
- return $this->runCount;
- }
-
- function getFailureCount()
- {
- return $this->failureCount;
- }
-
- function getErrorCount()
- {
- return $this->errorCount;
- }
-
- function getElapsedTime()
- {
- if ($this->timer)
- {
- return $this->timer->getElapsedTime();
- }
- else
- {
- return 0;
- }
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Task.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Task.php
deleted file mode 100644
index ffd36405..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Task.php
+++ /dev/null
@@ -1,239 +0,0 @@
-<?php
-/**
- * $Id: PHPUnit2Task.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'phing/Task.php';
-require_once 'phing/system/io/PhingFile.php';
-require_once 'phing/system/io/Writer.php';
-require_once 'phing/util/LogWriter.php';
-
-/**
- * Runs PHPUnit2 tests.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPUnit2Task.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @see BatchTest
- * @since 2.1.0
- */
-class PHPUnit2Task extends Task
-{
- private $batchtests = array();
- private $formatters = array();
- private $haltonerror = false;
- private $haltonfailure = false;
- private $failureproperty;
- private $errorproperty;
- private $printsummary = false;
- private $testfailed = false;
- private $codecoverage = false;
-
- /**
- * Initialize Task.
- * This method includes any necessary PHPUnit2 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.
- */
- function init() {
- include_once 'PHPUnit2/Util/Filter.php';
- if (!class_exists('PHPUnit2_Util_Filter')) {
- throw new BuildException("PHPUnit2Task depends on PEAR PHPUnit2 package being installed.", $this->getLocation());
- }
-
- if (version_compare(PHP_VERSION, '5.0.3') < 0) {
- throw new BuildException("PHPUnit2Task requires PHP version >= 5.0.3.", $this->getLocation());
- }
-
- // other dependencies that should only be loaded when class is actually used.
- require_once 'phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php';
- require_once 'phing/tasks/ext/phpunit2/BatchTest.php';
- require_once 'phing/tasks/ext/phpunit2/FormatterElement.php';
- require_once 'phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php';
-
- // add some defaults to the PHPUnit2 Filter
- PHPUnit2_Util_Filter::addFileToFilter('PHPUnit2Task.php');
- PHPUnit2_Util_Filter::addFileToFilter('PHPUnit2TestRunner.php');
- PHPUnit2_Util_Filter::addFileToFilter('phing/Task.php');
- PHPUnit2_Util_Filter::addFileToFilter('phing/Target.php');
- PHPUnit2_Util_Filter::addFileToFilter('phing/Project.php');
- PHPUnit2_Util_Filter::addFileToFilter('phing/Phing.php');
- PHPUnit2_Util_Filter::addFileToFilter('phing.php');
-
- }
-
- function setFailureproperty($value)
- {
- $this->failureproperty = $value;
- }
-
- function setErrorproperty($value)
- {
- $this->errorproperty = $value;
- }
-
- function setHaltonerror($value)
- {
- $this->haltonerror = $value;
- }
-
- function setHaltonfailure($value)
- {
- $this->haltonfailure = $value;
- }
-
- function setPrintsummary($printsummary)
- {
- $this->printsummary = $printsummary;
- }
-
- function setCodecoverage($codecoverage)
- {
- $this->codecoverage = $codecoverage;
- }
-
- /**
- * Add a new formatter to all tests of this task.
- *
- * @param FormatterElement formatter element
- */
- function addFormatter(FormatterElement $fe)
- {
- $this->formatters[] = $fe;
- }
-
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $tests = array();
-
- if ($this->printsummary)
- {
- $fe = new FormatterElement();
- $fe->setClassName('SummaryPHPUnit2ResultFormatter');
- $fe->setUseFile(false);
- $this->formatters[] = $fe;
- }
-
- foreach ($this->batchtests as $batchtest)
- {
- $tests = array_merge($tests, $batchtest->elements());
- }
-
- foreach ($this->formatters as $fe)
- {
- $formatter = $fe->getFormatter();
- $formatter->setProject($this->getProject());
-
- if ($fe->getUseFile())
- {
- $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
-
- $writer = new FileWriter($destFile->getAbsolutePath());
-
- $formatter->setOutput($writer);
- }
- else
- {
- $formatter->setOutput($this->getDefaultOutput());
- }
-
- $formatter->startTestRun();
- }
-
- foreach ($tests as $test)
- {
- $this->execute(new PHPUnit2_Framework_TestSuite(new ReflectionClass($test)));
- }
-
- foreach ($this->formatters as $fe)
- {
- $formatter = $fe->getFormatter();
- $formatter->endTestRun();
- }
-
- if ($this->testfailed)
- {
- throw new BuildException("One or more tests failed");
- }
- }
-
- /**
- * @throws BuildException
- */
- private function execute($suite)
- {
- $runner = new PHPUnit2TestRunner($suite, $this->project);
-
- $runner->setCodecoverage($this->codecoverage);
-
- foreach ($this->formatters as $fe)
- {
- $formatter = $fe->getFormatter();
-
- $runner->addFormatter($formatter);
- }
-
- $runner->run();
-
- $retcode = $runner->getRetCode();
-
- if ($retcode == PHPUnit2TestRunner::ERRORS) {
- if ($this->errorproperty) {
- $this->project->setNewProperty($this->errorproperty, true);
- }
- if ($this->haltonerror) {
- $this->testfailed = true;
- }
- } elseif ($retcode == PHPUnit2TestRunner::FAILURES) {
- if ($this->failureproperty) {
- $this->project->setNewProperty($this->failureproperty, true);
- }
-
- if ($this->haltonfailure) {
- $this->testfailed = true;
- }
- }
-
- }
-
- private function getDefaultOutput()
- {
- return new LogWriter($this);
- }
-
- /**
- * Adds a set of tests based on pattern matching.
- *
- * @return BatchTest a new instance of a batch test.
- */
- function createBatchTest()
- {
- $batchtest = new BatchTest($this->getProject());
-
- $this->batchtests[] = $batchtest;
-
- return $batchtest;
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php
deleted file mode 100644
index bbd19f34..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/**
- * $Id: PHPUnit2TestRunner.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'PHPUnit2/Framework/TestListener.php';
-require_once 'PHPUnit2/Framework/TestResult.php';
-require_once 'PHPUnit2/Framework/TestSuite.php';
-
-require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
-
-require_once 'phing/system/util/Timer.php';
-
-/**
- * Simple Testrunner for PHPUnit2 that runs all tests of a testsuite.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPUnit2TestRunner.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class PHPUnit2TestRunner
-{
- const SUCCESS = 0;
- const FAILURES = 1;
- const ERRORS = 2;
-
- private $test = NULL;
- private $suite = NULL;
- private $retCode = 0;
- private $formatters = array();
-
- private $codecoverage = false;
-
- private $project = NULL;
-
- function __construct(PHPUnit2_Framework_TestSuite $suite, Project $project)
- {
- $this->suite = $suite;
- $this->project = $project;
- $this->retCode = self::SUCCESS;
- }
-
- function setCodecoverage($codecoverage)
- {
- $this->codecoverage = $codecoverage;
- }
-
- function addFormatter(PHPUnit2_Framework_TestListener $formatter)
- {
- $this->formatters[] = $formatter;
- }
-
- function run()
- {
- $res = new PHPUnit2_Framework_TestResult();
-
- if ($this->codecoverage)
- {
- $res->collectCodeCoverageInformation(TRUE);
- }
-
- foreach ($this->formatters as $formatter)
- {
- $res->addListener($formatter);
- }
-
- $this->suite->run($res);
-
- if ($this->codecoverage)
- {
- CoverageMerger::merge($this->project, $res->getCodeCoverageInformation());
- }
-
- if ($res->errorCount() != 0)
- {
- $this->retCode = self::ERRORS;
- }
-
- else if ($res->failureCount() != 0 || $res->notImplementedCount() != 0)
- {
- $this->retCode = self::FAILURES;
- }
- }
-
- function getRetCode()
- {
- return $this->retCode;
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Util.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Util.php
deleted file mode 100644
index f4d1f62a..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PHPUnit2Util.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- * $Id: PHPUnit2Util.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-/**
- * Various utility functions
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PHPUnit2Util.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class PHPUnit2Util
-{
- protected static $definedClasses = array();
-
- /**
- * Returns the package of a class as defined in the docblock of the class using @package
- *
- * @param string the name of the class
- * @return string the name of the package
- */
- static function getPackageName($classname)
- {
- $reflect = new ReflectionClass($classname);
-
- if (preg_match('/@package[\s]+([\.\w]+)/', $reflect->getDocComment(), $matches))
- {
- return $matches[1];
- }
- else
- {
- return "default";
- }
- }
-
- /**
- * Derives the classname from a filename.
- * Assumes that there is only one class defined in that particular file, and that
- * the naming follows the dot-path (Java) notation scheme.
- *
- * @param string the filename
- * @return string the name fo the class
- */
- static function getClassFromFileName($filename)
- {
- $filename = basename($filename);
-
- $rpos = strrpos($filename, '.');
-
- if ($rpos != -1)
- {
- $filename = substr($filename, 0, $rpos);
- }
-
- return $filename;
- }
-
- /**
- * @param string the filename
- * @param Path optional classpath
- * @return array list of classes defined in the file
- */
- static function getDefinedClasses($filename, $classpath = NULL)
- {
- $filename = realpath($filename);
-
- if (!file_exists($filename))
- {
- throw new Exception("File '" . $filename . "' does not exist");
- }
-
- if (isset(self::$definedClasses[$filename]))
- {
- return self::$definedClasses[$filename];
- }
-
- Phing::__import($filename, $classpath);
-
- $declaredClasses = get_declared_classes();
-
- foreach ($declaredClasses as $classname)
- {
- $reflect = new ReflectionClass($classname);
-
- self::$definedClasses[$reflect->getFilename()][] = $classname;
-
- if (is_array(self::$definedClasses[$reflect->getFilename()]))
- {
- self::$definedClasses[$reflect->getFilename()] = array_unique(self::$definedClasses[$reflect->getFilename()]);
- }
- }
-
- return self::$definedClasses[$filename];
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php
deleted file mode 100644
index b0a9ae58..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * $Id: PlainPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'PHPUnit2/Framework/Test.php';
-require_once 'PHPUnit2/Util/Filter.php';
-
-require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php';
-
-/**
- * Prints plain text output of the test to a specified Writer.
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: PlainPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class PlainPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
-{
- private $inner = "";
-
- function getExtension()
- {
- return ".txt";
- }
-
- function getPreferredOutfile()
- {
- return "testresults";
- }
-
- function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- parent::startTestSuite($suite);
-
- $this->inner = "";
- }
-
- function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- parent::endTestSuite($suite);
-
- $sb = "Testsuite: " . $suite->getName() . "\n";
- $sb.= "Tests run: " . $this->getRunCount();
- $sb.= ", Failures: " . $this->getFailureCount();
- $sb.= ", Errors: " . $this->getErrorCount();
- $sb.= ", Time elapsed: " . $this->getElapsedTime();
- $sb.= " sec\n";
-
- if ($this->out != NULL)
- {
- $this->out->write($sb);
- $this->out->write($this->inner);
- }
- }
-
- function addError(PHPUnit2_Framework_Test $test, Exception $e)
- {
- parent::addError($test, $e);
-
- $this->formatError("ERROR", $test, $e);
- }
-
- function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
- {
- parent::addFailure($test, $t);
-
- $this->formatError("FAILED", $test, $t);
- }
-
- function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
- {
- parent::addIncompleteTest($test, $e);
-
- $this->formatError("INCOMPLETE", $test, $e);
- }
-
- private function formatError($type, PHPUnit2_Framework_Test $test, Exception $e)
- {
- if ($test != null)
- {
- $this->endTest($test);
- }
-
- $this->inner.= $test->getName() . " " . $type . "\n";
- $this->inner.= $e->getMessage() . "\n";
- $this->inner.= PHPUnit2_Util_Filter::getFilteredStackTrace($e) . "\n";
- }
-
- function endTestRun()
- {
- parent::endTestRun();
-
- if ($this->out != NULL)
- {
- $this->out->close();
- }
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php
deleted file mode 100644
index ac2fec8f..00000000
--- a/buildscripts/phing/classes/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * $Id: XMLPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- *
- * 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information please see
- * <http://phing.info>.
- */
-
-require_once 'PHPUnit2/Framework/Test.php';
-require_once 'PHPUnit2/Runner/Version.php';
-
-require_once 'PHPUnit2/Util/Log/XML.php';
-
-require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php';
-
-/**
- * Prints XML output of the test to a specified Writer
- *
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: XMLPHPUnit2ResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
- * @package phing.tasks.ext.phpunit2
- * @since 2.1.0
- */
-class XMLPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
-{
- private $logger = NULL;
-
- function __construct()
- {
- $this->logger = new PHPUnit2_Util_Log_XML();
- $this->logger->setWriteDocument(false);
- }
-
- function getExtension()
- {
- return ".xml";
- }
-
- function getPreferredOutfile()
- {
- return "testsuites";
- }
-
- function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- parent::startTestSuite($suite);
-
- $this->logger->startTestSuite($suite);
- }
-
- function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
- {
- parent::endTestSuite($suite);
-
- $this->logger->endTestSuite($suite);
- }
-
- function startTest(PHPUnit2_Framework_Test $test)
- {
- parent::startTest($test);
-
- $this->logger->startTest($test);
- }
-
- function endTest(PHPUnit2_Framework_Test $test)
- {
- parent::endTest($test);
-
- $this->logger->endTest($test);
- }
-
- function addError(PHPUnit2_Framework_Test $test, Exception $e)
- {
- parent::addError($test, $e);
-
- $this->logger->addError($test, $e);
- }
-
- function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
- {
- parent::addFailure($test, $t);
-
- $this->logger->addFailure($test, $t);
- }
-
- function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
- {
- parent::addIncompleteTest($test, $e);
-
- $this->logger->addIncompleteTest($test, $e);
- }
-
- function endTestRun()
- {
- parent::endTestRun();
-
- if ($this->out)
- {
- $this->out->write($this->logger->getXML());
- $this->out->close();
- }
- }
-}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/rSTTask.php b/buildscripts/phing/classes/phing/tasks/ext/rSTTask.php
new file mode 100644
index 00000000..77170f18
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/rSTTask.php
@@ -0,0 +1,476 @@
+<?php
+
+/**
+ * reStructuredText rendering task for Phing, the PHP build tool.
+ *
+ * PHP version 5
+ *
+ * @category Tasks
+ * @package phing.tasks.ext
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html
+ * @link http://www.phing.info/
+ * @version SVN: $Id: ad2ac21008b4635c4f557e3a65c9306a350ca1f2 $
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/util/FileUtils.php';
+
+/**
+ * reStructuredText rendering task for Phing, the PHP build tool.
+ *
+ * PHP version 5
+ *
+ * @category Tasks
+ * @package phing.tasks.ext
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html
+ * @link http://www.phing.info/
+ */
+class rSTTask extends Task
+{
+ /**
+ * @var string Taskname for logger
+ */
+ protected $taskName = 'rST';
+
+ /**
+ * Result format, defaults to "html".
+ * @see $supportedFormats for all possible options
+ *
+ * @var string
+ */
+ protected $format = 'html';
+
+ /**
+ * Array of supported output formats
+ *
+ * @var array
+ * @see $format
+ * @see $targetExt
+ */
+ protected static $supportedFormats = array(
+ 'html', 'latex', 'man', 'odt', 's5', 'xml'
+ );
+
+ /**
+ * Maps formats to file extensions
+ *
+ * @var array
+ */
+ protected static $targetExt = array(
+ 'html' => 'html',
+ 'latex' => 'tex',
+ 'man' => '3',
+ 'odt' => 'odt',
+ 's5' => 'html',
+ 'xml' => 'xml',
+ );
+
+ /**
+ * Input file in rST format.
+ * Required
+ *
+ * @var string
+ */
+ protected $file = null;
+
+ /**
+ * Additional rst2* tool parameters.
+ *
+ * @var string
+ */
+ protected $toolParam = null;
+
+ /**
+ * Full path to the tool, i.e. /usr/local/bin/rst2html
+ *
+ * @var string
+ */
+ protected $toolPath = null;
+
+ /**
+ * Output file or directory. May be omitted.
+ * When it ends with a slash, it is considered to be a directory
+ *
+ * @var string
+ */
+ protected $destination = null;
+
+ protected $filesets = array(); // all fileset objects assigned to this task
+ protected $mapperElement = null;
+
+ /**
+ * all filterchains objects assigned to this task
+ *
+ * @var array
+ */
+ protected $filterChains = array();
+
+ /**
+ * mode to create directories with
+ *
+ * @var integer
+ */
+ protected $mode = 0755;
+
+ /**
+ * Only render files whole source files are newer than the
+ * target files
+ *
+ * @var boolean
+ */
+ protected $uptodate = false;
+
+
+ /**
+ * Init method: requires the PEAR System class
+ */
+ public function init()
+ {
+ require_once 'System.php';
+ }
+
+ /**
+ * The main entry point method.
+ *
+ * @return void
+ */
+ public function main()
+ {
+ $tool = $this->getToolPath($this->format);
+ if (count($this->filterChains)) {
+ $this->fileUtils = new FileUtils();
+ }
+
+ if ($this->file != '') {
+ $file = $this->file;
+ $targetFile = $this->getTargetFile($file, $this->destination);
+ $this->render($tool, $file, $targetFile);
+ return;
+ }
+
+ if (!count($this->filesets)) {
+ throw new BuildException(
+ '"file" attribute or "fileset" subtag required'
+ );
+ }
+
+ // process filesets
+ $mapper = null;
+ if ($this->mapperElement !== null) {
+ $mapper = $this->mapperElement->getImplementation();
+ }
+
+ $project = $this->getProject();
+ foreach ($this->filesets as $fs) {
+ $ds = $fs->getDirectoryScanner($project);
+ $fromDir = $fs->getDir($project);
+ $srcFiles = $ds->getIncludedFiles();
+
+ foreach ($srcFiles as $src) {
+ $file = new PhingFile($fromDir, $src);
+ if ($mapper !== null) {
+ $results = $mapper->main($file);
+ if ($results === null) {
+ throw new BuildException(
+ sprintf(
+ 'No filename mapper found for "%s"',
+ $file
+ )
+ );
+ }
+ $targetFile = reset($results);
+ } else {
+ $targetFile = $this->getTargetFile($file, $this->destination);
+ }
+ $this->render($tool, $file, $targetFile);
+ }
+ }
+ }
+
+
+
+ /**
+ * Renders a single file and applies filters on it
+ *
+ * @param string $tool conversion tool to use
+ * @param string $source rST source file
+ * @param string $targetFile target file name
+ *
+ * @return void
+ */
+ protected function render($tool, $source, $targetFile)
+ {
+ if (count($this->filterChains) == 0) {
+ return $this->renderFile($tool, $source, $targetFile);
+ }
+
+ $tmpTarget = tempnam(sys_get_temp_dir(), 'rST-');
+ $this->renderFile($tool, $source, $tmpTarget);
+
+ $this->fileUtils->copyFile(
+ new PhingFile($tmpTarget),
+ new PhingFile($targetFile),
+ true, false, $this->filterChains,
+ $this->getProject(), $this->mode
+ );
+ unlink($tmpTarget);
+ }
+
+
+
+ /**
+ * Renders a single file with the rST tool.
+ *
+ * @param string $tool conversion tool to use
+ * @param string $source rST source file
+ * @param string $targetFile target file name
+ *
+ * @return void
+ *
+ * @throws BuildException When the conversion fails
+ */
+ protected function renderFile($tool, $source, $targetFile)
+ {
+ if ($this->uptodate && file_exists($targetFile)
+ && filemtime($source) <= filemtime($targetFile)
+ ) {
+ //target is up to date
+ return;
+ }
+ //work around a bug in php by replacing /./ with /
+ $targetDir = str_replace('/./', '/', dirname($targetFile));
+ if (!is_dir($targetDir)) {
+ $this->log("Creating directory '$targetDir'", Project::MSG_VERBOSE);
+ mkdir($targetDir, $this->mode, true);
+ }
+
+ $cmd = $tool
+ . ' --exit-status=2'
+ . ' ' . $this->toolParam
+ . ' ' . escapeshellarg($source)
+ . ' ' . escapeshellarg($targetFile)
+ . ' 2>&1';
+
+ $this->log('command: ' . $cmd, Project::MSG_VERBOSE);
+ exec($cmd, $arOutput, $retval);
+ if ($retval != 0) {
+ $this->log(implode("\n", $arOutput), Project::MSG_INFO);
+ throw new BuildException('Rendering rST failed');
+ }
+ $this->log(implode("\n", $arOutput), Project::MSG_DEBUG);
+ }
+
+
+
+ /**
+ * Finds the rst2* binary path
+ *
+ * @param string $format Output format
+ *
+ * @return string Full path to rst2$format
+ *
+ * @throws BuildException When the tool cannot be found
+ */
+ protected function getToolPath($format)
+ {
+ if ($this->toolPath !== null) {
+ return $this->toolPath;
+ }
+
+ $tool = 'rst2' . $format;
+ $path = System::which($tool);
+ if (!$path) {
+ throw new BuildException(
+ sprintf('"%s" not found. Install python-docutils.', $tool)
+ );
+ }
+
+ return $path;
+ }
+
+
+
+ /**
+ * Determines and returns the target file name from the
+ * input file and the configured destination name.
+ *
+ * @param string $file Input file
+ * @param string $destination Destination file or directory name,
+ * may be null
+ *
+ * @return string Target file name
+ *
+ * @uses $format
+ * @uses $targetExt
+ */
+ public function getTargetFile($file, $destination = null)
+ {
+ if ($destination != ''
+ && substr($destination, -1) !== '/'
+ && substr($destination, -1) !== '\\'
+ ) {
+ return $destination;
+ }
+
+ if (strtolower(substr($file, -4)) == '.rst') {
+ $file = substr($file, 0, -4);
+ }
+
+ return $destination . $file . '.' . self::$targetExt[$this->format];
+ }
+
+
+
+ /**
+ * The setter for the attribute "file"
+ *
+ * @param string $file Path of file to render
+ *
+ * @return void
+ */
+ public function setFile($file)
+ {
+ $this->file = $file;
+ }
+
+
+
+ /**
+ * The setter for the attribute "format"
+ *
+ * @param string $format Output format
+ *
+ * @return void
+ *
+ * @throws BuildException When the format is not supported
+ */
+ public function setFormat($format)
+ {
+ if (!in_array($format, self::$supportedFormats)) {
+ throw new BuildException(
+ sprintf(
+ 'Invalid output format "%s", allowed are: %s',
+ $format,
+ implode(', ', self::$supportedFormats)
+ )
+ );
+ }
+ $this->format = $format;
+ }
+
+
+
+ /**
+ * The setter for the attribute "destination"
+ *
+ * @param string $destination Output file or directory. When it ends
+ * with a slash, it is taken as directory.
+ *
+ * @return void
+ */
+ public function setDestination($destination)
+ {
+ $this->destination = $destination;
+ }
+
+ /**
+ * The setter for the attribute "toolparam"
+ *
+ * @param string $param Additional rst2* tool parameters
+ *
+ * @return void
+ */
+ public function setToolparam($param)
+ {
+ $this->toolParam = $param;
+ }
+
+ /**
+ * The setter for the attribute "toolpath"
+ *
+ * @param string $param Full path to tool path, i.e. /usr/local/bin/rst2html
+ *
+ * @return void
+ *
+ * @throws BuildException When the tool does not exist or is not executable
+ */
+ public function setToolpath($path)
+ {
+ if (!file_exists($path)) {
+ $fullpath = System::which($path);
+ if ($fullpath === false) {
+ throw new BuildException(
+ 'Tool does not exist. Path: ' . $path
+ );
+ }
+ $path = $fullpath;
+ }
+ if (!is_executable($path)) {
+ throw new BuildException(
+ 'Tool not executable. Path: ' . $path
+ );
+ }
+ $this->toolPath = $path;
+ }
+
+ /**
+ * The setter for the attribute "uptodate"
+ *
+ * @param string $uptodate True/false
+ *
+ * @return void
+ */
+ public function setUptodate($uptodate)
+ {
+ $this->uptodate = (boolean)$uptodate;
+ }
+
+
+
+ /**
+ * Add a set of files to be rendered.
+ *
+ * @param FileSet $fileset Set of rst files to render
+ *
+ * @return void
+ */
+ public function addFileset(FileSet $fileset)
+ {
+ $this->filesets[] = $fileset;
+ }
+
+
+
+ /**
+ * Nested creator, creates one Mapper for this task
+ *
+ * @return Mapper The created Mapper type object
+ *
+ * @throws BuildException
+ */
+ public function createMapper()
+ {
+ if ($this->mapperElement !== null) {
+ throw new BuildException(
+ 'Cannot define more than one mapper', $this->location
+ );
+ }
+ $this->mapperElement = new Mapper($this->project);
+ return $this->mapperElement;
+ }
+
+
+
+ /**
+ * Creates a filterchain, stores and returns it
+ *
+ * @return FilterChain The created filterchain object
+ */
+ public function createFilterChain()
+ {
+ $num = array_push($this->filterChains, new FilterChain($this->project));
+ return $this->filterChains[$num-1];
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php
index 654d65dd..32fbc212 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestCountResultFormatter.php 58 2006-04-28 14:41:04Z mrook $
+ * $Id: ae09aa1a433f4de854fa7c27903e7eb0957bc90b $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,29 +24,28 @@ require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Dummy result formatter used to count SimpleTest results
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestCountResultFormatter.php 58 2006-04-28 14:41:04Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: ae09aa1a433f4de854fa7c27903e7eb0957bc90b $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestCountResultFormatter extends SimpleTestResultFormatter
{
- const SUCCESS = 0;
- const FAILURES = 1;
- const ERRORS = 2;
-
- function getRetCode()
- {
- if ($this->getExceptionCount() != 0)
- {
- return self::ERRORS;
- }
- else if ($this->getFailCount() != 0)
- {
- return self::FAILURES;
- }
-
- return self::SUCCESS;
- }
+ const SUCCESS = 0;
+ const FAILURES = 1;
+ const ERRORS = 2;
+
+ function getRetCode()
+ {
+ if ($this->getExceptionCount() != 0)
+ {
+ return self::ERRORS;
+ }
+ else if ($this->getFailCount() != 0)
+ {
+ return self::FAILURES;
+ }
+
+ return self::SUCCESS;
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php
new file mode 100755
index 00000000..de78ab24
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * $Id: d7e7e397e81588c3eafcb9e758666fec0fa166f5 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: d7e7e397e81588c3eafcb9e758666fec0fa166f5 $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestDebugResultFormatter extends SimpleTestResultFormatter
+{
+ protected $current_case = "";
+ protected $current_test = "";
+ private $failingTests = array();
+
+ function printFailingTests() {
+ foreach ($this->failingTests as $test) {
+ $this->out->write($test . "\n");
+ }
+ }
+
+ function paintCaseStart($test_name)
+ {
+ parent::paintCaseStart($test_name);
+ $this->paint( "Testsuite: $test_name\n");
+ $this->current_case = $test_name;
+ }
+
+ function paintMethodStart($test_name)
+ {
+ parent::paintMethodStart($test_name);
+ $this->current_test = $test_name;
+ //$msg = "{$this->current_case} :: $test_name\n";
+ $msg = " TestCase: $test_name";
+ $this->paint($msg);
+ }
+
+ function paint($msg) {
+ if ($this->out == null ) {
+ print $msg;
+ } else {
+ $this->out->write($msg);
+ }
+ }
+
+ function paintMethodEnd($test_name) {
+ parent::paintMethodEnd($test_name);
+ $this->paint("\n");
+ }
+
+ function paintCaseEnd($test_name)
+ {
+ parent::paintCaseEnd($test_name);
+ $this->current_case = "";
+ /* Only count suites where more than one test was run */
+
+ if ($this->getRunCount() && false)
+ {
+ $sb = "";
+ $sb.= "Tests run: " . $this->getRunCount();
+ $sb.= ", Failures: " . $this->getFailureCount();
+ $sb.= ", Errors: " . $this->getErrorCount();
+ $sb.= ", Time elapsed: " . $this->getElapsedTime();
+ $sb.= " sec\n";
+ $this->paint($sb);
+ }
+
+ }
+
+ function paintError($message)
+ {
+ parent::paintError($message);
+ $this->formatError("ERROR", $message);
+ $this->failingTests[] = $this->current_case . "->" . $this->current_test;
+ }
+
+ function paintFail($message)
+ {
+ parent::paintFail($message);
+ $this->formatError("FAILED", $message);
+ $this->failingTests[] = $this->current_case . "->" . $this->current_test;
+ }
+ function paintException($message)
+ {
+ parent::paintException($message);
+ $this->failingTests[] = $this->current_case . "->" . $this->current_test;
+ $this->formatError("Exception", $message);
+ }
+
+
+
+ private function formatError($type, $message)
+ {
+ $this->paint("ERROR: $type: $message");
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php
index 768a041f..5ae9ba23 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestFormatterElement.php 58 2006-04-28 14:41:04Z mrook $
+ * $Id: 2441f1b83b9f9d1aeb2a4afd7e049c840d70bbd9 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -19,108 +19,50 @@
* <http://phing.info>.
*/
-require_once 'phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php';
-require_once 'phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php';
-require_once 'phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php';
+require_once 'phing/tasks/ext/phpunit/FormatterElement.php';
/**
* Child class of "FormatterElement", overrides setType to provide other
* formatter classes for SimpleTest
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestFormatterElement.php 58 2006-04-28 14:41:04Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 2441f1b83b9f9d1aeb2a4afd7e049c840d70bbd9 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
-class SimpleTestFormatterElement
+class SimpleTestFormatterElement extends FormatterElement
{
- protected $formatter = NULL;
-
- protected $type = "";
-
- protected $useFile = true;
-
- protected $toDir = ".";
-
- protected $outfile = "";
-
- function setType($type)
- {
- $this->type = $type;
-
- if ($this->type == "xml")
- {
- //$destFile = new PhingFile($this->toDir, 'testsuites.xml');
- $this->formatter = new SimpleTestXmlResultFormatter();
- }
- else
- if ($this->type == "plain")
- {
- $this->formatter = new SimpleTestPlainResultFormatter();
- }
- else
- if ($this->type == "summary")
- {
- $this->formatter = new SimpleTestSummaryResultFormatter();
- }
- else
- {
- throw new BuildException("Formatter '" . $this->type . "' not implemented");
- }
- }
-
- function setClassName($className)
- {
- $classNameNoDot = Phing::import($className);
-
- $this->formatter = new $classNameNoDot();
- }
-
- function setUseFile($useFile)
- {
- $this->useFile = $useFile;
- }
-
- function getUseFile()
- {
- return $this->useFile;
- }
-
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
-
- function getToDir()
- {
- return $this->toDir;
- }
-
- function setOutfile($outfile)
- {
- $this->outfile = $outfile;
- }
-
- function getOutfile()
- {
- if ($this->outfile)
- {
- return $this->outfile;
- }
- else
- {
- return $this->formatter->getPreferredOutfile() . $this->getExtension();
- }
- }
-
- function getExtension()
- {
- return $this->formatter->getExtension();
- }
-
- function getFormatter()
- {
- return $this->formatter;
- }
+ function setType($type)
+ {
+ $this->type = $type;
+
+ if ($this->type == "xml")
+ {
+ require_once 'phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php';
+ $destFile = new PhingFile($this->toDir, 'testsuites.xml');
+ $this->formatter = new SimpleTestXmlResultFormatter();
+ }
+ else
+ if ($this->type == "plain")
+ {
+ require_once 'phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php';
+ $this->formatter = new SimpleTestPlainResultFormatter();
+ }
+ else
+ if ($this->type == "summary")
+ {
+ require_once 'phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php';
+ $this->formatter = new SimpleTestSummaryResultFormatter();
+ }
+ else
+ if ($this->type == "debug")
+ {
+ require_once 'phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php';
+ $this->formatter = new SimpleTestDebugResultFormatter();
+ }
+ else
+ {
+ throw new BuildException("Formatter '" . $this->type . "' not implemented");
+ }
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php
index 9d570486..cfba9533 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestPlainResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: c0fa060b8f439f7d0013a0ec016ede4c5a76b42d $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,72 +24,72 @@ require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Prints plain text output of the test to a specified Writer.
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestPlainResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: c0fa060b8f439f7d0013a0ec016ede4c5a76b42d $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestPlainResultFormatter extends SimpleTestResultFormatter
{
- private $inner = "";
+ private $inner = "";
+
+ function getExtension()
+ {
+ return ".txt";
+ }
+
+ function getPreferredOutfile()
+ {
+ return "testresults";
+ }
- function getExtension()
- {
- return ".txt";
- }
+ function paintCaseStart($test_name)
+ {
+ parent::paintCaseStart($test_name);
+
+ $this->inner = "";
+ }
+
+ function paintCaseEnd($test_name)
+ {
+ parent::paintCaseEnd($test_name);
+
+ $sb = "";
+ /* Only count suites where more than one test was run */
+ if ($this->getRunCount())
+ {
+ $sb.= "Testsuite: $test_name\n";
+ $sb.= "Tests run: " . $this->getRunCount();
+ $sb.= ", Failures: " . $this->getFailureCount();
+ $sb.= ", Errors: " . $this->getErrorCount();
+ $sb.= ", Time elapsed: " . $this->getElapsedTime();
+ $sb.= " sec\n";
- function getPreferredOutfile()
- {
- return "testresults";
- }
+ if ($this->out != NULL)
+ {
+ $this->out->write($sb);
+ $this->out->write($this->inner);
+ }
+ }
+ }
- function paintCaseStart($test_name)
- {
- parent::paintCaseStart($test_name);
+ function paintError($message)
+ {
+ parent::paintError($message);
+
+ $this->formatError("ERROR", $message);
+ }
- $this->inner = "";
- }
+ function paintFail($message)
+ {
+ parent::paintFail($message);
+
+ $this->formatError("FAILED", $message);
+ }
- function paintCaseEnd($test_name)
- {
- parent::paintCaseEnd($test_name);
-
- /* Only count suites where more than one test was run */
- if ($this->getRunCount())
- {
- $sb = "Testsuite: $test_name\n";
- $sb.= "Tests run: " . $this->getRunCount();
- $sb.= ", Failures: " . $this->getFailureCount();
- $sb.= ", Errors: " . $this->getErrorCount();
- $sb.= ", Time elapsed: " . $this->getElapsedTime();
- $sb.= " sec\n";
-
- if ($this->out != NULL)
- {
- $this->out->write($sb);
- $this->out->write($this->inner);
- }
- }
- }
-
- function paintError($message)
- {
- parent::paintError($message);
-
- $this->formatError("ERROR", $message);
- }
-
- function paintFail($message)
- {
- parent::paintFail($message);
-
- $this->formatError("FAILED", $message);
- }
-
- private function formatError($type, $message)
- {
- $this->inner.= $this->getTestName() . " " . $type . "\n";
- $this->inner.= $message . "\n";
- }
+ private function formatError($type, $message)
+ {
+ $this->inner.= $this->getTestName() . " " . $type . "\n";
+ $this->inner.= $message . "\n";
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php
index 35077210..8efcbb63 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestResultFormatter.php 58 2006-04-28 14:41:04Z mrook $
+ * $Id: b9fbde1e1a21cccbcf6c3bdc29765cf0cf681e31 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -19,144 +19,143 @@
* <http://phing.info>.
*/
-//require_once 'simpletest/scorer.php';
+require_once 'simpletest/scorer.php';
require_once 'phing/system/io/Writer.php';
/**
* This abstract class describes classes that format the results of a SimpleTest testrun.
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestResultFormatter.php 58 2006-04-28 14:41:04Z mrook $
- * @package phing.tasks.ext.phpunit2
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: b9fbde1e1a21cccbcf6c3bdc29765cf0cf681e31 $
+ * @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
abstract class SimpleTestResultFormatter extends SimpleReporter
{
- protected $out = NULL;
-
- protected $project = NULL;
-
- private $timer = NULL;
-
- private $runCount = 0;
-
- private $failureCount = 0;
-
- private $errorCount = 0;
-
- private $currentTest = "";
-
- /**
- * Sets the writer the formatter is supposed to write its results to.
- */
- function setOutput(Writer $out)
- {
- $this->out = $out;
- }
-
- /**
- * Returns the extension used for this formatter
- *
- * @return string the extension
- */
- function getExtension()
- {
- return "";
- }
-
- /**
- * Sets the project
- *
- * @param Project the project
- */
- function setProject(Project $project)
- {
- $this->project = $project;
- }
-
- function getPreferredOutfile()
- {
- return "";
- }
-
- function paintMethodStart($test_name)
- {
- parent::paintMethodStart($test_name);
-
- $this->currentTest = $test_name;
- }
-
- function paintMethodEnd($test_name)
- {
- parent::paintMethodEnd($test_name);
-
- $this->runCount++;
- }
-
- function paintCaseStart($test_name)
- {
- parent::paintCaseStart($test_name);
-
- $this->runCount = 0;
- $this->failureCount = 0;
- $this->errorCount = 0;
-
- $this->timer = new Timer();
- $this->timer->start();
- }
-
- function paintCaseEnd($test_name)
- {
- parent::paintCaseEnd($test_name);
-
- $this->timer->stop();
- }
-
- function paintError($message)
- {
- parent::paintError($message);
-
- $this->errorCount++;
- }
-
- function paintFail($message)
- {
- parent::paintFail($message);
-
- $this->failureCount++;
- }
-
- function getRunCount()
- {
- return $this->runCount;
- }
-
- function getFailureCount()
- {
- return $this->failureCount;
- }
-
- function getErrorCount()
- {
- return $this->errorCount;
- }
-
- function getTestName()
- {
- return $this->currentTest;
- }
-
- function getElapsedTime()
- {
- if ($this->timer)
- {
- return $this->timer->getElapsedTime();
- }
- else
- {
- return 0;
- }
- }
+ protected $out = NULL;
+
+ protected $project = NULL;
+
+ private $timer = NULL;
+
+ private $runCount = 0;
+
+ private $failureCount = 0;
+
+ private $errorCount = 0;
+
+ private $currentTest = "";
+
+ /**
+ * Sets the writer the formatter is supposed to write its results to.
+ */
+ function setOutput(Writer $out)
+ {
+ $this->out = $out;
+ }
+
+ /**
+ * Returns the extension used for this formatter
+ *
+ * @return string the extension
+ */
+ function getExtension()
+ {
+ return "";
+ }
+
+ /**
+ * Sets the project
+ *
+ * @param Project the project
+ */
+ function setProject(Project $project)
+ {
+ $this->project = $project;
+ }
+
+ function getPreferredOutfile()
+ {
+ return "";
+ }
+
+ function paintMethodStart($test_name)
+ {
+ parent::paintMethodStart($test_name);
+
+ $this->currentTest = $test_name;
+ }
+
+ function paintMethodEnd($test_name)
+ {
+ parent::paintMethodEnd($test_name);
+
+ $this->runCount++;
+ }
+
+ function paintCaseStart($test_name)
+ {
+ parent::paintCaseStart($test_name);
+
+ $this->runCount = 0;
+ $this->failureCount = 0;
+ $this->errorCount = 0;
+
+ $this->timer = new Timer();
+ $this->timer->start();
+ }
+
+ function paintCaseEnd($test_name)
+ {
+ parent::paintCaseEnd($test_name);
+
+ $this->timer->stop();
+ }
+
+ function paintError($message)
+ {
+ parent::paintError($message);
+
+ $this->errorCount++;
+ }
+
+ function paintFail($message)
+ {
+ parent::paintFail($message);
+
+ $this->failureCount++;
+ }
+
+ function getRunCount()
+ {
+ return $this->runCount;
+ }
+
+ function getFailureCount()
+ {
+ return $this->failureCount;
+ }
+
+ function getErrorCount()
+ {
+ return $this->errorCount;
+ }
+
+ function getTestName()
+ {
+ return $this->currentTest;
+ }
+
+ function getElapsedTime()
+ {
+ if ($this->timer)
+ {
+ return $this->timer->getElapsedTime();
+ }
+ else
+ {
+ return 0;
+ }
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php
index a2fafb0a..e0a78f11 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestSummaryResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: cd15496bfbce39bfd20fe17d52f9348848df0706 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,31 +24,30 @@ require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Prints short summary output of the test to Phing's logging system.
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestSummaryResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: cd15496bfbce39bfd20fe17d52f9348848df0706 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestSummaryResultFormatter extends SimpleTestResultFormatter
{
- function paintCaseEnd($test_name)
- {
- parent::paintCaseEnd($test_name);
+ function paintCaseEnd($test_name)
+ {
+ parent::paintCaseEnd($test_name);
+
+ /* Only count suites where more than one test was run */
+ if ($this->getRunCount())
+ {
+ $sb.= "Tests run: " . $this->getRunCount();
+ $sb.= ", Failures: " . $this->getFailureCount();
+ $sb.= ", Errors: " . $this->getErrorCount();
+ $sb.= ", Time elapsed: " . $this->getElapsedTime();
+ $sb.= " sec\n";
- /* Only count suites where more than one test was run */
- if ($this->getRunCount())
- {
- $sb= "Tests run: " . $this->getRunCount();
- $sb.= ", Failures: " . $this->getFailureCount();
- $sb.= ", Errors: " . $this->getErrorCount();
- $sb.= ", Time elapsed: " . $this->getElapsedTime();
- $sb.= " sec\n";
-
- if ($this->out != NULL)
- {
- $this->out->write($sb);
- }
- }
- }
+ if ($this->out != NULL)
+ {
+ $this->out->write($sb);
+ }
+ }
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php
index e32c31c6..8082e1ee 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestTask.php 58 2006-04-28 14:41:04Z mrook $
+ * $Id: d53b946f773798618069fe162d47ac5f6643662a $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -27,208 +27,238 @@ require_once 'phing/util/LogWriter.php';
/**
* Runs SimpleTest tests.
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestTask.php 58 2006-04-28 14:41:04Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: d53b946f773798618069fe162d47ac5f6643662a $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestTask extends Task
{
- private $formatters = array();
- private $haltonerror = false;
- private $haltonfailure = false;
- private $failureproperty;
- private $errorproperty;
- private $printsummary = false;
- private $testfailed = false;
- private $filesets=array();
-
- /**
- * Initialize Task.
- * This method includes any necessary SimpleTest 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.
- */
- function init() {
-
- if (!class_exists('SimpleReporter')) {
- throw new BuildException("SimpleTestTask depends on SimpleTest package being installed.", $this->getLocation());
- }
- require_once 'phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php';
- require_once 'phing/tasks/ext/simpletest/SimpleTestFormatterElement.php';
- }
-
- function setFailureproperty($value)
- {
- $this->failureproperty = $value;
- }
-
- function setErrorproperty($value)
- {
- $this->errorproperty = $value;
- }
-
- function setHaltonerror($value)
- {
- $this->haltonerror = $value;
- }
-
- function setHaltonfailure($value)
- {
- $this->haltonfailure = $value;
- }
-
- function setPrintsummary($printsummary)
- {
- $this->printsummary = $printsummary;
- }
-
- /**
- * Add a new formatter to all tests of this task.
- *
- * @param SimpleTestFormatterElement formatter element
- */
- function addFormatter(SimpleTestFormatterElement $fe)
- {
- $this->formatters[] = $fe;
- }
-
- /**
- * Add a new fileset containing the XML results to aggregate
- *
- * @param FileSet the new fileset containing XML results.
- */
- function addFileSet(FileSet $fileset)
- {
- $this->filesets[] = $fileset;
- }
-
- /**
- * Iterate over all filesets and return the filename of all files
- * that end with .php.
- *
- * @return array an array of filenames
- */
- private function getFilenames()
- {
- $filenames = array();
-
- foreach ($this->filesets as $fileset)
- {
- $ds = $fileset->getDirectoryScanner($this->project);
- $ds->scan();
-
- $files = $ds->getIncludedFiles();
-
- foreach ($files as $file)
- {
- if (strstr($file, ".php"))
- {
- $filenames[] = $ds->getBaseDir() . "/" . $file;
- }
- }
- }
-
- return $filenames;
- }
-
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $group = new GroupTest();
-
- $filenames = $this->getFilenames();
-
- foreach ($filenames as $testfile)
- {
- $group->addTestFile($testfile);
- }
-
- if ($this->printsummary)
- {
- $fe = new SimpleTestFormatterElement();
- $fe->setType('summary');
- $fe->setUseFile(false);
- $this->formatters[] = $fe;
- }
-
- foreach ($this->formatters as $fe)
- {
- $formatter = $fe->getFormatter();
- $formatter->setProject($this->getProject());
-
- if ($fe->getUseFile())
- {
- $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
-
- $writer = new FileWriter($destFile->getAbsolutePath());
-
- $formatter->setOutput($writer);
- }
- else
- {
- $formatter->setOutput($this->getDefaultOutput());
- }
- }
-
- $this->execute($group);
-
- if ($this->testfailed)
- {
- throw new BuildException("One or more tests failed");
- }
- }
-
- private function execute($suite)
- {
- $counter = new SimpleTestCountResultFormatter();
- $reporter = new MultipleReporter();
- $reporter->attachReporter($counter);
-
- foreach ($this->formatters as $fe)
- {
- $formatter = $fe->getFormatter();
-
- $reporter->attachReporter($formatter);
- }
-
- $suite->run($reporter);
-
- $retcode = $counter->getRetCode();
-
- if ($retcode == SimpleTestCountResultFormatter::ERRORS)
- {
- if ($this->errorproperty)
- {
- $this->project->setNewProperty($this->errorproperty, true);
- }
-
- if ($this->haltonerror)
- {
- $this->testfailed = true;
- }
- }
- elseif ($retcode == SimpleTestCountResultFormatter::FAILURES)
- {
- if ($this->failureproperty)
- {
- $this->project->setNewProperty($this->failureproperty, true);
- }
-
- if ($this->haltonfailure)
- {
- $this->testfailed = true;
- }
- }
- }
-
- private function getDefaultOutput()
- {
- return new LogWriter($this);
- }
+ private $formatters = array();
+ private $haltonerror = false;
+ private $haltonfailure = false;
+ private $failureproperty;
+ private $errorproperty;
+ private $printsummary = false;
+ private $testfailed = false;
+ private $debug = false;
+
+ /**
+ * Initialize Task.
+ * This method includes any necessary SimpleTest 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.
+ */
+ function init() {
+ @include_once 'simpletest/scorer.php';
+
+ if (!class_exists('SimpleReporter')) {
+ throw new BuildException("SimpleTestTask depends on SimpleTest package being installed.", $this->getLocation());
+ }
+
+ require_once 'simpletest/reporter.php';
+ require_once 'simpletest/xml.php';
+ require_once 'simpletest/test_case.php';
+ require_once 'phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php';
+ require_once 'phing/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php';
+ require_once 'phing/tasks/ext/simpletest/SimpleTestFormatterElement.php';
+ }
+
+ function setFailureproperty($value)
+ {
+ $this->failureproperty = $value;
+ }
+
+ function setErrorproperty($value)
+ {
+ $this->errorproperty = $value;
+ }
+
+ function setHaltonerror($value)
+ {
+ $this->haltonerror = $value;
+ }
+
+ function setHaltonfailure($value)
+ {
+ $this->haltonfailure = $value;
+ }
+
+ function setPrintsummary($printsummary)
+ {
+ $this->printsummary = $printsummary;
+ }
+
+ public function setDebug($debug)
+ {
+ $this->debug = $debug;
+ }
+
+ public function getDebug()
+ {
+ return $this->debug;
+ }
+
+ /**
+ * Add a new formatter to all tests of this task.
+ *
+ * @param SimpleTestFormatterElement formatter element
+ */
+ function addFormatter(SimpleTestFormatterElement $fe)
+ {
+ $this->formatters[] = $fe;
+ }
+
+ /**
+ * Add a new fileset containing the XML results to aggregate
+ *
+ * @param FileSet the new fileset containing XML results.
+ */
+ function addFileSet(FileSet $fileset)
+ {
+ $this->filesets[] = $fileset;
+ }
+
+ /**
+ * Iterate over all filesets and return the filename of all files
+ * that end with .php.
+ *
+ * @return array an array of filenames
+ */
+ private function getFilenames()
+ {
+ $filenames = array();
+
+ foreach ($this->filesets as $fileset)
+ {
+ $ds = $fileset->getDirectoryScanner($this->project);
+ $ds->scan();
+
+ $files = $ds->getIncludedFiles();
+
+ foreach ($files as $file)
+ {
+ if (strstr($file, ".php"))
+ {
+ $filenames[] = $ds->getBaseDir() . "/" . $file;
+ }
+ }
+ }
+
+ return $filenames;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $suite= new TestSuite();
+
+ $filenames = $this->getFilenames();
+
+ foreach ($filenames as $testfile)
+ {
+ $suite->addFile($testfile);
+ }
+
+ if ($this->debug)
+ {
+ $fe = new SimpleTestFormatterElement();
+ $fe->setType('debug');
+ $fe->setUseFile(false);
+ $this->formatters[] = $fe;
+ }
+
+ if ($this->printsummary)
+ {
+ $fe = new SimpleTestFormatterElement();
+ $fe->setType('summary');
+ $fe->setUseFile(false);
+ $this->formatters[] = $fe;
+ }
+
+ foreach ($this->formatters as $fe)
+ {
+ $formatter = $fe->getFormatter();
+ $formatter->setProject($this->getProject());
+
+ if ($fe->getUseFile())
+ {
+ $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
+
+ $writer = new FileWriter($destFile->getAbsolutePath());
+
+ $formatter->setOutput($writer);
+ }
+ else
+ {
+ $formatter->setOutput($this->getDefaultOutput());
+ }
+ }
+
+ $this->execute($suite);
+
+ if ($this->testfailed && $this->formatters[0]->getFormatter() instanceof SimpleTestDebugResultFormatter )
+ {
+ $this->getDefaultOutput()->write("Failed tests: ");
+ $this->formatters[0]->getFormatter()->printFailingTests();
+ }
+
+ if ($this->testfailed)
+ {
+ throw new BuildException("One or more tests failed");
+ }
+ }
+
+ private function execute($suite)
+ {
+ $counter = new SimpleTestCountResultFormatter();
+ $reporter = new MultipleReporter();
+ $reporter->attachReporter($counter);
+
+ foreach ($this->formatters as $fe)
+ {
+ // SimpleTest 1.0.1 workaround
+ $formatterList[] = $fe->getFormatter();
+
+ $reporter->attachReporter(end($formatterList));
+ }
+
+ $suite->run($reporter);
+
+ $retcode = $counter->getRetCode();
+
+ if ($retcode == SimpleTestCountResultFormatter::ERRORS)
+ {
+ if ($this->errorproperty)
+ {
+ $this->project->setNewProperty($this->errorproperty, true);
+ }
+
+ if ($this->haltonerror)
+ {
+ $this->testfailed = true;
+ }
+ }
+ elseif ($retcode == SimpleTestCountResultFormatter::FAILURES)
+ {
+ if ($this->failureproperty)
+ {
+ $this->project->setNewProperty($this->failureproperty, true);
+ }
+
+ if ($this->haltonfailure)
+ {
+ $this->testfailed = true;
+ }
+ }
+ }
+
+ private function getDefaultOutput()
+ {
+ return new LogWriter($this);
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php
index 66c4ccd8..5ffa668b 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SimpleTestPlainResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * $Id: 03b9f976a961a2688d51c9429087a98c31326f42 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -20,135 +20,159 @@
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
+require_once 'simpletest/xml.php';
/**
* Prints plain text output of the test to a specified Writer.
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SimpleTestPlainResultFormatter.php 59 2006-04-28 14:49:47Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 03b9f976a961a2688d51c9429087a98c31326f42 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestXmlResultFormatter extends SimpleTestResultFormatter
{
- private $results=array();
- private $currentSuite;
- private $currentTest;
- private $methodCounts=0;
- private $methodTime=0;
+ /**
+ * @var XmlReporter
+ */
+ private $logger = NULL;
+
+ private $xmlData = "";
- function paintFooter($test_name)
- {
- if($test_name=='GroupTest')
- $this->printXml($test_name);
+ function __construct()
+ {
+ $this->logger = new XmlReporter();
+ }
+
+ function getExtension()
+ {
+ return ".xml";
+ }
+
+ function getPreferredOutfile()
+ {
+ return "testsuites";
+ }
+
+ private function captureStart()
+ {
+ ob_start();
+ }
+
+ private function captureStop()
+ {
+ $this->xmlData .= ob_get_contents();
+ ob_end_clean();
}
- protected function printXml($test_name)
- {
- $suites = $this->printXmlSuites($this->results);
-$content = <<<EOD
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuites total="{$this->getRunCount()}" name="{$test_name}">
-$suites
-</testsuites>
-EOD;
- $this->out->write($content);
- }
+ function paintGroupStart($test_name, $size)
+ {
+ parent::paintGroupStart($test_name, $size);
+
+ $this->captureStart();
+ $this->logger->paintGroupStart($test_name, $size);
+ $this->captureStop();
+ }
+
+ function paintGroupEnd($test_name)
+ {
+ parent::paintGroupEnd($test_name);
+
+ $this->captureStart();
+ $this->logger->paintGroupEnd($test_name);
+ $this->captureStop();
- protected function printXmlSuites($results)
- {
- $contents = '';
- foreach($results as $suiteName => $suite)
- {
- $tests = $this->printXmlTests($suite['tests'],$suiteName);
-$contents .= <<<EOD
-<testsuite name="{$suiteName}" tests="{$suite['total']}" failures="{$suite['failures']}" errors="{$suite['errors']}" time="{$suite['time']}">
- $tests
-</testsuite>
-EOD;
- }
- return $contents;
- }
+ if (count($this->_test_stack) == 0)
+ {
+ if ($this->out)
+ {
+ $this->out->write($this->xmlData);
+ $this->out->close();
+ }
+ }
+ }
- protected function printXmlTests($tests,$suiteName)
- {
- $contents = '';
- foreach($tests as $name => $result)
- {
- if(count($result['results'])==0)
- {
- $contents .= <<<EOD
-<testcase name="{$name}" class="{$suiteName}" result="success" time="{$result['time']}"/>
-EOD;
- }
- else
- {
- $type = strtolower($result['results']['type']);
- $message = htmlspecialchars($result['results']['message']);
-$contents .= <<<EOD
-<testcase name="{$name}" class="{$suiteName}" result="{$type}" time="{$result['time']}">
- <{$type}>$message</{$type}>
-</testcase>
-EOD;
- }
- }
- return $contents;
- }
+ function paintCaseStart($test_name)
+ {
+ $this->captureStart();
+ $this->logger->paintCaseStart($test_name);
+ $this->captureStop();
+ }
+
+ function paintCaseEnd($test_name)
+ {
+ $this->captureStart();
+ $this->logger->paintCaseEnd($test_name);
+ $this->captureStop();
+ }
- function paintCaseStart($test_name)
- {
- parent::paintCaseStart($test_name);
- $this->results[$test_name] = array('tests'=>array());
- $this->currentSuite=$test_name;
- $this->methodCounts=0;
- }
+ function paintMethodStart($test_name)
+ {
+ $this->captureStart();
+ $this->logger->paintMethodStart($test_name);
+ $this->captureStop();
+ }
+
+ function paintMethodEnd($test_name)
+ {
+ $this->captureStart();
+ $this->logger->paintMethodEnd($test_name);
+ $this->captureStop();
+ }
- function paintCaseEnd($test_name)
- {
- parent::paintCaseEnd($test_name);
- $details = array(
- 'total' => $this->methodCounts,
- 'failures' => $this->getFailureCount(),
- 'errors' => $this->getErrorCount(),
- 'time' => $this->getElapsedTime());
+ function paintPass($message)
+ {
+ $this->captureStart();
+ $this->logger->paintPass($message);
+ $this->captureStop();
+ }
+
+ function paintError($message)
+ {
+ $this->captureStart();
+ $this->logger->paintError($message);
+ $this->captureStop();
+ }
- $this->results[$test_name] = array_merge($this->results[$test_name],$details);
- }
+ function paintFail($message)
+ {
+ $this->captureStart();
+ $this->logger->paintFail($message);
+ $this->captureStop();
+ }
- function paintMethodStart($test_name)
- {
- $this->currentTest=$test_name;
- parent::paintMethodStart($test_name);
- $this->results[$this->currentSuite]['tests'][$test_name]['results'] = array();
- $this->methodCounts++;
- $this->methodTime = new Timer();
- $this->methodTime->start();
- }
+ function paintException($exception)
+ {
+ $this->captureStart();
+ $this->logger->paintException($exception);
+ $this->captureStop();
+ }
- function paintMethodEnd($test_name)
- {
- parent::paintMethodEnd($test_name);
- $this->methodTime->stop();
- $this->results[$this->currentSuite]['tests'][$test_name]['time'] = $this->methodTime->getElapsedTime();
- }
+ function paintSkip($message)
+ {
+ $this->captureStart();
+ $this->logger->paintSkip($message);
+ $this->captureStop();
+ }
- function paintError($message)
- {
- parent::paintError($message);
- $this->formatError("ERROR", $message);
- }
+ function paintMessage($message)
+ {
+ $this->captureStart();
+ $this->logger->paintMessage($message);
+ $this->captureStop();
+ }
- function paintFail($message)
- {
- parent::paintFail($message);
- $this->formatError("FAILED", $message);
- }
+ function paintFormattedMessage($message)
+ {
+ $this->captureStart();
+ $this->logger->paintFormattedMessage($message);
+ $this->captureStop();
+ }
- private function formatError($type, $message)
- {
- $result = array('type'=>$type, 'message' => $message);
- $this->results[$this->currentSuite]['tests'][$this->currentTest]['results'] =
- $result;
- }
+ function paintSignal($type, $payload)
+ {
+ $this->captureStart();
+ $this->logger->paintSignal($type, $payload);
+ $this->captureStop();
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php
index 55c695cf..ed9cb276 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php
@@ -1,6 +1,6 @@
<?php
/*
- * $Id: SvnBaseTask.php 38 2006-03-09 14:05:11Z mrook $
+ * $Id: b6c644f650a69cad32ced1d030685a7a7a46251c $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -22,159 +22,326 @@
include_once 'phing/Task.php';
/**
- * Send a message by mail()
+ * Base class for Subversion tasks
*
- * <mail to="user@example.org" subject="build complete">The build process is a success...</mail>
- *
- * @author Francois Harvey at SecuriWeb (http://www.securiweb.net)
- * @version $Id: SvnBaseTask.php 38 2006-03-09 14:05:11Z mrook $
- * @package phing.tasks.ext
+ * @author Michiel Rook <mrook@php.net>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: b6c644f650a69cad32ced1d030685a7a7a46251c $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.2.0
*/
abstract class SvnBaseTask extends Task
{
- private $workingCopy = "";
-
- private $repositoryUrl = "";
-
- private $svnPath = "/usr/bin/svn";
-
- private $svn = NULL;
-
- private $mode = "";
-
- private $svnArgs = array();
+ private $workingCopy = "";
+
+ private $repositoryUrl = "";
+
+ private $svnPath = "/usr/bin/svn";
+
+ private $svn = NULL;
+
+ private $mode = "";
+
+ private $svnArgs = array();
+
+ private $svnSwitches = array();
- /**
- * Initialize Task.
- * This method includes any necessary SVN 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.
- */
- function init() {
- include_once 'VersionControl/SVN.php';
- if (!class_exists('VersionControl_SVN')) {
- throw new Exception("SvnLastRevisionTask depends on PEAR VersionControl_SVN package being installed.");
- }
- }
+ private $toDir = "";
+
+ protected $fetchMode = VERSIONCONTROL_SVN_FETCHMODE_ASSOC;
- /**
- * Sets the path to the workingcopy
- */
- function setWorkingCopy($workingCopy)
- {
- $this->workingCopy = $workingCopy;
- }
+ /**
+ * Initialize Task.
+ * This method includes any necessary SVN 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.
+ */
+ function init() {
+ include_once 'VersionControl/SVN.php';
+ if (!class_exists('VersionControl_SVN')) {
+ throw new Exception("The SVN tasks depend on PEAR VersionControl_SVN package being installed.");
+ }
+ }
- /**
- * Returns the path to the workingcopy
- */
- function getWorkingCopy()
- {
- return $this->workingCopy;
- }
+ /**
+ * Sets the path to the workingcopy
+ */
+ function setWorkingCopy($workingCopy)
+ {
+ $this->workingCopy = $workingCopy;
+ }
- /**
- * Sets the path/URI to the repository
- */
- function setRepositoryUrl($repositoryUrl)
- {
- $this->repositoryUrl = $repositoryUrl;
- }
+ /**
+ * Returns the path to the workingcopy
+ */
+ function getWorkingCopy()
+ {
+ return $this->workingCopy;
+ }
- /**
- * Returns the path/URI to the repository
- */
- function getRepositoryUrl()
- {
- return $this->repositoryUrl;
- }
+ /**
+ * Sets the path/URI to the repository
+ */
+ function setRepositoryUrl($repositoryUrl)
+ {
+ $this->repositoryUrl = $repositoryUrl;
+ }
- /**
- * Sets the path to the SVN executable
- */
- function setSvnPath($svnPath)
- {
- $this->svnPath = $svnPath;
- }
+ /**
+ * Returns the path/URI to the repository
+ */
+ function getRepositoryUrl()
+ {
+ return $this->repositoryUrl;
+ }
+ /**
+ * Sets the path to the SVN executable
+ */
+ function setSvnPath($svnPath)
+ {
+ $this->svnPath = $svnPath;
+ }
+
+ /**
+ * Returns the path to the SVN executable
+ */
+ function getSvnPath()
+ {
+ return $this->svnPath;
+ }
+
+ //
+ // Args
+ //
+
+ /**
+ * Sets the path to export/checkout to
+ */
+ function setToDir($toDir)
+ {
+ $this->toDir = $toDir;
+ }
+
+ /**
+ * Returns the path to export/checkout to
+ */
+ function getToDir()
+ {
+ return $this->toDir;
+ }
+
+ //
+ // Switches
+ //
+
+ /**
+ * Sets the force switch
+ */
+ function setForce($value)
+ {
+ $this->svnSwitches['force'] = $value;
+ }
+
+ /**
+ * Returns the force switch
+ */
+ function getForce()
+ {
+ return isset( $this->svnSwitches['force'] ) ? $this->svnSwitches['force'] : '';
+ }
+
+ /**
+ * Sets the username of the user to export
+ */
+ function setUsername($value)
+ {
+ $this->svnSwitches['username'] = $value;
+ }
+
+ /**
+ * Returns the username
+ */
+ function getUsername()
+ {
+ return isset( $this->svnSwitches['username'] ) ? $this->svnSwitches['username'] : '';
+ }
+
+ /**
+ * Sets the password of the user to export
+ */
+ function setPassword($value)
+ {
+ $this->svnSwitches['password'] = $value;
+ }
+
+ /**
+ * Returns the password
+ */
+ function getPassword()
+ {
+ return isset( $this->svnSwitches['password'] ) ? $this->svnSwitches['password'] : '';
+ }
+
+ /**
+ * Sets the no-auth-cache switch
+ */
+ function setNoCache($value)
+ {
+ $this->svnSwitches['no-auth-cache'] = $value;
+ }
+
+ /**
+ * Returns the no-auth-cache switch
+ */
+ function getNoCache()
+ {
+ return isset( $this->svnSwitches['no-auth-cache'] ) ? $this->svnSwitches['no-auth-cache'] : '';
+ }
+
+ /**
+ * Sets the non-recursive switch
+ */
+ function setRecursive($value)
+ {
+ $this->svnSwitches['non-recursive'] = is_bool($value) ? !$value : true;
+ }
+
+ /**
+ * Returns the non-recursive switch
+ */
+ function getRecursive()
+ {
+ return isset( $this->svnSwitches['non-recursive'] ) ? !$this->svnSwitches['non-recursive'] : true;
+ }
+
+ /**
+ * Sets the ignore-externals switch
+ */
+ function setIgnoreExternals($value)
+ {
+ $this->svnSwitches['ignore-externals'] = $value;
+ }
+
+ /**
+ * Returns the ignore-externals switch
+ */
+ function getIgnoreExternals()
+ {
+ return isset( $this->svnSwitches['ignore-externals'] ) ? $this->svnSwitches['ignore-externals'] : '';
+ }
+
/**
- * Returns the path to the SVN executable
- */
- function getSvnPath()
- {
- return $this->svnPath;
- }
-
- /**
- * Creates a VersionControl_SVN class based on $mode
- *
- * @param string The SVN mode to use (info, export, checkout, ...)
- * @throws BuildException
- */
- protected function setup($mode)
- {
- $this->mode = $mode;
-
- // Set up runtime options. Will be passed to all
- // subclasses.
- $options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_ASSOC, 'svn_path' => $this->getSvnPath());
-
- // Pass array of subcommands we need to factory
- $this->svn = VersionControl_SVN::factory($mode, $options);
-
- if (!empty($this->repositoryUrl))
- {
- $this->svnArgs = array($this->repositoryUrl);
- }
- else
- if (!empty($this->workingCopy))
- {
- if (is_dir($this->workingCopy))
- {
- if (in_array(".svn", scandir($this->workingCopy)))
- {
- $this->svnArgs = array($this->workingCopy);
- }
- else
- {
- throw new BuildException("'".$this->workingCopy."' doesn't seem to be a working copy");
- }
- }
- else
- {
- throw new BuildException("'".$this->workingCopy."' is not a directory");
- }
- }
- }
-
- /**
- * Executes the constructed VersionControl_SVN instance
- *
- * @param array Additional arguments to pass to SVN.
- * @param array Switches to pass to SVN.
- * @return string Output generated by SVN.
- */
- protected function run($args = array(), $switches = array())
- {
- $svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN');
-
- $tempArgs = $this->svnArgs;
-
- $tempArgs = array_merge($tempArgs, $args);
-
- if ($output = $this->svn->run($tempArgs, $switches))
- {
- return $output;
- }
- else
- {
- if (count($errs = $svnstack->getErrors()))
- {
- $err = current($errs);
-
- throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $err['message']);
- }
- }
- }
+ * Sets the trust-server-cert switch
+ */
+ public function setTrustServerCert($value)
+ {
+ $this->svnSwitches['trust-server-cert'] = $value;
+ }
+
+ /**
+ * Returns the trust-server-cert switch
+ */
+ public function getTrustServerCert()
+ {
+ return isset($this->svnSwitches['trust-server-cert']) ? $this->svnSwitches['trust-server-cert'] : '';
+ }
+
+ /**
+ * Creates a VersionControl_SVN class based on $mode
+ *
+ * @param string The SVN mode to use (info, export, checkout, ...)
+ * @throws BuildException
+ */
+ protected function setup($mode)
+ {
+ $this->mode = $mode;
+
+ // Set up runtime options. Will be passed to all
+ // subclasses.
+ $options = array('fetchmode' => $this->fetchMode, 'svn_path' => $this->getSvnPath());
+
+ // Pass array of subcommands we need to factory
+ $this->svn = VersionControl_SVN::factory($mode, $options);
+
+ $this->svn->use_escapeshellcmd = false;
+
+ if (!empty($this->repositoryUrl))
+ {
+ $this->svnArgs = array($this->repositoryUrl);
+ }
+ else
+ if (!empty($this->workingCopy))
+ {
+ if (is_dir($this->workingCopy))
+ {
+ if (in_array(".svn", scandir($this->workingCopy)))
+ {
+ $this->svnArgs = array($this->workingCopy);
+ }
+ else
+ {
+ throw new BuildException("'".$this->workingCopy."' doesn't seem to be a working copy");
+ }
+ }
+ else
+ if ($mode=='info' )
+ {
+ if (is_file($this->workingCopy))
+ {
+ $this->svnArgs = array($this->workingCopy);
+ }
+ else
+ {
+ throw new BuildException("'".$this->workingCopy."' is not a directory nor a file");
+ }
+ }
+ else
+ {
+ throw new BuildException("'".$this->workingCopy."' is not a directory");
+ }
+ }
+ }
+
+ /**
+ * Executes the constructed VersionControl_SVN instance
+ *
+ * @param array Additional arguments to pass to SVN.
+ * @param array Switches to pass to SVN.
+ * @return string Output generated by SVN.
+ */
+ protected function run($args = array(), $switches = array())
+ {
+ $svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN');
+
+ $tempArgs = $this->svnArgs;
+
+ $tempArgs = array_merge($tempArgs, $args);
+
+ $tempSwitches = $this->svnSwitches;
+
+ $tempSwitches = array_merge($tempSwitches, $switches);
+
+ if ($output = $this->svn->run($tempArgs, $tempSwitches))
+ {
+ return $output;
+ }
+ else
+ {
+ if (count($errs = $svnstack->getErrors()))
+ {
+ $err = current($errs);
+
+ $errorMessage = $err['message'];
+
+ if (isset($err['params']['errstr'])) {
+ $errorMessage = $err['params']['errstr'];
+ }
+
+ throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $errorMessage);
+ }
+ }
+ }
}
-?> \ No newline at end of file
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php
new file mode 100644
index 00000000..76dc976a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * $Id: f8844430c9e30d1c603452d8763fbd1114d80051 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Checks out a repository to a local directory
+ *
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: f8844430c9e30d1c603452d8763fbd1114d80051 $
+ * @package phing.tasks.ext.svn
+ * @since 2.3.0
+ */
+class SvnCheckoutTask extends SvnBaseTask
+{
+ /**
+ * Which Revision to Export
+ *
+ * @todo check if version_control_svn supports constants
+ *
+ * @var string
+ */
+ private $revision = 'HEAD';
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('checkout');
+
+ $this->log("Checking out SVN repository to '" . $this->getToDir() . "'". ($this->revision=='HEAD'?'':" (revision: {$this->revision})"));
+
+ // revision
+ $switches = array(
+ 'r' => $this->revision,
+ );
+
+ $this->run(array($this->getToDir()), $switches);
+ }
+
+ public function setRevision($revision)
+ {
+ $this->revision = $revision;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCommitTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCommitTask.php
new file mode 100644
index 00000000..7eb1ce7a
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCommitTask.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * $Id: 6fdb36b57778f5c0cd46110fd36c8c261ced0e86 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Commits changes in a local working copy to the repository
+ *
+ * @author Johan Persson <johanp@aditus.nu>
+ * @version $Id: 6fdb36b57778f5c0cd46110fd36c8c261ced0e86 $
+ * @package phing.tasks.ext.svn
+ * @since 2.4.0
+ */
+class SvnCommitTask extends SvnBaseTask
+{
+ /**
+ * Commit message
+ */
+ private $message = '';
+
+ /**
+ * Property name where we store the revision number of the just
+ * commited version.
+ */
+ private $propertyName = "svn.committedrevision";
+
+ /**
+ * Sets the commit message
+ */
+ function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+ /**
+ * Gets the commit message
+ */
+ function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Sets the name of the property to use for returned revision
+ */
+ function setPropertyName($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
+
+ /**
+ * Returns the name of the property to use for returned revision
+ */
+ function getPropertyName()
+ {
+ return $this->propertyName;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ if( trim($this->message) === '' )
+ {
+ throw new BuildException('SVN Commit message can not be empty.');
+ }
+
+ $this->setup('commit');
+
+ $this->log("Commiting SVN working copy at '" . $this->getWorkingCopy() . "' with message '".$this->GetMessage()."'");
+
+ $output = $this->run(array(), array('message' => $this->GetMessage() ) );
+
+ if( preg_match('/[\s]*Committed revision[\s]+([\d]+)/', $output, $matches) )
+ {
+ $this->project->setProperty($this->getPropertyName(), $matches[1]);
+ }
+ else
+ {
+ /**
+ * If no new revision was committed set revision to "empty". Remember that
+ * this is not necessarily an error. It could be that the specified working
+ * copy is identical to to the copy in the repository and in that case
+ * there will be no update and no new revision number.
+ */
+ $this->project->setProperty($this->getPropertyName(), '' );
+ }
+
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCopyTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCopyTask.php
new file mode 100644
index 00000000..c1eb7089
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnCopyTask.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Copies a repository from the repository url to another
+ *
+ * @version $Id: 6f39598901c83ecaf8e7fcb9d4065f70b38324cb $
+ * @package phing.tasks.ext.svn
+ * @since 2.3.0
+ */
+class SvnCopyTask extends SvnBaseTask
+{
+ private $message = "";
+
+ /**
+ * Sets the message
+ */
+ function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+ /**
+ * Gets the message
+ */
+ function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('copy');
+
+ $this->log("Copying SVN repository from '" . $this->getRepositoryUrl() . "' to '" . $this->getToDir() . "'");
+
+ $options = array();
+
+ if (strlen($this->getMessage()) > 0) {
+ $options['message'] = $this->getMessage();
+ }
+
+ $this->run(array($this->getToDir()), $options);
+ }
+}
+
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnExportTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnExportTask.php
index 7cb6c897..e0b2e78b 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnExportTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnExportTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SvnExportTask.php 37 2006-03-09 14:04:22Z mrook $
+ * $Id: ca2d150a53b870fe410f5434f4d500decc7cda73 $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,45 +24,47 @@ require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
/**
* Exports/checks out a repository to a local directory
+ * with authentication
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SvnExportTask.php 37 2006-03-09 14:04:22Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: ca2d150a53b870fe410f5434f4d500decc7cda73 $
* @package phing.tasks.ext.svn
- * @see VersionControl_SVN
- * @since 2.1.0
+ * @since 2.2.0
*/
class SvnExportTask extends SvnBaseTask
{
- private $toDir = "";
+ /**
+ * Which Revision to Export
+ *
+ * @todo check if version_control_svn supports constants
+ *
+ * @var string
+ */
+ private $revision = 'HEAD';
- /**
- * Sets the path to export/checkout to
- */
- function setToDir($toDir)
- {
- $this->toDir = $toDir;
- }
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('export');
+
+ $this->log("Exporting SVN repository to '" . $this->getToDir() . "'");
- /**
- * Returns the path to export/checkout to
- */
- function getToDir()
- {
- return $this->toDir;
- }
+ $switches = array();
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $this->setup('export');
-
- $this->log("Exporting SVN repository to '" . $this->toDir . "'");
-
- $this->run(array($this->toDir));
- }
+ if (!empty($this->revision)) {
+ $switches['r'] = $this->revision;
+ }
+
+ $this->run(array($this->getToDir()), $switches);
+ }
+
+ public function setRevision($revision)
+ {
+ $this->revision = $revision;
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnInfoTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnInfoTask.php
new file mode 100644
index 00000000..68111d74
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnInfoTask.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * $Id: 36ffb2ececed4c83c9ca7ad3674b3fa11074f2a5 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Parses the output of 'svn info --xml' and
+ *
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 36ffb2ececed4c83c9ca7ad3674b3fa11074f2a5 $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.4.9
+ */
+class SvnInfoTask extends SvnBaseTask
+{
+ private $propertyName = "svn.info";
+
+ private $element = 'url';
+ private $subElement = null;
+
+ /**
+ * Sets the name of the property to use
+ */
+ public function setPropertyName($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
+
+ /**
+ * Returns the name of the property to use
+ */
+ public function getPropertyName()
+ {
+ return $this->propertyName;
+ }
+
+ /**
+ * Sets the name of the xml element to use
+ */
+ public function setElement($element)
+ {
+ $this->element = $element;
+ }
+
+ /**
+ * Returns the name of the xml element to use
+ */
+ public function getElement()
+ {
+ return $this->element;
+ }
+
+ /**
+ * Sets the name of the xml sub element to use
+ */
+ public function setSubElement($subElement)
+ {
+ $this->subElement = $subElement;
+ }
+
+ /**
+ * Returns the name of the xml sub element to use
+ */
+ public function getSubElement()
+ {
+ return $this->subElement;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('info');
+
+ $output = $this->run(array('--xml', '--incremental'));
+
+ if ($xmlObj = @simplexml_load_string($output)) {
+ $object = $xmlObj->{$this->element};
+
+ if (!empty($this->subElement)) {
+ $object = $object->{$this->subElement};
+ }
+
+ $this->project->setProperty($this->getPropertyName(), (string) $object);
+ } else {
+ throw new BuildException("Failed to parse the output of 'svn info --xml'.");
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php
index e45ac50c..7305c27b 100644..100755
--- a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php
@@ -1,6 +1,6 @@
<?php
/**
- * $Id: SvnLastRevisionTask.php 37 2006-03-09 14:04:22Z mrook $
+ * $Id: 74d61db8c11978a2383f071b7ab7ed0afae6953c $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -25,51 +25,96 @@ require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
/**
* Stores the number of the last revision of a workingcopy in a property
*
- * @author Michiel Rook <michiel@trendserver.nl>
- * @version $Id: SvnLastRevisionTask.php 37 2006-03-09 14:04:22Z mrook $
+ * @author Michiel Rook <mrook@php.net>
+ * @version $Id: 74d61db8c11978a2383f071b7ab7ed0afae6953c $
* @package phing.tasks.ext.svn
* @see VersionControl_SVN
* @since 2.1.0
*/
class SvnLastRevisionTask extends SvnBaseTask
{
- private $propertyName = "svn.lastrevision";
+ private $propertyName = "svn.lastrevision";
+ private $forceCompatible = false;
+ private $lastChanged = false;
- /**
- * Sets the name of the property to use
- */
- function setPropertyName($propertyName)
- {
- $this->propertyName = $propertyName;
- }
+ /**
+ * Sets the name of the property to use
+ */
+ function setPropertyName($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
- /**
- * Returns the name of the property to use
- */
- function getPropertyName()
- {
- return $this->propertyName;
- }
+ /**
+ * Returns the name of the property to use
+ */
+ function getPropertyName()
+ {
+ return $this->propertyName;
+ }
+
+ /**
+ * Sets whether to force compatibility with older SVN versions (< 1.2)
+ */
+ public function setForceCompatible($force)
+ {
+ $this->forceCompatible = (bool) $force;
+ }
+
+ /**
+ * Sets whether to retrieve the last changed revision
+ */
+ public function setLastChanged($lastChanged)
+ {
+ $this->lastChanged = (bool) $lastChanged;
+ }
- /**
- * The main entry point
- *
- * @throws BuildException
- */
- function main()
- {
- $this->setup('info');
-
- $output = $this->run();
-
- if (preg_match('/Rev:[\s]+([\d]+)/', $output, $matches))
- {
- $this->project->setProperty($this->getPropertyName(), $matches[1]);
- }
- else
- {
- throw new BuildException("Failed to parse the output of 'svn info'.");
- }
- }
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('info');
+
+ if ($this->forceCompatible)
+ {
+ $output = $this->run();
+
+ if ($this->lastChanged) {
+ $found = preg_match('/Rev:[\s]+([\d]+)/', $output, $matches);
+ } else {
+ $found = preg_match('/Last Changed Rev:[\s]+([\d]+)/', $output, $matches);
+ }
+
+ if ($found)
+ {
+ $this->project->setProperty($this->getPropertyName(), $matches[1]);
+ }
+ else
+ {
+ throw new BuildException("Failed to parse the output of 'svn info'.");
+ }
+ }
+ else
+ {
+ $output = $this->run(array('--xml'));
+
+ if ($xmlObj = @simplexml_load_string($output))
+ {
+ if ($this->lastChanged) {
+ $lastRevision = (int)$xmlObj->entry->commit['revision'];
+ } else {
+ $lastRevision = (int)$xmlObj->entry['revision'];
+ }
+
+ $this->project->setProperty($this->getPropertyName(), $lastRevision);
+ }
+ else
+ {
+ throw new BuildException("Failed to parse the output of 'svn info --xml'.");
+ }
+ }
+ }
}
-?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnListTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnListTask.php
new file mode 100755
index 00000000..63d8445c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnListTask.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * $Id: 5dfcc23bc58efaad0eb11ef4964bcd7be0fb99e9 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Stores the output of a list command on a workingcopy or repositoryurl in a property.
+ * This stems from the SvnLastRevisionTask.
+ *
+ * @author Anton Stöckl <anton@stoeckl.de>
+ * @author Michiel Rook <mrook@php.net> (SvnLastRevisionTask)
+ * @version $Id: 5dfcc23bc58efaad0eb11ef4964bcd7be0fb99e9 $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.1.0
+ */
+class SvnListTask extends SvnBaseTask
+{
+ private $propertyName = "svn.list";
+ private $forceCompatible = true;
+ private $limit = null;
+ private $orderDescending = false;
+
+ /**
+ * Sets the name of the property to use
+ */
+ function setPropertyName($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
+
+ /**
+ * Returns the name of the property to use
+ */
+ function getPropertyName()
+ {
+ return $this->propertyName;
+ }
+
+ /**
+ * Sets whether to force compatibility with older SVN versions (< 1.2)
+ */
+ public function setForceCompatible($force)
+ {
+ //$this->forceCompatible = (bool) $force;
+ // see below, we need this to be true as xml mode does not work
+ }
+
+ /**
+ * Sets the max num of tags to display
+ */
+ function setLimit($limit)
+ {
+ $this->limit = (int) $limit;
+ }
+
+ /**
+ * Sets whether to sort tags in descending order
+ */
+ function setOrderDescending($orderDescending)
+ {
+ $this->orderDescending = (bool) $orderDescending;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('list');
+
+ if ($this->forceCompatible) {
+ $output = $this->run(array('--verbose'));
+ $result = null;
+
+ $lines = $output['.']['name'];
+
+ if ($this->orderDescending) {
+ $lines = array_reverse($lines);
+ }
+
+ $count = 0;
+ foreach ($lines as $line) {
+ if ($this->limit > 0 && $count >= $this->limit) {
+ break;
+ }
+ if (preg_match('@\s+(\d+)\s+(\S+)\s+(\S+ \S+ \S+)\s+(\S+)@', $line, $matches)) {
+ if ($matches[4] == '.') {
+ continue;
+ }
+ $result .= (!empty($result)) ? "\n" : '';
+ $result .= $matches[1] . ' | ' . $matches[2] . ' | ' . $matches[3] . ' | ' . $matches[4];
+ $count++;
+ }
+ }
+
+ if (!empty($result)) {
+ $this->project->setProperty($this->getPropertyName(), $result);
+ } else {
+ throw new BuildException("Failed to parse the output of 'svn list --verbose'.");
+ }
+ } else {
+ // this is not possible at the moment as SvnBaseTask always uses fetchmode ASSOC
+ // which transfers everything into nasty assoc array instead of xml
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLogTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLogTask.php
new file mode 100755
index 00000000..7f5c4025
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnLogTask.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * $Id: fc8bc4cf4caa997c13dd66095997fa5478c47959 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Stores the output of a log command on a workingcopy or repositoryurl in a property.
+ * This stems from the SvnLastRevisionTask.
+ *
+ * @author Anton Stöckl <anton@stoeckl.de>
+ * @author Michiel Rook <mrook@php.net> (SvnLastRevisionTask)
+ * @version $Id: fc8bc4cf4caa997c13dd66095997fa5478c47959 $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.1.0
+ */
+class SvnLogTask extends SvnBaseTask
+{
+ private $propertyName = "svn.log";
+ private $forceCompatible = true;
+ private $limit = null;
+
+ /**
+ * Sets the name of the property to use
+ */
+ function setPropertyName($propertyName)
+ {
+ $this->propertyName = $propertyName;
+ }
+
+ /**
+ * Returns the name of the property to use
+ */
+ function getPropertyName()
+ {
+ return $this->propertyName;
+ }
+
+ /**
+ * Sets whether to force compatibility with older SVN versions (< 1.2)
+ */
+ public function setForceCompatible($force)
+ {
+ //$this->forceCompatible = (bool) $force;
+ // see below, we need this to be true as xml mode does not work
+ }
+
+ /**
+ * Sets the max num of log entries to get from svn
+ */
+ function setLimit($limit)
+ {
+ $this->limit = (int) $limit;
+ }
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('log');
+
+ $switches= array();
+ if ($this->limit > 0) {
+ $switches['limit'] = $this->limit;
+ }
+
+ if ($this->forceCompatible) {
+ $output = $this->run(array(), $switches);
+ $result = null;
+
+ foreach ($output as $line) {
+ $result .= (!empty($result)) ? "\n" : '';
+ $result .= "{$line['REVISION']} | {$line['AUTHOR']} | {$line['DATE']} | {$line['MSG']}";
+ }
+
+ if (!empty($result)) {
+ $this->project->setProperty($this->getPropertyName(), $result);
+ } else {
+ throw new BuildException("Failed to parse the output of 'svn log'.");
+ }
+ } else {
+ // this is not possible at the moment as SvnBaseTask always uses fetchmode ASSOC
+ // which transfers everything into nasty assoc array instead of xml
+ }
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnSwitchTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnSwitchTask.php
new file mode 100644
index 00000000..cb6c5ca4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnSwitchTask.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * $Id: 2beb14d928ee47f36cceb9467b4a2ac9d2c81ef4 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Switches a repository at a given local directory to a different location
+ *
+ * @author Dom Udall <dom.udall@clock.co.uk>
+ * @version $Id: 2beb14d928ee47f36cceb9467b4a2ac9d2c81ef4 $
+ * @package phing.tasks.ext.svn
+ * @since 2.4.3
+ */
+class SvnSwitchTask extends SvnBaseTask
+{
+ /**
+ * Which Revision to Export
+ *
+ * @todo check if version_control_svn supports constants
+ *
+ * @var string
+ */
+ private $revision = 'HEAD';
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('switch');
+
+ $this->log("Switching SVN repository at '" . $this->getToDir() . "' to '" . $this->getRepositoryUrl() . "' "
+ . ($this->getRevision()=='HEAD'?'':" (revision: {$this->getRevision()})"));
+
+ // revision
+ $switches = array(
+ 'r' => $this->getRevision(),
+ );
+
+ $this->run(array($this->getToDir()), $switches);
+ }
+
+ public function setRevision($revision)
+ {
+ $this->revision = $revision;
+ }
+
+ public function getRevision()
+ {
+ return $this->revision;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php
new file mode 100644
index 00000000..c70039fc
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * $Id: 9f5e4de2948b03eb6c9e459b1065bcedd851c025 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Updates a repository in local directory
+ *
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: 9f5e4de2948b03eb6c9e459b1065bcedd851c025 $
+ * @package phing.tasks.ext.svn
+ * @since 2.3.0
+ */
+class SvnUpdateTask extends SvnBaseTask
+{
+ /**
+ * Which Revision to Export
+ *
+ * @todo check if version_control_svn supports constants
+ *
+ * @var string
+ */
+ private $revision = 'HEAD';
+
+ /**
+ * The main entry point
+ *
+ * @throws BuildException
+ */
+ function main()
+ {
+ $this->setup('update');
+
+ $this->log("Updating SVN repository at '" . $this->getToDir() . "'". ($this->revision=='HEAD'?'':" (revision: {$this->revision})"));
+
+ // revision
+ $switches = array(
+ 'r' => $this->revision,
+ );
+
+ $this->run(array($this->getToDir()), $switches);
+ }
+
+ public function setRevision($revision)
+ {
+ $this->revision = $revision;
+ }
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardEncodeTask.php b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardEncodeTask.php
new file mode 100644
index 00000000..33d2e4e3
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardEncodeTask.php
@@ -0,0 +1,510 @@
+<?php
+
+/*
+ * $Id: cdbb2883ab70c650896a465a872b3da30f13eb00 $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+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 <petr@rynawe.net>
+ * @version $Id: cdbb2883ab70c650896a465a872b3da30f13eb00 $
+ * @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 <input_file>.<renameSourceExt> and save the encoded file in its
+ * place.
+ *
+ * If specified deleteSource will be automatically disabled.
+ *
+ * @var string
+ */
+ protected $renameSourceExt = null;
+ /**
+ * Turns short PHP tag (“<?” ) recognition either on or off.
+ * On or off must be specified as an argument when using this option.
+ * The default, when option is not used in the command-line, is - on
+ *
+ * @var bool
+ */
+ protected $shortTags = true;
+ /**
+ * Turn ASP tag (“<%” ) recognition on/off. (default: off). On or off must be specified
+ * as an argument when using this option.
+ * The default, when this option is not used in the command-line, is - off
+ *
+ * @var bool
+ */
+ protected $aspTags = false;
+ /**
+ *
+ * Disables the PHP-compatible header that is added to the top of every encoded file
+ * by default. Encoded files generated with this option will not display a meaningful
+ * error when loaded by PHP that doesn't have the Zend Optimizer properly installed.
+ * Using this option saves approximately 1.5KB for every encoded file. Do not use it
+ * unless disk space constraints are critica
+ *
+ * @var bool
+ */
+ protected $noHeader = false;
+ /**
+ * If cryptography should be used to encode the source code
+ *
+ * @var bool
+ */
+ protected $useCrypto = false;
+ /**
+ * Force cooperation with other encoded files only. This option generates files that
+ * work exclusively with associated encoded files. Associated encoded files are
+ * those generated by the same company. Files that do not share the same encoded
+ * company association cannot call these files
+ *
+ * @var bool
+ */
+ protected $encodedOnly = false;
+ /**
+ * Allow encoding previously encoded files. (NOT recommended!)
+ *
+ * @var bool
+ */
+ protected $forceEncode = false;
+ /**
+ * Make an encoded file to expire on the given date. Date is in yyyy-mm-dd format.
+ *
+ * @var string
+ */
+ protected $expires = null;
+ /**
+ * Level of obfuscation. Defaults to 0 (no obfuscation).
+ *
+ * @var int
+ */
+ protected $obfuscationLevel = 0;
+ /**
+ * Optimization mask. (default value: [+++++++])
+ * opt_mask is an integer representing a bit-mask.
+ * The default value enables all of the optimization passes.
+ * Each optimization pass of the Zend Optimizer can be turned on or off based on
+ * the mask entered
+ *
+ * @var int
+ */
+ protected $optMask = null;
+ /**
+ * Path to the zend encoder binary
+ *
+ * @var string
+ */
+ protected $zendEncoderPath = null;
+ /**
+ * Path to private key for licensing
+ *
+ * @var string
+ */
+ protected $privateKeyPath = null;
+ /**
+ * Enable licensing.
+ * If enabled, productName must be defined.
+ *
+ * @var bool
+ */
+ protected $licenseProduct = false;
+ /**
+ * If true the ownership, permissions and timestamps
+ * of the encoded files won't be preserved.
+ *
+ * @var bool
+ */
+ protected $ignoreFileModes = false;
+ /**
+ * Enable signing
+ * If enabled, productName must be defined.
+ *
+ * @var bool
+ */
+ protected $signProduct = false;
+ /**
+ * Product name. Must be defined if licenseProduct
+ * or signProduct is set to 1
+ *
+ * @var string
+ */
+ protected $productName = null;
+ /**
+ * Embed the information in the specified file into the header of the encoded file
+ * (overrides noHeader)
+ *
+ * @var string
+ */
+ protected $prologFile = null;
+
+ /**
+ * TASK PROPERTIES SETTERS
+ */
+ public function setZendEncoderPath($value)
+ {
+ $this->zendEncoderPath = $value;
+ }
+
+ public function setPrivateKeyPath($value)
+ {
+ $this->privateKeyPath = $value;
+ }
+
+ public function setShortTags($value)
+ {
+ $this->shortTags = (bool) $value;
+ }
+
+ public function setAspTags($value)
+ {
+ $this->aspTags = (bool) $value;
+ }
+
+ public function setDeleteSource($value)
+ {
+ $this->shortTags = (bool) $value;
+ }
+
+ public function setUseCrypto($value)
+ {
+ $this->useCrypto = (bool) $value;
+ }
+
+ public function setObfuscationLevel($value)
+ {
+ $this->obfuscationLevel = (int) $value;
+ }
+
+ public function setLicenseProduct($value)
+ {
+ $this->licenseProduct = (bool) $value;
+ }
+
+ public function setPrologFile($value)
+ {
+ $this->prologFile = $value;
+ }
+
+ public function setSignProduct($value)
+ {
+ $this->signProduct = (bool) $value;
+ }
+
+ public function setForceEncode($value)
+ {
+ $this->forceEncode = (bool) $value;
+ }
+
+ public function setEncodedOnly($value)
+ {
+ $this->encodedOnly = (bool) $value;
+ }
+
+ public function setIgnoreFileModes($value)
+ {
+ $this->ignoreFileModes = (bool) $value;
+ }
+
+ public function setExpires($value)
+ {
+ $this->expires = $value;
+ }
+
+ public function setProductName($value)
+ {
+ $this->productName = $value;
+ }
+
+ public function setOptMask($value)
+ {
+ $this->optMask = (int) $value;
+ }
+
+ public function setRenameSourceExt($value)
+ {
+ $this->renameSourceExt = $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 . " \\\n";
+
+ if (!empty($this->renameSourceExt)) {
+ $command .= " --rename-source " . $this->renameSourceExt . " \\\n";
+ } elseif ($this->deleteSource) {
+ // delete source
+ $command .= " --delete-source \\\n";
+ }
+
+ // short tags
+ $command .= " --short-tags " . (($this->shortTags) ? 'on' : 'off') . " \\\n";
+
+ // asp tags
+ $command .= " --asp-tags " . (($this->aspTags) ? 'on' : 'off') . " \\\n";
+
+ // use crypto
+ if ($this->useCrypto) {
+ $command .= " --use-crypto \\\n";
+ }
+
+ // ignore file modes
+ if ($this->ignoreFileModes) {
+ $command .= " --ignore-file-modes \\\n";
+ }
+
+ // force encode
+ if ($this->forceEncode) {
+ $command .= " --force-encode \\\n";
+ }
+
+ // expires
+ if (!empty($this->expires)) {
+ $command .= " --expires " . $this->expires . " \\\n";
+ }
+
+ // insert prolog file name or no-header
+ if (!empty($this->prologFile)) {
+ $command .= " --prolog-filename " . $this->prologFile . " \\\n";
+ } elseif ($this->noHeader) {
+ // no-header
+ $command .= " --no-header \\\n";
+ }
+
+ // obfuscation level
+ if ($this->obfuscationLevel > 0) {
+ $command .= " --obfuscation-level " . $this->obfuscationLevel . " \\\n";
+ }
+
+ // encoded only
+ if ($this->encodedOnly) {
+ $command .= " --encoded-only \\\n";
+ }
+
+ // opt mask
+ if (null !== $this->optMask) {
+ $command .= " --optimizations " . $this->optMask . " \\\n";
+ }
+
+ // Signing or licensing
+ if ($this->signProduct) {
+ $command .= " --sign-product " . $this->productName . " --private-key " . $this->privateKeyPath . " \\\n";
+ } elseif ($this->licenseProduct) {
+ $command .= " --license-product " . $this->productName . " --private-key " . $this->privateKeyPath . " \\\n";
+ }
+
+ // 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
+ */
+ 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.
+ * @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;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php
new file mode 100644
index 00000000..2a3f71ca
--- /dev/null
+++ b/buildscripts/phing/classes/phing/tasks/ext/zendguard/ZendGuardLicenseTask.php
@@ -0,0 +1,524 @@
+<?php
+
+/*
+ * $Id: 96af59b9cbecaf7f146dffab1d0b5a806a56b47f $
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * 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 <petr@rynawe.net>
+ * @version $Id: 96af59b9cbecaf7f146dffab1d0b5a806a56b47f $
+ * @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;
+
+
+ public function setLicenseTemplate($value)
+ {
+ $this->licenseTemplate = $value;
+ }
+
+ public function setProductName($productName)
+ {
+ $this->productName = $productName;
+ }
+
+ 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
+ *
+ * @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);
+ }
+ }
+
+ public function setIpRange($iprange)
+ {
+ $this->ipRange = $iprange;
+ }
+
+ public function setHostID($hostID)
+ {
+ $this->hostID = $hostID;
+ }
+
+ public function setHardwareLocked($hardwareLocked)
+ {
+ $this->hardwareLocked = (bool) $hardwareLocked;
+ }
+
+ public function setUserDefinedValues($userDefinedValues)
+ {
+ $this->userDefinedValues = $userDefinedValues;
+ }
+
+ public function setXUserDefinedValues($xUserDefinedValues)
+ {
+ $this->xUserDefinedValues = $xUserDefinedValues;
+ }
+
+ public function setZendsignPath($zendsignPath)
+ {
+ $this->zendsignPath = $zendsignPath;
+ }
+
+ public function setPrivateKeyPath($privateKeyPath)
+ {
+ $this->privateKeyPath = $privateKeyPath;
+ }
+
+ 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
+ *
+ * @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.
+ *
+ * @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 stirng $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
+ *
+ * @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);
+ }
+ }
+ }
+
+}