* @version $Id: 7ef44b418426e61cb1ea3b8cf87b289d79f663aa $
* @since 2.4.1
*/
class PhpDependTask extends Task
{
/**
* A php source code filename or directory
*
* @var PhingFile
*/
protected $file = null;
/**
* All fileset objects assigned to this task
*
* @var FileSet[]
*/
protected $filesets = array();
/**
* List of allowed file extensions. Default file extensions are php
* and php5.
*
* @var array
*/
protected $allowedFileExtensions = array('php', 'php5');
/**
* List of exclude directories. Default exclude dirs are .git ,
* .svn and CVS .
*
* @var array
*/
protected $excludeDirectories = array('.git', '.svn', 'CVS');
/**
* List of exclude packages
*
* @var array
*/
protected $excludePackages = array();
/**
* Should the parse ignore doc comment annotations?
*
* @var boolean
*/
protected $withoutAnnotations = false;
/**
* Should PHP_Depend treat +global as a regular project package?
*
* @var boolean
*/
protected $supportBadDocumentation = false;
/**
* Flag for enable/disable debugging
*
* @var boolean
*/
protected $debug = false;
/**
* PHP_Depend configuration file
*
* @var PhingFile
*/
protected $configFile = null;
/**
* Logger elements
*
* @var PhpDependLoggerElement[]
*/
protected $loggers = array();
/**
* Analyzer elements
*
* @var PhpDependAnalyzerElement[]
*/
protected $analyzers = array();
/**
* Holds the PHP_Depend runner instance
*
* @var PHP_Depend_TextUI_Runner
*/
protected $runner = null;
/**
* Flag that determines whether to halt on error
*
* @var boolean
*/
protected $haltonerror = false;
/**
* @var bool
*/
private $oldVersion = false;
/**
* @var string
*/
protected $pharLocation = "";
/**
* Load the necessary environment for running PHP_Depend
*
* @throws BuildException
*/
protected function requireDependencies()
{
if (!empty($this->pharLocation)) {
include_once 'phar://' . $this->pharLocation . '/vendor/autoload.php';
}
// check 2.x version (composer/phar)
if (class_exists('PDepend\\TextUI\\Runner')) {
return;
}
$this->oldVersion = true;
// check 1.x version (composer)
if (class_exists('PHP_Depend_TextUI_Runner')) {
// include_path hack for PHP_Depend 1.1.3
$rc = new ReflectionClass('PHP_Depend');
set_include_path(get_include_path() . ":" . realpath(dirname($rc->getFileName()) . "/../"));
return;
}
@include_once 'PHP/Depend/Autoload.php';
if (!class_exists('PHP_Depend_Autoload')) {
throw new BuildException(
'PhpDependTask depends on PHP_Depend being installed and on include_path',
$this->getLocation()
);
}
// register PHP_Depend autoloader
$autoload = new PHP_Depend_Autoload();
$autoload->register();
}
/**
* Set the input source file or directory
*
* @param PhingFile $file The input source file or directory
*/
public function setFile(PhingFile $file)
{
$this->file = $file;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Sets a list of filename extensions for valid php source code files
*
* @param string $fileExtensions List of valid file extensions
*/
public function setAllowedFileExtensions($fileExtensions)
{
$this->allowedFileExtensions = array();
$token = ' ,;';
$ext = strtok($fileExtensions, $token);
while ($ext !== false) {
$this->allowedFileExtensions[] = $ext;
$ext = strtok($token);
}
}
/**
* Sets a list of exclude directories
*
* @param string $excludeDirectories List of exclude directories
*/
public function setExcludeDirectories($excludeDirectories)
{
$this->excludeDirectories = array();
$token = ' ,;';
$pattern = strtok($excludeDirectories, $token);
while ($pattern !== false) {
$this->excludeDirectories[] = $pattern;
$pattern = strtok($token);
}
}
/**
* Sets a list of exclude packages
*
* @param string $excludePackages Exclude packages
*/
public function setExcludePackages($excludePackages)
{
$this->excludePackages = array();
$token = ' ,;';
$pattern = strtok($excludePackages, $token);
while ($pattern !== false) {
$this->excludePackages[] = $pattern;
$pattern = strtok($token);
}
}
/**
* Should the parser ignore doc comment annotations?
*
* @param boolean $withoutAnnotations
*/
public function setWithoutAnnotations($withoutAnnotations)
{
$this->withoutAnnotations = StringHelper::booleanValue($withoutAnnotations);
}
/**
* Should PHP_Depend support projects with a bad documentation. If this
* option is set to true , PHP_Depend will treat the default package
* +global as a regular project package.
*
* @param boolean $supportBadDocumentation
*/
public function setSupportBadDocumentation($supportBadDocumentation)
{
$this->supportBadDocumentation = StringHelper::booleanValue($supportBadDocumentation);
}
/**
* Set debugging On/Off
*
* @param boolean $debug
*/
public function setDebug($debug)
{
$this->debug = StringHelper::booleanValue($debug);
}
/**
* Set halt on error
*
* @param boolean $haltonerror
*/
public function setHaltonerror($haltonerror)
{
$this->haltonerror = StringHelper::booleanValue($haltonerror);
}
/**
* Set the configuration file
*
* @param PhingFile $configFile The configuration file
*/
public function setConfigFile(PhingFile $configFile)
{
$this->configFile = $configFile;
}
/**
* Create object for nested logger element
*
* @return PhpDependLoggerElement
*/
public function createLogger()
{
$num = array_push($this->loggers, new PhpDependLoggerElement());
return $this->loggers[$num - 1];
}
/**
* Create object for nested analyzer element
*
* @return PhpDependAnalyzerElement
*/
public function createAnalyzer()
{
$num = array_push($this->analyzers, new PhpDependAnalyzerElement());
return $this->analyzers[$num - 1];
}
/**
* @param string $pharLocation
*/
public function setPharLocation($pharLocation)
{
$this->pharLocation = $pharLocation;
}
/**
* Executes PHP_Depend_TextUI_Runner against PhingFile or a FileSet
*
* @throws BuildException
*/
public function main()
{
$this->requireDependencies();
if (!isset($this->file) and count($this->filesets) == 0) {
throw new BuildException('Missing either a nested fileset or attribute "file" set');
}
if (count($this->loggers) == 0) {
throw new BuildException('Missing nested "logger" element');
}
$this->validateLoggers();
$this->validateAnalyzers();
$filesToParse = $this->getFilesToParse();
$runner = $this->createRunner();
$runner->setSourceArguments($filesToParse);
foreach ($this->loggers as $logger) {
// Register logger
if ($this->oldVersion) {
$runner->addLogger(
$logger->getType(),
$logger->getOutfile()->__toString()
);
} else {
$runner->addReportGenerator(
$logger->getType(),
$logger->getOutfile()->__toString()
);
}
}
foreach ($this->analyzers as $analyzer) {
// Register additional analyzer
$runner->addOption(
$analyzer->getType(),
$analyzer->getValue()
);
}
// Disable annotation parsing
if ($this->withoutAnnotations) {
$runner->setWithoutAnnotations();
}
// Enable bad documentation support
if ($this->supportBadDocumentation) {
$runner->setSupportBadDocumentation();
}
// Check for suffix
if (count($this->allowedFileExtensions) > 0) {
$runner->setFileExtensions($this->allowedFileExtensions);
}
// Check for ignore directories
if (count($this->excludeDirectories) > 0) {
$runner->setExcludeDirectories($this->excludeDirectories);
}
// Check for exclude packages
if (count($this->excludePackages) > 0) {
$runner->setExcludePackages($this->excludePackages);
}
$runner->run();
if ($runner->hasParseErrors() === true) {
$this->log('Following errors occurred:');
foreach ($runner->getParseErrors() as $error) {
$this->log($error);
}
if ($this->haltonerror === true) {
throw new BuildException('Errors occurred during parse process');
}
}
}
/**
* Validates the available loggers
*
* @throws BuildException
*/
protected function validateLoggers()
{
foreach ($this->loggers as $logger) {
if ($logger->getType() === '') {
throw new BuildException('Logger missing required "type" attribute');
}
if ($logger->getOutfile() === null) {
throw new BuildException('Logger requires "outfile" attribute');
}
}
}
/**
* Validates the available analyzers
*
* @throws BuildException
*/
protected function validateAnalyzers()
{
foreach ($this->analyzers as $analyzer) {
if ($analyzer->getType() === '') {
throw new BuildException('Analyzer missing required "type" attribute');
}
if (count($analyzer->getValue()) === 0) {
throw new BuildException('Analyzer missing required "value" attribute');
}
}
}
/**
* @return array
*/
private function getFilesToParse()
{
$filesToParse = array();
if ($this->file instanceof PhingFile) {
$filesToParse[] = $this->file->__toString();
return $filesToParse;
} else {
// append any files in filesets
foreach ($this->filesets as $fs) {
$files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
foreach ($files as $filename) {
$f = new PhingFile($fs->getDir($this->project), $filename);
$filesToParse[] = $f->getAbsolutePath();
}
}
return $filesToParse;
}
}
/**
* @return object
*/
private function createRunner()
{
if ($this->oldVersion) {
return $this->createLegacyRunner();
}
$applicationClassName = 'PDepend\\Application';
$application = new $applicationClassName();
$runner = $application->getRunner();
$configuration = $this->getConfiguration();
if ($configuration === null) {
$configuration = $application->getConfiguration();
}
if ($this->debug) {
// Enable debug logging
call_user_func('PDepend\\Util\\Log::setSeverity', 1);
}
call_user_func('PDepend\\Util\\ConfigurationInstance::set', $configuration);
return $runner;
}
/**
* @return PHP_Depend_TextUI_Runner
*/
private function createLegacyRunner()
{
$runner = new PHP_Depend_TextUI_Runner();
$runner->addProcessListener(new PHP_Depend_TextUI_ResultPrinter());
if ($this->debug) {
require_once 'PHP/Depend/Util/Log.php';
// Enable debug logging
PHP_Depend_Util_Log::setSeverity(PHP_Depend_Util_Log::DEBUG);
}
$configuration = $this->getConfiguration();
if ($configuration === null) {
$configurationFactory = new PHP_Depend_Util_Configuration_Factory();
$configuration = $configurationFactory->createDefault();
}
PHP_Depend_Util_ConfigurationInstance::set($configuration);
$runner->setConfiguration($configuration);
return $runner;
}
/**
* Loads configuration file
* @return null|PHP_Depend_Util_Configuration
* @throws BuildException
*/
private function getConfiguration()
{
// Check for configuration option
if ($this->configFile == null || ! ($this->configFile instanceof PhingFile)) {
return null;
}
if (file_exists($this->configFile->__toString()) === false) {
throw new BuildException(
'The configuration file "' . $this->configFile->__toString() . '" doesn\'t exist.'
);
}
if ($this->oldVersion) {
$configurationClassName = 'PHP_Depend_Util_Configuration';
} else {
$configurationClassName = 'PDepend\\Util\\Configuration';
}
return new $configurationClassName(
$this->configFile->__toString(),
null,
true
);
}
}
phing-2.16.0/tasks/ext/CapsuleTask.php 0000644 0001750 0001750 00000036350 13027032674 016575 0 ustar druid druid .
*/
include_once 'phing/Task.php';
include_once 'phing/BuildException.php';
include_once 'phing/lib/Capsule.php';
include_once 'phing/util/StringHelper.php';
/**
* A phing task for generating output by using Capsule.
*
* This is based on the interface to TexenTask from Apache's Velocity engine.
*
* @author Hans Lellelid
*
* @package phing.tasks.ext
*/
class CapsuleTask extends Task
{
/**
* Capsule "template" engine.
* @var Capsule
*/
protected $context;
/**
* Any vars assigned via the build file.
* @var array AssignedVar[]
*/
protected $assignedVars = array();
/**
* This is the control template that governs the output.
* It may or may not invoke the services of worker
* templates.
* @var string
*/
protected $controlTemplate;
/**
* This is where Velocity will look for templates
* using the file template loader.
* @var string
*/
protected $templatePath;
/**
* This is where texen will place all the output
* that is a product of the generation process.
* @var string
*/
protected $outputDirectory;
/**
* This is the file where the generated text
* will be placed.
* @var string
*/
protected $outputFile;
/**
*
* These are properties that are fed into the
* initial context from a properties file. This
* is simply a convenient way to set some values
* that you wish to make available in the context.
*
*
* These values are not critical, like the template path
* or output path, but allow a convenient way to
* set a value that may be specific to a particular
* generation task.
*
*
* For example, if you are generating scripts to allow
* user to automatically create a database, then
* you might want the $databaseName
* to be placed
* in the initial context so that it is available
* in a script that might look something like the
* following:
*
* #!bin/sh
*
* echo y | mysqladmin create $databaseName
*
* The value of $databaseName
isn't critical to
* output, and you obviously don't want to change
* the ant task to simply take a database name.
* So initial context values can be set with
* properties file.
*
* @var array
*/
protected $contextProperties;
// -----------------------------------------------------------------------
// The following getters & setters are used by phing to set properties
// specified in the XML for the capsule task.
// -----------------------------------------------------------------------
/**
* [REQUIRED] Set the control template for the
* generating process.
* @param string $controlTemplate
* @return void
*/
public function setControlTemplate($controlTemplate)
{
$this->controlTemplate = $controlTemplate;
}
/**
* Get the control template for the
* generating process.
* @return string
*/
public function getControlTemplate()
{
return $this->controlTemplate;
}
/**
* [REQUIRED] Set the path where Velocity will look
* for templates using the file template
* loader.
* @param $templatePath
* @return void
*/
public function setTemplatePath($templatePath)
{
$resolvedPath = "";
$tok = strtok($templatePath, ",");
while ($tok) {
// resolve relative path from basedir and leave
// absolute path untouched.
$fullPath = $this->project->resolveFile($tok);
$cpath = $fullPath->getCanonicalPath();
if ($cpath === false) {
$this->log("Template directory does not exist: " . $fullPath->getAbsolutePath());
} else {
$resolvedPath .= $cpath;
}
$tok = strtok(",");
if ($tok) {
$resolvedPath .= ",";
}
}
$this->templatePath = $resolvedPath;
}
/**
* Get the path where Velocity will look
* for templates using the file template
* loader.
* @return string
*/
public function getTemplatePath()
{
return $this->templatePath;
}
/**
* [REQUIRED] Set the output directory. It will be
* created if it doesn't exist.
* @param PhingFile $outputDirectory
* @return void
* @throws Exception
*/
public function setOutputDirectory(PhingFile $outputDirectory)
{
try {
if (!$outputDirectory->exists()) {
$this->log(
"Output directory does not exist, creating: " . $outputDirectory->getPath(),
Project::MSG_VERBOSE
);
if (!$outputDirectory->mkdirs()) {
throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath());
}
}
$this->outputDirectory = $outputDirectory->getCanonicalPath();
} catch (IOException $ioe) {
throw new BuildException($ioe);
}
}
/**
* Get the output directory.
* @return string
*/
public function getOutputDirectory()
{
return $this->outputDirectory;
}
/**
* [REQUIRED] Set the output file for the
* generation process.
* @param string $outputFile (TODO: change this to File)
* @return void
*/
public function setOutputFile($outputFile)
{
$this->outputFile = $outputFile;
}
/**
* Get the output file for the
* generation process.
* @return string
*/
public function getOutputFile()
{
return $this->outputFile;
}
/**
* Set the context properties that will be
* fed into the initial context be the
* generating process starts.
* @param string $file
* @throws BuildException
* @return void
*/
public function setContextProperties($file)
{
$sources = explode(",", $file);
$this->contextProperties = new Properties();
// Always try to get the context properties resource
// from a file first. Templates may be taken from a JAR
// file but the context properties resource may be a
// resource in the filesystem. If this fails than attempt
// to get the context properties resource from the
// classpath.
for ($i = 0, $sourcesLength = count($sources); $i < $sourcesLength; $i++) {
$source = new Properties();
try {
// resolve relative path from basedir and leave
// absolute path untouched.
$fullPath = $this->project->resolveFile($sources[$i]);
$this->log("Using contextProperties file: " . $fullPath->toString());
$source->load($fullPath);
} catch (Exception $e) {
throw new BuildException("Context properties file " . $sources[$i] .
" could not be found in the file system!");
}
$keys = $source->keys();
foreach ($keys as $key) {
$name = $key;
$value = $this->project->replaceProperties($source->getProperty($name));
$this->contextProperties->setProperty($name, $value);
}
}
}
/**
* Get the context properties that will be
* fed into the initial context be the
* generating process starts.
* @return Properties
*/
public function getContextProperties()
{
return $this->contextProperties;
}
/**
* Creates an "AssignedVar" class.
*/
public function createAssign()
{
$a = new AssignedVar();
$this->assignedVars[] = $a;
return $a;
}
// ---------------------------------------------------------------
// End of XML setters & getters
// ---------------------------------------------------------------
/**
* Creates a Smarty object.
*
* @return Capsule initialized (cleared) Smarty context.
* @throws Exception the execute method will catch
* and rethrow as a BuildException
*/
public function initControlContext()
{
$this->context->clear();
foreach ($this->assignedVars as $var) {
$this->context->put($var->getName(), $var->getValue());
}
return $this->context;
}
/**
* Execute the input script with Velocity
*
* @throws BuildException
* BuildExceptions are thrown when required attributes are missing.
* Exceptions thrown by Velocity are rethrown as BuildExceptions.
*/
public function main()
{
// Make sure the template path is set.
if (empty($this->templatePath)) {
throw new BuildException("The template path needs to be defined!");
}
// Make sure the control template is set.
if ($this->controlTemplate === null) {
throw new BuildException("The control template needs to be defined!");
}
// Make sure the output directory is set.
if ($this->outputDirectory === null) {
throw new BuildException("The output directory needs to be defined!");
}
// Make sure there is an output file.
if ($this->outputFile === null) {
throw new BuildException("The output file needs to be defined!");
}
// Setup Smarty runtime.
// Smarty uses one object to store properties and to store
// the context for the template (unlike Velocity). We setup this object, calling it
// $this->context, and then initControlContext simply zeros out
// any assigned variables.
$this->context = new Capsule();
if ($this->templatePath !== null) {
$this->log("Using templatePath: " . $this->templatePath);
$this->context->setTemplatePath($this->templatePath);
}
// Make sure the output directory exists, if it doesn't
// then create it.
$outputDir = new PhingFile($this->outputDirectory);
if (!$outputDir->exists()) {
$this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath());
$outputDir->mkdirs();
}
$this->context->setOutputDirectory($outputDir->getAbsolutePath());
$path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
$this->log("Generating to file " . $path);
//$writer = new FileWriter($path);
// The generator and the output path should
// be placed in the init context here and
// not in the generator class itself.
$c = $this->initControlContext();
// Set any variables that need to always
// be loaded
$this->populateInitialContext($c);
// Feed all the options into the initial
// control context so they are available
// in the control/worker templates.
if ($this->contextProperties !== null) {
foreach ($this->contextProperties->keys() as $property) {
$value = $this->contextProperties->getProperty($property);
// Special exception (from Texen)
// for properties ending in file.contents:
// in that case we dump the contents of the file
// as the "value" for the Property.
if (preg_match('/file\.contents$/', $property)) {
// pull in contents of file specified
$property = substr($property, 0, strpos($property, "file.contents") - 1);
// reset value, and then
// read in the contents of the file into that var
$value = "";
$f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath());
if ($f->exists()) {
$fr = new FileReader($f);
$fr->readInto($value);
}
} // if ends with file.contents
if (StringHelper::isBoolean($value)) {
$value = StringHelper::booleanValue($value);
}
$c->put($property, $value);
} // foreach property
} // if contextProperties !== null
try {
$this->log("Parsing control template: " . $this->controlTemplate);
$c->parse($this->controlTemplate, $path);
} catch (Exception $ioe) {
throw new BuildException("Cannot write parsed template: " . $ioe->getMessage());
}
$this->cleanup();
}
/**
* Place useful objects into the initial context.
*
*
* @param Capsule $context The context to populate, as retrieved from
* {@link #initControlContext()}.
* @return void
* @throws Exception Error while populating context. The {@link
* #main()} method will catch and rethrow as a
* BuildException
.
*/
protected function populateInitialContext(Capsule $context)
{
$this->context->put("now", strftime("%c", time()));
$this->context->put("task", $this);
}
/**
* A hook method called at the end of {@link #execute()} which can
* be overridden to perform any necessary cleanup activities (such
* as the release of database connections, etc.). By default,
* does nothing.
*
* @return void
*/
protected function cleanup()
{
}
}
/**
* An "inner" class for holding assigned var values.
* May be need to expand beyond name/value in the future.
*
* @package phing.tasks.ext
*/
class AssignedVar
{
private $name;
private $value;
/**
* @param string $v
*/
public function setName($v)
{
$this->name = $v;
}
/**
* @param mixed $v
*/
public function setValue($v)
{
$this->value = $v;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return mixed
*/
public function getValue()
{
return $this->value;
}
}
phing-2.16.0/tasks/ext/sonar/SonarProperty.php 0000644 0001750 0001750 00000003427 13027032674 020326 0 ustar druid druid .
*/
/**
* A property element nested in SonarTask.
*
* @author Bernhard Mendl
* @package phing.tasks.ext.sonar
*/
class SonarProperty
{
/**
*
* @var string
*/
private $name;
/**
*
* @var string
*/
private $value;
/**
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
*
* @param string $name
* @return void
*/
public function setName($name)
{
$this->name = (string) $name;
}
/**
*
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
*
* @param string $value
* @return void
*/
public function setValue($value)
{
$this->value = (string) $value;
}
}
phing-2.16.0/tasks/ext/sonar/SonarTask.php 0000644 0001750 0001750 00000030511 13027032674 017376 0 ustar druid druid .
*/
require_once 'phing/BuildException.php';
require_once 'phing/Project.php';
require_once 'phing/Task.php';
require_once 'phing/tasks/ext/sonar/SonarConfigurationFileParser.php';
require_once 'phing/tasks/ext/sonar/SonarProperty.php';
/**
* Runs SonarQube Scanner.
*
* @author Bernhard Mendl
* @package phing.tasks.ext.sonar
* @see http://www.sonarqube.org
*/
class SonarTask extends Task
{
const EXIT_SUCCESS = 0;
/**
*
* @var string|null
*/
private $executable = null;
/**
*
* @var string
*/
private $errors = 'false';
/**
*
* @var string
*/
private $debug = 'false';
/**
*
* @var string|null
*/
private $configuration = null;
/**
*
* @var array Nested *Property* elements.
* @see Property
*/
private $propertyElements = array();
/**
* The command-line options passed to the SonarQube Scanner executable.
*
* @var array
*/
private $commandLineOptions = array();
/**
* Map containing SonarQube's "analysis parameters".
*
* Map keys are SonarQube parameter names. Map values are parameter values.
* See {@link http://docs.sonarqube.org/display/SONAR/Analysis+Parameters}.
*
* @var array
*/
private $properties = array();
/**
* Sets the path of the SonarQube Scanner executable.
*
* If the SonarQube Scanner is included in the PATH environment variable,
* the file name is sufficient.
*
* @param string $executable
* @return void
*/
public function setExecutable($executable)
{
$this->executable = (string) $executable;
$message = sprintf("Set executable to [%s].", $this->executable);
$this->log($message, Project::MSG_DEBUG);
}
/**
* Sets or unsets the "--errors" flag of SonarQube Scanner.
*
* @param string $errors
* Allowed values are "true"/"false", "yes"/"no", or "1"/"0".
* @return void
*/
public function setErrors($errors)
{
$this->errors = strtolower((string) $errors);
$message = sprintf("Set errors flag to [%s].", $this->errors);
$this->log($message, Project::MSG_DEBUG);
}
/**
* Sets or unsets the "--debug" flag of SonarQube Scanner.
*
* @param string $debug
* Allowed values are "true"/"false", "yes"/"no", or "1"/"0".
* @return void
*/
public function setDebug($debug)
{
$this->debug = strtolower((string) $debug);
$message = sprintf("Set debug flag to [%s].", $this->debug);
$this->log($message, Project::MSG_DEBUG);
}
/**
* Sets the path of a configuration file for SonarQube Scanner.
*
* @param string $configuration
* @return void
*/
public function setConfiguration($configuration)
{
$this->configuration = (string) $configuration;
$message = sprintf("Set configuration to [%s].", $this->configuration);
$this->log($message, Project::MSG_DEBUG);
}
/**
* Adds a nested Property element.
*
* @param SonarProperty $property
* @return void
*/
public function addProperty(SonarProperty $property)
{
$this->propertyElements[] = $property;
$message = sprintf("Added property: [%s] = [%s].", $property->getName(), $property->getValue());
$this->log($message, Project::MSG_DEBUG);
}
/**
*
* {@inheritdoc}
*
* @see Task::init()
*/
public function init()
{
$this->checkExecAllowed();
}
/**
*
* {@inheritdoc}
*
* @see Task::main()
*/
public function main()
{
$this->validateErrors();
$this->validateDebug();
$this->validateConfiguration();
$this->validateProperties();
$this->validateExecutable();
$command = sprintf('%s %s', escapeshellcmd($this->executable), $this->constructOptionsString());
$message = sprintf('Executing: [%s]', $command);
$this->log($message, Project::MSG_VERBOSE);
exec($command, $output, $returnCode);
foreach ($output as $line) {
$this->log($line);
}
if ($returnCode !== self::EXIT_SUCCESS) {
throw new BuildException('Execution of SonarQube Scanner failed.');
}
}
/**
* Constructs command-line options string for SonarQube Scanner.
*
* @return string
*/
private function constructOptionsString()
{
$options = implode(' ', $this->commandLineOptions);
foreach ($this->properties as $name => $value) {
$arg = sprintf('%s=%s', $name, $value);
$options .= ' -D ' . escapeshellarg($arg);
}
return $options;
}
/**
* Check whether PHP function 'exec()' is available.
*
* @throws BuildException
* @return void
*/
private function checkExecAllowed()
{
if (! function_exists('exec') || ! is_callable('exec')) {
$message = 'Cannot execute SonarQube Scanner because calling PHP function exec() is not permitted by PHP configuration.';
throw new BuildException($message);
}
}
/**
*
* @throws BuildException
* @return void
*/
private function validateExecutable()
{
if (($this->executable === null) || ($this->executable === '')) {
$message = 'You must specify the path of the SonarQube Scanner using the "executable" attribute.';
throw new BuildException($message);
}
// Note that executable is used as argument here.
$escapedExecutable = escapeshellarg($this->executable);
if ($this->isWindows()) {
$message = 'Assuming a Windows system. Looking for SonarQube Scanner ...';
$command = 'where ' . $escapedExecutable;
} else {
$message = 'Assuming a Linux or Mac system. Looking for SonarQube Scanner ...';
$command = 'which ' . $escapedExecutable;
}
$this->log($message, Project::MSG_VERBOSE);
unset($output);
exec($command, $output, $returnCode);
if ($returnCode !== self::EXIT_SUCCESS) {
$message = sprintf('Cannot find SonarQube Scanner: [%s].', $this->executable);
throw new BuildException($message);
}
// Verify that executable is indeed SonarQube Scanner ...
$escapedExecutable = escapeshellcmd($this->executable);
unset($output);
exec($escapedExecutable . ' --version', $output, $returnCode);
if ($returnCode !== self::EXIT_SUCCESS) {
$message = sprintf('Could not check version string. Executable appears not to be SonarQube Scanner: [%s].', $this->executable);
throw new BuildException($message);
}
$isOk = false;
foreach ($output as $line) {
if (preg_match('/SonarQube Scanner [0-9]+\\.[0-9]+/', $line) === 1) {
$isOk = true;
break;
}
}
if ($isOk) {
$message = sprintf('Found SonarQube Scanner: [%s].', $this->executable);
$this->log($message, Project::MSG_VERBOSE);
} else {
$message = sprintf('Could not find name of SonarQube Scanner in version string. Executable appears not to be SonarQube Scanner: [%s].', $this->executable);
throw new BuildException($message);
}
}
/**
*
* @throws BuildException
* @return void
*/
private function validateErrors()
{
if (($this->errors === '1') || ($this->errors === 'true') || ($this->errors === 'yes')) {
$errors = true;
} elseif (($this->errors === '0') || ($this->errors === 'false') || ($this->errors === 'no')) {
$errors = false;
} else {
throw new BuildException('Expected a boolean value.');
}
if ($errors) {
$this->commandLineOptions[] = '--errors';
}
}
/**
*
* @throws BuildException
* @return void
*/
private function validateDebug()
{
if (($this->debug === '1') || ($this->debug === 'true') || ($this->debug === 'yes')) {
$debug = true;
} elseif (($this->debug === '0') || ($this->debug === 'false') || ($this->debug === 'no')) {
$debug = false;
} else {
throw new BuildException('Expected a boolean value.');
}
if ($debug) {
$this->commandLineOptions[] = '--debug';
}
}
/**
*
* @throws BuildException
* @return void
*/
private function validateConfiguration()
{
if (($this->configuration === null) || ($this->configuration === '')) {
// NOTE: Ignore an empty configuration. This allows for
// using Phing properties as attribute values, e.g.
// .
return;
}
if (! @file_exists($this->configuration)) {
$message = sprintf('Cannot find configuration file [%s].', $this->configuration);
throw new BuildException($message);
}
if (! @is_readable($this->configuration)) {
$message = sprintf('Cannot read configuration file [%s].', $this->configuration);
throw new BuildException($message);
}
// TODO: Maybe check file type?
}
/**
*
* @throws BuildException
* @return void
*/
private function validateProperties()
{
$this->properties = $this->parseConfigurationFile();
foreach ($this->propertyElements as $property) {
$name = $property->getName();
$value = $property->getValue();
if ($name === null || $name === '') {
throw new BuildException('Property name must not be null or empty.');
}
if (array_key_exists($name, $this->properties)) {
$message = sprintf('Property [%s] overwritten: old value [%s], new value [%s].',
$name,
$this->properties[$name],
$value);
$this->log($message, Project::MSG_WARN);
}
$this->properties[$name] = $value;
}
// Check if all properties required by SonarQube Scanner are set ...
$requiredProperties = array(
'sonar.projectKey',
'sonar.projectName',
'sonar.projectVersion',
'sonar.sources'
);
$intersection = array_intersect($requiredProperties, array_keys($this->properties));
if (count($intersection) < count($requiredProperties)) {
$message = 'SonarQube Scanner misses some parameters. The following properties are mandatory: ' . implode(', ', $requiredProperties) . '.';
throw new BuildException($message);
}
}
/**
*
* @return array
*/
private function parseConfigurationFile() {
if (($this->configuration === null) || ($this->configuration === '')) {
return array();
}
$parser = new SonarConfigurationFileParser($this->configuration, $this->project);
return $parser->parse();
}
/**
*
* @return boolean
*/
private function isWindows()
{
$operatingSystemName = php_uname('s');
return strtoupper(substr($operatingSystemName, 0, 3)) === 'WIN';
}
}
phing-2.16.0/tasks/ext/sonar/SonarConfigurationFileParser.php 0000644 0001750 0001750 00000012736 13027032674 023271 0 ustar druid druid .
*/
require_once 'phing/BuildException.php';
require_once 'phing/Project.php';
require_once 'phing/tasks/ext/sonar/SonarProperty.php';
/**
*
* @author Bernhard Mendl
* @package phing.tasks.ext.sonar
*/
class SonarConfigurationFileParser
{
/**
*
* @var Project
*/
private $project;
/**
*
* @var string
*/
private $file;
/**
* This map holds the properties read from the configuration file.
*
* @var array
*/
private $properties;
/**
* Name of currently parsed property.
*
* @var string|null
*/
private $name;
/**
* Value of currently parsed property.
*
* @var string
*/
private $value;
/**
*
* @param string $file
* The properties file.
*/
public function __construct($file, Project $project)
{
if (($file === null) || ($file === '')) {
throw new BuildException('File name must not be null or empty.');
}
$this->file = $file;
$this->project = $project;
}
/**
*
* @throws BuildException
* @return array
*/
public function parse()
{
$this->properties = array();
$contents = @file_get_contents($this->file);
if ($contents === false) {
$message = sprintf('Could not read file [%s].', $this->file);
throw new BuildException($message);
}
$lines = explode("\n", $contents);
$count = count($lines);
$isMultiLine = false;
for ($i = 0; $i < $count; $i ++) {
$line = $lines[$i];
if ($isMultiLine) {
$isMultiLine = $this->extractContinuedValue($line);
} else {
$this->name = null;
$this->value = '';
$isMultiLine = $this->extractNameAndValue($line);
}
if (($this->name !== null) && (! $isMultiLine)) {
if (array_key_exists($this->name, $this->properties)) {
$message = sprintf('Property [%s] overwritten: old value [%s], new value [%s].',
$this->name,
$this->properties[$this->name],
$this->value);
$this->project->log($message, Project::MSG_WARN);
}
// Unescape backslashes.
$this->value = str_replace('\\\\', '\\', $this->value);
$this->properties[$this->name] = $this->value;
}
}
if ($isMultiLine) {
$message = sprintf('Last property looks like a multi-lined value, but end of file found. Name = [%s].', $this->name);
throw new BuildException($message);
}
return $this->properties;
}
/**
*
* @param string $line
* @return boolean
*/
private function extractNameAndValue($line)
{
$isMultiLine = false;
if ($this->isCommentLine($line)) {
return $isMultiLine;
}
// Find key and value.
$hasMatch = preg_match('/\\s*([^=:]*[^=:\\s]+)\\s*[=:]\\s*(.*)$/s', $line, $matches);
if (($hasMatch === 1) && (count($matches) === 3)) {
$this->name = $matches[1];
$this->value = $matches[2];
$isMultiLine = $this->checkMultiLine();
}
return $isMultiLine;
}
/**
*
* @param string $line
* @return boolean
*/
private function extractContinuedValue($line) {
$isMultiLine = false;
if ($this->isCommentLine($line)) {
return $isMultiLine;
}
// Find continued value.
$hasMatch = preg_match('/\\s*(.*)$/s', $line, $matches);
if (($hasMatch === 1) && (count($matches) === 2)) {
$this->value .= $matches[1];
$isMultiLine = $this->checkMultiLine();
}
return $isMultiLine;
}
/**
*
* @return boolean
*/
private function checkMultiLine()
{
$isMultiLine = false;
// Is there a single(!) backslash at the end of the line?
if (preg_match('/[^\\\]\\\$/', $this->value) === 1) {
// Remove last char, i.e. the backslash.
$this->value = substr($this->value, 0, -1);
$isMultiLine = true;
}
return $isMultiLine;
}
/**
*
* @param string $line
* @return boolean
*/
private function isCommentLine($line)
{
return preg_match('/^\\s*[!#]/', $line) === 1;
}
}
phing-2.16.0/tasks/ext/FileSizeTask.php 0000644 0001750 0001750 00000006537 13027032674 016717 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* fileHash
*
* Calculate either MD5 or SHA hash value of a specified file and retun the
* value in a property
*
* @author Johan Persson
* @version $Id: d4b97a2e512ffe10394e203d6a94c498e11ca986 $
* @package phing.tasks.ext
*/
class FileSizeTask extends Task
{
/**
* Property for File
* @var PhingFile file
*/
private $file;
/**
* Property where the file size will be stored
* @var string $property
*/
private $propertyName = "filesize";
/**
* Which file to calculate the file size of
* @param PhingFile $file
*/
public function setFile($file)
{
$this->file = $file;
}
/**
* Set the name of the property to store the file size
* @param $property
* @return void
*/
public function setPropertyName($property)
{
$this->propertyName = $property;
}
/**
* Main-Method for the Task
*
* @return void
* @throws BuildException
*/
public function main()
{
$this->checkFile();
$this->checkPropertyName();
$size = filesize($this->file);
if ($size === false) {
throw new BuildException(sprintf('[FileSize] Cannot determine size of file: %s', $this->file));
}
// publish hash value
$this->project->setProperty($this->propertyName, $size);
}
/**
* checks file attribute
* @return void
* @throws BuildException
*/
private function checkFile()
{
// check File
if ($this->file === null ||
strlen($this->file) == 0
) {
throw new BuildException('[FileSize] You must specify an input file.', $this->file);
}
if (!is_readable($this->file)) {
throw new BuildException(sprintf(
'[FileSize] Input file does not exist or is not readable: %s',
$this->file
));
}
}
/**
* checks property attribute
* @return void
* @throws BuildException
*/
private function checkPropertyName()
{
if (is_null($this->propertyName) ||
strlen($this->propertyName) === 0
) {
throw new BuildException('[FileSize] Property name for publishing file size is not set');
}
}
}
phing-2.16.0/tasks/ext/coverage/CoverageReportTask.php 0000644 0001750 0001750 00000046412 13027032674 021723 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/Writer.php';
require_once 'phing/system/util/Properties.php';
require_once 'phing/tasks/ext/phpunit/PHPUnitUtil.php';
require_once 'phing/tasks/ext/coverage/CoverageReportTransformer.php';
/**
* Transforms information in a code coverage database to XML
*
* @author Michiel Rook
* @version $Id: 9a15437e8ba7eb26f59aa20fd6c10e682b26e697 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageReportTask extends Task
{
private $outfile = "coverage.xml";
private $transformers = array();
/** the classpath to use (optional) */
private $classpath = null;
/** the path to the GeSHi library (optional) */
private $geshipath = "";
/** the path to the GeSHi language files (optional) */
private $geshilanguagespath = "";
/**
* @param Path $classpath
*/
public function setClasspath(Path $classpath)
{
if ($this->classpath === null) {
$this->classpath = $classpath;
} else {
$this->classpath->append($classpath);
}
}
/**
* @return null|Path
*/
public function createClasspath()
{
$this->classpath = new Path();
return $this->classpath;
}
/**
* @param $path
*/
public function setGeshiPath($path)
{
$this->geshipath = $path;
}
/**
* @param $path
*/
public function setGeshiLanguagesPath($path)
{
$this->geshilanguagespath = $path;
}
/**
*
*/
public function __construct()
{
$this->doc = new DOMDocument();
$this->doc->encoding = 'UTF-8';
$this->doc->formatOutput = true;
$this->doc->appendChild($this->doc->createElement('snapshot'));
}
/**
* @param $outfile
*/
public function setOutfile($outfile)
{
$this->outfile = $outfile;
}
/**
* Generate a report based on the XML created by this task
*/
public function createReport()
{
$transformer = new CoverageReportTransformer($this);
$this->transformers[] = $transformer;
return $transformer;
}
/**
* @param $packageName
* @return null
*/
protected function getPackageElement($packageName)
{
$packages = $this->doc->documentElement->getElementsByTagName('package');
foreach ($packages as $package) {
if ($package->getAttribute('name') == $packageName) {
return $package;
}
}
return null;
}
/**
* @param $packageName
* @param $element
*/
protected function addClassToPackage($packageName, $element)
{
$package = $this->getPackageElement($packageName);
if ($package === null) {
$package = $this->doc->createElement('package');
$package->setAttribute('name', $packageName);
$this->doc->documentElement->appendChild($package);
}
$package->appendChild($element);
}
/**
* Adds a subpackage to their package
*
* @param string $packageName The name of the package
* @param string $subpackageName The name of the subpackage
*
* @author Benjamin Schultz
* @return void
*/
protected function addSubpackageToPackage($packageName, $subpackageName)
{
$package = $this->getPackageElement($packageName);
$subpackage = $this->getSubpackageElement($subpackageName);
if ($package === null) {
$package = $this->doc->createElement('package');
$package->setAttribute('name', $packageName);
$this->doc->documentElement->appendChild($package);
}
if ($subpackage === null) {
$subpackage = $this->doc->createElement('subpackage');
$subpackage->setAttribute('name', $subpackageName);
}
$package->appendChild($subpackage);
}
/**
* Returns the subpackage element
*
* @param string $subpackageName The name of the subpackage
*
* @author Benjamin Schultz
* @return DOMNode|null null when no DOMNode with the given name exists
*/
protected function getSubpackageElement($subpackageName)
{
$subpackages = $this->doc->documentElement->getElementsByTagName('subpackage');
foreach ($subpackages as $subpackage) {
if ($subpackage->getAttribute('name') == $subpackageName) {
return $subpackage;
}
}
return null;
}
/**
* Adds a class to their subpackage
*
* @param string $classname The name of the class
* @param DOMNode $element The dom node to append to the subpackage element
*
* @author Benjamin Schultz
* @return void
*/
protected function addClassToSubpackage($classname, $element)
{
$subpackageName = PHPUnitUtil::getSubpackageName($classname);
$subpackage = $this->getSubpackageElement($subpackageName);
if ($subpackage === null) {
$subpackage = $this->doc->createElement('subpackage');
$subpackage->setAttribute('name', $subpackageName);
$this->doc->documentElement->appendChild($subpackage);
}
$subpackage->appendChild($element);
}
/**
* @param $source
* @return string
*/
protected function stripDiv($source)
{
$openpos = strpos($source, "", $openpos);
$line = substr($source, $closepos + 1);
$tagclosepos = strpos($line, "
");
$line = substr($line, 0, $tagclosepos);
return $line;
}
/**
* @param $filename
* @return array
*/
protected function highlightSourceFile($filename)
{
if ($this->geshipath) {
require_once $this->geshipath . '/geshi.php';
$source = file_get_contents($filename);
$geshi = new GeSHi($source, 'php', $this->geshilanguagespath);
$geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
$geshi->enable_strict_mode(true);
$geshi->enable_classes(true);
$geshi->set_url_for_keyword_group(3, '');
$html = $geshi->parse_code();
$lines = preg_split("#?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;
}
}
/**
* @param $filename
* @param $coverageInformation
* @param int $classStartLine
* @return DOMElement
*/
protected function transformSourceFile($filename, $coverageInformation, $classStartLine = 1)
{
$sourceElement = $this->doc->createElement('sourcefile');
$sourceElement->setAttribute('name', basename($filename));
/**
* Add original/full filename to document
*/
$sourceElement->setAttribute('sourcefile', $filename);
$filelines = $this->highlightSourceFile($filename);
$linenr = 1;
foreach ($filelines as $line) {
$lineElement = $this->doc->createElement('sourceline');
$lineElement->setAttribute(
'coveredcount',
(isset($coverageInformation[$linenr]) ? $coverageInformation[$linenr] : '0')
);
if ($linenr == $classStartLine) {
$lineElement->setAttribute('startclass', 1);
}
$textnode = $this->doc->createTextNode($line);
$lineElement->appendChild($textnode);
$sourceElement->appendChild($lineElement);
$linenr++;
}
return $sourceElement;
}
/**
* Transforms the coverage information
*
* @param string $filename The filename
* @param array $coverageInformation Array with covergae information
*
* @author Michiel Rook
* @author Benjamin Schultz
* @return void
*/
protected function transformCoverageInformation($filename, $coverageInformation)
{
$classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath);
if (is_array($classes)) {
foreach ($classes as $classname) {
$reflection = new ReflectionClass($classname);
$methods = $reflection->getMethods();
if (method_exists($reflection, 'getShortName')) {
$className = $reflection->getShortName();
} else {
$className = $reflection->getName();
}
$classElement = $this->doc->createElement('class');
$classElement->setAttribute('name', $className);
$packageName = PHPUnitUtil::getPackageName($reflection->getName());
$subpackageName = PHPUnitUtil::getSubpackageName($reflection->getName());
if ($subpackageName !== null) {
$this->addSubpackageToPackage($packageName, $subpackageName);
$this->addClassToSubpackage($reflection->getName(), $classElement);
} else {
$this->addClassToPackage($packageName, $classElement);
}
$classStartLine = $reflection->getStartLine();
$methodscovered = 0;
$methodcount = 0;
// Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off
if ($reflection->getParentClass() == null && count($reflection->getInterfaces()) == 0) {
unset($coverageInformation[$classStartLine + 1]);
} else {
unset($coverageInformation[$classStartLine]);
}
// Remove out-of-bounds info
unset($coverageInformation[0]);
reset($coverageInformation);
foreach ($methods as $method) {
// PHP5 reflection considers methods of a parent class to be part of a subclass, we don't
if ($method->getDeclaringClass()->getName() != $reflection->getName()) {
continue;
}
// small fix for XDEBUG_CC_UNUSED
if (isset($coverageInformation[$method->getStartLine()])) {
unset($coverageInformation[$method->getStartLine()]);
}
if (isset($coverageInformation[$method->getEndLine()])) {
unset($coverageInformation[$method->getEndLine()]);
}
if ($method->isAbstract()) {
continue;
}
$linenr = key($coverageInformation);
while ($linenr !== null && $linenr < $method->getStartLine()) {
next($coverageInformation);
$linenr = key($coverageInformation);
}
$methodCoveredCount = 0;
$methodTotalCount = 0;
$methodHasCoveredLine = false;
while ($linenr !== null && $linenr <= $method->getEndLine()) {
$methodTotalCount++;
$methodHasCoveredLine = true;
// set covered when CODE is other than -1 (not executed)
if ($coverageInformation[$linenr] > 0 || $coverageInformation[$linenr] == -2) {
$methodCoveredCount++;
}
next($coverageInformation);
$linenr = key($coverageInformation);
}
if (($methodTotalCount == $methodCoveredCount) && $methodHasCoveredLine) {
$methodscovered++;
}
$methodcount++;
}
$statementcount = count(
array_filter(
$coverageInformation,
create_function('$var', 'return ($var != -2);')
)
);
$statementscovered = count(
array_filter(
$coverageInformation,
create_function('$var', 'return ($var >= 0);')
)
);
$classElement->appendChild(
$this->transformSourceFile($filename, $coverageInformation, $classStartLine)
);
$classElement->setAttribute('methodcount', $methodcount);
$classElement->setAttribute('methodscovered', $methodscovered);
$classElement->setAttribute('statementcount', $statementcount);
$classElement->setAttribute('statementscovered', $statementscovered);
$classElement->setAttribute('totalcount', $methodcount + $statementcount);
$classElement->setAttribute('totalcovered', $methodscovered + $statementscovered);
}
}
}
protected function calculateStatistics()
{
$packages = $this->doc->documentElement->getElementsByTagName('package');
$totalmethodcount = 0;
$totalmethodscovered = 0;
$totalstatementcount = 0;
$totalstatementscovered = 0;
foreach ($packages as $package) {
$methodcount = 0;
$methodscovered = 0;
$statementcount = 0;
$statementscovered = 0;
$subpackages = $package->getElementsByTagName('subpackage');
foreach ($subpackages as $subpackage) {
$subpackageMethodCount = 0;
$subpackageMethodsCovered = 0;
$subpackageStatementCount = 0;
$subpackageStatementsCovered = 0;
$subpackageClasses = $subpackage->getElementsByTagName('class');
foreach ($subpackageClasses as $subpackageClass) {
$subpackageMethodCount += $subpackageClass->getAttribute('methodcount');
$subpackageMethodsCovered += $subpackageClass->getAttribute('methodscovered');
$subpackageStatementCount += $subpackageClass->getAttribute('statementcount');
$subpackageStatementsCovered += $subpackageClass->getAttribute('statementscovered');
}
$subpackage->setAttribute('methodcount', $subpackageMethodCount);
$subpackage->setAttribute('methodscovered', $subpackageMethodsCovered);
$subpackage->setAttribute('statementcount', $subpackageStatementCount);
$subpackage->setAttribute('statementscovered', $subpackageStatementsCovered);
$subpackage->setAttribute('totalcount', $subpackageMethodCount + $subpackageStatementCount);
$subpackage->setAttribute('totalcovered', $subpackageMethodsCovered + $subpackageStatementsCovered);
}
$classes = $package->getElementsByTagName('class');
foreach ($classes as $class) {
$methodcount += $class->getAttribute('methodcount');
$methodscovered += $class->getAttribute('methodscovered');
$statementcount += $class->getAttribute('statementcount');
$statementscovered += $class->getAttribute('statementscovered');
}
$package->setAttribute('methodcount', $methodcount);
$package->setAttribute('methodscovered', $methodscovered);
$package->setAttribute('statementcount', $statementcount);
$package->setAttribute('statementscovered', $statementscovered);
$package->setAttribute('totalcount', $methodcount + $statementcount);
$package->setAttribute('totalcovered', $methodscovered + $statementscovered);
$totalmethodcount += $methodcount;
$totalmethodscovered += $methodscovered;
$totalstatementcount += $statementcount;
$totalstatementscovered += $statementscovered;
}
$this->doc->documentElement->setAttribute('methodcount', $totalmethodcount);
$this->doc->documentElement->setAttribute('methodscovered', $totalmethodscovered);
$this->doc->documentElement->setAttribute('statementcount', $totalstatementcount);
$this->doc->documentElement->setAttribute('statementscovered', $totalstatementscovered);
$this->doc->documentElement->setAttribute('totalcount', $totalmethodcount + $totalstatementcount);
$this->doc->documentElement->setAttribute('totalcovered', $totalmethodscovered + $totalstatementscovered);
}
public function main()
{
$coverageDatabase = $this->project->getProperty('coverage.database');
if (!$coverageDatabase) {
throw new BuildException("Property coverage.database is not set - please include coverage-setup in your build file");
}
$database = new PhingFile($coverageDatabase);
$this->log("Transforming coverage report");
$props = new Properties();
$props->load($database);
foreach ($props->keys() as $filename) {
$file = unserialize($props->getProperty($filename));
$this->transformCoverageInformation($file['fullname'], $file['coverage']);
}
$this->calculateStatistics();
$this->doc->save($this->outfile);
foreach ($this->transformers as $transformer) {
$transformer->setXmlDocument($this->doc);
$transformer->transform();
}
}
}
phing-2.16.0/tasks/ext/coverage/CoverageSetupTask.php 0000644 0001750 0001750 00000011432 13027032674 021542 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/Writer.php';
require_once 'phing/system/util/Properties.php';
require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
/**
* Initializes a code coverage database
*
* @author Michiel Rook
* @version $Id: bde7020012ba4f24e0d97768c76a5a8af99a6fbb $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageSetupTask extends Task
{
/** the list of filesets containing the .php filename rules */
private $filesets = array();
/** Any filelists of files containing the .php filenames */
private $filelists = array();
/** the filename of the coverage database */
private $database = "coverage.db";
/** the classpath to use (optional) */
private $classpath = null;
/**
* Add a new fileset containing the .php files to process
*
* @param FileSet the new fileset containing .php files
*/
public function addFileSet(FileSet $fileset)
{
$this->filesets[] = $fileset;
}
/**
* Supports embedded element.
* @return FileList
*/
public function createFileList()
{
$num = array_push($this->filelists, new FileList());
return $this->filelists[$num - 1];
}
/**
* Sets the filename of the coverage database to use
*
* @param string the filename of the database
*/
public function setDatabase($database)
{
$this->database = $database;
}
/**
* @param Path $classpath
*/
public function setClasspath(Path $classpath)
{
if ($this->classpath === null) {
$this->classpath = $classpath;
} else {
$this->classpath->append($classpath);
}
}
/**
* @return null|Path
*/
public function createClasspath()
{
$this->classpath = new Path();
return $this->classpath;
}
/**
* Iterate over all filesets and return the filename of all files.
*
* @return array an array of (basedir, filenames) pairs
*/
private function getFilenames()
{
$files = array();
foreach ($this->filelists as $fl) {
try {
$list = $fl->getFiles($this->project);
foreach ($list as $file) {
$fs = new PhingFile(strval($fl->getDir($this->project)), $file);
$files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath());
}
} catch (BuildException $be) {
$this->log($be->getMessage(), Project::MSG_WARN);
}
}
foreach ($this->filesets as $fileset) {
$ds = $fileset->getDirectoryScanner($this->project);
$ds->scan();
$includedFiles = $ds->getIncludedFiles();
foreach ($includedFiles as $file) {
$fs = new PhingFile(realpath($ds->getBaseDir()), $file);
$files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath());
}
}
return $files;
}
public function init()
{
}
public function main()
{
$files = $this->getFilenames();
$this->log("Setting up coverage database for " . count($files) . " files");
$props = new Properties();
foreach ($files as $file) {
$fullname = $file['fullname'];
$filename = $file['key'];
$props->setProperty($filename, serialize(array('fullname' => $fullname, 'coverage' => array())));
}
$dbfile = new PhingFile($this->database);
$props->store($dbfile);
$this->project->setProperty('coverage.database', $dbfile->getAbsolutePath());
}
}
phing-2.16.0/tasks/ext/coverage/CoverageThresholdTask.php 0000644 0001750 0001750 00000035210 13027032674 022376 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/util/Properties.php';
require_once 'phing/types/Excludes.php';
/**
* Stops the build if any of the specified coverage threshold was not reached
*
* @author Benjamin Schultz
* @version $Id: 1cf68f1a4ec652811a5fd9db8353cae9a88ee03e $
* @package phing.tasks.ext.coverage
* @since 2.4.1
*/
class CoverageThresholdTask extends Task
{
/**
* Holds an optional classpath
*
* @var Path
*/
private $_classpath = null;
/**
* Holds the exclusions
*
* @var Excludes
*/
private $_excludes = null;
/**
* Holds an optional database file
*
* @var PhingFile
*/
private $_database = null;
/**
* Holds the coverage threshold for the entire project
*
* @var integer
*/
private $_perProject = 25;
/**
* Holds the coverage threshold for any class
*
* @var integer
*/
private $_perClass = 25;
/**
* Holds the coverage threshold for any method
*
* @var integer
*/
private $_perMethod = 25;
/**
* Holds the minimum found coverage value for a class
*
* @var integer
*/
private $_minClassCoverageFound = null;
/**
* Holds the minimum found coverage value for a method
*
* @var integer
*/
private $_minMethodCoverageFound = null;
/**
* Number of statements in the entire project
*
* @var integer
*/
private $_projectStatementCount = 0;
/**
* Number of covered statements in the entire project
*
* @var integer
*/
private $_projectStatementsCovered = 0;
/**
* Whether to enable detailed logging
*
* @var boolean
*/
private $_verbose = false;
/**
* Sets an optional classpath
*
* @param Path $classpath The classpath
*/
public function setClasspath(Path $classpath)
{
if ($this->_classpath === null) {
$this->_classpath = $classpath;
} else {
$this->_classpath->append($classpath);
}
}
/**
* Sets the optional coverage database to use
*
* @param PhingFile The database file
*/
public function setDatabase(PhingFile $database)
{
$this->_database = $database;
}
/**
* Create classpath object
*
* @return Path
*/
public function createClasspath()
{
$this->_classpath = new Path();
return $this->_classpath;
}
/**
* Sets the coverage threshold for entire project
*
* @param integer $threshold Coverage threshold for entire project
*/
public function setPerProject($threshold)
{
$this->_perProject = $threshold;
}
/**
* Sets the coverage threshold for any class
*
* @param integer $threshold Coverage threshold for any class
*/
public function setPerClass($threshold)
{
$this->_perClass = $threshold;
}
/**
* Sets the coverage threshold for any method
*
* @param integer $threshold Coverage threshold for any method
*/
public function setPerMethod($threshold)
{
$this->_perMethod = $threshold;
}
/**
* Sets whether to enable detailed logging or not
*
* @param boolean $verbose
*/
public function setVerbose($verbose)
{
$this->_verbose = StringHelper::booleanValue($verbose);
}
/**
* Filter covered statements
*
* @param integer $var Coverage CODE/count
* @return boolean
*/
protected function filterCovered($var)
{
return ($var >= 0 || $var === -2);
}
/**
* Create excludes object
*
* @return Excludes
*/
public function createExcludes()
{
$this->_excludes = new Excludes($this->project);
return $this->_excludes;
}
/**
* Calculates the coverage threshold
*
* @param string $filename The filename to analyse
* @param array $coverageInformation Array with coverage information
* @throws BuildException
*/
protected function calculateCoverageThreshold($filename, $coverageInformation)
{
$classes = PHPUnitUtil::getDefinedClasses($filename, $this->_classpath);
if (is_array($classes)) {
foreach ($classes as $className) {
// Skip class if excluded from coverage threshold validation
if ($this->_excludes !== null) {
if (in_array($className, $this->_excludes->getExcludedClasses())) {
continue;
}
}
$reflection = new ReflectionClass($className);
$classStartLine = $reflection->getStartLine();
// Strange PHP5 reflection bug, classes without parent class
// or implemented interfaces seem to start one line off
if ($reflection->getParentClass() === null
&& count($reflection->getInterfaces()) === 0
) {
unset($coverageInformation[$classStartLine + 1]);
} else {
unset($coverageInformation[$classStartLine]);
}
reset($coverageInformation);
$methods = $reflection->getMethods();
foreach ($methods as $method) {
// PHP5 reflection considers methods of a parent class
// to be part of a subclass, we don't
if ($method->getDeclaringClass()->getName() != $reflection->getName()) {
continue;
}
// Skip method if excluded from coverage threshold validation
if ($this->_excludes !== null) {
$excludedMethods = $this->_excludes->getExcludedMethods();
if (isset($excludedMethods[$className])) {
if (in_array($method->getName(), $excludedMethods[$className])
|| in_array($method->getName() . '()', $excludedMethods[$className])
) {
continue;
}
}
}
$methodStartLine = $method->getStartLine();
$methodEndLine = $method->getEndLine();
// small fix for XDEBUG_CC_UNUSED
if (isset($coverageInformation[$methodStartLine])) {
unset($coverageInformation[$methodStartLine]);
}
if (isset($coverageInformation[$methodEndLine])) {
unset($coverageInformation[$methodEndLine]);
}
if ($method->isAbstract()) {
continue;
}
$lineNr = key($coverageInformation);
while ($lineNr !== null && $lineNr < $methodStartLine) {
next($coverageInformation);
$lineNr = key($coverageInformation);
}
$methodStatementsCovered = 0;
$methodStatementCount = 0;
while ($lineNr !== null && $lineNr <= $methodEndLine) {
$methodStatementCount++;
$lineCoverageInfo = $coverageInformation[$lineNr];
// set covered when CODE is other than -1 (not executed)
if ($lineCoverageInfo > 0 || $lineCoverageInfo === -2) {
$methodStatementsCovered++;
}
next($coverageInformation);
$lineNr = key($coverageInformation);
}
if ($methodStatementCount > 0) {
$methodCoverage = ($methodStatementsCovered
/ $methodStatementCount) * 100;
} else {
$methodCoverage = 0;
}
if ($methodCoverage < $this->_perMethod
&& !$method->isAbstract()
) {
throw new BuildException(
'The coverage (' . round($methodCoverage, 2) . '%) '
. 'for method "' . $method->getName() . '" is lower'
. ' than the specified threshold ('
. $this->_perMethod . '%), see file: "'
. $filename . '"'
);
} elseif ($methodCoverage < $this->_perMethod
&& $method->isAbstract()
&& $this->_verbose === true
) {
$this->log(
'Skipped coverage threshold for abstract method "'
. $method->getName() . '"'
);
}
// store the minimum coverage value for logging (see #466)
if ($this->_minMethodCoverageFound !== null) {
if ($this->_minMethodCoverageFound > $methodCoverage) {
$this->_minMethodCoverageFound = $methodCoverage;
}
} else {
$this->_minMethodCoverageFound = $methodCoverage;
}
}
$classStatementCount = count($coverageInformation);
$classStatementsCovered = count(
array_filter(
$coverageInformation,
array($this, 'filterCovered')
)
);
if ($classStatementCount > 0) {
$classCoverage = ($classStatementsCovered
/ $classStatementCount) * 100;
} else {
$classCoverage = 0;
}
if ($classCoverage < $this->_perClass
&& !$reflection->isAbstract()
) {
throw new BuildException(
'The coverage (' . round($classCoverage, 2) . '%) for class "'
. $reflection->getName() . '" is lower than the '
. 'specified threshold (' . $this->_perClass . '%), '
. 'see file: "' . $filename . '"'
);
} elseif ($classCoverage < $this->_perClass
&& $reflection->isAbstract()
&& $this->_verbose === true
) {
$this->log(
'Skipped coverage threshold for abstract class "'
. $reflection->getName() . '"'
);
}
// store the minimum coverage value for logging (see #466)
if ($this->_minClassCoverageFound !== null) {
if ($this->_minClassCoverageFound > $classCoverage) {
$this->_minClassCoverageFound = $classCoverage;
}
} else {
$this->_minClassCoverageFound = $classCoverage;
}
$this->_projectStatementCount += $classStatementCount;
$this->_projectStatementsCovered += $classStatementsCovered;
}
}
}
public function main()
{
if ($this->_database === null) {
$coverageDatabase = $this->project
->getProperty('coverage.database');
if (!$coverageDatabase) {
throw new BuildException(
'Either include coverage-setup in your build file or set '
. 'the "database" attribute'
);
}
$database = new PhingFile($coverageDatabase);
} else {
$database = $this->_database;
}
$this->log(
'Calculating coverage threshold: min. '
. $this->_perProject . '% per project, '
. $this->_perClass . '% per class and '
. $this->_perMethod . '% per method is required'
);
$props = new Properties();
$props->load($database);
foreach ($props->keys() as $filename) {
$file = unserialize($props->getProperty($filename));
// Skip file if excluded from coverage threshold validation
if ($this->_excludes !== null) {
if (in_array($file['fullname'], $this->_excludes->getExcludedFiles())) {
continue;
}
}
$this->calculateCoverageThreshold(
$file['fullname'],
$file['coverage']
);
}
if ($this->_projectStatementCount > 0) {
$coverage = ($this->_projectStatementsCovered
/ $this->_projectStatementCount) * 100;
} else {
$coverage = 0;
}
if ($coverage < $this->_perProject) {
throw new BuildException(
'The coverage (' . round($coverage, 2) . '%) for the entire project '
. 'is lower than the specified threshold ('
. $this->_perProject . '%)'
);
}
$this->log(
'Passed coverage threshold. Minimum found coverage values are: '
. round($coverage, 2) . '% per project, '
. round($this->_minClassCoverageFound, 2) . '% per class and '
. round($this->_minMethodCoverageFound, 2) . '% per method'
);
}
}
phing-2.16.0/tasks/ext/coverage/CoverageMergerTask.php 0000644 0001750 0001750 00000005434 13027032674 021670 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/Writer.php';
require_once 'phing/system/util/Properties.php';
require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
/**
* Merges code coverage snippets into a code coverage database
*
* @author Michiel Rook
* @version $Id: 6d4732d2b352c992dc03cd92cd83ad1b81bf9e45 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageMergerTask extends Task
{
/** the list of filesets containing the .php filename rules */
private $filesets = array();
/**
* Add a new fileset containing the .php files to process
*
* @param FileSet the new fileset containing .php files
*/
public function addFileSet(FileSet $fileset)
{
$this->filesets[] = $fileset;
}
/**
* Iterate over all filesets and return all the filenames.
*
* @return array an array of filenames
*/
private function getFilenames()
{
$files = array();
foreach ($this->filesets as $fileset) {
$ds = $fileset->getDirectoryScanner($this->project);
$ds->scan();
$includedFiles = $ds->getIncludedFiles();
foreach ($includedFiles as $file) {
$fs = new PhingFile(basename($ds->getBaseDir()), $file);
$files[] = $fs->getAbsolutePath();
}
}
return $files;
}
public function main()
{
$files = $this->getFilenames();
$this->log("Merging " . count($files) . " coverage files");
foreach ($files as $file) {
$coverageInformation = unserialize(file_get_contents($file));
CoverageMerger::merge($this->project, array($coverageInformation));
}
}
}
phing-2.16.0/tasks/ext/coverage/CoverageMerger.php 0000644 0001750 0001750 00000012450 13027032674 021041 0 ustar druid druid .
*/
require_once 'phing/system/util/Properties.php';
/**
* Saves coverage output of the test to a specified database
*
* @author Michiel Rook
* @version $Id: 18a66018595b27816f2bd0ac5f2d67a42ea16416 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageMerger
{
/**
* @param $left
* @param $right
* @return array
*/
private static function mergeCodeCoverage($left, $right)
{
$coverageMerged = array();
reset($left);
reset($right);
while (current($left) !== false && current($right) !== false) {
$linenr_left = key($left);
$linenr_right = key($right);
if ($linenr_left < $linenr_right) {
$coverageMerged[$linenr_left] = current($left);
next($left);
} elseif ($linenr_right < $linenr_left) {
$coverageMerged[$linenr_right] = current($right);
next($right);
} else {
if ((current($left) < 0) || (current($right) < 0)) {
$coverageMerged[$linenr_right] = current($right);
} else {
$coverageMerged[$linenr_right] = current($left) + current($right);
}
next($left);
next($right);
}
}
while (current($left) !== false) {
$coverageMerged[key($left)] = current($left);
next($left);
}
while (current($right) !== false) {
$coverageMerged[key($right)] = current($right);
next($right);
}
return $coverageMerged;
}
/**
* @param Project $project
* @return Properties
* @throws BuildException
*/
protected static function _getDatabase($project)
{
$coverageDatabase = $project->getProperty('coverage.database');
if (!$coverageDatabase) {
throw new BuildException("Property coverage.database is not set - please include coverage-setup in your build file");
}
$database = new PhingFile($coverageDatabase);
$props = new Properties();
$props->load($database);
return $props;
}
/**
* @param $project
* @return array
* @throws BuildException
*/
public static function getWhiteList($project)
{
$whitelist = array();
$props = self::_getDatabase($project);
foreach ($props->getProperties() as $property) {
$data = unserialize($property);
$whitelist[] = $data['fullname'];
}
return $whitelist;
}
/**
* @param $project
* @param $codeCoverageInformation
* @throws BuildException
* @throws IOException
*/
public static function merge($project, $codeCoverageInformation)
{
$props = self::_getDatabase($project);
$coverageTotal = $codeCoverageInformation;
foreach ($coverageTotal as $filename => $data) {
$lines = array();
$filename = strtolower($filename);
if ($props->getProperty($filename) != null) {
foreach ($data as $_line => $_data) {
if ($_data === null) {
continue;
}
if (is_array($_data)) {
$count = count($_data);
if ($count == 0) {
$count = -1;
}
} else {
if ($_data == -1) {
// not executed
$count = -1;
} else {
if ($_data == -2) {
// dead code
$count = -2;
}
}
}
$lines[$_line] = $count;
}
ksort($lines);
$file = unserialize($props->getProperty($filename));
$left = $file['coverage'];
$coverageMerged = CoverageMerger::mergeCodeCoverage($left, $lines);
$file['coverage'] = $coverageMerged;
$props->setProperty($filename, serialize($file));
}
}
$props->store();
}
}
phing-2.16.0/tasks/ext/coverage/CoverageReportTransformer.php 0000644 0001750 0001750 00000012070 13027032674 023314 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/FileWriter.php';
require_once 'phing/util/ExtendedFileStream.php';
/**
* Transform a Phing/Xdebug code coverage xml report.
* The default transformation generates an html report in framed style.
*
* @author Michiel Rook
* @version $Id: d3a5fbec986f8d4d1fde4875192fb243c82f1e68 $
* @package phing.tasks.ext.coverage
* @since 2.1.0
*/
class CoverageReportTransformer
{
private $task = null;
private $styleDir = "";
/**
* @var PhingFile
*/
private $toDir = "";
private $document = null;
/** title of the project, used in the coverage report */
private $title = "";
/**
* Whether to use the sorttable JavaScript library, defaults to false
* See {@link http://www.kryogenix.org/code/browser/sorttable/)}
*
* @var boolean
*/
private $useSortTable = false;
/**
* @param Task $task
*/
public function __construct(Task $task)
{
$this->task = $task;
}
/**
* @param $styleDir
*/
public function setStyleDir($styleDir)
{
$this->styleDir = $styleDir;
}
/**
* @param PhingFile $toDir
*/
public function setToDir(PhingFile $toDir)
{
$this->toDir = $toDir;
}
/**
* @param $document
*/
public function setXmlDocument($document)
{
$this->document = $document;
}
/**
* Setter for title parameter
* @param $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Sets whether to use the sorttable JavaScript library, defaults to false
* See {@link http://www.kryogenix.org/code/browser/sorttable/)}
*
* @param boolean $useSortTable
*/
public function setUseSortTable($useSortTable)
{
$this->useSortTable = (boolean) $useSortTable;
}
public function transform()
{
if (!$this->toDir->exists()) {
throw new BuildException("Directory '" . $this->toDir . "' does not exist");
}
$xslfile = $this->getStyleSheet();
$xsl = new DOMDocument();
$xsl->load($xslfile->getAbsolutePath());
$proc = new XSLTProcessor();
if (defined('XSL_SECPREF_WRITE_FILE')) {
if (version_compare(PHP_VERSION, '5.4', "<")) {
ini_set("xsl.security_prefs", XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY);
} else {
$proc->setSecurityPrefs(XSL_SECPREF_WRITE_FILE | XSL_SECPREF_CREATE_DIRECTORY);
}
}
$proc->importStyleSheet($xsl);
ExtendedFileStream::registerStream();
$toDir = (string) $this->toDir;
// urlencode() the path if we're on Windows
if (FileSystem::getFileSystem()->getSeparator() == '\\') {
$toDir = urlencode($toDir);
}
// no output for the framed report
// it's all done by extension...
$proc->setParameter('', 'output.dir', $toDir);
$proc->setParameter('', 'output.sorttable', $this->useSortTable);
$proc->setParameter('', 'document.title', $this->title);
$proc->transformToXML($this->document);
ExtendedFileStream::unregisterStream();
}
/**
* @return PhingFile
* @throws BuildException
*/
private function getStyleSheet()
{
$xslname = "coverage-frames.xsl";
if ($this->styleDir) {
$file = new PhingFile($this->styleDir, $xslname);
} else {
$path = Phing::getResourcePath("phing/etc/$xslname");
if ($path === null) {
$path = Phing::getResourcePath("etc/$xslname");
if ($path === null) {
throw new BuildException("Could not find $xslname in resource path");
}
}
$file = new PhingFile($path);
}
if (!$file->exists()) {
throw new BuildException("Could not find file " . $file->getPath());
}
return $file;
}
}
phing-2.16.0/tasks/ext/zendguard/ZendGuardEncodeTask.php 0000644 0001750 0001750 00000036313 13027032674 022164 0 ustar druid druid .
*/
require_once 'phing/tasks/system/MatchingTask.php';
include_once 'phing/util/SourceFileScanner.php';
include_once 'phing/mappers/MergeMapper.php';
include_once 'phing/util/StringHelper.php';
/**
* Encodes files using Zeng Guard Encoder
*
* @author Petr Rybak
* @version $Id: aacbd9ea1b3f9e13178cea0f5ff625f921076a32 $
* @package phing.tasks.ext.zendguard
* @since 2.4.3
*/
class ZendGuardEncodeTask extends MatchingTask
{
protected $filesets = array();
protected $encodeCommand;
/**
* TASK PROPERTIES
*
* See http://static.zend.com/topics/Zend-Guard-User-Guidev5x.pdf
* for more information on how to use ZendGuard
*
*/
/**
* Permanently deletes (see warning below) the original source files specified in the
* SourceInputPath and saves the encoded files in its place.
* This option has no option parameter.
* When this option is use, do not use the output_file parameter.
*
* Warning:
* To avoid permanent loss of non-encoded scripts, make a backup. Deleted files
* cannot be restored or recovered and will be permanently deleted with this option.
* If you are unsure about deleting the source files, use the ––rename-source option
* instead
*
* @var bool
*/
protected $deleteSource = true;
/**
* Move the original source file to . and save the encoded file in its
* place.
*
* If specified deleteSource will be automatically disabled.
*
* @var string
*/
protected $renameSourceExt = null;
/**
* Turns short PHP tag (“” ) 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
* @param $value
*/
public function setZendEncoderPath($value)
{
$this->zendEncoderPath = $value;
}
/**
* @param $value
*/
public function setPrivateKeyPath($value)
{
$this->privateKeyPath = $value;
}
/**
* @param $value
*/
public function setShortTags($value)
{
$this->shortTags = (bool) $value;
}
/**
* @param $value
*/
public function setAspTags($value)
{
$this->aspTags = (bool) $value;
}
/**
* @param $value
*/
public function setDeleteSource($value)
{
$this->shortTags = (bool) $value;
}
/**
* @param $value
*/
public function setUseCrypto($value)
{
$this->useCrypto = (bool) $value;
}
/**
* @param $value
*/
public function setObfuscationLevel($value)
{
$this->obfuscationLevel = (int) $value;
}
/**
* @param $value
*/
public function setLicenseProduct($value)
{
$this->licenseProduct = (bool) $value;
}
/**
* @param $value
*/
public function setPrologFile($value)
{
$this->prologFile = $value;
}
/**
* @param $value
*/
public function setSignProduct($value)
{
$this->signProduct = (bool) $value;
}
/**
* @param $value
*/
public function setForceEncode($value)
{
$this->forceEncode = (bool) $value;
}
/**
* @param $value
*/
public function setEncodedOnly($value)
{
$this->encodedOnly = (bool) $value;
}
/**
* @param $value
*/
public function setIgnoreFileModes($value)
{
$this->ignoreFileModes = (bool) $value;
}
/**
* @param $value
*/
public function setExpires($value)
{
$this->expires = $value;
}
/**
* @param $value
*/
public function setProductName($value)
{
$this->productName = $value;
}
/**
* @param $value
*/
public function setOptMask($value)
{
$this->optMask = (int) $value;
}
/**
* @param $value
*/
public function setRenameSourceExt($value)
{
$this->renameSourceExt = $value;
}
/**
* @param $value
*/
public function setNoHeader($value)
{
$this->noHeader = (bool) $value;
}
/**
* Add a new fileset.
*
* @return FileSet
*/
public function createFileSet()
{
$this->fileset = new ZendGuardFileSet();
$this->filesets[] = $this->fileset;
return $this->fileset;
}
/**
* Verifies that the configuration is correct
*
* @throws BuildException
*/
protected function verifyConfiguration()
{
// Check that the zend encoder path is specified
if (empty($this->zendEncoderPath)) {
throw new BuildException("Zend Encoder path must be specified");
}
// verify that the zend encoder binary exists
if (!file_exists($this->zendEncoderPath)) {
throw new BuildException("Zend Encoder not found on path " . $this->zendEncoderPath);
}
// if either sign or license is required the private key path needs to be defined
// and the file has to exist and product name has to be specified
if ($this->signProduct || $this->licenseProduct) {
if (empty($this->privateKeyPath)) {
throw new BuildException("Licensing or signing requested but privateKeyPath not provided.");
}
if (!is_readable($this->privateKeyPath)) {
throw new BuildException("Licensing or signing requested but private key path doesn't exist or is unreadable.");
}
if (empty($this->productName)) {
throw new BuildException("Licensing or signing requested but product name not provided.");
}
}
// verify prolog file exists
if (!empty($this->prologFile)) {
if (!file_exists($this->prologFile)) {
throw new BuildException("The prolog file doesn't exist: " . $this->prologFile);
}
}
}
/**
* Do the work
*
* @throws BuildException
*/
public function main()
{
$this->verifyConfiguration();
$this->prepareEncoderCommand();
try {
if (empty($this->filesets)) {
throw new BuildException("You must supply nested fileset.",
$this->getLocation());
}
$encodedFilesCounter = 0;
foreach ($this->filesets as $fs) {
/* @var $fs FileSet */
/* @var $fsBasedir PhingFile */
$fsBasedir = $fs->getDir($this->project)->getAbsolutePath();
$files = $fs->getFiles($this->project, false);
foreach ($files as $file) {
$f = new PhingFile($fsBasedir, $file);
if ($f->isFile()) {
$path = $f->getAbsolutePath();
$this->log("Encoding " . $path, Project::MSG_VERBOSE);
$this->encodeFile($path);
$encodedFilesCounter++;
}
}
}
$this->log("Encoded files: " . $encodedFilesCounter);
} catch (IOException $ioe) {
$msg = "Problem encoding files: " . $ioe->getMessage();
throw new BuildException($msg, $ioe, $this->getLocation());
}
}
/**
* Prepares the main part of the command that will be
* used to encode the given file(s).
*/
protected function prepareEncoderCommand()
{
$command = $this->zendEncoderPath . " ";
if (!empty($this->renameSourceExt)) {
$command .= " --rename-source " . $this->renameSourceExt . " ";
} elseif ($this->deleteSource) {
// delete source
$command .= " --delete-source ";
}
// short tags
$command .= " --short-tags " . (($this->shortTags) ? 'on' : 'off') . " ";
// asp tags
$command .= " --asp-tags " . (($this->aspTags) ? 'on' : 'off') . " ";
// use crypto
if ($this->useCrypto) {
$command .= " --use-crypto ";
}
// ignore file modes
if ($this->ignoreFileModes) {
$command .= " --ignore-file-modes ";
}
// force encode
if ($this->forceEncode) {
$command .= " --force-encode ";
}
// expires
if (!empty($this->expires)) {
$command .= " --expires " . $this->expires . " ";
}
// insert prolog file name or no-header
if (!empty($this->prologFile)) {
$command .= " --prolog-filename " . $this->prologFile . " ";
} elseif ($this->noHeader) {
// no-header
$command .= " --no-header ";
}
// obfuscation level
if ($this->obfuscationLevel > 0) {
$command .= " --obfuscation-level " . $this->obfuscationLevel . " ";
}
// encoded only
if ($this->encodedOnly) {
$command .= " --encoded-only ";
}
// opt mask
if (null !== $this->optMask) {
$command .= " --optimizations " . $this->optMask . " ";
}
// Signing or licensing
if ($this->signProduct) {
$command .= " --sign-product " . $this->productName . " --private-key " . $this->privateKeyPath . " ";
} elseif ($this->licenseProduct) {
$command .= " --license-product " . $this->productName . " --private-key " . $this->privateKeyPath . " ";
}
// add a blank space
$command .= " ";
$this->encodeCommand = $command;
}
/**
* Encodes a file using currently defined Zend Guard settings
*
* @param string $filePath Path to the encoded file
* @throws BuildException
* @return bool
*/
protected function encodeFile($filePath)
{
$command = $this->encodeCommand . $filePath . ' 2>&1';
$this->log('Running: ' . $command, Project::MSG_VERBOSE);
$tmp = exec($command, $output, $return_var);
if ($return_var !== 0) {
throw new BuildException("Encoding failed. \n Msg: " . $tmp . " \n Encode command: " . $command);
}
return true;
}
}
/**
* This is a FileSet with the to specify permissions.
*
* Permissions are currently not implemented by PEAR Archive_Tar,
* but hopefully they will be in the future.
*
* @package phing.tasks.ext.zendguard
*/
class ZendGuardFileSet extends FileSet
{
private $files = null;
/**
* Get a list of files and directories specified in the fileset.
* @param Project $p
* @param bool $includeEmpty
* @throws BuildException
* @return array a list of file and directory names, relative to
* the baseDir for the project.
*/
public function getFiles(Project $p, $includeEmpty = true)
{
if ($this->files === null) {
$ds = $this->getDirectoryScanner($p);
$this->files = $ds->getIncludedFiles();
} // if ($this->files===null)
return $this->files;
}
}
phing-2.16.0/tasks/ext/zendguard/ZendGuardLicenseTask.php 0000644 0001750 0001750 00000041216 13027032674 022347 0 ustar druid druid .
*/
/**
* Produce license files using Zeng Guard.
* The task can produce a license file from the given
* license properties or it can use a template.
*
* @author Petr Rybak
* @version $Id: 2e1e3730b96f5d5ea32d54fda8d9333b34eeaaba $
* @package phing.tasks.ext.zendguard
* @since 2.4.3
*/
class ZendGuardLicenseTask extends Task
{
protected $zendsignCommand;
private $tmpLicensePath;
/**
* TASK PROPERTIES
*
* See http://static.zend.com/topics/Zend-Guard-User-Guidev5x.pdf
* for more information on how to use ZendGuard
*
*/
/**
* Path to Zend Guard zendenc_sign executable
*
* @var string
*/
protected $zendsignPath;
/**
* Path to private key that will be used to sign the license
*
* @var string
*/
protected $privateKeyPath;
/**
* Where to store the signed license file
*
* @var string
*/
protected $outputFile;
/**
* Path to license template. If specified all
* license properties will be ignored and the
* template will be used to generate the file.
*
* @var string
*/
protected $licenseTemplate;
/**
* The name assigned to Product. This must be the same name used when encoding
* the PHP files.
*
* REQUIRED
*
* @var string
*/
protected $productName;
/**
* The Name of the Registered owner of the license.
*
* REQUIRED
*
* @var string
*/
protected $registeredTo;
/**
* Expiration date of the license. Used if the license is issued with a date restriction.
* Possible values:
* - 'Never', '0' or false: the license won't expire
* - A Date in format DD-MM-YYYY to set expiration for that date
* - Relative date supported by the PHP strtotime function (e.g. +1 month)
*
* REQUIRED
*
* @var string
*/
protected $expires;
/**
* Limits the use of the license to IP addresses that fall within specification. Supports
* wildcards for any of the IP place holders, as well as the two types of net masks
* (filters).
* Netmask pair An IP a.b.c.d, and a netmask w.x.y.z. (That is., 10.1.0.0/255.255.0.0),
* where the binary of mask is applied to filter IP addresses.
* ip/nnn (similar to a CIDR specification) This mask consists of nnn high-order 1 bits.
* (That is, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0). Instead of spelling out
* the bits of the subnet mask, this mask notation is simply listed as the number of 1s
* bits that start the mask. Rather than writing the address and subnet mask as
* 192.60.128.0/255.255.252.0 the network address would be written simply as:
* 192.60.128.0/22 which indicates starting address of the network and number of 1s
* bits (22) in the network portion of the address. The mask in binary is
* (11111111.11111111.11111100.00000000).
*
* OPTIONAL
*
* Example (Wildcard):
* IP-Range = 10.1.*.*
* Example (Net Mask):
* IP-Range = 10.1.0.0/255.255.0.0
* Example (Net Mask):
* IP-Range = 10.1.0.0/16
*
* @var string
*/
protected $ipRange;
/**
* Coded string (Zend Host ID) used to lock the license to a specific hardware. The
* Zend Host ID obtained from the machine where the encoded files and license are
* to be installed. The Zend Host ID code can be obtained by using the zendid utility.
* For more details, see Getting the Zend Host ID.
*
* REQUIRED if Hardware-Locked is set equal to YES.
* Meaningless if Hardware-Locked is set equal to NO.
*
* User semicolon to enter more than one Host-ID
*
* Example:
* Host-ID = H:MFM43-Q9CXC-B9EDX-GWYSU;H:MFM43-Q9CXC-B9EDX-GWYTY
*
* @var string
*/
protected $hostID;
/**
* Option that indicates if the license will be locked to a specific machine
* using the Zend Host ID code(s). If set to YES, the Host-ID is required.
*
* OPTIONAL
*
* @var bool
*/
protected $hardwareLocked;
/**
* Semi-colon separated user defined values that will be part of the license. These values
* CANNOT be modified after the license is produced. Modification
* would invalidate the license.
*
* OPTIONAL
* Example:
* Tea=Mint Flavor;Coffee=Arabica
*
* @var string
*/
protected $userDefinedValues;
/**
* Semi-colon separated user defined x-values that will be part of the license. These values
* CAN be modified after the license is produced. Modification
* won't invalidate the license.
*
* OPTIONAL
* Example:
* Tea=Mint Flavor;Coffee=Arabica
*
* @var string
*/
protected $xUserDefinedValues;
/**
* @param $value
*/
public function setLicenseTemplate($value)
{
$this->licenseTemplate = $value;
}
/**
* @param $productName
*/
public function setProductName($productName)
{
$this->productName = $productName;
}
/**
* @param $registeredTo
*/
public function setRegisteredTo($registeredTo)
{
$this->registeredTo = $registeredTo;
}
/**
* Process the expires property. If the value is
* empty (false, '', ...) it will set the value to 'Never'
* Otherwise it will run the value through strtotime so relative
* date and time notation can be used (e.g. +1 month)
*
* @param mixed $expires
*
* @throws BuildException
* @return string
*/
public function setExpires($expires)
{
// process the expires value
if (false === $expires || '0' === $expires || strtolower($expires) == 'never' || '' === $expires) {
$this->expires = 'Never';
} else {
$time = strtotime($expires);
if (!$time) {
throw new BuildException("Unsupported expires format: " . $expires);
}
$this->expires = date('d-M-Y', $time);
}
}
/**
* @param $iprange
*/
public function setIpRange($iprange)
{
$this->ipRange = $iprange;
}
/**
* @param $hostID
*/
public function setHostID($hostID)
{
$this->hostID = $hostID;
}
/**
* @param $hardwareLocked
*/
public function setHardwareLocked($hardwareLocked)
{
$this->hardwareLocked = (bool) $hardwareLocked;
}
/**
* @param $userDefinedValues
*/
public function setUserDefinedValues($userDefinedValues)
{
$this->userDefinedValues = $userDefinedValues;
}
/**
* @param $xUserDefinedValues
*/
public function setXUserDefinedValues($xUserDefinedValues)
{
$this->xUserDefinedValues = $xUserDefinedValues;
}
/**
* @param $zendsignPath
*/
public function setZendsignPath($zendsignPath)
{
$this->zendsignPath = $zendsignPath;
}
/**
* @param $privateKeyPath
*/
public function setPrivateKeyPath($privateKeyPath)
{
$this->privateKeyPath = $privateKeyPath;
}
/**
* @param $outputFile
*/
public function setOutputFile($outputFile)
{
$this->outputFile = $outputFile;
}
/**
* Verifies that the configuration is correct
*
* @throws BuildException
*/
protected function verifyConfiguration()
{
// Check that the zend encoder path is specified
if (empty($this->zendsignPath)) {
throw new BuildException("Zendenc_sign path must be specified");
}
// verify that the zend encoder binary exists
if (!file_exists($this->zendsignPath)) {
throw new BuildException("Zendenc_sign not found on path " . $this->zendsignPath);
}
// verify that the private key path is defined
if (empty($this->privateKeyPath)) {
throw new BuildException("You must define privateKeyPath.");
}
// verify that the private key file is readable
if (!is_readable($this->privateKeyPath)) {
throw new BuildException("Private key file is not readable: " . $this->privateKeyPath);
}
// if template is passed, verify that it is readable
if (!empty($this->licenseTemplate)) {
if (!is_readable($this->licenseTemplate)) {
throw new BuildException("License template file is not readable " . $this->licenseTemplate);
}
}
// check that output file path is defined
if (empty($this->outputFile)) {
throw new BuildException("Path where to store the result file needs to be defined in outputFile property");
}
// if license template is NOT provided check that all required parameters are defined
if (empty($this->licenseTemplate)) {
// check productName
if (empty($this->productName)) {
throw new BuildException("Property must be defined: productName");
}
// check expires
if (null === $this->expires) {
throw new BuildException("Property must be defined: expires");
}
// check registeredTo
if (empty($this->registeredTo)) {
throw new BuildException("Property must be defined: registeredTo");
}
// check hardwareLocked
if (null === $this->hardwareLocked) {
throw new BuildException("Property must be defined: hardwareLocked");
}
// if hardwareLocked is set to true, check that Host-ID is set
if ($this->hardwareLocked) {
if (empty($this->hostID)) {
throw new BuildException("If you set hardwareLocked to true hostID must be provided");
}
}
}
}
/**
* Do the work
*
* @throws BuildException
*/
public function main()
{
try {
$this->verifyConfiguration();
$this->generateLicense();
} catch (Exception $e) {
// remove the license temp file if it was created
$this->cleanupTmpFiles();
throw $e;
}
$this->cleanupTmpFiles();
}
/**
* If temporary license file was created during the process
* this will remove it
*
* @return void
*/
private function cleanupTmpFiles()
{
if (!empty($this->tmpLicensePath) && file_exists($this->tmpLicensePath)) {
$this->log("Deleting temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE);
unlink($this->tmpLicensePath);
}
}
/**
* Prepares and returns the command that will be
* used to create the license.
*
* @return string
*/
protected function prepareSignCommand()
{
$command = $this->zendsignPath;
// add license path
$command .= ' ' . $this->getLicenseTemplatePath();
// add result file path
$command .= ' ' . $this->outputFile;
// add key path
$command .= ' ' . $this->privateKeyPath;
$this->zendsignCommand = $command;
return $command;
}
/**
* Checks if the license template path is defined
* and returns it.
* If it the license template path is not defined
* it will generate a temporary template file and
* provide it as a template.
*
* @return string
*/
protected function getLicenseTemplatePath()
{
if (!empty($this->licenseTemplate)) {
return $this->licenseTemplate;
} else {
return $this->generateLicenseTemplate();
}
}
/**
* Creates the signed license at the defined output path
*
* @throws BuildException
* @return void
*/
protected function generateLicense()
{
$command = $this->prepareSignCommand() . ' 2>&1';
$this->log('Creating license at ' . $this->outputFile);
$this->log('Running: ' . $command, Project::MSG_VERBOSE);
$tmp = exec($command, $output, $return_var);
// Check for exit value 1. Zendenc_sign command for some reason
// returns 0 in case of failure and 1 in case of success...
if ($return_var !== 1) {
throw new BuildException("Creating license failed. \n\nZendenc_sign msg:\n" . join("\n", $output) . "\n\n");
}
}
/**
* It will generate a temporary license template
* based on the properties defined.
*
* @throws BuildException
* @return string Path of the temporary license template file
*/
protected function generateLicenseTemplate()
{
$this->tmpLicensePath = tempnam(sys_get_temp_dir(), 'zendlicense');
$this->log("Creating temporary license template " . $this->tmpLicensePath, Project::MSG_VERBOSE);
if (file_put_contents($this->tmpLicensePath, $this->generateLicenseTemplateContent()) === false) {
throw new BuildException("Unable to create temporary template license file: " . $this->tmpLicensePath);
}
return $this->tmpLicensePath;
}
/**
* Generates license template content based
* on the defined parameters
*
* @return string
*/
protected function generateLicenseTemplateContent()
{
$contentArr = array();
// Product Name
$contentArr[] = array('Product-Name', $this->productName);
// Registered to
$contentArr[] = array('Registered-To', $this->registeredTo);
// Hardware locked
$contentArr[] = array('Hardware-Locked', ($this->hardwareLocked ? 'Yes' : 'No'));
// Expires
$contentArr[] = array('Expires', $this->expires);
// IP-Range
if (!empty($this->ipRange)) {
$contentArr[] = array('IP-Range', $this->ipRange);
}
// Host-ID
if (!empty($this->hostID)) {
foreach (explode(';', $this->hostID) as $hostID) {
$contentArr[] = array('Host-ID', $hostID);
}
} else {
$contentArr[] = array('Host-ID', 'Not-Locked');
}
// parse user defined fields
if (!empty($this->userDefinedValues)) {
$this->parseAndAddUserDefinedValues($this->userDefinedValues, $contentArr);
}
// parse user defined x-fields
if (!empty($this->xUserDefinedValues)) {
$this->parseAndAddUserDefinedValues($this->xUserDefinedValues, $contentArr, 'X-');
}
// merge all the values
$content = '';
foreach ($contentArr as $valuePair) {
list($key, $value) = $valuePair;
$content .= $key . " = " . $value . "\n";
}
return $content;
}
/**
* Parse the given string in format like key1=value1;key2=value2;... and
* converts it to array
* (key1=>value1, key2=value2, ...)
*
* @param string $valueString Semi-colon separated value pairs
* @param array $valueArray Array to which the values will be added
* @param string $keyPrefix Prefix to use when adding the key
*
* @param string $pairSeparator
* @return void
*/
protected function parseAndAddUserDefinedValues(
$valueString,
array &$valueArray,
$keyPrefix = '',
$pairSeparator = ';'
) {
// explode the valueString (semicolon)
$valuePairs = explode($pairSeparator, $valueString);
if (!empty($valuePairs)) {
foreach ($valuePairs as $valuePair) {
list($key, $value) = explode('=', $valuePair, 2);
// add pair into the valueArray
$valueArray[] = array($keyPrefix . $key, $value);
}
}
}
}
phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php 0000644 0001750 0001750 00000006227 13027032674 024146 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* Class ZendServerDeploymentToolTask
*
* @author Siad Ardroumli
* @package phing.tasks.ext.zendserverdevelopmenttools
*/
abstract class zsdtBaseTask extends Task
{
protected $action;
protected $arguments = '';
/** @var string $descriptor */
protected $descriptor;
/** @var string $schema */
protected $schema;
/** @var array $path */
private $path = array(
'NIX' => '/usr/local/zend/bin/zdpack',
'WIN' => 'C:\Program Files (x86)\Zend\ZendServer\bin\zdpack',
'USR' => ''
);
/**
* The package descriptor file.
*
* @param string $descriptor
*
* @return void
*/
public function setDescriptor($descriptor)
{
$this->descriptor = escapeshellarg($descriptor);
}
/**
* The path to the package descriptor schema used for validation.
*
* @param string $schema
*
* @return void
*/
public function setSchema($schema)
{
$this->schema = escapeshellarg($schema);
}
/**
* @param string $path
*
* @return void
*/
public function setPath($path)
{
$this->path['USR'] = $path;
}
/**
* {@inheritdoc}
*/
public function main()
{
$this->validate();
$command = '';
if ($this->path['USR'] !== '') {
$command .= $this->path['USR'];
} elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$command .= escapeshellarg($this->path['WIN']);
} else {
$command .= $this->path['NIX'];
}
$commandString = sprintf('%s %s %s', $command, $this->action, $this->arguments);
$msg = exec($commandString . ' 2>&1', $output, $code);
if ($code !== 0) {
throw new BuildException("Build package failed. \n Msg: " . $msg . " \n Pack command: " . $commandString);
}
}
/**
* Validates argument list.
*
* @return void
*/
protected function validate()
{
if ($this->schema !== null) {
$this->arguments .= "--schema=$this->schema ";
}
}
}
phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtValidateTask.php 0000644 0001750 0001750 00000003421 13027032674 025016 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php';
/**
* Class ZendServerDeploymentToolTask
*
* @author Siad Ardroumli
* @package phing.tasks.ext.zendserverdevelopmenttools
*/
class zsdtValidateTask extends zsdtBaseTask
{
/**
* @inheritdoc}
*
* @return void
*/
public function init()
{
$this->action = 'validate';
}
/**
* {@inheritdoc}
*
* @throws BuildException
*
* @return void
*/
protected function validate()
{
parent::validate();
if ($this->descriptor === null) {
throw new BuildException('The package descriptor file have to be set.');
}
$this->arguments .= $this->descriptor;
}
}
phing-2.16.0/tasks/ext/zendserverdeploymenttool/zsdtPackTask.php 0000644 0001750 0001750 00000011334 13027032674 024145 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/zendserverdeploymenttool/zsdtBaseTask.php';
/**
* Class ZendServerDeploymentToolTask
*
* @author Siad Ardroumli
* @package phing.tasks.ext.zendserverdevelopmenttools
*/
class zsdtPackTask extends zsdtBaseTask
{
/** @var string $package */
private $package;
/** @var string $source */
private $source;
/** @var string $scripts */
private $scripts;
/** @var string $output */
private $output;
/** @var string $phpbin */
private $phpbin;
/** @var bool $lint */
private $lint = false;
/**
* A directory containing the data and the script directories, in addition to the package descriptor file.
*
* @param string $package
*
* @return void
*/
public function setPackage($package)
{
$this->package = escapeshellarg($package);
}
/**
* Performs a PHP lint test on the deployment scripts before creating the package.
*
* @param boolean $lint
*
* @return void
*/
public function setLint($lint)
{
$this->lint = $lint;
}
/**
* The directory in which the package is created.
* The package name will be created as "-.zpk".
*
* @param string $output
*
* @return void
*/
public function setOutput($output)
{
$this->output = escapeshellarg($output);
}
/**
* The PHP executable to use for lint.
*
* @param string $phpbin
*
* @return void
*/
public function setPhpbin($phpbin)
{
$this->phpbin = escapeshellarg($phpbin);
}
/**
* The directory which contains the package deployment scripts.
* The Deployment Tool will search this directory for the expected files and then packs them.
*
* @param string $scripts
*
* @return void
*/
public function setScripts($scripts)
{
$this->scripts = escapeshellarg($scripts);
}
/**
* The directory that contains the application resources (PHP sources, JavaScript, etc.).
* The directory's internal structure must match the necessary structure for the application to be functional.
*
* @param string $source
*
* @return void
*/
public function setSource($source)
{
$this->source = escapeshellarg($source);
}
/**
* {@inheritdoc}
*
* @return void
*/
public function init()
{
$this->action = 'pack';
}
/**
* {@inheritdoc}
*
* @return void
*
* @throws BuildException
*/
protected function validate()
{
if ($this->descriptor === null || $this->scripts === null || $this->package === null) {
throw new BuildException(
'The deployment tool needs at least the project descriptor, '
. 'the scripts folder and package folder to be set.'
);
} elseif ($this->lint !== false && $this->phpbin === null) {
throw new BuildException('You set the lint option but not the path to the php executable.');
}
parent::validate();
if ($this->lint !== false) {
$this->arguments .= '--lint ';
}
if ($this->source !== null) {
$this->arguments .= "--src-dir=$this->source ";
}
if ($this->output !== null) {
$this->arguments .= "--output-dir=$this->output ";
}
if ($this->phpbin !== null) {
$this->arguments .= "--php-exe=$this->phpbin ";
}
$this->arguments .= "--scripts-dir=$this->scripts ";
$this->arguments .= "--package-descriptor=$this->descriptor ";
$this->arguments .= $this->package;
}
}
phing-2.16.0/tasks/ext/PhpCodeSnifferTask.php 0000644 0001750 0001750 00000056771 13027032674 020051 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* A PHP code sniffer task. Checking the style of one or more PHP source files.
*
* @author Dirk Thomas
* @version $Id: 1cb309b7992d03271825878803e5cabb757b9d63 $
* @package phing.tasks.ext
*/
class PhpCodeSnifferTask extends Task
{
/**
* A php source code filename or directory
*
* @var PhingFile
*/
protected $file; // the source file (from xml attribute)
/**
* All fileset objects assigned to this task
*
* @var FileSet[]
*/
protected $filesets = array(); // all fileset objects assigned to this task
// parameters for php code sniffer
protected $standards = array('Generic');
protected $sniffs = array();
protected $showWarnings = true;
protected $showSources = false;
protected $reportWidth = 80;
protected $verbosity = 0;
protected $tabWidth = 0;
protected $allowedFileExtensions = array('php', 'inc', 'js', 'css');
protected $allowedTypes = array();
protected $ignorePatterns = false;
protected $noSubdirectories = false;
protected $configData = array();
protected $encoding = 'iso-8859-1';
// parameters to customize output
protected $showSniffs = false;
protected $format = 'full';
/**
* @var PhpCodeSnifferTask_FormatterElement[]
*/
protected $formatters = array();
/**
* Holds the type of the doc generator
*
* @var string
*/
protected $docGenerator = '';
/**
* Holds the outfile for the documentation
*
* @var PhingFile
*/
protected $docFile = null;
private $haltonerror = false;
private $haltonwarning = false;
private $skipversioncheck = false;
private $propertyName = null;
/**
* Cache data storage
* @var DataStore
*/
protected $cache;
/**
* Load the necessary environment for running PHP_CodeSniffer.
*
* @return void
*/
public function init()
{
}
/**
* File to be performed syntax check on
* @param PhingFile $file
*/
public function setFile(PhingFile $file)
{
$this->file = $file;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Sets the coding standard to test for
*
* @param string $standards The coding standards
*
* @return void
*/
public function setStandard($standards)
{
$this->standards = array();
$token = ' ,;';
$ext = strtok($standards, $token);
while ($ext !== false) {
$this->standards[] = $ext;
$ext = strtok($token);
}
}
/**
* Sets the sniffs which the standard should be restricted to
* @param string $sniffs
*/
public function setSniffs($sniffs)
{
$token = ' ,;';
$sniff = strtok($sniffs, $token);
while ($sniff !== false) {
$this->sniffs[] = $sniff;
$sniff = strtok($token);
}
}
/**
* Sets the type of the doc generator
*
* @param string $generator HTML or Text
*
* @return void
*/
public function setDocGenerator($generator)
{
$this->docGenerator = $generator;
}
/**
* Sets the outfile for the documentation
*
* @param PhingFile $file The outfile for the doc
*
* @return void
*/
public function setDocFile(PhingFile $file)
{
$this->docFile = $file;
}
/**
* Sets the flag if warnings should be shown
* @param boolean $show
*/
public function setShowWarnings($show)
{
$this->showWarnings = StringHelper::booleanValue($show);
}
/**
* Sets the flag if sources should be shown
*
* @param boolean $show Whether to show sources or not
*
* @return void
*/
public function setShowSources($show)
{
$this->showSources = StringHelper::booleanValue($show);
}
/**
* Sets the width of the report
*
* @param int $width How wide the screen reports should be.
*
* @return void
*/
public function setReportWidth($width)
{
$this->reportWidth = (int) $width;
}
/**
* Sets the verbosity level
* @param int $level
*/
public function setVerbosity($level)
{
$this->verbosity = (int) $level;
}
/**
* Sets the tab width to replace tabs with spaces
* @param int $width
*/
public function setTabWidth($width)
{
$this->tabWidth = (int) $width;
}
/**
* Sets file encoding
* @param string $encoding
*/
public function setEncoding($encoding)
{
$this->encoding = $encoding;
}
/**
* Sets the allowed file extensions when using directories instead of specific files
* @param array $extensions
*/
public function setAllowedFileExtensions($extensions)
{
$this->allowedFileExtensions = array();
$token = ' ,;';
$ext = strtok($extensions, $token);
while ($ext !== false) {
$this->allowedFileExtensions[] = $ext;
$ext = strtok($token);
}
}
/**
* Sets the allowed types for the PHP_CodeSniffer::suggestType()
* @param array $types
*/
public function setAllowedTypes($types)
{
$this->allowedTypes = array();
$token = ' ,;';
$type = strtok($types, $token);
while ($type !== false) {
$this->allowedTypes[] = $type;
$type = strtok($token);
}
}
/**
* Sets the ignore patterns to skip files when using directories instead of specific files
* @param $patterns
* @internal param array $extensions
*/
public function setIgnorePatterns($patterns)
{
$this->ignorePatterns = array();
$token = ' ,;';
$pattern = strtok($patterns, $token);
while ($pattern !== false) {
$this->ignorePatterns[$pattern] = 'relative';
$pattern = strtok($token);
}
}
/**
* Sets the flag if subdirectories should be skipped
* @param boolean $subdirectories
*/
public function setNoSubdirectories($subdirectories)
{
$this->noSubdirectories = StringHelper::booleanValue($subdirectories);
}
/**
* Creates a config parameter for this task
*
* @return Parameter The created parameter
*/
public function createConfig()
{
$num = array_push($this->configData, new Parameter());
return $this->configData[$num - 1];
}
/**
* Sets the flag if the used sniffs should be listed
* @param boolean $show
*/
public function setShowSniffs($show)
{
$this->showSniffs = StringHelper::booleanValue($show);
}
/**
* Sets the output format
* @param string $format
*/
public function setFormat($format)
{
$this->format = $format;
}
/**
* Create object for nested formatter element.
* @return PhpCodeSnifferTask_FormatterElement
*/
public function createFormatter()
{
$num = array_push(
$this->formatters,
new PhpCodeSnifferTask_FormatterElement()
);
return $this->formatters[$num - 1];
}
/**
* Sets the haltonerror flag
* @param boolean $value
*/
public function setHaltonerror($value)
{
$this->haltonerror = $value;
}
/**
* Sets the haltonwarning flag
* @param boolean $value
*/
public function setHaltonwarning($value)
{
$this->haltonwarning = $value;
}
/**
* Sets the skipversioncheck flag
* @param boolean $value
*/
public function setSkipVersionCheck($value)
{
$this->skipversioncheck = $value;
}
/**
* Sets the name of the property to use
* @param $propertyName
*/
public function setPropertyName($propertyName)
{
$this->propertyName = $propertyName;
}
/**
* Returns the name of the property to use
*/
public function getPropertyName()
{
return $this->propertyName;
}
/**
* Whether to store last-modified times in cache
*
* @param PhingFile $file
*/
public function setCacheFile(PhingFile $file)
{
$this->cache = new DataStore($file);
}
/**
* Return the list of files to parse
*
* @return string[] list of absolute files to parse
*/
protected function getFilesToParse()
{
$filesToParse = array();
if ($this->file instanceof PhingFile) {
$filesToParse[] = $this->file->getPath();
} else {
// append any files in filesets
foreach ($this->filesets as $fs) {
$dir = $fs->getDir($this->project)->getAbsolutePath();
foreach ($fs->getDirectoryScanner($this->project)->getIncludedFiles() as $filename) {
$fileAbsolutePath = $dir . DIRECTORY_SEPARATOR . $filename;
if ($this->cache) {
$lastMTime = $this->cache->get($fileAbsolutePath);
$currentMTime = filemtime($fileAbsolutePath);
if ($lastMTime >= $currentMTime) {
continue;
} else {
$this->cache->put($fileAbsolutePath, $currentMTime);
}
}
$filesToParse[] = $fileAbsolutePath;
}
}
}
return $filesToParse;
}
/**
* Executes PHP code sniffer against PhingFile or a FileSet
*/
public function main()
{
if (!class_exists('PHP_CodeSniffer')) {
@include_once 'PHP/CodeSniffer.php';
if (!class_exists('PHP_CodeSniffer')) {
throw new BuildException("This task requires the PHP_CodeSniffer package installed and available on the include path", $this->getLocation(
));
}
}
/**
* Determine PHP_CodeSniffer version number
*/
if (!$this->skipversioncheck) {
if (defined('PHP_CodeSniffer::VERSION')) {
preg_match('/\d\.\d\.\d/', PHP_CodeSniffer::VERSION, $version);
} else {
preg_match('/\d\.\d\.\d/', shell_exec('phpcs --version'), $version);
}
if (version_compare($version[0], '1.2.2') < 0) {
throw new BuildException(
'PhpCodeSnifferTask requires PHP_CodeSniffer version >= 1.2.2',
$this->getLocation()
);
}
}
if (!isset($this->file) and count($this->filesets) == 0) {
throw new BuildException("Missing either a nested fileset or attribute 'file' set");
}
if (count($this->formatters) == 0) {
// turn legacy format attribute into formatter
$fmt = new PhpCodeSnifferTask_FormatterElement();
$fmt->setType($this->format);
$fmt->setUseFile(false);
$this->formatters[] = $fmt;
}
$fileList = $this->getFilesToParse();
$cwd = getcwd();
// Save command line arguments because it confuses PHPCS (version 1.3.0)
$oldArgs = $_SERVER['argv'];
$_SERVER['argv'] = array();
$_SERVER['argc'] = 0;
include_once 'phing/tasks/ext/phpcs/PhpCodeSnifferTask_Wrapper.php';
$codeSniffer = new PhpCodeSnifferTask_Wrapper($this->verbosity, $this->tabWidth, $this->encoding);
$codeSniffer->setAllowedFileExtensions($this->allowedFileExtensions);
if ($this->allowedTypes) {
PhpCodeSnifferTask_Wrapper::$allowedTypes = $this->allowedTypes;
}
if (is_array($this->ignorePatterns)) {
$codeSniffer->setIgnorePatterns($this->ignorePatterns);
}
foreach ($this->configData as $configData) {
$codeSniffer->setConfigData($configData->getName(), $configData->getValue(), true);
}
/*
* Verifying if standard is installed only after setting config data.
* Custom standard paths could be provided via installed_paths config parameter.
*/
foreach($this->standards as $standard) {
if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
// They didn't select a valid coding standard, so help them
// out by letting them know which standards are installed.
$installedStandards = PHP_CodeSniffer::getInstalledStandards();
$numStandards = count($installedStandards);
$errMsg = '';
if ($numStandards === 0) {
$errMsg = 'No coding standards are installed.';
} else {
$lastStandard = array_pop($installedStandards);
if ($numStandards === 1) {
$errMsg = 'The only coding standard installed is ' . $lastStandard;
} else {
$standardList = implode(', ', $installedStandards);
$standardList .= ' and ' . $lastStandard;
$errMsg = 'The installed coding standards are ' . $standardList;
}
}
throw new BuildException(
'ERROR: the "' . $standard . '" coding standard is not installed. ' . $errMsg,
$this->getLocation()
);
}
}
if (!$this->showWarnings) {
$codeSniffer->cli->warningSeverity = 0;
}
// nasty integration hack
$values = $codeSniffer->cli->getDefaults();
$_SERVER['argv'] = array('t');
$_SERVER['argc'] = 1;
foreach ($this->formatters as $fe) {
if ($fe->getUseFile()) {
$_SERVER['argv'][] = '--report-' . $fe->getType() . '=' . $fe->getOutfile();
} else {
$_SERVER['argv'][] = '--report-' . $fe->getType();
}
$_SERVER['argc']++;
}
if ($this->cache) {
require_once 'phing/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php';
PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache($this->cache);
// add a fake report to remove from cache
$_SERVER['argv'][] = '--report-phingRemoveFromCache=';
$_SERVER['argc']++;
}
$codeSniffer->process($fileList, $this->standards, $this->sniffs, $this->noSubdirectories);
$_SERVER['argv'] = array();
$_SERVER['argc'] = 0;
if ($this->cache) {
PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache(null);
$this->cache->commit();
}
$this->printErrorReport($codeSniffer);
// generate the documentation
if ($this->docGenerator !== '' && $this->docFile !== null) {
ob_start();
$codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator);
$output = ob_get_contents();
ob_end_clean();
// write to file
$outputFile = $this->docFile->getPath();
$check = file_put_contents($outputFile, $output);
if ($check === false) {
throw new BuildException('Error writing doc to ' . $outputFile);
}
} elseif ($this->docGenerator !== '' && $this->docFile === null) {
$codeSniffer->generateDocs($this->standards, $this->sniffs, $this->docGenerator);
}
if ($this->haltonerror && $codeSniffer->reporting->totalErrors > 0) {
throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalErrors . ' error' . ($codeSniffer->reporting->totalErrors > 1 ? 's' : ''));
}
if ($this->haltonwarning && $codeSniffer->reporting->totalWarnings > 0) {
throw new BuildException('phpcodesniffer detected ' . $codeSniffer->reporting->totalWarnings . ' warning' . ($codeSniffer->reporting->totalWarnings > 1 ? 's' : ''));
}
$_SERVER['argv'] = $oldArgs;
$_SERVER['argc'] = count($oldArgs);
chdir($cwd);
}
/**
* Prints the error report.
*
* @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing
* the errors.
*/
protected function printErrorReport($phpcs)
{
$sniffs = $phpcs->getSniffs();
$sniffStr = '';
foreach ($sniffs as $sniff) {
if (is_string($sniff)) {
$sniffStr .= '- ' . $sniff . PHP_EOL;
} else {
$sniffStr .= '- ' . get_class($sniff) . PHP_EOL;
}
}
$this->project->setProperty($this->getPropertyName(), (string) $sniffStr);
if ($this->showSniffs) {
$this->log('The list of used sniffs (#' . count($sniffs) . '): ' . PHP_EOL . $sniffStr, Project::MSG_INFO);
}
// process output
$reporting = $phpcs->reporting;
foreach ($this->formatters as $fe) {
$reportFile = null;
if ($fe->getUseFile()) {
$reportFile = $fe->getOutfile();
//ob_start();
}
// Crude check, but they broke backwards compatibility
// with a minor version release.
if (PHP_CodeSniffer::VERSION >= '2.2.0') {
$cliValues = array('colors' => false);
$reporting->printReport($fe->getType(),
$this->showSources,
$cliValues,
$reportFile,
$this->reportWidth);
} else {
$reporting->printReport($fe->getType(),
$this->showSources,
$reportFile,
$this->reportWidth);
}
// reporting class uses ob_end_flush(), but we don't want
// an output if we use a file
if ($fe->getUseFile()) {
//ob_end_clean();
}
}
}
/**
* Outputs the results with a custom format
*
* @param array $report Packaged list of all errors in each file
*/
protected function outputCustomFormat($report)
{
$files = $report['files'];
foreach ($files as $file => $attributes) {
$errors = $attributes['errors'];
$warnings = $attributes['warnings'];
$messages = $attributes['messages'];
if ($errors > 0) {
$this->log(
$file . ': ' . $errors . ' error' . ($errors > 1 ? 's' : '') . ' detected',
Project::MSG_ERR
);
$this->outputCustomFormatMessages($messages, 'ERROR');
} else {
$this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE);
}
if ($warnings > 0) {
$this->log(
$file . ': ' . $warnings . ' warning' . ($warnings > 1 ? 's' : '') . ' detected',
Project::MSG_WARN
);
$this->outputCustomFormatMessages($messages, 'WARNING');
}
}
$totalErrors = $report['totals']['errors'];
$totalWarnings = $report['totals']['warnings'];
$this->log(count($files) . ' files were checked', Project::MSG_INFO);
if ($totalErrors > 0) {
$this->log($totalErrors . ' error' . ($totalErrors > 1 ? 's' : '') . ' detected', Project::MSG_ERR);
} else {
$this->log('No syntax errors detected', Project::MSG_INFO);
}
if ($totalWarnings > 0) {
$this->log($totalWarnings . ' warning' . ($totalWarnings > 1 ? 's' : '') . ' detected', Project::MSG_INFO);
}
}
/**
* Outputs the messages of a specific type for one file
* @param array $messages
* @param string $type
*/
protected function outputCustomFormatMessages($messages, $type)
{
foreach ($messages as $line => $messagesPerLine) {
foreach ($messagesPerLine as $column => $messagesPerColumn) {
foreach ($messagesPerColumn as $message) {
$msgType = $message['type'];
if ($type == $msgType) {
$logLevel = Project::MSG_INFO;
if ($msgType == 'ERROR') {
$logLevel = Project::MSG_ERR;
} else {
if ($msgType == 'WARNING') {
$logLevel = Project::MSG_WARN;
}
}
$text = $message['message'];
$string = $msgType . ' in line ' . $line . ' column ' . $column . ': ' . $text;
$this->log($string, $logLevel);
}
}
}
}
}
} //end phpCodeSnifferTask
/**
* @package phing.tasks.ext
*/
class PhpCodeSnifferTask_FormatterElement extends DataType
{
/**
* Type of output to generate
* @var string
*/
protected $type = "";
/**
* Output to file?
* @var bool
*/
protected $useFile = true;
/**
* Output file.
* @var string
*/
protected $outfile = "";
/**
* Validate config.
*/
public function parsingComplete()
{
if (empty($this->type)) {
throw new BuildException("Format missing required 'type' attribute.");
}
if ($this->useFile && empty($this->outfile)) {
throw new BuildException("Format requires 'outfile' attribute when 'useFile' is true.");
}
}
/**
* @param $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param $useFile
*/
public function setUseFile($useFile)
{
$this->useFile = $useFile;
}
/**
* @return bool
*/
public function getUseFile()
{
return $this->useFile;
}
/**
* @param $outfile
*/
public function setOutfile($outfile)
{
$this->outfile = $outfile;
}
/**
* @return string
*/
public function getOutfile()
{
return $this->outfile;
}
} //end FormatterElement
phing-2.16.0/tasks/ext/PearPackage2Task.php 0000644 0001750 0001750 00000025516 13027032674 017430 0 ustar druid druid .
*/
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 and
* nested elements. All options are set using PEAR_PackageFileManager2::setOptions().
*
* The tag is used to set a simple option value.
*
*
* or option_value
*
*
* The tag represents a complex data type. You can use nested (and nested with
* 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().
*
*
*
*
*
*
*
* Here's an over-simple example of how this could be used:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* 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
* @author Hans Lellelid
* @package phing.tasks.ext
* @version $Id: 2d0f1f7fa10c416782647339da7fc5d26780d911 $
*/
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.
* @throws BuildException
* @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()));
}
}
}
phing-2.16.0/tasks/ext/XmlLintTask.php 0000644 0001750 0001750 00000014565 13027032674 016574 0 ustar druid druid .
*/
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
* @version $Id: d9b238ee17a88afe34f9db53a4c944c92ac27278 $
* @package phing.tasks.ext
*/
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
*
* @param PhingFile $file
*/
public function setFile(PhingFile $file)
{
$this->file = $file;
}
/**
* XML Schema Description file to validate against
*
* @param PhingFile $schema
*/
public function setSchema(PhingFile $schema)
{
$this->schema = $schema;
}
/**
* Use RNG instead of DTD schema validation
*
* @param bool $bool
*/
public function setUseRNG($bool)
{
$this->useRNG = (boolean) $bool;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
*
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Sets the haltonfailure attribute
*
* @param bool $haltonfailure
*
* @return void
*/
public function setHaltonfailure($haltonfailure)
{
$this->haltonfailure = (bool) $haltonfailure;
}
/**
* Execute lint check against PhingFile or a FileSet.
*
* {@inheritdoc}
*
* @throws BuildException
*
* @return void
*/
public function main()
{
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");
}
set_error_handler(array($this, 'errorHandler'));
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);
}
}
}
restore_error_handler();
}
/**
* @param $message
*
* @return void
*
* @throws BuildException
*/
protected function logError($message)
{
if ($this->haltonfailure) {
throw new BuildException($message);
} else {
$this->log($message, Project::MSG_ERR);
}
}
/**
* Performs validation
*
* @param string $file
*
* @return void
*/
protected function lint($file)
{
if (file_exists($file)) {
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 {
$this->logError('Permission denied to read file: ' . $file);
}
} else {
$this->logError('File not found: ' . $file);
}
}
/**
* Local error handler to catch validation errors and log them through Phing
*
* @param int $level
* @param string $message
* @param string $file
* @param int $line
* @param mixed $context
*
* @return void
*/
public function errorHandler($level, $message, $file, $line, $context)
{
$matches = array();
preg_match('/^.*\(\): (.*)$/', $message, $matches);
$this->log($matches[1], Project::MSG_ERR);
}
}
phing-2.16.0/tasks/ext/jsmin/JsMinTask.php 0000644 0001750 0001750 00000012204 13027032674 017331 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* Task to minify javascript files.
*
* Requires JShrink (https://github.com/tedivm/JShrink) which
* can be installed using composer
*
* @author Frank Kleine
* @version $Id: 5581c575662a85f7e1b8c80af2291e74a3aca3f9 $
* @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 occurred
*
* @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 adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Whether the build should fail, if an error occurred.
*
* @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 into
*
* @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()
{
// if composer autoloader is not yet loaded, load it here
@include_once 'vendor/autoload.php';
if (!class_exists('\\JShrink\\Minifier')) {
throw new BuildException(
'JsMinTask depends on JShrink being installed and on include_path.',
$this->getLocation()
);
}
if (version_compare(PHP_VERSION, '5.3.0') < 0) {
throw new BuildException('JsMinTask requires PHP 5.3+');
}
if (empty($this->targetDir)) {
throw new BuildException('Attribute "targetDir" is required');
}
foreach ($this->filesets as $fs) {
try {
$this->processFileSet($fs);
} 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);
}
}
}
}
/**
* @param FileSet $fs
* @throws BuildException
*/
protected function processFileSet(FileSet $fs)
{
$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), 0777 - umask(), true);
}
$contents = file_get_contents($fullPath . '/' . $file);
// nasty hack to not trip PHP 5.2 parser
$minified = forward_static_call(array('\\JShrink\\Minifier', 'minify'), $contents);
file_put_contents($target, $minified);
} catch (Exception $jsme) {
$this->log("Could not minify file $file: " . $jsme->getMessage(), Project::MSG_ERR);
}
}
}
}
phing-2.16.0/tasks/ext/ssh/Ssh2MethodParam.php 0000644 0001750 0001750 00000012134 13027032674 020106 0 ustar druid druid .
*/
require_once 'phing/types/DataType.php';
require_once 'Ssh2MethodConnectionParam.php';
/**
* Class that holds parameters for an ssh2_connect $methods parameter
* This corresponds to the optional $methods parameter
* for the ssh2_connect function
* @see http://php.net/ssh2_connect
*
* @author Derek Gallo
*
* @package phing.tasks.ext
*/
class Ssh2MethodParam extends DataType
{
/**
* @var string
*/
private $kex;
/**
* @var string
*/
private $hostkey;
/**
* @var Ssh2MethodConnectionParam
*/
private $client_to_server;
/**
* @var Ssh2MethodConnectionParam
*/
private $server_to_client;
/**
* @param string $hostkey
*/
public function setHostkey($hostkey)
{
$this->hostkey = $hostkey;
}
/**
* @param Project $p
* @throws BuildException
* @return string
*/
public function getHostkey(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getHostkey($p);
}
return $this->hostkey;
}
/**
* @param string $kex
*/
public function setKex($kex)
{
$this->kex = $kex;
}
/**
* @param Project $p
* @throws BuildException
* @return string
*/
public function getKex(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getKex($p);
}
return $this->kex;
}
/**
* @param Project $p
* @throws BuildException
* @return \Ssh2MethodConnectionParam
*/
public function getClientToServer(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getClientToServer($p);
}
return $this->client_to_server;
}
/**
* @param Project $p
* @throws BuildException
* @return \Ssh2MethodConnectionParam
*/
public function getServerToClient(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getServerToClient($p);
}
return $this->server_to_client;
}
/**
* Handles the nested element
* @return Ssh2MethodConnectionParam
*/
public function createClient()
{
$this->client_to_server = new Ssh2MethodConnectionParam();
return $this->client_to_server;
}
/**
* Handles the nested element
* @return Ssh2MethodConnectionParam
*/
public function createServer()
{
$this->server_to_client = new Ssh2MethodConnectionParam();
return $this->server_to_client;
}
/**
* Convert the params to an array that is suitable to be passed in the ssh2_connect $methods parameter
* @param Project $p
* @return array
*/
public function toArray(Project $p)
{
$client_to_server = $this->getClientToServer($p);
$server_to_client = $this->getServerToClient($p);
$array = array(
'kex' => $this->getKex($p),
'hostkey' => $this->getHostkey($p),
'client_to_server' => !is_null($client_to_server) ? $client_to_server->toArray() : null,
'server_to_client' => !is_null($server_to_client) ? $server_to_client->toArray() : null
);
return array_filter($array, array($this, '_filterParam'));
}
/**
* @param $var
* @return boolean
*/
protected function _filterParam($var)
{
if (is_array($var)) {
return !empty($var);
}
return !is_null($var);
}
/**
*
* @param Project $p
* @throws BuildException
* @return Ssh2MethodParam
*/
public function getRef(Project $p)
{
if (!$this->checked) {
$stk = array();
array_push($stk, $this);
$this->dieOnCircularReference($stk, $p);
}
$o = $this->ref->getReferencedObject($p);
if (!($o instanceof Ssh2MethodParam)) {
throw new BuildException($this->ref->getRefId() . " doesn't denote a Ssh2MethodParam");
} else {
return $o;
}
}
}
phing-2.16.0/tasks/ext/ssh/SshTask.php 0000644 0001750 0001750 00000020063 13027032674 016525 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'Ssh2MethodParam.php';
/**
* Execute commands on a remote host using ssh.
*
* @author Johan Van den Brande
* @version $Id: fcc9b201c6ff1159698d67f5966f6dd39c7591c7 $
* @package phing.tasks.ext
*/
class SshTask extends Task
{
private $host = "";
private $port = 22;
private $methods = null;
private $username = "";
private $password = "";
private $command = "";
private $pubkeyfile = '';
private $privkeyfile = '';
private $privkeyfilepassphrase = '';
private $pty = '';
private $failonerror = false;
/**
* 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;
/**
* @param $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* @param $port
*/
public function setPort($port)
{
$this->port = $port;
}
/**
* @return int
*/
public function getPort()
{
return $this->port;
}
/**
* @param $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* @param $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Sets the public key file of the user to scp
* @param $pubkeyfile
*/
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
* @param $privkeyfile
*/
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
* @param $privkeyfilepassphrase
*/
public function setPrivkeyfilepassphrase($privkeyfilepassphrase)
{
$this->privkeyfilepassphrase = $privkeyfilepassphrase;
}
/**
* Returns the private keyfile passphrase
* @param $privkeyfilepassphrase
* @return string
*/
public function getPrivkeyfilepassphrase($privkeyfilepassphrase)
{
return $this->privkeyfilepassphrase;
}
/**
* @param $command
*/
public function setCommand($command)
{
$this->command = $command;
}
/**
* @return string
*/
public function getCommand()
{
return $this->command;
}
/**
* @param $pty
*/
public function setPty($pty)
{
$this->pty = $pty;
}
/**
* @return string
*/
public function getPty()
{
return $this->pty;
}
/**
* 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;
}
/**
* Sets whether to fail the task on any error
* @param $failonerror
* @internal param bool $failOnError
*/
public function setFailonerror($failonerror)
{
$this->failonerror = (boolean) $failonerror;
}
/**
* Creates an Ssh2MethodParam object. Handles the nested tag
* @return Ssh2MethodParam
*/
public function createSshconfig()
{
$this->methods = new Ssh2MethodParam();
return $this->methods;
}
public function init()
{
}
/**
* Initiates a ssh connection and stores
* it in $this->connection
*/
protected function setupConnection()
{
$p = $this->getProject();
if (!function_exists('ssh2_connect')) {
throw new BuildException("To use SshTask, you need to install the PHP SSH2 extension.");
}
$methods = !empty($this->methods) ? $this->methods->toArray($p) : array();
$this->connection = ssh2_connect($this->host, $this->port, $methods);
if (!$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!");
}
}
public function main()
{
$this->setupConnection();
if ($this->pty != '') {
$stream = ssh2_exec($this->connection, $this->command, $this->pty);
} else {
$stream = ssh2_exec($this->connection, $this->command);
}
$this->handleStream($stream);
}
/**
* This function reads the streams from the ssh2_exec
* command, stores output data, checks for errors and
* closes the streams properly.
* @param $stream
* @throws BuildException
*/
protected function handleStream($stream)
{
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);
// always load contents of error stream, to make sure not one command failed
$stderr_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
stream_set_blocking($stderr_stream, true);
$result_error = 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);
}
if ($this->failonerror && !empty($result_error)) {
throw new BuildException("SSH Task failed: " . $result_error);
}
}
}
phing-2.16.0/tasks/ext/ssh/Ssh2MethodConnectionParam.php 0000644 0001750 0001750 00000005213 13027032674 022126 0 ustar druid druid .
*/
/**
* Class that holds parameters for an ssh2_connect $methods parameter
* This corresponds to the client_to_server and server_to_client keys of the optional $methods parameter
* for the ssh2_connect function
* @see http://php.net/ssh2_connect
*
* @author Derek Gallo
*
* @package phing.tasks.ext
*/
class Ssh2MethodConnectionParam
{
/**
* @var string
*/
private $crypt = null;
/**
* @var string
*/
private $comp = null;
/**
* @var string
*/
private $mac = null;
/**
* @param string $comp
*/
public function setComp($comp)
{
$this->comp = $comp;
}
/**
* @return string
*/
public function getComp()
{
return $this->comp;
}
/**
* @param string $crypt
*/
public function setCrypt($crypt)
{
$this->crypt = $crypt;
}
/**
* @return string
*/
public function getCrypt()
{
return $this->crypt;
}
/**
* @param string $mac
*/
public function setMac($mac)
{
$this->mac = $mac;
}
/**
* @return string
*/
public function getMac()
{
return $this->mac;
}
/**
* Get the params as an array
* unset/null params are excluded from the array
* @return array
*/
public function toArray()
{
return array_filter(
get_object_vars($this),
array($this, '_filterParam')
);
}
/**
* @param $var
* @return bool
*/
protected function _filterParam($var)
{
return !is_null($var);
}
}
phing-2.16.0/tasks/ext/ssh/ScpTask.php 0000644 0001750 0001750 00000031532 13027032674 016520 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* Copy files to and from a remote host using scp.
*
* @author Michiel Rook
* @author Johan Van den Brande
* @version $Id: 34d699a555092a5473d0636c5e45232dc2019c1d $
* @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 $methods = null;
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 $counter = 0;
protected $logLevel = Project::MSG_VERBOSE;
/**
* If number of success of "sftp" is grater than declared number
* decide to skip "scp" operation.
*
* @var int
*/
protected $heuristicDecision = 5;
/**
* Indicate number of failures in sending files via "scp" over "sftp"
*
* - If number is negative - scp & sftp failed
* - If number is positive - scp failed & sftp succeed
* - If number is 0 - scp succeed
*
* @var integer
*/
protected $heuristicScpSftp = 0;
/**
* Sets the remote host
* @param $h
*/
public function setHost($h)
{
$this->host = $h;
}
/**
* Returns the remote host
*/
public function getHost()
{
return $this->host;
}
/**
* Sets the remote host port
* @param $p
*/
public function setPort($p)
{
$this->port = $p;
}
/**
* Returns the remote host port
*/
public function getPort()
{
return $this->port;
}
/**
* Sets the mode value
* @param $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
* @param $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Returns the username
*/
public function getUsername()
{
return $this->username;
}
/**
* Sets the password of the user to scp
* @param $password
*/
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
* @param $pubkeyfile
*/
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
* @param $privkeyfile
*/
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
* @param $privkeyfilepassphrase
*/
public function setPrivkeyfilepassphrase($privkeyfilepassphrase)
{
$this->privkeyfilepassphrase = $privkeyfilepassphrase;
}
/**
* Returns the private keyfile passphrase
* @param $privkeyfilepassphrase
* @return string
*/
public function getPrivkeyfilepassphrase($privkeyfilepassphrase)
{
return $this->privkeyfilepassphrase;
}
/**
* Sets whether to autocreate remote directories
* @param $autocreate
*/
public function setAutocreate($autocreate)
{
$this->autocreate = (bool) $autocreate;
}
/**
* Returns whether to autocreate remote directories
*/
public function getAutocreate()
{
return $this->autocreate;
}
/**
* Set destination directory
* @param $todir
*/
public function setTodir($todir)
{
$this->todir = $todir;
}
/**
* Returns the destination directory
*/
public function getTodir()
{
return $this->todir;
}
/**
* Sets local filename
* @param $file
*/
public function setFile($file)
{
$this->file = $file;
}
/**
* Returns local filename
*/
public function getFile()
{
return $this->file;
}
/**
* Sets whether to send (default) or fetch files
* @param $fetch
*/
public function setFetch($fetch)
{
$this->fetch = (bool) $fetch;
}
/**
* Returns whether to send (default) or fetch files
*/
public function getFetch()
{
return $this->fetch;
}
/**
* Declare number of successful operations above which "sftp" will be chosen over "scp".
*
* @param int $heuristicDecision Number
*/
public function setHeuristicDecision($heuristicDecision)
{
$this->heuristicDecision = (int) $heuristicDecision;
}
/**
* Get declared number of successful operations above which "sftp" will be chosen over "scp".
*
* @return int
*/
public function getHeuristicDecision()
{
return $this->heuristicDecision;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Creates an Ssh2MethodParam object. Handles the nested tag
* @return Ssh2MethodParam
*/
public function createSshconfig()
{
$this->methods = new Ssh2MethodParam();
return $this->methods;
}
/**
* 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()
{
$p = $this->getProject();
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");
}
$methods = !empty($this->methods) ? $this->methods->toArray($p) : array();
$this->connection = ssh2_connect($this->host, $this->port, $methods);
if (!$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');
}
/**
* @param $local
* @param $remote
* @throws BuildException
*/
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);
$ret = false;
// If more than "$this->heuristicDecision" successfully send files by "ssh2.sftp" over "ssh2_scp_send"
// then ship this step (task finish ~40% faster)
if ($this->heuristicScpSftp < $this->heuristicDecision) {
if (null !== $this->mode) {
$ret = @ssh2_scp_send($this->connection, $localEndpoint, $remoteEndpoint, $this->mode);
} else {
$ret = @ssh2_scp_send($this->connection, $localEndpoint, $remoteEndpoint);
}
}
// sometimes remote server allow only create files via sftp (eg. phpcloud.com)
if (false === $ret && $this->sftp) {
// mark failure of "scp"
--$this->heuristicScpSftp;
// try create file via ssh2.sftp://file wrapper
$fh = @fopen("ssh2.sftp://$this->sftp/$remoteEndpoint", 'wb');
if (is_resource($fh)) {
$ret = fwrite($fh, file_get_contents($localEndpoint));
fclose($fh);
// mark success of "sftp"
$this->heuristicScpSftp += 2;
}
}
if ($ret === false) {
throw new BuildException("Could not create remote file '" . $remoteEndpoint . "'");
}
}
$this->counter++;
}
}
phing-2.16.0/tasks/ext/phpcpd/PHPCPDTask.php 0000644 0001750 0001750 00000023247 13027032674 017436 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/tasks/ext/phpcpd/PHPCPDFormatterElement.php';
/**
* Runs PHP Copy & Paste Detector. Checking PHP files for duplicated code.
* Refactored original PhpCpdTask provided by
* Timo Haberkern
*
* @package phing.tasks.ext.phpcpd
* @author Benjamin Schultz
* @version $Id: 99ac61885f274b13a79c125b92a133b65db3b726 $
*/
class PHPCPDTask extends Task
{
/**
* A php source code filename or directory
*
* @var PhingFile
*/
protected $file = null;
/**
* All fileset objects assigned to this task
*
* @var FileSet[]
*/
protected $filesets = array();
/**
* Minimum number of identical lines.
*
* @var integer
*/
protected $minLines = 5;
/**
* Minimum number of identical tokens.
*
* @var integer
*/
protected $minTokens = 70;
/**
* Allow for fuzzy matches.
*
* @var boolean
*/
protected $fuzzy = false;
/**
* 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 PHPCPDFormatterElement[]
*/
protected $formatters = array();
/**
* @var bool
*/
protected $oldVersion = false;
/**
* @var string
*/
private $pharLocation = "";
/**
* Set the input source file or directory.
*
* @param PhingFile $file The input source file or directory.
*/
public function setFile(PhingFile $file)
{
$this->file = $file;
}
/**
* Nested creator, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs List of files to scan
*/
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
*/
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 the fuzzy match (default: false).
*
* @param boolean $fuzzy fuzzy match
*/
public function setFuzzy($fuzzy)
{
$this->fuzzy = $fuzzy;
}
/**
* Sets a list of filename extensions for valid php source code files.
*
* @param string $fileExtensions List of valid file extensions.
*/
public function setAllowedFileExtensions($fileExtensions)
{
$this->allowedFileExtensions = array();
$token = ' ,;';
$ext = strtok($fileExtensions, $token);
while ($ext !== false) {
$this->allowedFileExtensions[] = $ext;
$ext = strtok($token);
}
}
/**
* Sets a list of ignore patterns that is used to exclude directories from the source analysis.
*
* @param string $ignorePatterns List of ignore patterns.
*/
public function setIgnorePatterns($ignorePatterns)
{
$this->ignorePatterns = array();
$token = ' ,;';
$pattern = strtok($ignorePatterns, $token);
while ($pattern !== false) {
$this->ignorePatterns[] = $pattern;
$pattern = strtok($token);
}
}
/**
* 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];
}
/**
* @param string $pharLocation
*/
public function setPharLocation($pharLocation)
{
$this->pharLocation = $pharLocation;
}
/**
* @throws BuildException if the phpcpd classes can't be loaded
*/
private function loadDependencies()
{
if (!empty($this->pharLocation)) {
// hack to prevent PHPCPD from starting in CLI mode and halting Phing
eval("namespace SebastianBergmann\PHPCPD\CLI;
class Application
{
public function run() {}
}");
ob_start();
include $this->pharLocation;
ob_end_clean();
if (class_exists('\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy')) {
return;
}
}
if (class_exists('Composer\\Autoload\\ClassLoader', false) && class_exists(
'\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy'
)
) {
return;
}
if ($handler = @fopen('SebastianBergmann/PHPCPD/autoload.php', 'r', true)) {
fclose($handler);
@include_once 'SebastianBergmann/PHPCPD/autoload.php';
if (version_compare(PHP_VERSION, '5.3.0') < 0) {
throw new BuildException('The PHPCPD task now requires PHP 5.3+');
}
return;
}
if ($handler = @fopen('PHPCPD/Autoload.php', 'r', true)) {
fclose($handler);
@include_once 'PHPCPD/Autoload.php';
$this->oldVersion = true;
return;
}
throw new BuildException(
'PHPCPDTask depends on PHPCPD being installed and on include_path.',
$this->getLocation()
);
}
/**
* Executes PHPCPD against PhingFile or a FileSet
*
* @throws BuildException
*/
public function main()
{
$this->loadDependencies();
if (!isset($this->file) && 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...');
if ($this->oldVersion) {
$detectorClass = 'PHPCPD_Detector';
$strategyClass = 'PHPCPD_Detector_Strategy_Default';
} else {
$detectorClass = '\\SebastianBergmann\\PHPCPD\\Detector\\Detector';
$strategyClass = '\\SebastianBergmann\\PHPCPD\\Detector\\Strategy\\DefaultStrategy';
}
$detector = new $detectorClass(new $strategyClass());
$clones = $detector->copyPasteDetection(
$filesToParse,
$this->minLines,
$this->minTokens,
$this->fuzzy
);
$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
*/
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.');
}
}
}
}
phing-2.16.0/tasks/ext/phpcpd/formatter/PMDPHPCPDResultFormatter.php 0000644 0001750 0001750 00000004023 13027032674 024231 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php';
/**
* Prints PMD-XML output of phpcpd run
*
* @author Benjamin Schultz
*
* @package phing.tasks.ext.phpcpd.formatter
*/
class PMDPHPCPDResultFormatter extends PHPCPDResultFormatter
{
/**
* Processes a list of clones.
*
* @param PHPCPD_CloneMap|CodeCloneMap $clones
* @param Project $project
* @param boolean $useFile
* @param PhingFile|null $outFile
*
* @throws BuildException
*/
public function processClones($clones, Project $project, $useFile = false, $outFile = null)
{
if (!$useFile || empty($outFile)) {
throw new BuildException('Output filename required for this formatter');
}
if (get_class($clones) == 'PHPCPD_CloneMap') {
$logger = new PHPCPD_Log_XML_PMD($outFile);
} else {
$logger = new \SebastianBergmann\PHPCPD\Log\PMD($outFile);
}
$logger->processClones($clones);
}
}
phing-2.16.0/tasks/ext/phpcpd/formatter/PHPCPDResultFormatter.php 0000644 0001750 0001750 00000003143 13027032674 023672 0 ustar druid druid .
*/
/**
* This abstract class describes classes that format the results of a PHPCPD run.
*
* @package phing.tasks.ext.phpcpd.formatter
* @author Benjamin Schultz
* @version $Id: e8921b5a15fd23ce437471250c7161884560e202 $
*/
abstract class PHPCPDResultFormatter
{
/**
* Processes a list of clones.
*
* @param object $clones
* @param Project $project
* @param boolean $useFile
* @param PhingFile|null $outFile
*/
abstract public function processClones($clones, Project $project, $useFile = false, $outFile = null);
}
phing-2.16.0/tasks/ext/phpcpd/formatter/DefaultPHPCPDResultFormatter.php 0000644 0001750 0001750 00000006023 13027032674 025177 0 ustar druid druid .
*/
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
* @version $Id: 20db9b04d2f5ea6acc7db0f00d83daa6b8580cec $
*/
class DefaultPHPCPDResultFormatter extends PHPCPDResultFormatter
{
/**
* Processes a list of clones.
*
* @param CodeCloneMap $clones
* @param Project $project
* @param boolean $useFile
* @param PhingFile|null $outFile
*/
public function processClones($clones, Project $project, $useFile = false, $outFile = null)
{
if (get_class($clones) == 'SebastianBergmann\PHPCPD\CodeCloneMap') {
if (class_exists('SebastianBergmann\PHPCPD\Log\Text')) {
$this->processClonesNew($clones, $useFile, $outFile);
return;
}
$logger = new \SebastianBergmann\PHPCPD\TextUI\ResultPrinter();
} else {
$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);
}
}
/**
* Wrapper for PHPCPD 2.0
*
* @param CodeCloneMap $clones
* @param boolean $useFile
* @param PhingFile|null $outFile
*/
private function processClonesNew($clones, $useFile = false, $outFile = null)
{
if ($useFile) {
$resource = fopen($outFile->getPath(), "w");
} else {
$resource = fopen("php://output", "w");
}
$output = new \Symfony\Component\Console\Output\StreamOutput($resource);
$logger = new \SebastianBergmann\PHPCPD\Log\Text();
$logger->printResult($output, $clones);
}
}
phing-2.16.0/tasks/ext/phpcpd/PHPCPDFormatterElement.php 0000644 0001750 0001750 00000010247 13027032674 022005 0 ustar druid druid .
*/
require_once 'phing/system/io/PhingFile.php';
/**
* A wrapper for the implementations of PHPCPDResultFormatter.
*
* @package phing.tasks.ext.phpcpd
* @author Benjamin Schultz
* @version $Id: c430c57cb2db4bff221d0bcf96ed4396b738da6d $
*/
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
*
* @throws BuildException
*/
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.
*/
public function setUseFile($useFile)
{
$this->useFile = StringHelper::booleanValue($useFile);
}
/**
* Return whether to write formatter results to file or not.
*
* @return boolean
*/
public function getUseFile()
{
return $this->useFile;
}
/**
* Sets the output file for the formatter results.
*
* @param PhingFile $outfile The output file
*/
public function setOutfile(PhingFile $outfile)
{
$this->outfile = $outfile;
}
/**
* Get the output file.
*
* @return PhingFile
*/
public function getOutfile()
{
return $this->outfile;
}
/**
* Returns the report formatter.
*
* @return PHPCPDResultFormatter
*/
public function getFormatter()
{
return $this->formatter;
}
}
phing-2.16.0/tasks/ext/HttpTask.php 0000644 0001750 0001750 00000014066 13027032674 016120 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* Base class for HTTP_Request2-backed tasks
*
* Handles nested and tags, contains a method for
* HTTP_Request2 instance creation
*
* @package phing.tasks.ext
* @author Alexey Borzov
* @version $Id: 4b9d4bc0ada3044961fd261245d566a72b3789a9 $
*/
abstract class HttpTask extends Task
{
/**
* Holds the request URL
*
* @var string
*/
protected $url = null;
/**
* Prototype HTTP_Request2 object, cloned in createRequest()
*
* @var HTTP_Request2
*/
protected $requestPrototype = null;
/**
* Holds additional header data
*
* @var Parameter[]
*/
protected $headers = array();
/**
* Holds additional config data for HTTP_Request2
*
* @var 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;
/**
* 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(
get_class($this) . ' depends on HTTP_Request2 being installed '
. 'and on include_path.',
$this->getLocation()
);
}
}
/**
* Sets the request URL
*
* @param string $url
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* Sets the prototype object that will be cloned in createRequest()
*
* Used in tests to inject an instance of HTTP_Request2 containing a custom adapter
*
* @param HTTP_Request2 $request
*/
public function setRequestPrototype(HTTP_Request2 $request)
{
$this->requestPrototype = $request;
}
/**
* Creates and configures an instance of HTTP_Request2
*
* @return HTTP_Request2
*/
protected function createRequest()
{
if (!$this->requestPrototype) {
$request = new HTTP_Request2($this->url);
} else {
$request = clone $this->requestPrototype;
$request->setUrl($this->url);
}
foreach (array_keys($this->getProject()->getProperties()) as $propName) {
if (0 === strpos($propName, 'phing.http.')) {
$request->setConfig(substr($propName, 11), $this->getProject()->getProperty($propName));
}
}
// 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());
}
return $request;
}
/**
* Processes the server's response
*
* @param HTTP_Request2_Response $response
* @return void
* @throws BuildException
*/
abstract protected function processResponse(HTTP_Request2_Response $response);
/**
* Makes a HTTP request and processes its response
*
* @throws BuildException
*/
public function main()
{
if (!isset($this->url)) {
throw new BuildException("Required attribute 'url' is missing");
}
try {
$this->processResponse($this->createRequest()->send());
} catch (HTTP_Request2_MessageException $e) {
throw new BuildException($e);
}
}
/**
* 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 config parameter
*/
public function createConfig()
{
$num = array_push($this->configData, new Parameter());
return $this->configData[$num - 1];
}
/**
* 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;
}
}
phing-2.16.0/tasks/ext/PhpLintTask.php 0000644 0001750 0001750 00000021163 13027032674 016553 0 ustar druid druid .
*/
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
* @author Stefan Priebsch
* @version $Id: 6352a87c4c3b940a0afd55b21645206a23960e0b $
* @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
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 php.interpreter
*/
public function init()
{
$this->setInterpreter($this->project->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)
{
if (strpos($sPhp, ' ') !== false) {
$sPhp = escapeshellarg($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 $tofile
* @internal param PhingFile $file
*/
public function setToFile(PhingFile $tofile)
{
$this->tofile = $tofile;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* 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;
}
/**
* 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
* @throws BuildException
* @return void
*/
protected function lint($file)
{
$command = $this->interpreter == ''
? 'php'
: $this->interpreter;
if (strpos($command, 'hhvm') !== false) {
$command .= ' --no-config -l';
} else {
if ($this->deprecatedAsError) {
$command .= ' -d error_reporting=32767 ';
}
$command .= ' -n -l ';
}
if (! file_exists($file)) {
throw new BuildException('File not found: ' . $file);
}
if (! is_readable($file)) {
throw new BuildException('Permission denied: ' . $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); $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));
}
}
}
}
phing-2.16.0/tasks/ext/FileSyncTask.php 0000644 0001750 0001750 00000037461 13027032674 016721 0 ustar druid druid .
*/
require_once "phing/Task.php";
/**
* The FileSyncTask class copies files either to or from a remote host, or locally
* on the current host. It allows rsync to transfer the differences between two
* sets of files across the network connection, using an efficient checksum-search
* algorithm.
*
* There are 4 different ways of using FileSyncTask:
*
* 1. For copying local files.
* 2. For copying from the local machine to a remote machine using a remote
* shell program as the transport (ssh).
* 3. For copying from a remote machine to the local machine using a remote
* shell program.
* 4. For listing files on a remote machine.
*
* This is extended from Federico's original code, all his docs are kept in here below.
*
* @author Federico Cargnelutti
* @author Anton Stöckl
* @version $Revision$
* @package phing.tasks.ext
* @see http://svn.fedecarg.com/repo/Phing/tasks/ext/FileSyncTask.php
* @example http://fedecarg.com/wiki/FileSyncTask
*/
class FileSyncTask extends Task
{
/**
* Path to rsync command.
* @var string
*/
protected $rsyncPath = '/usr/bin/rsync';
/**
* Source directory.
* For remote sources this must contain user and host, e.g.: user@host:/my/source/dir
* @var string
*/
protected $sourceDir;
/**
* Destination directory.
* For remote targets this must contain user and host, e.g.: user@host:/my/target/dir
* @var string
*/
protected $destinationDir;
/**
* Remote host.
* @var string
*/
protected $remoteHost;
/**
* Rsync auth username.
* @var string
*/
protected $remoteUser;
/**
* Rsync auth password.
* @var string
*/
protected $remotePass;
/**
* Remote shell.
* @var string
*/
protected $remoteShell;
/**
* Exclude file matching pattern.
* Use comma seperated values to exclude multiple files/directories, e.g.: a,b
* @var string
*/
protected $exclude;
/**
* Excluded patterns file.
* @var string
*/
protected $excludeFile;
/**
* This option creates a backup so users can rollback to an existing restore
* point. The remote directory is copied to a new directory specified by the
* user.
* @var string
*/
protected $backupDir;
/**
* Default command options.
* r - recursive
* p - preserve permissions
* K - treat symlinked dir on receiver as dir
* z - compress
* l - copy symlinks as symlinks
* @var string
*/
protected $defaultOptions = '-rpKzl';
/**
* Command options.
* @var string
*/
protected $options;
/**
* Connection type.
* @var boolean
*/
protected $isRemoteConnection = false;
/**
* This option increases the amount of information you are given during the
* transfer. The verbose option set to true will give you information about
* what files are being transferred and a brief summary at the end.
* @var boolean
*/
protected $verbose = true;
/**
* This option makes rsync perform a trial run that doesn’t make any changes
* (and produces mostly the same output as a real run).
* @var boolean
*/
protected $dryRun = false;
/**
* This option makes requests a simple itemized list of the changes that are
* being made to each file, including attribute changes.
* @var boolean
*/
protected $itemizeChanges = false;
/**
* This option will cause rsync to skip files based on checksum, not mod-time & size.
* @var boolean
*/
protected $checksum = false;
/**
* This option deletes files that don't exist on sender.
* @var boolean
*/
protected $delete = false;
/**
* Identity file.
* @var string
*/
protected $identityFile;
/**
* Phing's main method. Wraps the executeCommand() method.
*
* @return void
*/
public function main()
{
$this->executeCommand();
}
/**
* Executes the rsync command and returns the exit code.
*
* @return int Return code from execution.
* @throws BuildException
*/
public function executeCommand()
{
if ($this->rsyncPath === null) {
throw new BuildException('The "rsyncPath" attribute is missing or undefined.');
}
if ($this->sourceDir === null) {
throw new BuildException('The "sourcedir" attribute is missing or undefined.');
} else {
if ($this->destinationDir === null) {
throw new BuildException('The "destinationdir" attribute is missing or undefined.');
}
}
if (strpos($this->destinationDir, ':')) {
$this->setIsRemoteConnection(true);
}
if (strpos($this->sourceDir, ':')) {
if ($this->isRemoteConnection) {
throw new BuildException('The source and destination cannot both be remote.');
}
$this->setIsRemoteConnection(true);
} else {
if (!(is_dir($this->sourceDir) && is_readable($this->sourceDir))) {
throw new BuildException('No such file or directory: ' . $this->sourceDir);
}
}
if ($this->backupDir !== null && $this->backupDir == $this->destinationDir) {
throw new BuildException("Invalid backup directory: " . $this->backupDir);
}
$command = $this->getCommand();
$output = array();
$return = null;
exec($command, $output, $return);
$lines = '';
foreach ($output as $line) {
if (!empty($line)) {
$lines .= "\r\n" . "\t\t\t" . $line;
}
}
$this->log($command);
if ($return != 0) {
$this->log('Task exited with code: ' . $return, Project::MSG_ERR);
$this->log(
'Task exited with message: (' . $return . ') ' . $this->getErrorMessage($return),
Project::MSG_ERR
);
throw new BuildException($return . ': ' . $this->getErrorMessage($return));
} else {
$this->log($lines, Project::MSG_INFO);
}
return $return;
}
/**
* Returns the rsync command line options.
*
* @return string
*/
public function getCommand()
{
$options = $this->defaultOptions;
if ($this->options !== null) {
$options = $this->options;
}
if ($this->verbose === true) {
$options .= ' --verbose';
}
if ($this->checksum === true) {
$options .= ' --checksum';
}
if ($this->identityFile !== null) {
$options .= ' -e "ssh -i ' . $this->identityFile . '"';
} else {
if ($this->remoteShell !== null) {
$options .= ' -e "' . $this->remoteShell . '"';
}
}
if ($this->dryRun === true) {
$options .= ' --dry-run';
}
if ($this->delete === true) {
$options .= ' --delete-after --ignore-errors --force';
}
if ($this->itemizeChanges === true) {
$options .= ' --itemize-changes';
}
if ($this->backupDir !== null) {
$options .= ' -b --backup-dir="' . $this->backupDir . '"';
}
if ($this->exclude !== null) {
//remove trailing comma if any
$this->exclude = trim($this->exclude, ',');
$options .= ' --exclude="' . str_replace(',', '" --exclude="', $this->exclude) . '"';
}
if ($this->excludeFile !== null) {
$options .= ' --exclude-from="' . $this->excludeFile . '"';
}
$this->setOptions($options);
$options .= ' "' . $this->sourceDir . '" "' . $this->destinationDir . '"';
escapeshellcmd($options);
$options .= ' 2>&1';
return $this->rsyncPath . ' ' . $options;
}
/**
* Returns an error message based on a given error code.
*
* @param int $code Error code
* @return null|string
*/
public function getErrorMessage($code)
{
$error[0] = 'Success';
$error[1] = 'Syntax or usage error';
$error[2] = 'Protocol incompatibility';
$error[3] = 'Errors selecting input/output files, dirs';
$error[4] = 'Requested action not supported: an attempt was made to manipulate '
. '64-bit files on a platform that cannot support them; or an option '
. 'was specified that is supported by the client and not by the server';
$error[5] = 'Error starting client-server protocol';
$error[10] = 'Error in socket I/O';
$error[11] = 'Error in file I/O';
$error[12] = 'Error in rsync protocol data stream';
$error[13] = 'Errors with program diagnostics';
$error[14] = 'Error in IPC code';
$error[20] = 'Received SIGUSR1 or SIGINT';
$error[21] = 'Some error returned by waitpid()';
$error[22] = 'Error allocating core memory buffers';
$error[23] = 'Partial transfer due to error';
$error[24] = 'Partial transfer due to vanished source files';
$error[30] = 'Timeout in data send/receive';
if (array_key_exists($code, $error)) {
return $error[$code];
}
return null;
}
/**
* Sets the path to the rsync command.
*
* @param string $path
* @return void
*/
public function setRsyncPath($path)
{
$this->rsyncPath = $path;
}
/**
* Sets the isRemoteConnection property.
*
* @param boolean $isRemote
* @return void
*/
protected function setIsRemoteConnection($isRemote)
{
$this->isRemoteConnection = $isRemote;
}
/**
* Sets the source directory.
*
* @param string $dir
* @return void
*/
public function setSourceDir($dir)
{
$this->sourceDir = $dir;
}
/**
* Sets the command options.
*
* @param string $options
* @return void
*/
public function setOptions($options)
{
$this->options = $options;
}
/**
* Sets the destination directory. If the option remotehost is not included
* in the build.xml file, rsync will point to a local directory instead.
*
* @param string $dir
* @return void
*/
public function setDestinationDir($dir)
{
$this->destinationDir = $dir;
}
/**
* Sets the remote host.
*
* @param string $host
* @return void
*/
public function setRemoteHost($host)
{
$this->remoteHost = $host;
}
/**
* Specifies the user to log in as on the remote machine. This also may be
* specified in the properties file.
*
* @param string $user
* @return void
*/
public function setRemoteUser($user)
{
$this->remoteUser = $user;
}
/**
* This option allows you to provide a password for accessing a remote rsync
* daemon. Note that this option is only useful when accessing an rsync daemon
* using the built in transport, not when using a remote shell as the transport.
*
* @param string $pass
* @return void
*/
public function setRemotePass($pass)
{
$this->remotePass = $pass;
}
/**
* Allows the user to choose an alternative remote shell program to use for
* communication between the local and remote copies of rsync. Typically,
* rsync is configured to use ssh by default, but you may prefer to use rsh
* on a local network.
*
* @param string $shell
* @return void
*/
public function setRemoteShell($shell)
{
$this->remoteShell = $shell;
}
/**
* Increases the amount of information you are given during the
* transfer. By default, rsync works silently. A single -v will give you
* information about what files are being transferred and a brief summary at
* the end.
*
* @param boolean $verbose
* @return void
*/
public function setVerbose($verbose)
{
$this->verbose = (bool) $verbose;
}
/**
* This changes the way rsync checks if the files have been changed and are in need of a transfer.
* Without this option, rsync uses a "quick check" that (by default) checks if each file’s
* size and time of last modification match between the sender and receiver.
* This option changes this to compare a 128-bit checksum for each file that has a matching size.
*
* @param boolean $checksum
* @return void
*/
public function setChecksum($checksum)
{
$this->checksum = (bool) $checksum;
}
/**
* This makes rsync perform a trial run that doesn’t make any changes (and produces mostly the same
* output as a real run). It is most commonly used in combination with the -v, --verbose and/or
* -i, --itemize-changes options to see what an rsync command is going to do before one actually runs it.
*
* @param boolean $dryRun
* @return void
*/
public function setDryRun($dryRun)
{
$this->dryRun = (bool) $dryRun;
}
/**
* Requests a simple itemized list of the changes that are being made to each file, including attribute changes.
*
* @param boolean $itemizeChanges
* @return void
*/
public function setItemizeChanges($itemizeChanges)
{
$this->itemizeChanges = (bool) $itemizeChanges;
}
/**
* Tells rsync to delete extraneous files from the receiving side, but only
* for the directories that are being synchronized. Files that are excluded
* from transfer are also excluded from being deleted.
*
* @param boolean $delete
* @return void
*/
public function setDelete($delete)
{
$this->delete = (bool) $delete;
}
/**
* Exclude files matching patterns from $file, Blank lines in $file and
* lines starting with ';' or '#' are ignored.
*
* @param string $file
* @return void
*/
public function setExcludeFile($file)
{
$this->excludeFile = $file;
}
/**
* Makes backups into hierarchy based in $dir.
*
* @param string dir
* @return void
*/
public function setBackupDir($dir)
{
$this->backupDir = $dir;
}
/**
* Sets the identity file for public key transfers.
*
* @param string location of ssh identity file
* @return void
*/
public function setIdentityFile($identity)
{
$this->identityFile = $identity;
}
/**
* Sets exclude matching pattern.
*
* @param string $exclude
* @return void
*/
public function setExclude($exclude)
{
$this->exclude = $exclude;
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestDebugResultFormatter.php 0000644 0001750 0001750 00000010213 13027032674 024660 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Prints plain text output of the test to a specified Writer.
*
* @author Michiel Rook
* @version $Id: 6a0564d9f5a6757229f329a0d39018796ae9c751 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestDebugResultFormatter extends SimpleTestResultFormatter
{
protected $current_case = "";
protected $current_test = "";
private $failingTests = array();
public function printFailingTests()
{
foreach ($this->failingTests as $test) {
$this->out->write($test . "\n");
}
}
/**
* @param string $test_name
*/
public function paintCaseStart($test_name)
{
parent::paintCaseStart($test_name);
$this->paint("Testsuite: $test_name\n");
$this->current_case = $test_name;
}
/**
* @param string $test_name
*/
public 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);
}
/**
* @param $msg
*/
public function paint($msg)
{
if ($this->out == null) {
print $msg;
} else {
$this->out->write($msg);
}
}
/**
* @param string $test_name
*/
public function paintMethodEnd($test_name)
{
parent::paintMethodEnd($test_name);
$this->paint("\n");
}
/**
* @param string $test_name
*/
public 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);
}
}
/**
* @param string $message
*/
public function paintError($message)
{
parent::paintError($message);
$this->formatError("ERROR", $message);
$this->failingTests[] = $this->current_case . "->" . $this->current_test;
}
/**
* @param string $message
*/
public function paintFail($message)
{
parent::paintFail($message);
$this->formatError("FAILED", $message);
$this->failingTests[] = $this->current_case . "->" . $this->current_test;
}
/**
* @param Exception $message
*/
public function paintException($message)
{
parent::paintException($message);
$this->failingTests[] = $this->current_case . "->" . $this->current_test;
$this->formatError("Exception", $message);
}
/**
* @param $type
* @param $message
*/
private function formatError($type, $message)
{
$this->paint("ERROR: $type: $message");
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestCountResultFormatter.php 0000644 0001750 0001750 00000003376 13027032674 024736 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Dummy result formatter used to count SimpleTest results
*
* @author Michiel Rook
* @version $Id: f3db5ef14b0d98fcfbcabf12e421edb3dabc9508 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestCountResultFormatter extends SimpleTestResultFormatter
{
const SUCCESS = 0;
const FAILURES = 1;
const ERRORS = 2;
/**
* @return int
*/
public function getRetCode()
{
if ($this->getExceptionCount() != 0) {
return self::ERRORS;
} else {
if ($this->getFailCount() != 0) {
return self::FAILURES;
}
}
return self::SUCCESS;
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php 0000644 0001750 0001750 00000006156 13027032674 024710 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Prints plain text output of the test to a specified Writer.
*
* @author Michiel Rook
* @version $Id: 87be819ddfd82c1e76e794571d50890482e89394 $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestPlainResultFormatter extends SimpleTestResultFormatter
{
private $inner = "";
/**
* @return string
*/
public function getExtension()
{
return ".txt";
}
/**
* @return string
*/
public function getPreferredOutfile()
{
return "testresults";
}
/**
* @param string $test_name
*/
public function paintCaseStart($test_name)
{
parent::paintCaseStart($test_name);
$this->inner = "";
}
/**
* @param string $test_name
*/
public 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";
if ($this->out != null) {
$this->out->write($sb);
$this->out->write($this->inner);
}
}
}
/**
* @param string $message
*/
public function paintError($message)
{
parent::paintError($message);
$this->formatError("ERROR", $message);
}
/**
* @param string $message
*/
public function paintFail($message)
{
parent::paintFail($message);
$this->formatError("FAILED", $message);
}
/**
* @param $type
* @param $message
*/
private function formatError($type, $message)
{
$this->inner .= $this->getTestName() . " " . $type . "\n";
$this->inner .= $message . "\n";
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestTask.php 0000644 0001750 0001750 00000016614 13027032674 021464 0 ustar druid druid .
*/
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 SimpleTest tests.
*
* @author Michiel Rook
* @version $Id: d94834e70b1522ae68a116f449d10cf309c2b063 $
* @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 $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.
*/
public 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';
}
/**
* @param $value
*/
public function setFailureproperty($value)
{
$this->failureproperty = $value;
}
/**
* @param $value
*/
public function setErrorproperty($value)
{
$this->errorproperty = $value;
}
/**
* @param $value
*/
public function setHaltonerror($value)
{
$this->haltonerror = $value;
}
/**
* @param $value
*/
public function setHaltonfailure($value)
{
$this->haltonfailure = $value;
}
/**
* @param $printsummary
*/
public function setPrintsummary($printsummary)
{
$this->printsummary = $printsummary;
}
/**
* @param $debug
*/
public function setDebug($debug)
{
$this->debug = $debug;
}
/**
* @return bool
*/
public function getDebug()
{
return $this->debug;
}
/**
* Add a new formatter to all tests of this task.
*
* @param SimpleTestFormatterElement formatter element
*/
public 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.
*/
public 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
*/
public 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");
}
}
/**
* @param $suite
*/
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;
}
}
}
/**
* @return LogWriter
*/
private function getDefaultOutput()
{
return new LogWriter($this);
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestXmlResultFormatter.php 0000644 0001750 0001750 00000012317 13027032674 024401 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
@include_once 'simpletest/xml.php';
/**
* Prints plain text output of the test to a specified Writer.
*
* @author Michiel Rook
*
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestXmlResultFormatter extends SimpleTestResultFormatter
{
/**
* @var XmlReporter
*/
private $logger = null;
private $xmlData = "";
/**
*
*/
public function __construct()
{
$this->logger = new XmlReporter();
}
/**
* @return string
*/
public function getExtension()
{
return ".xml";
}
/**
* @return string
*/
public function getPreferredOutfile()
{
return "testsuites";
}
private function captureStart()
{
ob_start();
}
private function captureStop()
{
$this->xmlData .= ob_get_contents();
ob_end_clean();
}
/**
* @param string $test_name
* @param int $size
*/
public function paintGroupStart($test_name, $size)
{
parent::paintGroupStart($test_name, $size);
$this->captureStart();
$this->logger->paintGroupStart($test_name, $size);
$this->captureStop();
}
/**
* @param string $test_name
*/
public function paintGroupEnd($test_name)
{
parent::paintGroupEnd($test_name);
$this->captureStart();
$this->logger->paintGroupEnd($test_name);
$this->captureStop();
if (count($this->_test_stack) == 0) {
if ($this->out) {
$this->out->write($this->xmlData);
$this->out->close();
}
}
}
/**
* @param string $test_name
*/
public function paintCaseStart($test_name)
{
$this->captureStart();
$this->logger->paintCaseStart($test_name);
$this->captureStop();
}
/**
* @param string $test_name
*/
public function paintCaseEnd($test_name)
{
$this->captureStart();
$this->logger->paintCaseEnd($test_name);
$this->captureStop();
}
/**
* @param string $test_name
*/
public function paintMethodStart($test_name)
{
$this->captureStart();
$this->logger->paintMethodStart($test_name);
$this->captureStop();
}
/**
* @param string $test_name
*/
public function paintMethodEnd($test_name)
{
$this->captureStart();
$this->logger->paintMethodEnd($test_name);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintPass($message)
{
$this->captureStart();
$this->logger->paintPass($message);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintError($message)
{
$this->captureStart();
$this->logger->paintError($message);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintFail($message)
{
$this->captureStart();
$this->logger->paintFail($message);
$this->captureStop();
}
/**
* @param Exception $exception
*/
public function paintException($exception)
{
$this->captureStart();
$this->logger->paintException($exception);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintSkip($message)
{
$this->captureStart();
$this->logger->paintSkip($message);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintMessage($message)
{
$this->captureStart();
$this->logger->paintMessage($message);
$this->captureStop();
}
/**
* @param string $message
*/
public function paintFormattedMessage($message)
{
$this->captureStart();
$this->logger->paintFormattedMessage($message);
$this->captureStop();
}
/**
* @param string $type
* @param mixed $payload
*/
public function paintSignal($type, $payload)
{
$this->captureStart();
$this->logger->paintSignal($type, $payload);
$this->captureStop();
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestResultFormatter.php 0000644 0001750 0001750 00000010160 13027032674 023712 0 ustar druid druid .
*/
@include_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
* @version $Id: 019c9ca9df741e3a91efdb19aa9988db486e725b $
* @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.
* @param Writer $out
*/
public function setOutput(Writer $out)
{
$this->out = $out;
}
/**
* Returns the extension used for this formatter
*
* @return string the extension
*/
public function getExtension()
{
return "";
}
/**
* Sets the project
*
* @param Project the project
*/
public function setProject(Project $project)
{
$this->project = $project;
}
/**
* @return string
*/
public function getPreferredOutfile()
{
return "";
}
/**
* @param string $test_name
*/
public function paintMethodStart($test_name)
{
parent::paintMethodStart($test_name);
$this->currentTest = $test_name;
}
/**
* @param string $test_name
*/
public function paintMethodEnd($test_name)
{
parent::paintMethodEnd($test_name);
$this->runCount++;
}
/**
* @param string $test_name
*/
public function paintCaseStart($test_name)
{
parent::paintCaseStart($test_name);
$this->runCount = 0;
$this->failureCount = 0;
$this->errorCount = 0;
$this->timer = new Timer();
$this->timer->start();
}
/**
* @param string $test_name
*/
public function paintCaseEnd($test_name)
{
parent::paintCaseEnd($test_name);
$this->timer->stop();
}
/**
* @param string $message
*/
public function paintError($message)
{
parent::paintError($message);
$this->errorCount++;
}
/**
* @param string $message
*/
public function paintFail($message)
{
parent::paintFail($message);
$this->failureCount++;
}
/**
* @return int
*/
public function getRunCount()
{
return $this->runCount;
}
/**
* @return int
*/
public function getFailureCount()
{
return $this->failureCount;
}
/**
* @return int
*/
public function getErrorCount()
{
return $this->errorCount;
}
/**
* @return string
*/
public function getTestName()
{
return $this->currentTest;
}
/**
* @return int
*/
public function getElapsedTime()
{
if ($this->timer) {
return $this->timer->getElapsedTime();
} else {
return 0;
}
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestFormatterElement.php 0000644 0001750 0001750 00000005137 13027032674 024035 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phpunit/FormatterElement.php';
/**
* Child class of "FormatterElement", overrides setType to provide other
* formatter classes for SimpleTest
*
* @author Michiel Rook
*
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestFormatterElement extends FormatterElement
{
/**
* @param string $type
* @throws BuildException
*/
public 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");
}
}
}
}
}
}
phing-2.16.0/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php 0000644 0001750 0001750 00000003767 13027032674 025307 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
/**
* Prints short summary output of the test to Phing's logging system.
*
* @author Michiel Rook
* @version $Id: 3b2f67ab5e1a8dec51d3e7f1128bcaeceee3e75c $
* @package phing.tasks.ext.simpletest
* @since 2.2.0
*/
class SimpleTestSummaryResultFormatter extends SimpleTestResultFormatter
{
/**
* @param string $test_name
*/
public 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";
if ($this->out != null) {
$this->out->write($sb);
}
}
}
}
phing-2.16.0/tasks/ext/ComposerTask.php 0000644 0001750 0001750 00000010675 13027032674 016772 0 ustar druid druid .
*/
require_once "phing/Task.php";
require_once "phing/types/Commandline.php";
/**
* Composer Task
* Run composer straight from phing
*
* @author nuno costa
* @license MIT
* @version $Id: be79ded318bcd97deb5b1d7bac9f216dff9bbdfe $
* @package phing.tasks.ext
*/
class ComposerTask extends Task
{
/**
* @var string the path to php interpreter
*/
private $php = '';
/**
*
* @var string the Composer command to execute
*/
private $command = null;
/**
*
* @var Commandline
*/
private $commandLine = null;
/**
*
* @var string path to Composer application
*/
private $composer = 'composer.phar';
/**
*
*/
public function __construct()
{
$this->commandLine = new Commandline();
}
/**
* Initialize the interpreter with the Phing property php.interpreter
*/
public function init()
{
$this->setPhp($this->project->getProperty('php.interpreter'));
}
/**
* Sets the path to php executable.
*
* @param string $php
*/
public function setPhp($php)
{
$this->php = $php;
}
/**
* gets the path to php executable.
*
* @return string
*/
public function getPhp()
{
return $this->php;
}
/**
* sets the Composer command to execute
* @param string $command
*/
public function setCommand($command)
{
$this->command = $command;
}
/**
* return the Composer command to execute
* @return String
*/
public function getCommand()
{
return $this->command;
}
/**
* sets the path to Composer application
* @param string $console
*/
public function setComposer($console)
{
$this->composer = $console;
}
/**
* returns the path to Composer application
* @return string
*/
public function getComposer()
{
return $this->composer;
}
/**
* creates a nested arg task
*
* @return Arg Argument object
*/
public function createArg()
{
return $this->commandLine->createArgument();
}
/**
* Prepares the command string to be executed
* @return string
*/
private function prepareCommandLine()
{
$this->commandLine->setExecutable($this->getPhp());
//We are un-shifting arguments to the beginning of the command line because arguments should be at the end
$this->commandLine->createArgument(true)->setValue($this->getCommand());
$this->commandLine->createArgument(true)->setValue($this->getComposer());
$commandLine = strval($this->commandLine);
//Creating new Commandline instance. It allows to handle subsequent calls correctly
$this->commandLine = new Commandline();
return $commandLine;
}
/**
* executes the Composer task
*/
public function main()
{
$commandLine = $this->prepareCommandLine();
$this->log("executing " . $commandLine);
$composerFile = new SplFileInfo($this->getComposer());
if (false === $composerFile->isFile()) {
throw new BuildException(sprintf('Composer binary not found, path is "%s"', $composerFile));
}
$return = 0;
passthru($commandLine, $return);
if ($return > 0) {
throw new BuildException("Composer execution failed");
}
}
}
phing-2.16.0/tasks/ext/phploc/PHPLocXMLFormatter.php 0000644 0001750 0001750 00000003063 13027032674 021170 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phploc/AbstractPHPLocFormatter.php';
/**
* @author Michiel Rook
* @version $Id: 11510e1b71f4f3a91df7fd8ce39ed5d24615d991 $
* @package phing.tasks.ext.phploc
*/
class PHPLocXMLFormatter extends AbstractPHPLocFormatter
{
public function printResult(array $count, $countTests = false)
{
$printerClass = '\\SebastianBergmann\\PHPLOC\\Log\\XML';
$printer = new $printerClass();
$printer->printResult($this->getToDir() . DIRECTORY_SEPARATOR . $this->getOutfile(), $count);
}
}
phing-2.16.0/tasks/ext/phploc/PHPLocTask.php 0000644 0001750 0001750 00000023025 13027032674 017546 0 ustar druid druid .
*/
require_once 'phing/Task.php';
require_once 'phing/BuildException.php';
require_once 'phing/tasks/ext/phploc/PHPLocFormatterElement.php';
require_once 'phing/tasks/ext/phploc/PHPLocFormatterFactory.php';
/**
* Runs phploc a tool for quickly measuring the size of PHP projects.
*
* @package phing.tasks.ext.phploc
* @author Raphael Stolt
*/
class PHPLocTask extends Task
{
/**
* @var array
*/
protected $suffixesToCheck = array('php');
/**
* @var array
*/
protected $acceptedReportTypes = array('cli', 'txt', 'xml', 'csv');
/**
* @var null
*/
protected $reportDirectory = null;
/**
* @var string
*/
protected $reportType = 'cli';
/**
* @var string
*/
protected $reportFileName = 'phploc-report';
/**
* @var bool
*/
protected $countTests = false;
/**
* @var null|PhingFile
*/
protected $fileToCheck = null;
/**
* @var array
*/
protected $filesToCheck = array();
/**
* @var FileSet[]
*/
protected $fileSets = array();
/**
* @var PHPLocFormatterElement[]
*/
protected $formatterElements = array();
/**
* @var string
*/
private $pharLocation = "";
/**
* @param string $suffixListOrSingleSuffix
*/
public function setSuffixes($suffixListOrSingleSuffix)
{
if (stripos($suffixListOrSingleSuffix, ',')) {
$suffixes = explode(',', $suffixListOrSingleSuffix);
$this->suffixesToCheck = array_map('trim', $suffixes);
} else {
$this->suffixesToCheck[] = trim($suffixListOrSingleSuffix);
}
}
/**
* @param PhingFile $file
*/
public function setFile(PhingFile $file)
{
$this->fileToCheck = trim($file);
}
/**
* @param boolean $countTests
*/
public function setCountTests($countTests)
{
$this->countTests = StringHelper::booleanValue($countTests);
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->fileSets[] = $fs;
}
/**
* @param string $type
*/
public function setReportType($type)
{
$this->reportType = trim($type);
}
/**
* @param string $name
*/
public function setReportName($name)
{
$this->reportFileName = trim($name);
}
/**
* @param string $directory
*/
public function setReportDirectory($directory)
{
$this->reportDirectory = trim($directory);
}
/**
* @param string $pharLocation
*/
public function setPharLocation($pharLocation)
{
$this->pharLocation = $pharLocation;
}
/**
* @param PHPLocFormatterElement $formatterElement
*/
public function addFormatter(PHPLocFormatterElement $formatterElement)
{
$this->formatterElements[] = $formatterElement;
}
/**
* @throws BuildException
*/
protected function loadDependencies()
{
if (!empty($this->pharLocation)) {
// hack to prevent PHPLOC from starting in CLI mode and halting Phing
eval("namespace SebastianBergmann\PHPLOC\CLI;
class Application
{
public function run() {}
}");
ob_start();
include $this->pharLocation;
ob_end_clean();
}
if (!class_exists('\SebastianBergmann\PHPLOC\Analyser')) {
if (!@include_once 'SebastianBergmann/PHPLOC/autoload.php') {
throw new BuildException(
'PHPLocTask depends on PHPLoc being installed and on include_path.',
$this->getLocation()
);
}
}
}
public function main()
{
$this->loadDependencies();
$this->validateProperties();
if (count($this->fileSets) > 0) {
foreach ($this->fileSets as $fileSet) {
$directoryScanner = $fileSet->getDirectoryScanner($this->project);
$files = $directoryScanner->getIncludedFiles();
$directory = $fileSet->getDir($this->project)->getPath();
foreach ($files as $file) {
if ($this->isFileSuffixSet($file)) {
$this->filesToCheck[] = $directory . DIRECTORY_SEPARATOR . $file;
}
}
}
$this->filesToCheck = array_unique($this->filesToCheck);
}
$this->runPhpLocCheck();
}
/**
* @throws BuildException
*/
private function validateProperties()
{
if ($this->fileToCheck === null && count($this->fileSets) === 0) {
throw new BuildException('Missing either a nested fileset or the attribute "file" set.');
}
if ($this->fileToCheck !== null) {
if (!file_exists($this->fileToCheck)) {
throw new BuildException("File to check doesn't exist.");
}
if (!$this->isFileSuffixSet($this->fileToCheck)) {
throw new BuildException('Suffix of file to check is not defined in "suffixes" attribute.');
}
if (count($this->fileSets) > 0) {
throw new BuildException('Either use a nested fileset or "file" attribute; not both.');
}
}
if (count($this->suffixesToCheck) === 0) {
throw new BuildException('No file suffix defined.');
}
if (count($this->formatterElements) == 0) {
if ($this->reportType === null) {
throw new BuildException('No report type or formatters defined.');
}
if ($this->reportType !== null && !in_array($this->reportType, $this->acceptedReportTypes)) {
throw new BuildException('Unaccepted report type defined.');
}
if ($this->reportType !== 'cli' && $this->reportDirectory === null) {
throw new BuildException('No report output directory defined.');
}
if ($this->reportDirectory !== null && !is_dir($this->reportDirectory)) {
$reportOutputDir = new PhingFile($this->reportDirectory);
$logMessage = "Report output directory doesn't exist, creating: "
. $reportOutputDir->getAbsolutePath() . '.';
$this->log($logMessage);
$reportOutputDir->mkdirs();
}
if ($this->reportType !== 'cli') {
$this->reportFileName .= '.' . $this->reportType;
}
$formatterElement = new PHPLocFormatterElement();
$formatterElement->setType($this->reportType);
$formatterElement->setUseFile($this->reportDirectory !== null);
$formatterElement->setToDir($this->reportDirectory);
$formatterElement->setOutfile($this->reportFileName);
$this->formatterElements[] = $formatterElement;
}
}
/**
* @param string $filename
*
* @return boolean
*/
protected function isFileSuffixSet($filename)
{
return in_array(pathinfo($filename, PATHINFO_EXTENSION), $this->suffixesToCheck);
}
protected function runPhpLocCheck()
{
$files = $this->getFilesToCheck();
$count = $this->getCountForFiles($files);
foreach ($this->formatterElements as $formatterElement) {
$formatter = PHPLocFormatterFactory::createFormatter($formatterElement);
if ($formatterElement->getType() != 'cli') {
$logMessage = 'Writing report to: '
. $formatterElement->getToDir() . DIRECTORY_SEPARATOR . $formatterElement->getOutfile();
$this->log($logMessage);
}
$formatter->printResult($count, $this->countTests);
}
}
/**
* @return SplFileInfo[]
*/
protected function getFilesToCheck()
{
$files = array();
if (count($this->filesToCheck) > 0) {
foreach ($this->filesToCheck as $file) {
$files[] = new SplFileInfo($file);
}
} elseif ($this->fileToCheck !== null) {
$files = array(new SplFileInfo($this->fileToCheck));
}
return $files;
}
/**
* @param SplFileInfo[] $files
*
* @return array
*/
protected function getCountForFiles(array $files)
{
$analyserClass = '\\SebastianBergmann\\PHPLOC\\Analyser';
$analyser = new $analyserClass();
return $analyser->countFiles($files, $this->countTests);
}
}
phing-2.16.0/tasks/ext/phploc/AbstractPHPLocFormatter.php 0000644 0001750 0001750 00000005203 13027032674 022271 0 ustar druid druid .
*/
require_once 'phing/system/io/PhingFile.php';
/**
* @author Michiel Rook
* @version $Id: a2989958865651cca9c94d8b17c5ecf041f78614 $
* @package phing.tasks.ext.phploc
*/
abstract class AbstractPHPLocFormatter
{
/**
* @param array $count
* @param bool $countTests
* @return mixed
*/
abstract public function printResult(array $count, $countTests = false);
/**
* @var bool
*/
protected $useFile = true;
/**
* @var string
*/
protected $toDir = ".";
/**
* @var string
*/
protected $outfile = "";
/**
* Sets whether to store formatting results in a file
* @param $useFile
*/
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)
{
if (!is_dir($toDir)) {
$toDir = new PhingFile($toDir);
$toDir->mkdirs();
}
$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()
{
return $this->outfile;
}
} phing-2.16.0/tasks/ext/phploc/PHPLocFormatterElement.php 0000644 0001750 0001750 00000005177 13027032674 022131 0 ustar druid druid .
*/
/**
* @author Michiel Rook
* @version $Id: 5911dc47d5037c87f6c0c11d815c05361cad9bc0 $
* @package phing.tasks.ext.phploc
*/
class PHPLocFormatterElement
{
/**
* @var string
*/
protected $type = "";
/**
* @var bool
*/
protected $useFile = true;
/**
* @var string
*/
protected $toDir = ".";
/**
* @var string
*/
protected $outfile = "phploc-report";
/**
* Loads a specific formatter type
* @param string $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Sets whether to store formatting results in a file
* @param $useFile
*/
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()
{
return $this->outfile;
}
}
phing-2.16.0/tasks/ext/phploc/PHPLocTextFormatter.php 0000644 0001750 0001750 00000003655 13027032674 021463 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phploc/AbstractPHPLocFormatter.php';
/**
* @author Michiel Rook
* @version $Id: d9e8d9450dcecf7f3691236655b802512460618b $
* @package phing.tasks.ext.phploc
*/
class PHPLocTextFormatter extends AbstractPHPLocFormatter
{
public function printResult(array $count, $countTests = false)
{
if ($this->getUseFile()) {
$outputClass = '\\Symfony\\Component\\Console\\Output\\StreamOutput';
$stream = fopen($this->getToDir() . DIRECTORY_SEPARATOR . $this->getOutfile(), 'a+');
$output = new $outputClass($stream);
} else {
$outputClass = '\\Symfony\\Component\\Console\\Output\\ConsoleOutput';
$output = new $outputClass();
}
$printerClass = '\\SebastianBergmann\\PHPLOC\\Log\\Text';
$printer = new $printerClass();
$printer->printResult($output, $count, $countTests);
}
}
phing-2.16.0/tasks/ext/phploc/PHPLocCSVFormatter.php 0000644 0001750 0001750 00000003073 13027032674 021164 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phploc/AbstractPHPLocFormatter.php';
/**
* @author Michiel Rook
* @version $Id: d7cc7bea3ec2cc98a53da57434dc778d1697f565 $
* @package phing.tasks.ext.phploc
*/
class PHPLocCSVFormatter extends AbstractPHPLocFormatter
{
public function printResult(array $count, $countTests = false)
{
$printerClass = '\\SebastianBergmann\\PHPLOC\\Log\\CSV\\Single';
$printer = new $printerClass();
$printer->printResult($this->getToDir() . DIRECTORY_SEPARATOR . $this->getOutfile(), $count);
}
}
phing-2.16.0/tasks/ext/phploc/PHPLocFormatterFactory.php 0000644 0001750 0001750 00000005037 13027032674 022142 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/phploc/AbstractPHPLocFormatter.php';
/**
* A wrapper for the implementations of PHPUnit2ResultFormatter.
*
* @author Michiel Rook
* @version $Id: df866a6b5cdfae3f31e201fe05789f9616db2059 $
* @package phing.tasks.ext.phploc
*/
class PHPLocFormatterFactory
{
/**
* Returns formatter object
* @param PHPLocFormatterElement $formatterElement
* @throws BuildException
* @return AbstractPHPLocFormatter
*/
public static function createFormatter($formatterElement)
{
$formatter = null;
$type = $formatterElement->getType();
switch ($type) {
case "xml":
require_once 'phing/tasks/ext/phploc/PHPLocXMLFormatter.php';
$formatter = new PHPLocXMLFormatter();
break;
case "csv":
require_once 'phing/tasks/ext/phploc/PHPLocCSVFormatter.php';
$formatter = new PHPLocCSVFormatter();
break;
case "txt":
case "cli":
require_once 'phing/tasks/ext/phploc/PHPLocTextFormatter.php';
$formatter = new PHPLocTextFormatter();
break;
default:
throw new BuildException("Formatter '" . $type . "' not implemented");
}
$formatter->setOutfile($formatterElement->getOutfile());
$formatter->setToDir($formatterElement->getToDir());
$formatter->setUseFile($formatterElement->getUseFile());
return $formatter;
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxMysql.php 0000644 0001750 0001750 00000002632 13027032674 021276 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: 2df6bddd9e2070c0cbc8d8eab2ee0a3caafb9b20 $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxMysql extends DbmsSyntax
{
/**
* @return string
*/
public function generateTimestamp()
{
return "NOW()";
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntax.php 0000644 0001750 0001750 00000002643 13027032674 020252 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: e8f266768b58a63d2f0a4a40e1c4c220b81901ec $
* @package phing.tasks.ext.dbdeploy
*/
abstract class DbmsSyntax
{
/**
* @param $db
*/
public function applyAttributes($db)
{
}
abstract public function generateTimestamp();
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php 0000644 0001750 0001750 00000002667 13027032674 021240 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: ff91eb484802be6835d70ee11c6c9d7fed1e09df $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxMsSql extends DbmsSyntax
{
/**
* @return string
*/
public function generateTimestamp()
{
return "DATEDIFF(s, '19700101', GETDATE())";
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxOracle.php 0000644 0001750 0001750 00000003144 13027032674 021375 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: adc9b31780df2145519b4d451cb462527bd200f5 $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxOracle extends DbmsSyntax
{
/**
* @param $db
*/
public function applyAttributes($db)
{
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
}
/**
* @return string
*/
public function generateTimestamp()
{
return "(sysdate - to_date('01-JAN-1970','DD-MON-YYYY')) * (86400)";
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxPgSQL.php 0000644 0001750 0001750 00000002563 13027032674 021122 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Remy BREUILS
* @version $Id: ee3d162c42e59a87e2cde17d64360fa16955fa85 $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxPgSQL extends DbmsSyntax
{
/**
* @return string
*/
public function generateTimestamp()
{
return "NOW()";
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxFactory.php 0000644 0001750 0001750 00000004744 13027032674 021606 0 ustar druid druid .
*/
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: 1d817a30c44e1f87a0f51ecebdc9fefe3177790c $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxFactory
{
private $dbms;
/**
* @param $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.');
}
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php 0000644 0001750 0001750 00000002652 13027032674 021334 0 ustar druid druid .
*/
/**
* Utility class for generating necessary server-specific SQL commands
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: f154ae7623dcdc04e60284fe70bea1da99ab1254 $
* @package phing.tasks.ext.dbdeploy
*/
class DbmsSyntaxSQLite extends DbmsSyntax
{
/**
* @return string
*/
public function generateTimestamp()
{
return "strftime('%s','now')";
}
}
phing-2.16.0/tasks/ext/dbdeploy/DbDeployTask.php 0000644 0001750 0001750 00000032634 13027032674 020506 0 ustar druid druid .
*/
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
*
*
*
* @author Luke Crouch at SourceForge (http://sourceforge.net)
* @version $Id: 4a3c05035ee7d8e1b9c019e218eaa84cf6979df8 $
* @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 value of the 'applied_by' column for
* each changelog entry
*
* @var string
*/
protected $appliedBy = 'dbdeploy';
/**
* 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 ? 'On' : 'Off'));
$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);
$this->dbmsSyntax->applyAttributes($dbh);
$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() .
', \'' . $this->appliedBy . '\', \'' . $fileName . '\');' . "\n";
}
// read the file
$fullFileName = $this->dir . '/' . $fileName;
$fh = fopen($fullFileName, 'r');
$contents = fread($fh, filesize($fullFileName));
$count_bad_comments = substr_count($contents, '--//');
if ($count_bad_comments > 0) {
$this->log('Your SQL delta includes "--//" which, if a comment, should be replaced with "-- //"
to avoid the delta failing. You may need to manually undo part of this delta.\n\n'
. $contents, Project::MSG_WARN);
}
// allow construct with and without space added
$split = strpos($contents, '-- //@UNDO');
if ($split === false) {
$split = strpos($contents, '--//@UNDO');
}
if ($split === false) {
$split = strlen($contents);
}
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);
// Ensuring there's a newline after the final -- //
$sql .= PHP_EOL;
$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);
if ($dh === false) {
return $files;
}
$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;
}
/**
* Set the appliedBy property
*
* @param string $appliedBy
* @return void
*/
public function setAppliedBy($appliedBy)
{
$this->appliedBy = $appliedBy;
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
}
phing-2.16.0/tasks/ext/pdo/PlainPDOResultFormatter.php 0000644 0001750 0001750 00000006734 13027032674 021634 0 ustar druid druid .
*/
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/tasks/ext/pdo/PDOResultFormatter.php';
/**
* Plain text formatter for PDO results.
*
* @author Hans Lellelid
* @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);
}
/**
* @return PhingFile
*/
public function getPreferredOutfile()
{
return new PhingFile('results.txt');
}
}
phing-2.16.0/tasks/ext/pdo/XMLPDOResultFormatter.php 0000644 0001750 0001750 00000007357 13027032674 021233 0 ustar druid druid .
*/
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.
*
*
*
* value
* value2
*
*
* value
* value2
*
*
*
* The actual names of the colums will depend on the fetchmode that was used
* with PDO.
*
* @author Hans Lellelid
* @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();
}
}
phing-2.16.0/tasks/ext/pdo/PDOSQLExecTask.php 0000644 0001750 0001750 00000045452 13027032674 017575 0 ustar druid druid .
*/
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.
*
* Statements can
* either be read in from a text file using the src attribute or from
* between the enclosing SQL tags.
*
* Multiple statements can be provided, separated by semicolons (or the
* defined delimiter ). Individual lines within the statements can be
* commented using either --, // or REM at the start of the line.
*
* The autocommit attribute specifies whether auto-commit should be
* turned on or off whilst executing the statements. If auto-commit is turned
* on each statement will be executed and committed. If it is turned off the
* statements will all be executed as one transaction.
*
* The onerror attribute specifies how to proceed when an error occurs
* during the execution of one of the statements.
* The possible values are: continue execution, only show the error;
* stop execution and commit transaction;
* and abort execution and transaction and fail task.
*
* @author Hans Lellelid (Phing)
* @author Jeff Martin (Ant)
* @author Michael McCallum (Ant)
* @author Tim Stephenson (Ant)
* @package phing.tasks.ext.pdo
* @version $Id: 6f0271c4fe34f85450002311f9fdb18b359bea8d $
*/
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";
const DELIM_NONE = "none";
/**
* 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 = "none"; // 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
* @param PhingFile $srcFile
*/
public function setSrc(PhingFile $srcFile)
{
$this->srcFile = $srcFile;
}
/**
* Set an inline SQL command to execute.
* NB: Properties are not expanded in this text.
* @param $sql
*/
public function addText($sql)
{
$this->sqlCommand .= $sql;
}
/**
* Adds a set of files (nested fileset attribute).
* @param FileSet $set
*/
public function addFileset(FileSet $set)
{
$this->filesets[] = $set;
}
/**
* Adds a set of files (nested filelist attribute).
* @param FileList $list
*/
public function addFilelist(FileList $list)
{
$this->filelists[] = $list;
}
/**
* Creates a new PDOSQLExecFormatterElement for 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 the $encoding
* @internal param the $encoding encoding to use on the files
*/
public function setEncoding($encoding)
{
$this->encoding = $encoding;
}
/**
* Set the statement delimiter.
*
* For example, set this to "go" and delimitertype to "ROW" for
* Sybase ASE or MS SQL Server.
*
* @param delimiter
*/
public function setDelimiter($delimiter)
{
$this->delimiter = $delimiter;
}
/**
* 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 occurrence of the delimiter
* terminate the SQL command whereas with row, only a line containing just
* the delimiter is recognized as the end of the command.
*
* @param string $delimiterType
*/
public function setDelimiterType($delimiterType)
{
$this->delimiterType = $delimiterType;
}
/**
* Action to perform when statement fails: continue, stop, or abort
* optional; default "abort"
* @param $action
*/
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.
* @throws BuildException
*/
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.
*
* {@inheritdoc}
*
* @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("Committing 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
* @param Reader $reader
* @throws BuildException
*/
public function runStatements(Reader $reader)
{
if (self::DELIM_NONE == $this->delimiterType) {
require_once 'phing/tasks/ext/pdo/DummyPDOQuerySplitter.php';
$splitter = new DummyPDOQuerySplitter($this, $reader);
} elseif (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.
*
* @param $sql
*
* @throws BuildException
* @throws Exception
*/
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);
$this->conn = null;
}
}
}
/**
* "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;
/**
* @param $parent
*/
public function __construct($parent)
{
// Parent is required so that we can log things ...
$this->parent = $parent;
}
/**
* @param PhingFile $src
*/
public function setSrc(PhingFile $src)
{
$this->tSrcFile = $src;
}
/**
* @param $sql
*/
public function addText($sql)
{
$this->tSqlCommand .= $sql;
}
/**
* @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();
}
}
}
phing-2.16.0/tasks/ext/pdo/DefaultPDOQuerySplitter.php 0000644 0001750 0001750 00000013130 13027032674 021633 0 ustar druid druid .
*
* @version SVN: $Id: 43afd902ddb58980b64121603ad61d308ca88975 $
* @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
* @author Alexey Borzov
* @package phing.tasks.ext.pdo
* @version $Id: 43afd902ddb58980b64121603ad61d308ca88975 $
*/
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;
}
}
phing-2.16.0/tasks/ext/pdo/PDOSQLExecFormatterElement.php 0000644 0001750 0001750 00000020764 13027032674 022147 0 ustar druid druid .
*/
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 element for PDO SQL results.
*
* This class is inspired by the similarly-named class in the PHPUnit tasks.
*
* @author Hans Lellelid
* @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 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
* @throws BuildException
*/
public 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
*/
public function setClassName($className)
{
$classNameNoDot = Phing::import($className);
$this->formatter = new $classNameNoDot();
}
/**
* Set whether to write formatter results to file.
* @param boolean $useFile
*/
public function setUseFile($useFile)
{
$this->useFile = (boolean) $useFile;
}
/**
* Return whether to write formatter results to file.
* @return boolean
*/
public function getUseFile()
{
return $this->useFile;
}
/**
* Sets the output file for the formatter results.
* @param PhingFile $outfile
* @internal param PhingFile $outFile
*/
public function setOutfile(PhingFile $outfile)
{
$this->outfile = $outfile;
}
/**
* Get the output file.
* @return PhingFile
*/
public 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
*/
public function getFormatter()
{
return $this->formatter;
}
}
phing-2.16.0/tasks/ext/pdo/PgsqlPDOQuerySplitter.php 0000644 0001750 0001750 00000024017 13027032674 021343 0 ustar druid druid .
*
* @version SVN: $Id: 2e4cf5659024930ba454c239c5e288e2fd7dab37 $
* @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
* @package phing.tasks.ext.pdo
* @version $Id: 2e4cf5659024930ba454c239c5e288e2fd7dab37 $
* @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;
}
}
}
}
/**
* @return null|string
*/
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;
}
}
phing-2.16.0/tasks/ext/pdo/DummyPDOQuerySplitter.php 0000644 0001750 0001750 00000004702 13027032674 021347 0 ustar druid druid .
*
* @version $Id: 9e64e7e9e66982fa11e85ccde7b9ab5756076872 $
* @package phing.tasks.ext.pdo
*/
require_once 'phing/tasks/ext/pdo/PDOQuerySplitter.php';
/**
* Dummy query splitter: converts entire input into single
* SQL string
*
* @author Michiel Rook
* @package phing.tasks.ext.pdo
* @version $Id: 9e64e7e9e66982fa11e85ccde7b9ab5756076872 $
*/
class DummyPDOQuerySplitter extends PDOQuerySplitter
{
/**
* Returns entire SQL source
*
* @return string|null
*/
public function nextQuery()
{
$sql = null;
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;
}
$sql .= " " . $line . "\n";
/**
* fix issue with PDO and wrong formated multistatements
* @issue 1108
*/
if (StringHelper::endsWith($delimiter, $line)) {
break;
}
}
return $sql;
}
}
phing-2.16.0/tasks/ext/pdo/PDOTask.php 0000644 0001750 0001750 00000014025 13027032674 016400 0 ustar druid druid .
*/
require_once 'phing/Task.php';
include_once 'phing/types/Reference.php';
/**
* Handles PDO configuration needed by SQL type tasks.
*
* @author Hans Lellelid (Phing)
* @author Nick Chalko (Ant)
* @author Jeff Martin (Ant)
* @author Michael McCallum (Ant)
* @author Tim Stephenson (Ant)
* @version $Id: ff221a5d49c565473f836701865b39a315acddb9 $
* @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 the PDOTask
* This method checks if the PDO classes are available 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()
{
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 The $url
* @internal param The $url url to set
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* Sets the password; required.
* @param The $password
* @internal param The $password password to set
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Auto commit flag for database connection;
* optional, default false.
* @param The $autocommit
* @internal param The $autocommit autocommit to set
*/
public function setAutocommit($autocommit)
{
$this->autocommit = $autocommit;
}
/**
* Sets the version string, execute task only if
* rdbms version match; optional.
* @param The $version
* @internal param The $version version to set
*/
public function setVersion($version)
{
$this->version = $version;
}
/**
* @return mixed
*/
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 (PDOException $e) {
throw new BuildException($e->getMessage(), $this->location);
}
}
/**
* @param $value
*/
public function isCaching($value)
{
$this->caching = $value;
}
/**
* Gets the autocommit.
* @return Returns a boolean
*/
public function isAutocommit()
{
return $this->autocommit;
}
/**
* Gets the url.
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Gets the userId.
* @return string
*/
public function getUserId()
{
return $this->userId;
}
/**
* Set the user name for the connection; required.
* @param string $userId
*/
public function setUserid($userId)
{
$this->userId = $userId;
}
/**
* Gets the password.
* @return string
*/
public function getPassword()
{
return $this->password;
}
}
phing-2.16.0/tasks/ext/pdo/PDOQuerySplitter.php 0000644 0001750 0001750 00000003751 13027032674 020336 0 ustar druid druid .
*
* @version $Id: 918ec6d58131d6aea966b154be71a83c27e94b7c $
* @package phing.tasks.ext.pdo
*/
/**
* Base class for classes that split SQL source into separate queries
*
* @author Alexey Borzov
* @package phing.tasks.ext.pdo
* @version $Id: 918ec6d58131d6aea966b154be71a83c27e94b7c $
*/
abstract class PDOQuerySplitter
{
/**
* 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();
}
phing-2.16.0/tasks/ext/pdo/PDOResultFormatter.php 0000644 0001750 0001750 00000004207 13027032674 020641 0 ustar druid druid .
*/
require_once 'phing/system/io/PhingFile.php';
/**
* Abstract
*
* @author Hans Lellelid
* @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();
}
}
phing-2.16.0/tasks/ext/SymfonyConsole/SymfonyConsoleTask.php 0000644 0001750 0001750 00000012735 13027032674 023160 0 ustar druid druid .
*/
require_once "phing/Task.php";
require_once dirname(__FILE__) . "/Arg.php";
/**
* Symfony Console Task
* @author nuno costa
* @license GPL
* @version $Id: e2d3229326c8a6b49e75ef4e9bf892816e26e350 $
* @package phing.tasks.ext.symfony
*/
class SymfonyConsoleTask extends Task
{
/**
*
* @var 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';
/**
*
* @var string property to be set
*/
private $propertyName = null;
/**
* Whether to check the return code.
* @var boolean
*/
private $checkreturn = false;
/**
* Is the symfony cli debug mode set? (true by default)
* @var boolean
*/
private $debug = true;
/**
* 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;
}
/**
* Set the name of the property to store the application output in
* @param $property
* @return void
*/
public function setPropertyName($property)
{
$this->propertyName = $property;
}
/**
* Whether to check the return code.
*
* @param boolean $checkreturn If the return code shall be checked
*
* @return void
*/
public function setCheckreturn($checkreturn)
{
$this->checkreturn = (bool) $checkreturn;
}
/**
* Whether to set the symfony cli debug mode
*
* @param boolean $debug If the symfony cli debug mode is set
*
* @return void
*/
public function setDebug($debug)
{
$this->debug = (bool) $debug;
}
/**
* Get if the symfony cli debug mode is set
* @return boolean
*/
public function getDebug()
{
return $this->debug;
}
/**
* 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;
}
/**
* Check if the no-debug option was added via args
* @return boolean
*/
private function isNoDebugArgPresent()
{
foreach($this->args as $arg) {
if ($arg->getName() == "no-debug") {
return true;
}
}
return false;
}
/**
* Gets the command string to be executed
* @return string
*/
public function getCmdString()
{
// Add no-debug arg if it isn't already present
if (!$this->debug && !$this->isNoDebugArgPresent()) {
$this->createArg()->setName("no-debug");
}
$cmd = array(
Commandline::quoteArgument($this->console),
$this->command,
implode(' ', $this->args)
);
$cmd = implode(' ', $cmd);
return $cmd;
}
/**
* executes the synfony console application
*/
public function main()
{
$cmd = $this->getCmdString();
$this->log("executing $cmd");
$return = null;
$output = array();
exec($cmd, $output, $return);
$lines = implode("\r\n", $output);
$this->log($lines, Project::MSG_INFO);
if ($this->propertyName != null) {
$this->project->setProperty($this->propertyName, $lines);
}
if ($return != 0 && $this->checkreturn) {
$this->log('Task exited with code: ' . $return, Project::MSG_ERR);
throw new BuildException("SymfonyConsole execution failed");
}
}
}
phing-2.16.0/tasks/ext/SymfonyConsole/Arg.php 0000644 0001750 0001750 00000005651 13027032674 020056 0 ustar druid druid .
*/
require_once "phing/types/DataType.php";
/**
* Implementation of console argument
*
* @author nuno costa
* @license GPL
* @version $Id: 0e03453bfaa39363850a37e44da2cf435cdf66e6 $
* @package phing.tasks.ext.symfony
*/
class Arg extends DataType
{
private $name = null;
private $value = null;
private $quotes = false;
/**
* Gets the argument 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;
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseUpdateTask.php 0000644 0001750 0001750 00000002165 13027032674 022235 0 ustar druid druid
* @version $Id: 9bc3829efb98aff78729b2da69cfde7d9c1204ff $
* @since 2.4.10
* @package phing.tasks.ext.liquibase
*/
class LiquibaseUpdateTask extends AbstractLiquibaseTask
{
/**
* @see Task::main()
*/
public function main()
{
$this->checkParams();
$this->execute('update');
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseDiffTask.php 0000644 0001750 0001750 00000007704 13027032674 021667 0 ustar druid druid
* @version $Id: d678839b8d9ff66611eac44926d340bc8fe97128 $
* @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 reference 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.
*
* jdbc:postgresql://psqlhost/myrefdatabase
*
*
* @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');
}
}
phing-2.16.0/tasks/ext/liquibase/AbstractLiquibaseTask.php 0000644 0001750 0001750 00000025654 13027032674 022566 0 ustar druid druid
* @version $Id: e60f3f6a7b9c03e72b55f514ab85f2e8bb1e3f81 $
* @since 2.4.10
* @package phing.tasks.ext.liquibase
*/
abstract class AbstractLiquibaseTask extends Task
{
/**
* Used for liquibase -Dname=value properties.
*/
private $properties = array();
/**
* Used to set liquibase --name=value parameters
*/
private $parameters = array();
protected $jar;
protected $changeLogFile;
protected $username;
protected $password;
protected $url;
protected $classpathref;
/**
* Whether to display the output of the command.
* True by default to preserve old behaviour
* @var boolean
*/
protected $display = true;
/**
* Whether liquibase return code can cause a Phing failure.
* @var boolean
*/
protected $checkreturn = false;
/**
* Set true if we should run liquibase with PHP passthru
* instead of exec.
*/
protected $passthru = true;
/**
* Property name to set with output value from exec call.
*
* @var string
*/
protected $outputProperty;
/**
* 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.
*
* jdbc:postgresql://psqlhost/mydatabase
*
*
* @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;
}
/**
* Sets whether to display the output of the command
* @param boolean $display
*/
public function setDisplay($display)
{
$this->display = StringHelper::booleanValue($display);
}
/**
* Whether to check the liquibase return code.
*
* @param boolean $checkreturn
*/
public function setCheckreturn($checkreturn)
{
$this->checkreturn = StringHelper::booleanValue($checkreturn);
}
/**
* Whether to check the liquibase return code.
*
* @param $passthru
* @internal param bool $checkreturn
*/
public function setPassthru($passthru)
{
$this->passthru = StringHelper::booleanValue($passthru);
}
/**
* the name of property to set to output value from exec() call.
*
* @param string $prop property name
*
* @return void
*/
public function setOutputProperty($prop)
{
$this->outputProperty = $prop;
}
/**
* Creates a nested tag.
*
* @return LiquibaseProperty Argument object
*/
public function createProperty()
{
$prop = new LiquibaseProperty();
$this->properties[] = $prop;
return $prop;
}
/**
* Creates a nested tag.
*
* @return LiquibaseParameter Argument object
*/
public function createParameter()
{
$param = new LiquibaseParameter();
$this->parameters[] = $param;
return $param;
}
/**
* Ensure that correct parameters were passed in.
*
* @throws BuildException
* @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
)
);
}
$this->checkChangeLogFile();
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 $lbcommand
* @param string $lbparams the command to execute
* @throws BuildException
* @return string the output of the executed command
*/
protected function execute($lbcommand, $lbparams = '')
{
$nestedparams = "";
foreach ($this->parameters as $p) {
$nestedparams .= $p->getCommandline($this->project) . ' ';
}
$nestedprops = "";
foreach ($this->properties as $p) {
$nestedprops .= $p->getCommandline($this->project) . ' ';
}
$command = sprintf(
'java -jar %s --changeLogFile=%s --url=%s --username=%s --password=%s --classpath=%s %s %s %s %s 2>&1',
escapeshellarg($this->jar),
escapeshellarg($this->changeLogFile),
escapeshellarg($this->url),
escapeshellarg($this->username),
escapeshellarg($this->password),
escapeshellarg($this->classpathref),
$nestedparams,
escapeshellarg($lbcommand),
$lbparams,
$nestedprops
);
if ($this->passthru) {
passthru($command);
} else {
$output = array();
$return = null;
exec($command, $output, $return);
$output = implode(PHP_EOL, $output);
if ($this->display) {
print $output;
}
if (!empty($this->outputProperty)) {
$this->project->setProperty($this->outputProperty, $output);
}
if ($this->checkreturn && $return != 0) {
throw new BuildException("Liquibase exited with code $return");
}
}
return;
}
protected function checkChangeLogFile()
{
if (null === $this->changeLogFile) {
throw new BuildException('Specify the name of the changelog file.');
}
foreach (explode(":", $this->classpathref) as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $this->changeLogFile)) {
return;
}
}
if (!file_exists($this->changeLogFile)) {
throw new BuildException(
sprintf(
'The changelog file "%s" does not exist!',
$this->changeLogFile
)
);
}
}
}
/**
* @author Stephan Hochdoerfer
* @version $Id: e60f3f6a7b9c03e72b55f514ab85f2e8bb1e3f81 $
* @since 2.4.10
* @package phing.tasks.ext.liquibase
*/
class LiquibaseParameter extends DataType
{
private $name;
private $value;
/**
* @param $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param $value
*/
public function setValue($value)
{
$this->value = $value;
}
/**
* @param Project $p
* @return string
* @throws BuildException
*/
public function getCommandline(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getCommandline($p);
}
return sprintf("--%s=%s", $this->name, escapeshellarg($this->value));
}
/**
* @param Project $p
* @return mixed
* @throws BuildException
*/
public function getRef(Project $p)
{
if (!$this->checked) {
$stk = array();
array_push($stk, $this);
$this->dieOnCircularReference($stk, $p);
}
$o = $this->ref->getReferencedObject($p);
if (!($o instanceof LiquibaseParameter)) {
throw new BuildException($this->ref->getRefId() . " doesn't denote a LiquibaseParameter");
} else {
return $o;
}
}
}
/**
* @author Stephan Hochdoerfer
* @version $Id: e60f3f6a7b9c03e72b55f514ab85f2e8bb1e3f81 $
* @since 2.4.10
* @package phing.tasks.ext.liquibase
*/
class LiquibaseProperty extends DataType
{
private $name;
private $value;
/**
* @param $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param $value
*/
public function setValue($value)
{
$this->value = $value;
}
/**
* @param Project $p
* @return string
* @throws BuildException
*/
public function getCommandline(Project $p)
{
if ($this->isReference()) {
return $this->getRef($p)->getCommandline($p);
}
return sprintf("-D%s=%s", $this->name, escapeshellarg($this->value));
}
/**
* @param Project $p
* @return mixed
* @throws BuildException
*/
public function getRef(Project $p)
{
if (!$this->checked) {
$stk = array();
array_push($stk, $this);
$this->dieOnCircularReference($stk, $p);
}
$o = $this->ref->getReferencedObject($p);
if (!($o instanceof LiquibaseProperty)) {
throw new BuildException($this->ref->getRefId() . " doesn't denote a LiquibaseProperty");
} else {
return $o;
}
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseDbDocTask.php 0000644 0001750 0001750 00000004274 13027032674 021771 0 ustar druid druid
* @version $Id: a8df74bfdcd6fceb45725bbaa7076682223fc8b1 $
* @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));
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseChangeLogTask.php 0000644 0001750 0001750 00000002137 13027032674 022641 0 ustar druid druid
* @version $Id: 5d14d92ab948ab412f1b18b54189278f939a34d5 $
* @since 2.4.10
* @package phing.tasks.ext.liquibase
*/
class LiquibaseChangeLogTask extends AbstractLiquibaseTask
{
/**
* @see Task::main()
*/
public function main()
{
$this->checkParams();
$this->execute('generateChangeLog');
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseTask.php 0000644 0001750 0001750 00000004056 13027032674 021073 0 ustar druid druid .
*/
require_once 'phing/tasks/ext/liquibase/AbstractLiquibaseTask.php';
/**
* Task for running liquibase commands that doesn't have their own
* commands yet.
*
* Parameters can be provided by nested tags.
* That will result in --foo='bar' on the command line.
*
* @author Joakim Israelsson
* @version $Id: c492370d37df91fd100b00fd3a7c1ba7f628b0e1 $
* @package phing.tasks.ext.liquibase
*/
class LiquibaseTask extends AbstractLiquibaseTask
{
/**
* What liquibase command you wish to run.
*/
private $command;
/**
* @param $command
*/
public function setCommand($command)
{
$this->command = (string) $command;
}
protected function checkParams()
{
parent::checkParams();
if (null === $this->command) {
throw new BuildException('Please provide a liquibase command.');
}
}
public function main()
{
$this->checkParams();
$this->execute($this->command, '');
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseRollbackTask.php 0000644 0001750 0001750 00000003370 13027032674 022543 0 ustar druid druid
* @version $Id: 1915fb3b50b9c646643a44df4cf4457a2c79f6f1 $
* @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));
}
}
phing-2.16.0/tasks/ext/liquibase/LiquibaseTagTask.php 0000644 0001750 0001750 00000003550 13027032674 021525 0 ustar druid druid
* @version $Id: 1a967314c731282d7e026e0e8670b003eaab9802 $
* @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));
}
}
phing-2.16.0/tasks/ext/rSTTask.php 0000644 0001750 0001750 00000027537 13027032674 015720 0 ustar druid druid
* @license LGPL v3 or later http://www.gnu.org/licenses/lgpl.html
* @link http://www.phing.info/
* @version SVN: $Id: 5b4d68c019e0f3f6f497b8ec7c268c5600116ba0 $
*/
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
* @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 = 0;
/**
* Only render files whole source files are newer than the
* target files
*
* @var boolean
*/
protected $uptodate = false;
/**
* Sets up this object internal stuff. i.e. the default mode.
*/
public function __construct()
{
$this->mode = 0777 - umask();
}
/**
* Init method: requires the PEAR System class
*/
public function init()
{
require_once 'System.php';
}
/**
* The main entry point method.
*
* @throws BuildException
* @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 $path
* @throws BuildException
* @internal param string $param Full path to tool path, i.e. /usr/local/bin/rst2html
*
* @return void
*
*/
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];
}
}
phing-2.16.0/tasks/ext/StopwatchTask.php 0000644 0001750 0001750 00000012420 13027032674 017145 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* Stopwatch.
*
* @author Siad Ardroumli
* @version $Id: 46a07222af7bd1fbfd0e39169d5f80a83c6525e1 $
* @package phing.tasks.ext.stopwatch
*/
class StopwatchTask extends Task
{
/**
* Name of the timer.
*
* @var string $name
*/
private $name = '';
/**
* Category of the timer.
*
* @var string $category optional
*/
private $category = '';
/**
* Timer action.
*
* @var string $action
*/
private $action = 'start';
/**
* Holds an instance of Stopwatch.
*
* @var Stopwatch $timer
*/
private static $timer = null;
/**
* Initialize Task.
*
* @return void
*/
public function init()
{
}
/**
* Load stopwatch.
*
* @return void
*
* @throws BuildException
*/
private function loadStopwatch()
{
if (version_compare(PHP_VERSION, '5.3.3', '<')) {
throw new BuildException("StopwatchTask requires at least PHP 5.3.3 installed.");
}
@include_once 'Symfony/Component/Stopwatch/autoload.php';
@include_once 'vendor/autoload.php';
if (!class_exists('\\Symfony\\Component\\Stopwatch\\Stopwatch')) {
throw new BuildException("StopwatchTask requires Stopwatch to be installed");
}
}
/**
* Get the stopwatch instance.
*
* @return \Symfony\Component\Stopwatch\Stopwatch
*/
private function getStopwatchInstance()
{
if (self::$timer === null) {
$stopwatch = '\\Symfony\\Component\\Stopwatch\\Stopwatch';
self::$timer = new $stopwatch;
}
return self::$timer;
}
/**
* Start timer.
*
* @return void
*/
private function start()
{
$timer = $this->getStopwatchInstance();
$timer->start($this->name, $this->category);
}
/**
* Stop timer.
*
* @return void
*/
private function stop()
{
$timer = $this->getStopwatchInstance();
$event = $timer->stop($this->name);
foreach ($event->getPeriods() as $period) {
$this->log('Starttime: ' . $period->getStartTime() . ' - Endtime: ' . $period->getEndTime() . ' - Duration: ' . $period->getDuration() . ' - Memory: ' . $period->getMemory(), Project::MSG_INFO);
}
$this->log('Category: ' . $event->getCategory(), Project::MSG_INFO);
$this->log('Origin: ' . $event->getOrigin(), Project::MSG_INFO);
$this->log('Start time: ' . $event->getStartTime(), Project::MSG_INFO);
$this->log('End time: ' . $event->getEndTime(), Project::MSG_INFO);
$this->log('Duration: ' . $event->getDuration(), Project::MSG_INFO);
$this->log('Memory: ' . $event->getMemory(), Project::MSG_INFO);
}
/**
* Measure lap time.
*
* @return void
*/
private function lap()
{
$timer = $this->getStopwatchInstance();
$timer->lap($this->name);
}
/**
* Set the name of the stopwatch.
*
* @param string $name the name of the stopwatch timer
*
* @return void
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Set the category of the stopwatch.
*
* @param string $category
*
* @return void
*/
public function setCategory($category)
{
$this->category = $category;
}
/**
* Set the action.
* Action could be one of
* - start
* - lap
* - stop
*
* @param string $action
*
* @return void
*/
public function setAction($action)
{
$this->action = $action;
}
/**
* The main entry point
*
* @return void
*
* @throws BuildException
*/
public function main()
{
$this->loadStopwatch();
switch ($this->action) {
case "start":
$this->start();
break;
case "stop":
$this->stop();
break;
case "lap":
$this->lap();
break;
default:
throw new BuildException('action should be one of start, stop, lap.');
}
}
}
phing-2.16.0/tasks/ext/TarTask.php 0000644 0001750 0001750 00000036041 13027032674 015724 0 ustar druid druid .
*/
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';
/**
* Creates a tar archive using PEAR Archive_Tar.
*
* @author Hans Lellelid (Phing)
* @author Stefano Mazzocchi (Ant)
* @author Stefan Bodewig (Ant)
* @author Magesh Umasankar
*
* @package phing.tasks.ext
*/
class TarTask extends MatchingTask
{
const TAR_NAMELEN = 100;
const WARN = "warn";
const FAIL = "fail";
const OMIT = "omit";
private $tarFile;
private $baseDir;
private $includeEmpty = true; // Whether to include empty dirs in the TAR
private $longFileMode = "warn";
private $filesets = array();
private $fileSetFiles = array();
/**
* Indicates whether the user has been warned about long files already.
*/
private $longWarningGiven = false;
/**
* 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.
*/
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 TarTask.");
}
}
/**
* Add a new fileset
* @return FileSet
*/
public function createTarFileSet()
{
$this->fileset = new TarFileSet();
$this->filesets[] = $this->fileset;
return $this->fileset;
}
/**
* Add a new fileset. Alias to createTarFileSet() for backwards compatibility.
* @return FileSet
* @see createTarFileSet()
*/
public function createFileSet()
{
$this->fileset = new TarFileSet();
$this->filesets[] = $this->fileset;
return $this->fileset;
}
/**
* Set is the name/location of where to create the tar file.
* @param PhingFile $destFile The output of the tar
*/
public function setDestFile(PhingFile $destFile)
{
$this->tarFile = $destFile;
}
/**
* This is the base directory to look in for things to tar.
* @param PhingFile $baseDir
*/
public function setBasedir(PhingFile $baseDir)
{
$this->baseDir = $baseDir;
}
/**
* Set the include empty dirs flag.
*
* @param boolean $bool Flag if empty dirs should be tarred too
*
* @return void
*/
public function setIncludeEmptyDirs($bool)
{
$this->includeEmpty = (boolean) $bool;
}
/**
* Set how to handle long files, those with a path>100 chars.
* Optional, default=warn.
*
* Allowable values are
*
* truncate - paths are truncated to the maximum length
* fail - paths greater than the maximim cause a build exception
* warn - paths greater than the maximum cause a warning and GNU is used
* gnu - GNU extensions are used for any paths greater than the maximum.
* omit - paths greater than the maximum are omitted from the archive
*
* @param $mode
*/
public function setLongfile($mode)
{
$this->longFileMode = $mode;
}
/**
* Set compression method.
* Allowable values are
*
* none - no compression
* gzip - Gzip compression
* bzip2 - Bzip2 compression
*
* @param string $mode
*/
public function setCompression($mode)
{
switch ($mode) {
case "gzip":
$this->compression = "gz";
break;
case "bzip2":
$this->compression = "bz2";
break;
case "none":
$this->compression = null;
break;
default:
$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
* @throws BuildException
*/
public function main()
{
if ($this->tarFile === null) {
throw new BuildException("tarfile attribute must be set!", $this->getLocation());
}
if ($this->tarFile->exists() && $this->tarFile->isDirectory()) {
throw new BuildException("tarfile is a directory!", $this->getLocation());
}
if ($this->tarFile->exists() && !$this->tarFile->canWrite()) {
throw new BuildException("Can not write to the specified tarfile!", $this->getLocation());
}
// shouldn't need to clone, since the entries in filesets
// themselves won't be modified -- only elements will be added
$savedFileSets = $this->filesets;
try {
if ($this->baseDir !== null) {
if (!$this->baseDir->exists()) {
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;
}
}
if (empty($this->filesets)) {
throw new BuildException("You must supply either a basedir "
. "attribute or some nested filesets.",
$this->getLocation());
}
// check if tar is out of date with respect to each fileset
if ($this->tarFile->exists() && $this->isArchiveUpToDate()) {
$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);
$tar = new Archive_Tar($this->tarFile->getAbsolutePath(), $this->compression);
$pear = new PEAR();
if ($pear->isError($tar->error_object)) {
throw new BuildException($tar->error_object->getMessage());
}
foreach ($this->filesets as $fs) {
$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.");
}
$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();
$this->log("Adding file " . $f->getPath() . " to archive.", Project::MSG_VERBOSE);
}
$tar->addModify($filesToTar, $this->prefix, $fsBasedir->getAbsolutePath());
if ($pear->isError($tar->error_object)) {
throw new BuildException($tar->error_object->getMessage());
}
}
} catch (IOException $ioe) {
$msg = "Problem creating TAR: " . $ioe->getMessage();
$this->filesets = $savedFileSets;
throw new BuildException($msg, $ioe, $this->getLocation());
}
$this->filesets = $savedFileSets;
}
/**
* @param array $files array of filenames
* @param PhingFile $dir
*
* @return boolean
*/
protected function areFilesUpToDate($files, $dir)
{
$sfs = new SourceFileScanner($this);
$mm = new MergeMapper();
$mm->setTo($this->tarFile->getAbsolutePath());
return count($sfs->restrict($files, $dir, null, $mm)) == 0;
}
/**
* @return array
* @throws BuildException
*/
private function isArchiveUpToDate()
{
foreach ($this->filesets as $fs) {
$files = $fs->getFiles($this->project, $this->includeEmpty);
if (!$this->areFilesUpToDate($files, $fs->getDir($this->project))) {
return 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());
}
}
}
return true;
}
}
/**
* This is a FileSet with the option 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 TarFileSet extends FileSet
{
private $files = null;
private $mode = 0100644;
private $userName = "";
private $groupName = "";
private $prefix = "";
private $fullpath = "";
private $preserveLeadingSlashes = false;
/**
* Get a list of files and directories specified in the fileset.
*
* @param Project $p
* @param bool $includeEmpty
*
* @throws BuildException
*
* @return array a list of file and directory names, relative to
* the baseDir for the project.
*/
public function getFiles(Project $p, $includeEmpty = true)
{
if ($this->files === null) {
$ds = $this->getDirectoryScanner($p);
$this->files = $ds->getIncludedFiles();
if ($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;
}
/**
* A 3 digit octal string, specify the user, group and
* other modes in the standard Unix fashion;
* optional, default=0644
* @param string $octalString
*/
public function setMode($octalString)
{
$octal = (int) $octalString;
$this->mode = 0100000 | $octal;
}
/**
* @return int
*/
public function getMode()
{
return $this->mode;
}
/**
* The username for the tar entry
* This is not the same as the UID, which is
* not currently set by the task.
* @param $userName
*/
public function setUserName($userName)
{
$this->userName = $userName;
}
/**
* @return string
*/
public function getUserName()
{
return $this->userName;
}
/**
* The groupname for the tar entry; optional, default=""
* This is not the same as the GID, which is
* not currently set by the task.
* @param $groupName
*/
public function setGroup($groupName)
{
$this->groupName = $groupName;
}
/**
* @return string
*/
public function getGroup()
{
return $this->groupName;
}
/**
* If the prefix attribute is set, all files in the fileset
* are prefixed with that path in the archive.
* optional.
* @param bool $prefix
*/
public function setPrefix($prefix)
{
$this->prefix = $prefix;
}
/**
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* If the fullpath attribute is set, the file in the fileset
* is written with that path in the archive. The prefix attribute,
* if specified, is ignored. It is an error to have more than one file specified in
* such a fileset.
* @param $fullpath
*/
public function setFullpath($fullpath)
{
$this->fullpath = $fullpath;
}
/**
* @return string
*/
public function getFullpath()
{
return $this->fullpath;
}
/**
* Flag to indicates whether leading `/'s` should
* be preserved in the file names.
* Optional, default is false
.
*
* @param bool $b
*
* @return void
*/
public function setPreserveLeadingSlashes($b)
{
$this->preserveLeadingSlashes = (boolean) $b;
}
/**
* @return bool
*/
public function getPreserveLeadingSlashes()
{
return $this->preserveLeadingSlashes;
}
}
phing-2.16.0/tasks/ext/SmartyTask.php 0000644 0001750 0001750 00000046737 13027032674 016472 0 ustar druid druid .
*/
require_once 'phing/Task.php';
include_once 'phing/BuildException.php';
include_once 'phing/util/StringHelper.php';
/**
* A phing task for generating output by using Smarty.
*
* This is based on the TexenTask from Apache's Velocity engine. This class
* was originally proted in order to provide a template compiling system for
* Torque.
*
* TODO:
* - Add Path / useClasspath support?
*
* @author Hans Lellelid (SmartyTask)
* @author Jason van Zyl (TexenTask)
* @author Robert Burrell Donkin
* @version $Id: 7c13e08dfd78388be8bdd0920677dc855c78c525 $
* @package phing.tasks.ext
*/
class SmartyTask extends Task
{
/**
* Smarty template engine.
* @var Smarty
*/
protected $context;
/**
* Variables that are assigned to the context on parse/compile.
* @var array
*/
protected $properties = array();
/**
* This is the control template that governs the output.
* It may or may not invoke the services of worker
* templates.
* @var string
*/
protected $controlTemplate;
/**
* This is where Smarty will look for templates
* using the file template loader.
* @var string
*/
protected $templatePath;
/**
* This is where texen will place all the output
* that is a product of the generation process.
* @var string
*/
protected $outputDirectory;
/**
* This is the file where the generated text
* will be placed.
* @var string
*/
protected $outputFile;
/**
*
* These are properties that are fed into the
* initial context from a properties file. This
* is simply a convenient way to set some values
* that you wish to make available in the context.
*
*
* These values are not critical, like the template path
* or output path, but allow a convenient way to
* set a value that may be specific to a particular
* generation task.
*
*
* For example, if you are generating scripts to allow
* user to automatically create a database, then
* you might want the $databaseName
* to be placed
* in the initial context so that it is available
* in a script that might look something like the
* following:
*
* #!bin/sh
*
* echo y | mysqladmin create $databaseName
*
* The value of $databaseName
isn't critical to
* output, and you obviously don't want to change
* the ant task to simply take a database name.
* So initial context values can be set with
* properties file.
*
* @var array
*/
protected $contextProperties;
/**
* Smarty compiles templates before parsing / replacing tokens in them.
* By default it will try ./templates_c, but you may wish to override this.
* @var string
*/
protected $compilePath;
/**
* Whether to force Smarty to recompile templates.
* Smarty does check file modification time, but you can set this
* to be *sure* that the template will be compiled (of course it will
* be slower if you do).
* @var boolean
*/
protected $forceCompile = false;
/**
* Smarty can use config files.
* This tells Smarty where to look for the config files.
* @var string
*/
protected $configPath;
/**
* Customize the left delimiter for Smarty tags.
* @var string
*/
protected $leftDelimiter;
/**
* Customize the right delimiter for Smarty tags.
* @var string
*/
protected $rightDelimiter;
// -----------------------------------------------------------------------
// The following getters & setters are used by phing to set properties
// specified in the XML for the smarty task.
// -----------------------------------------------------------------------
public function init()
{
// This check returns true for smarty 3 and false otherwise.
if (stream_resolve_include_path('SmartyBC.class.php')) {
include_once 'SmartyBC.class.php';
} else {
include_once 'Smarty.class.php';
}
if (!class_exists('Smarty')) {
throw new BuildException("To use SmartyTask, you must have the path to Smarty.class.php on your include_path or your \$PHP_CLASSPATH environment variable.");
}
}
/**
* [REQUIRED] Set the control template for the
* generating process.
* @param string $controlTemplate
* @return void
*/
public function setControlTemplate($controlTemplate)
{
$this->controlTemplate = $controlTemplate;
}
/**
* Get the control template for the
* generating process.
* @return string
*/
public function getControlTemplate()
{
return $this->controlTemplate;
}
/**
* [REQUIRED] Set the path where Smarty will look
* for templates using the file template
* loader.
* @param $templatePath
* @return void
*/
public function setTemplatePath($templatePath)
{
$resolvedPath = "";
$tok = strtok($templatePath, ",");
while ($tok) {
// resolve relative path from basedir and leave
// absolute path untouched.
$fullPath = $this->project->resolveFile($tok);
$cpath = $fullPath->getCanonicalPath();
if ($cpath === false) {
$this->log("Template directory does not exist: " . $fullPath->getAbsolutePath());
} else {
$resolvedPath .= $cpath;
}
$tok = strtok(",");
if ($tok) {
$resolvedPath .= ",";
}
}
$this->templatePath = $resolvedPath;
}
/**
* Get the path where Smarty will look
* for templates using the file template
* loader.
* @return string
*/
public function getTemplatePath()
{
return $this->templatePath;
}
/**
* [REQUIRED] Set the output directory. It will be
* created if it doesn't exist.
* @param PhingFile $outputDirectory
* @return void
* @throws Exception
*/
public function setOutputDirectory(PhingFile $outputDirectory)
{
try {
if (!$outputDirectory->exists()) {
$this->log(
"Output directory does not exist, creating: " . $outputDirectory->getPath(),
Project::MSG_VERBOSE
);
if (!$outputDirectory->mkdirs()) {
throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath());
}
}
$this->outputDirectory = $outputDirectory->getCanonicalPath();
} catch (IOException $ioe) {
throw new BuildException($ioe->getMessage());
}
}
/**
* Get the output directory.
* @return string
*/
public function getOutputDirectory()
{
return $this->outputDirectory;
}
/**
* [REQUIRED] Set the output file for the
* generation process.
* @param $outputFile
* @return void
*/
public function setOutputFile($outputFile)
{
$this->outputFile = $outputFile;
}
/**
* Get the output file for the
* generation process.
* @return string
*/
public function getOutputFile()
{
return $this->outputFile;
}
/**
* Set the path Smarty uses as a "cache" for compiled templates.
* @param string $compilePath
*/
public function setCompilePath($compilePath)
{
$this->compilePath = $compilePath;
}
/**
* Get the path Smarty uses for compiling templates.
* @return string
*/
public function getCompilePath()
{
return $this->compilePath;
}
/**
* Set whether Smarty should always recompile templates.
* @param boolean $force
* @return void
*/
public function setForceCompile($force)
{
$this->forceCompile = (boolean) $force;
}
/**
* Get whether Smarty should always recompile template.
* @return boolean
*/
public function getForceCompile()
{
return $this->forceCompile;
}
/**
* Set where Smarty looks for config files.
* @param string $configPath
* @return void
*/
public function setConfigPath($configPath)
{
$this->configPath = $configPath;
}
/**
* Get the path that Smarty uses for looking for config files.
* @return string
*/
public function getConfigPath()
{
return $this->configPath;
}
/**
* Set Smarty template left delimiter.
* @param string $delim
* @return void
*/
public function setLeftDelimiter($delim)
{
$this->leftDelimiter = $delim;
}
/**
* Get Smarty template right delimiter
* @return string
*/
public function getLeftDelimiter()
{
return $this->leftDelimiter;
}
/**
* Set Smarty template right delimiter.
* @param string $delim
* @return void
*/
public function setRightDelimiter($delim)
{
$this->rightDelimiter = $delim;
}
/**
* Get Smarty template right delimiter
* @return string
*/
public function getRightDelimiter()
{
return $this->rightDelimiter;
}
/**
* Set the context properties that will be
* fed into the initial context be the
* generating process starts.
* @param string $file
* @throws BuildException
* @return void
*/
public function setContextProperties($file)
{
$sources = explode(",", $file);
$this->contextProperties = new Properties();
// Always try to get the context properties resource
// from a file first. Templates may be taken from a JAR
// file but the context properties resource may be a
// resource in the filesystem. If this fails than attempt
// to get the context properties resource from the
// classpath.
for ($i = 0, $sourcesLength = count($sources); $i < $sourcesLength; $i++) {
$source = new Properties();
try {
// resolve relative path from basedir and leave
// absolute path untouched.
$fullPath = $this->project->resolveFile($sources[$i]);
$this->log("Using contextProperties file: " . $fullPath->__toString());
$source->load($fullPath);
} catch (Exception $e) {
throw new BuildException("Context properties file " . $sources[$i] .
" could not be found in the file system!");
}
$keys = $source->keys();
foreach ($keys as $key) {
$name = $key;
$value = $this->project->replaceProperties($source->getProperty($name));
$this->contextProperties->setProperty($name, $value);
}
}
}
/**
* Get the context properties that will be
* fed into the initial context be the
* generating process starts.
* @return Properties
*/
public function getContextProperties()
{
return $this->contextProperties;
}
// ---------------------------------------------------------------
// End of XML setters & getters
// ---------------------------------------------------------------
/**
* Creates a Smarty object.
*
* @return Smarty initialized (cleared) Smarty context.
* @throws Exception the execute method will catch
* and rethrow as a BuildException
*/
public function initControlContext()
{
$this->context->clear_all_assign();
return $this->context;
}
/**
* Execute the input script with Smarty
*
* @throws BuildException
* BuildExceptions are thrown when required attributes are missing.
* Exceptions thrown by Smarty are rethrown as BuildExceptions.
*/
public function main()
{
// Make sure the template path is set.
if (empty($this->templatePath)) {
throw new BuildException("The template path needs to be defined!");
}
// Make sure the control template is set.
if ($this->controlTemplate === null) {
throw new BuildException("The control template needs to be defined!");
}
// Make sure the output directory is set.
if ($this->outputDirectory === null) {
throw new BuildException("The output directory needs to be defined!");
}
// Make sure there is an output file.
if ($this->outputFile === null) {
throw new BuildException("The output file needs to be defined!");
}
// Setup Smarty runtime.
// Smarty uses one object to store properties and to store
// the context for the template (unlike Smarty). We setup this object, calling it
// $this->context, and then initControlContext simply zeros out
// any assigned variables.
//
// Use the smarty backwards compatibility layer if existent.
if (class_exists('SmartyBC')) {
$this->context = new SmartyBC();
} else {
$this->context = new Smarty();
}
if ($this->compilePath !== null) {
$this->log("Using compilePath: " . $this->compilePath);
$this->context->compile_dir = $this->compilePath;
}
if ($this->configPath !== null) {
$this->log("Using configPath: " . $this->configPath);
$this->context->config_dir = $this->configPath;
}
if ($this->forceCompile !== null) {
$this->context->force_compile = $this->forceCompile;
}
if ($this->leftDelimiter !== null) {
$this->context->left_delimiter = $this->leftDelimiter;
}
if ($this->rightDelimiter !== null) {
$this->context->right_delimiter = $this->rightDelimiter;
}
if ($this->templatePath !== null) {
$this->log("Using templatePath: " . $this->templatePath);
$this->context->template_dir = $this->templatePath;
}
$smartyCompilePath = new PhingFile($this->context->compile_dir);
if (!$smartyCompilePath->exists()) {
$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);
}
}
// Make sure the output directory exists, if it doesn't
// then create it.
$file = new PhingFile($this->outputDirectory);
if (!$file->exists()) {
$this->log("Output directory does not exist, creating: " . $file->getAbsolutePath());
$file->mkdirs();
}
$path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
$this->log("Generating to file " . $path);
$writer = new FileWriter($path);
// The generator and the output path should
// be placed in the init context here and
// not in the generator class itself.
$c = $this->initControlContext();
// Set any variables that need to always
// be loaded
$this->populateInitialContext($c);
// Feed all the options into the initial
// control context so they are available
// in the control/worker templates.
if ($this->contextProperties !== null) {
foreach ($this->contextProperties->keys() as $property) {
$value = $this->contextProperties->getProperty($property);
// Special exception (from Texen)
// for properties ending in file.contents:
// in that case we dump the contents of the file
// as the "value" for the Property.
if (StringHelper::endsWith("file.contents", $property)) {
// pull in contents of file specified
$property = substr($property, 0, strpos($property, "file.contents") - 1);
// reset value, and then
// read in the contents of the file into that var
$value = "";
$f = new PhingFile($this->project->resolveFile($value)->getCanonicalPath());
if ($f->exists()) {
try {
$fr = new FileReader($f);
$fr->readInto($value);
} catch (Exception $e) {
throw $e;
}
}
} // if ends with file.contents
if (StringHelper::isBoolean($value)) {
$value = StringHelper::booleanValue($value);
}
$c->assign($property, $value);
} // foreach property
} // if contextProperties !== null
try {
//$c->display($this->controlTemplate);
$writer->write($c->fetch($this->controlTemplate));
$writer->close();
} catch (IOException $ioe) {
$writer->close();
throw new BuildException("Cannot write parsed template.");
}
$this->cleanup();
}
/**
*
Place useful objects into the initial context.
*
* TexenTask places Date().toString()
into the
* context as $now
. Subclasses who want to vary the
* objects in the context should override this method.
*
* $generator
is not put into the context in this
* method.
*
* @param Smarty|The $context
* @internal param The $context context to populate, as retrieved from
* {@link #initControlContext()}.
* @return void
*/
protected function populateInitialContext(Smarty $context)
{
}
/**
* A hook method called at the end of {@link #execute()} which can
* be overridden to perform any necessary cleanup activities (such
* as the release of database connections, etc.). By default,
* does nothing.
* @return void
* @throws Exception Problem cleaning up.
*/
protected function cleanup()
{
}
}
phing-2.16.0/tasks/ext/AutoloaderTask.php 0000644 0001750 0001750 00000004701 13027032674 017273 0 ustar druid druid .
*/
require_once "phing/Task.php";
/**
* @author Max Romanovsky
* @package phing.tasks.ext
*/
class AutoloaderTask extends Task
{
const DEFAULT_AUTOLOAD_PATH = 'vendor/autoload.php';
private $autoloaderPath = self::DEFAULT_AUTOLOAD_PATH;
/**
* @return string
*/
public function getAutoloaderPath()
{
return $this->autoloaderPath;
}
/**
* @param string $autoloaderPath
*/
public function setAutoloaderPath($autoloaderPath)
{
$this->autoloaderPath = $autoloaderPath;
}
/**
* Called by the project to let the task do it's work. This method may be
* called more than once, if the task is invoked more than once. For
* example, if target1 and target2 both depend on target3, then running
* phing target1 target2 will run all tasks in target3 twice.
*
* Should throw a BuildException if someting goes wrong with the build
*
* This is here. Must be overloaded by real tasks.
*/
public function main()
{
if (is_dir($this->autoloaderPath) || !is_readable($this->autoloaderPath)) {
throw new BuildException(sprintf(
'Provided autoloader file "%s" is not a readable file',
$this->autoloaderPath
));
}
$this->log('Loading autoloader from ' . $this->autoloaderPath);
require_once $this->autoloaderPath;
}
}
phing-2.16.0/tasks/ext/FtpDeployTask.php 0000644 0001750 0001750 00000035147 13027032674 017112 0 ustar druid druid .
*/
require_once 'phing/Task.php';
/**
* FtpDeployTask
*
* Deploys a set of files to a remote FTP server.
*
*
* Example usage:
*
*
*
*
*
*
*
*
*
*
*
* @author Jorrit Schippers
* @contributor Steffen Sørensen
* @version $Id: e52538418d5dac1ccf34f61e145a44b1fb18b34f $
* @since 2.3.1
* @package phing.tasks.ext
*/
class FtpDeployTask extends Task
{
private $host = null;
private $port = 21;
private $ssl = false;
private $username = null;
private $password = null;
private $dir = null;
private $filesets;
private $completeDirMap;
private $mode = FTP_BINARY;
private $clearFirst = false;
private $passive = false;
private $depends = false;
private $dirmode = false;
private $filemode = false;
private $rawDataFallback = false;
private $skipOnSameSize = false;
protected $logLevel = Project::MSG_VERBOSE;
/**
*
*/
public function __construct()
{
$this->filesets = array();
$this->completeDirMap = array();
}
/**
* @param $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* @param $port
*/
public function setPort($port)
{
$this->port = (int) $port;
}
/**
* @param $ssl
*/
public function setSsl($ssl)
{
$this->ssl = (bool) $ssl;
}
/**
* @param $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @param $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @param $dir
*/
public function setDir($dir)
{
$this->dir = $dir;
}
/**
* @param $mode
*/
public function setMode($mode)
{
switch (strtolower($mode)) {
case 'ascii':
$this->mode = FTP_ASCII;
break;
case 'binary':
case 'bin':
$this->mode = FTP_BINARY;
break;
}
}
/**
* @param $passive
*/
public function setPassive($passive)
{
$this->passive = (bool) $passive;
}
/**
* @param $clearFirst
*/
public function setClearFirst($clearFirst)
{
$this->clearFirst = (bool) $clearFirst;
}
/**
* @param $depends
*/
public function setDepends($depends)
{
$this->depends = (bool) $depends;
}
/**
* @param $filemode
*/
public function setFilemode($filemode)
{
$this->filemode = octdec(str_pad($filemode, 4, '0', STR_PAD_LEFT));
}
/**
* @param $dirmode
*/
public function setDirmode($dirmode)
{
$this->dirmode = octdec(str_pad($dirmode, 4, '0', STR_PAD_LEFT));
}
/**
* @param $fallback
*/
public function setRawdatafallback($fallback)
{
$this->rawDataFallback = (bool) $fallback;
}
/**
* @param bool|string|int $skipOnSameSize
*/
public function setSkipOnSameSize($skipOnSameSize)
{
$this->skipOnSameSize = StringHelper::booleanValue($skipOnSameSize);
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* 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()
{
$paths = Phing::explodeIncludePath();
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 'PEAR.php';
require_once 'Net/FTP.php';
$ftp = new Net_FTP($this->host, $this->port);
if ($this->ssl) {
$ret = $ftp->setSsl();
if (@PEAR::isError($ret)) {
throw new BuildException('SSL connection not supported by php' . ': ' . $ret->getMessage(
));
} else {
$this->log('Use SSL connection', $this->logLevel);
}
}
$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) {
// Array for holding directory content informations
$remoteFileInformations = array();
$ds = $fs->getDirectoryScanner($project);
$fromDir = $fs->getDir($project);
$srcFiles = $ds->getIncludedFiles();
$srcDirs = $ds->getIncludedDirectories();
foreach ($srcDirs as $dirname) {
if ($convert) {
$dirname = str_replace('\\', '/', $dirname);
}
// Read directory informations, if file exists, else create the directory
if (!$this->_directoryInformations($ftp, $remoteFileInformations, $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());
}
}
if ($this->dirmode) {
if ($this->dirmode == 'inherit') {
$mode = fileperms($dirname);
} else {
$mode = $this->dirmode;
}
// Because Net_FTP does not support a chmod call we call ftp_chmod directly
ftp_chmod($ftp->_handle, $mode, $dirname);
}
}
foreach ($srcFiles as $filename) {
$file = new PhingFile($fromDir->getAbsolutePath(), $filename);
if ($convert) {
$filename = str_replace('\\', '/', $filename);
}
$local_filemtime = filemtime($file->getCanonicalPath());
if (isset($remoteFileInformations[$filename]['stamp'])) {
$remoteFileModificationTime = $remoteFileInformations[$filename]['stamp'];
} else {
$remoteFileModificationTime = 0;
}
if (!$this->depends || ($local_filemtime > $remoteFileModificationTime)) {
if ($this->skipOnSameSize === true && $file->length() === $ftp->size($filename)) {
$this->log('Skipped ' . $file->getCanonicalPath(), $this->logLevel);
continue;
}
$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());
}
}
if ($this->filemode) {
if ($this->filemode == 'inherit') {
$mode = fileperms($filename);
} else {
$mode = $this->filemode;
}
// Because Net_FTP does not support a chmod call we call ftp_chmod directly
ftp_chmod($ftp->_handle, $mode, $filename);
}
}
}
$ftp->disconnect();
$this->log('Disconnected from FTP server', $this->logLevel);
}
/**
* @param Net_FTP $ftp
* @param $remoteFileInformations
* @param $directory
* @return bool
*/
private function _directoryInformations(Net_FTP $ftp, &$remoteFileInformations, $directory)
{
$content = $ftp->ls($directory);
if (@PEAR::isError($content)) {
if ($this->rawDataFallback) {
$content = $ftp->ls($directory, NET_FTP_RAWLIST);
}
if (@PEAR::isError($content)) {
return false;
}
$content = $this->parseRawFtpContent($content, $directory);
}
if (sizeof($content) == 0) {
return false;
} else {
if (!empty($directory)) {
$directory .= '/';
}
while (list(, $val) = each($content)) {
if ($val['name'] != '.' && $val['name'] != '..') {
$remoteFileInformations[$directory . $val['name']] = $val;
}
}
return true;
}
}
/**
* @param $content
* @param null $directory
* @return array
*/
private function parseRawFtpContent($content, $directory = null)
{
if (!is_array($content)) {
return array();
}
$this->log('Start parsing FTP_RAW_DATA in ' . $directory);
$retval = array();
foreach ($content as $rawInfo) {
$rawInfo = explode(' ', $rawInfo);
$rawInfo2 = array();
foreach ($rawInfo as $part) {
$part = trim($part);
if (!empty($part)) {
$rawInfo2[] = $part;
}
}
$date = date_parse($rawInfo2[5] . ' ' . $rawInfo2[6] . ' ' . $rawInfo2[7]);
if ($date['year'] === false) {
$date['year'] = date('Y');
}
$date = mktime(
$date['hour'],
$date['minute'],
$date['second'],
$date['month'],
$date['day'],
$date['year']
);
$retval[] = array(
'name' => $rawInfo2[8],
'rights' => substr($rawInfo2[0], 1),
'user' => $rawInfo2[2],
'group' => $rawInfo2[3],
'date' => $date,
'stamp' => $date,
'is_dir' => strpos($rawInfo2[0], 'd') === 0,
'files_inside' => (int) $rawInfo2[1],
'size' => (int) $rawInfo2[4],
);
}
$this->log('Finished parsing FTP_RAW_DATA in ' . $directory);
return $retval;
}
}
phing-2.16.0/tasks/ext/XmlPropertyTask.php 0000644 0001750 0001750 00000020144 13027032674 017500 0 ustar druid druid .
*/
include_once 'phing/tasks/system/PropertyTask.php';
/**
* Task for setting properties from an XML file in buildfiles.
*
* @author Jonathan Bond-Caron
* @version $Id: d9741f5e9084e1c59c5dfeb32524d56fe052ecfc $
* @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.
* @param $file
*/
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 file
.
* 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());
}
$props = $this->loadFile($this->file);
$this->addProperties($props);
}
/**
* load properties from an XML file.
* @param PhingFile $file
* @throws BuildException
* @return Properties
*/
protected function loadFile(PhingFile $file)
{
$props = new Properties();
$this->log("Loading " . $file->getAbsolutePath(), Project::MSG_INFO);
try { // try to load file
if ($file->exists()) {
return $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
*
* @throws IOException
* @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
//
// file/a.php
// file/a.php
//
//
// Would be come project.exclude = file/a.php,file/a.php
$p = empty($prefix) ? $tag : $prefix . $tag;
$prop->append($p, (string) $val, $this->_delimiter);
}
}
}
}
phing-2.16.0/tasks/ext/ReplaceRegexpTask.php 0000644 0001750 0001750 00000014653 13027032674 017731 0 ustar druid druid .
*/
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.
*
*
*
*
*
* @author Jonathan Bond-Caron
*
* @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.
*
* @var array $filesets
*/
private $filesets = array();
/**
* Regular expression
*
* @var RegularExpression
*/
private $_regexp;
/**
* File to apply regexp on
*
* @param PhingFile $path
*
* @return void
*/
public function setFile(PhingFile $path)
{
$this->file = $path;
}
/**
* Sets the regexp match pattern
*
* @param string $regexp
*
* @return void
*/
public function setMatch($regexp)
{
$this->_regexp->setPattern($regexp);
}
/**
* @see setMatch()
*
* @param $regexp
*
* @return void
*/
public function setPattern($regexp)
{
$this->setMatch($regexp);
}
/**
* Sets the replacement string
*
* @param string $string
*
* @return void
*/
public function setReplace($string)
{
$this->_regexp->setReplace($string);
}
/**
* Sets the regexp flags
*
* @param string $flags
*
* @return void
*
* todo ... `$this->_regexp->setFlags( $flags );`
*/
public function setFlags($flags)
{
}
/**
* Match only per line
*
* @param bool $yesNo
*
* @return void
*/
public function setByline($yesNo)
{
// TODO... $this->_regexp->
}
/**
* Nested adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
*
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* {@inheritdoc}
*
* @return void
*/
public function init()
{
$this->_regexp = new RegularExpression();
}
/**
* {@inheritdoc}
*
* @return void
*
* @throws BuildException
*/
public function main()
{
if ($this->file === null && empty($this->filesets)) {
throw new BuildException("You must specify a file or fileset(s) for the 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);
}
}
}
}
phing-2.16.0/tasks/ext/ManifestTask.php 0000644 0001750 0001750 00000021574 13027032674 016751 0 ustar druid druid .
*/
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:
*
*
*
*
*
*
*
*
*
*
* @author David Persson
*
* @package phing.tasks.ext
*
* @since 2.3.1
*/
class ManifestTask extends Task
{
public $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 bool|string
*/
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 PhingFile $file 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 adder, adds a set of files (nested fileset attribute).
*
* @param FileSet $fs
*
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* The init method: Do init steps.
*
* {@inheritdoc}
*
* @internal nothing to do here
*/
public function init()
{
}
/**
* Delegate the work.
*
* {@inheritdoc}
*/
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 file's contents
*
* @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);
return $this->hash($msg, $algo);
}
/**
* Validates attributes coming in from XML
*
* @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.");
}
}
}
phing-2.16.0/tasks/ext/PearPackageTask.php 0000644 0001750 0001750 00000034646 13027032674 017352 0 ustar druid druid .
*/
require_once 'phing/tasks/system/MatchingTask.php';
include_once 'phing/types/FileSet.php';
/**
* A task to create PEAR package.xml file.
*
* This class uses the PEAR_PackageFileMaintainer 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 and
* nested elements. All options are set using PEAR_PackageFileMaintainer::setOptions().
*
* The tag is used to set a simple option value.
*
*
* or option_value
*
*
* The tag represents a complex data type. You can use nested (and nested with
* 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_PackageFileMaintainer::setOptions().
*
*
*
*
*
*
*
* Here's an over-simple example of how this could be used:
*
*
*
*
*
* Sample release notes here.
* Package description
* Short description
*
*
*
*
*
*
*
*
*
*
*
*
*
* 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 Hans Lellelid
* @package phing.tasks.ext
* @version $Id: 11ecf61bf1d7f534232f2394df745ee147f2b9b7 $
*/
class PearPackageTask extends MatchingTask
{
/** */
protected $package;
/** Base directory for reading files. */
protected $dir;
/** Package file */
private $packageFile;
/** @var array FileSet[] */
private $filesets = array();
/** @var PEAR_PackageFileManager */
protected $pkg;
private $preparedOptions = array();
/** @var array PearPkgOption[] */
protected $options = array();
/** Nested (complex options) types. */
protected $mappings = array();
/**
* Nested elements
* @var PearPkgRole[]
*/
protected $roles = array();
public function init()
{
include_once 'PEAR/PackageFileManager.php';
if (!class_exists('PEAR_PackageFileManager')) {
throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml file.");
}
}
/**
* Sets PEAR package.xml options, based on class properties.
* @throws BuildException
* @return void
*/
protected function setOptions()
{
// 1) first prepare/populate options
$this->populateOptions();
// 2) make any final adjustments (this could move into populateOptions() also)
// default PEAR basedir would be the name of the package (e.g."phing")
if (!isset($this->preparedOptions['baseinstalldir'])) {
$this->preparedOptions['baseinstalldir'] = $this->package;
}
// unless filelistgenerator has been overridden, we use Phing FileSet generator
if (!isset($this->preparedOptions['filelistgenerator'])) {
if (empty($this->filesets)) {
throw new BuildException("You must use a tag to specify the files to include in the package.xml");
}
$this->preparedOptions['filelistgenerator'] = 'Fileset';
$this->preparedOptions['usergeneratordir'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pearpackage';
// Some PHING-specific options needed by our Fileset reader
$this->preparedOptions['phing_project'] = $this->project;
$this->preparedOptions['phing_filesets'] = $this->filesets;
} elseif ($this->preparedOptions['filelistgenerator'] != 'Fileset' && !empty($this->filesets)) {
throw new BuildException("You cannot use element if you have specified the \"filelistgenerator\" option.");
}
// 3) Set the options
// No need for excessive validation here, since the PEAR class will do its own
// validation & return errors
$e = $this->pkg->setOptions($this->preparedOptions);
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());
}
}
/**
* Fixes the boolean in optional dependencies
* @param $deps
* @return
*/
private function fixDeps($deps)
{
foreach (array_keys($deps) as $dep) {
if (isset($deps[$dep]['optional']) && $deps[$dep]['optional']) {
$deps[$dep]['optional'] = "yes";
}
}
return $deps;
}
/**
* Adds the options that are set via attributes and the nested tags to the options array.
*/
private function populateOptions()
{
// These values could be overridden if explicitly defined using nested tags
$this->preparedOptions['package'] = $this->package;
$this->preparedOptions['packagedirectory'] = $this->dir->getAbsolutePath();
if ($this->packageFile !== null) {
// create one w/ full path
$f = new PhingFile($this->packageFile->getAbsolutePath());
$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);
} else {
$this->log("Creating [default] package.xml file in base directory.", Project::MSG_INFO);
}
// converts option objects and mapping objects into
// key => value options that can be passed to PEAR_PackageFileManager
foreach ($this->options as $opt) {
$this->preparedOptions[$opt->getName()] = $opt->getValue(
); //no arrays yet. preg_split('/\s*,\s*/', $opt->getValue());
}
foreach ($this->mappings as $map) {
$value = $map->getValue(); // getValue returns complex value
if ($map->getName() == 'deps') {
$value = $this->fixDeps($value);
}
$this->preparedOptions[$map->getName()] = $value;
}
}
/**
* Main entry point.
* @throws BuildException
* @return void
*/
public function main()
{
if ($this->dir === null) {
throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
}
if ($this->package === null) {
throw new BuildException("You must specify the \"name\" attribute for PEAR package task.");
}
$this->pkg = new PEAR_PackageFileManager();
$this->setOptions();
$e = $this->pkg->writePackageFile();
if (@PEAR::isError($e)) {
throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
}
}
/**
* Used by the PEAR_PackageFileManager_PhingFileSet lister.
* @return array FileSet[]
*/
public function getFileSets()
{
return $this->filesets;
}
// -------------------------------
// Set properties from XML
// -------------------------------
/**
* Nested creator, creates a FileSet for this task
*
* @param FileSet $fs
* @internal param FileSet $fileset Set of files to add to the package
*
* @return void
*/
public function addFileSet(FileSet $fs)
{
$this->filesets[] = $fs;
}
/**
* Set "package" property from XML.
* @see setName()
* @param string $v
* @return void
*/
public function setPackage($v)
{
$this->package = $v;
}
/**
* Sets "dir" property from XML.
* @param PhingFile $f
* @return void
*/
public function setDir(PhingFile $f)
{
$this->dir = $f;
}
/**
* Sets "name" property from XML.
* @param string $v
* @return void
*/
public function setName($v)
{
$this->package = $v;
}
/**
* Sets the file to use for generated package.xml
* @param PhingFile $f
*/
public function setDestFile(PhingFile $f)
{
$this->packageFile = $f;
}
/**
* Handles nested generic elements.
*/
public function createOption()
{
$o = new PearPkgOption();
$this->options[] = $o;
return $o;
}
/**
* Handles nested generic elements.
*/
public function createMapping()
{
$o = new PearPkgMapping();
$this->mappings[] = $o;
return $o;
}
/**
* Handles nested 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
{
private $name;
private $value;
/**
* @param $v
*/
public function setName($v)
{
$this->name = $v;
}
public function getName()
{
return $this->name;
}
/**
* @param $v
*/
public function setValue($v)
{
$this->value = $v;
}
public function getValue()
{
return $this->value;
}
/**
* @param $txt
*/
public function addText($txt)
{
$this->value = trim($txt);
}
}
/**
* Handles complex options elements which are hashes (assoc arrays).
*
* @package phing.tasks.ext
*/
class PearPkgMapping
{
private $name;
private $elements = array();
/**
* @param $v
*/
public function setName($v)
{
$this->name = $v;
}
public function getName()
{
return $this->name;
}
/**
* @return PearPkgMappingElement
*/
public function createElement()
{
$e = new PearPkgMappingElement();
$this->elements[] = $e;
return $e;
}
/**
* @return array
*/
public function getElements()
{
return $this->elements;
}
/**
* Returns the PHP hash or array of hashes (etc.) that this mapping represents.
* @return array
*/
public function getValue()
{
$value = array();
foreach ($this->getElements() as $el) {
if ($el->getKey() !== null) {
$value[$el->getKey()] = $el->getValue();
} else {
$value[] = $el->getValue();
}
}
return $value;
}
}
/**
* Sub-element of