Build That Phing!

Post on 23-Aug-2014

321 views 6 download

Tags:

description

PHPMD, PHPCS, PHPUnit and PHPLint; these are all tools to maintain code quality. Executing these tasks is a chore and there are many ways to automate this process, Phing being one of them. The goal of this talk is to really discover what Phing has to offer, from implementing code logic to creating your own task.

Transcript of Build That Phing!

Build that Phing!PHing Is Not GNU make

/ Rick Kuipers @rskuipersio@rskuipers.com

whoamiRick Kuipers@rskuipersApeldoornThe WebmenMagentoZend Framework

><A build tool developed for and in PHPInstallation through PEAR or Composer$ pear channel-discover pear.phing.info$ pear install --alldeps phing/phing

>< vs PHPPEAR

build.xml

Javaapt-get

build.xml

Skeleton Application

build.xml

<?xml version="1.0"?><project name="zf2" default="build">

<target name="build" />

</project>

$ phing -lBuildfile: /var/www/zf2/build.xmlWarning: target 'build' has no tasks or dependenciesDefault target:------------------------------------------------------------------------------- build

Subtargets:------------------------------------------------------------------------------- build

$ phingBuildfile: /var/www/zf2/build.xmlWarning: target 'build' has no tasks or dependencies

zf2 tutorial > build:

BUILD FINISHED

Total time: 0.0457 seconds

FundamentalsProperties

FileSetsPatternSets

Tasks

Properties<property name="build.dir" value="${project.basedir}/build" /><property name="dist.dir" value="${build.dir}/dist" /><property name="logs.dir" value="${build.dir}/logs" /><property name="cache.dir" value="${build.dir}/cache" /><property name="src.dir" value="${project.basedir}/module" />

FileSets<fileset id="php.files" dir="."> <include name="*.php" /></fileset>

.|-- build.xml|-- example.php|-- phing-logic-1| ̀-- build.xml|-- phing-logic-2| |-- build.xml| ̀-- continue|-- phing-logic-foreach| |-- build.xml| ̀-- fruits| |-- apple.php| |-- banana.xml| |-- orange.xml| ̀-- pear.php-̀- qa-basics |-- build.xml |-- example.php ̀-- tests ̀-- ExampleTest.php

<fileset id="php.files" dir="."> <include name="*/*.php" /></fileset>

.|-- build.xml|-- example.php|-- phing-logic-1| ̀-- build.xml|-- phing-logic-2| |-- build.xml| ̀-- continue|-- phing-logic-foreach| |-- build.xml| ̀-- fruits| |-- apple.php| |-- banana.xml| |-- orange.xml| ̀-- pear.php-̀- qa-basics |-- build.xml |-- example.php ̀-- tests ̀-- ExampleTest.php

<fileset id="php.files" dir="."> <include name="**/*.php" /></fileset>

.|-- build.xml|-- example.php|-- phing-logic-1| ̀-- build.xml|-- phing-logic-2| |-- build.xml| ̀-- continue|-- phing-logic-foreach| |-- build.xml| ̀-- fruits| |-- apple.php| |-- banana.xml| |-- orange.xml| ̀-- pear.php-̀- qa-basics |-- build.xml |-- example.php ̀-- tests ̀-- ExampleTest.php

PatternSets<patternset id="php.patternset"> <include name="*/src/**/*.php" /> <include name="*/view/**/*.phtml" /></patternset>

<fileset id="php.files" dir="${src.dir}"> <patternset refid="php.patternset" /></fileset>

Let's put it together!<?xml version="1.0"?><project name="zf2" default="build">

<property name="build.dir" value="${project.basedir}/build" /> <property name="dist.dir" value="${build.dir}/dist" /> <property name="logs.dir" value="${build.dir}/logs" /> <property name="cache.dir" value="${build.dir}/cache" /> <property name="src.dir" value="${project.basedir}/module" />

<fileset id="php.files" dir="${src.dir}"> <include name="*/*.php" /> <include name="*/src/**/*.php" /> <include name="*/view/**/*.phtml" /> </fileset>

<target name="build" />

</project>

$ phingBuildfile: /var/www/zf2/build.xmlWarning: target 'build' has no tasks or dependencies

zf2 > build:

BUILD FINISHED

Total time: 0.0492 seconds

How do we use PhingQA during module development

Combination with CI

Quality Assurance"Quality Assurance (QA) is a way of preventing

mistakes or defects in manufactured products andavoiding problems when delivering solutions or

services to customers."

QA ToolsPHP LintPHP Mess DetectorPHP Code SnifferPHP Unit

Example 1. <?php 2. 3. namespace My\Module 4. 5. class Example { 6. 7. function sum($x, $y, $z) 8. { 9. return $x + $y;10. }11.12. }13. ?>

PHP LintBuilt into the PHP executable.Checks for syntax errors.

$ php -l example.php

PHP Parse error: syntax error, unexpected 'class' (T_CLASS), expecting \\ (T_NS_SEPARATOR) or ';' or '{' in example.php on line 5Errors parsing example.php

Example 1. <?php 2. 3. namespace My\Module 4. 5. class Example { 6. 7. function sum($x, $y, $z) 8. { 9. return $x + $y;10. }11.12. }13. ?>

PHP Mess DetectorInstallation through Git, Composer or as a PEAR package.Detects code smells such as:

Possible bugsSuboptimal codeOvercomplicated expressionsUnused parameters, methods, properties

$ phpmd example.php text cleancode,codesize,controversial,design,naming,unusedcode

example.php:7 Avoid variables with short names like $x. Configured minimum length is 3.example.php:7 Avoid variables with short names like $y. Configured minimum length is 3.example.php:7 Avoid variables with short names like $z. Configured minimum length is 3.example.php:7 Avoid unused parameters such as '$z'.

Example 1. <?php 2. 3. namespace My\Module; 4. 5. class Example { 6. 7. function sum($x, $y, $z) 8. { 9. return $x + $y;10. }11.12. }13. ?>

PHP Code SnifferInstallation through Git, Composer or as a PEAR package.Checks your code for coding standards such as:

PEARPSR1PSR2ZendSquiz

$ phpcs --standard=PSR2 example.php

--------------------------------------------------------------------------------FOUND 4 ERROR(S) AFFECTING 4 LINE(S)-------------------------------------------------------------------------------- 5 | ERROR | Opening brace of a class must be on the line after the definition 7 | ERROR | Visibility must be declared on method "sum" 12 | ERROR | The closing brace for the class must go on the next line after | | the body 13 | ERROR | A closing tag is not permitted at the end of a PHP file--------------------------------------------------------------------------------

Example 1. <?php 2. 3. namespace My\Module; 4. 5. class Example { 6. 7. function sum($x, $y, $z) 8. { 9. return $x + $y;10. }11.12. }13. ?>

PHP UnitInstallation through PHAR, Composer or as a PEAR package.Runs tests on your code.Provides a framework to create tests.

<?php

namespace My\Module;

require_once('example.php');

class ExampleTest extends \PHPUnit_Framework_TestCase{

public function testSum() { $example = new Example(); $this->assertEquals($example->sum(2, 3, 5), 10); }}

PHP Unit$ phpunit .

PHPUnit 3.7.29 by Sebastian Bergmann.

F

Time: 17 ms, Memory: 2.75Mb

There was 1 failure:

1) My\Module\ExampleTest::testSumFailed asserting that 5 matches expected 10.

/var/www/talk-phing/web/examples/qa-basics/tests/ExampleTest.php:13

FAILURES!Tests: 1, Assertions: 1, Failures: 1.

Example 1. <?php 2. 3. namespace My\Module; 4. 5. class Example { 6. 7. function sum($x, $y, $z) 8. { 9. return $x + $y;10. }11.12. }13. ?>

TasksCore Tasks

AdhocTaskdefTaskAdhocTypedefTaskAppendTaskApplyTaskAvailableTaskChmodTaskChownTaskConditionTaskCopyTaskCvsTaskCvsPassTaskDeleteTaskEchoTask

ExecTaskFailTaskForeachTaskIfTaskImportTaskIncludePathTaskInputTaskLoadFileTaskMkdirTaskMoveTaskPhingTaskPhingCallTaskPhpEvalTask

PropertyTaskPropertyPromptTaskReflexiveTaskResolvePathTaskTaskdefTaskTouchTaskTryCatchTaskTstampTaskTypedefTaskUpToDateTaskWaitForTaskXsltTask

Optional TasksApiGenTaskCoverageMergerTaskCoverageReportTaskCoverageSetupTaskCoverageThresholdTaskDbDeployTaskDocBloxTaskExportPropertiesTaskFileHashTaskFileSizeTaskFileSyncTaskFtpDeployTaskGitInitTaskGitCloneTaskGitGcTaskGitBranchTaskGitFetchTaskGitCheckoutTaskGitCommitTaskGitMergeTask

GitPullTaskGitPushTaskGitTagTaskGitLogTaskGrowlNotifyTaskHttpGetTaskHttpRequestTaskIoncubeEncoderTaskIoncubeLicenseTaskJslLintTaskJsMinTaskLiquibaseChangeLogTaskLiquibaseDbDocTaskLiquibaseDiffTaskLiquibaseRollbackTaskLiquibaseTagTaskLiquibaseUpdateTaskMailTaskParallelTaskPatchTask

PDOSQLExecTaskPearPackageTaskPearPackage2TaskPharPackageTaskPhkPackageTaskPhpCodeSnifferTaskPHPCPDTaskPHPLocTaskPHPMDTaskPhpDependTaskPhpDocumentorTaskDocBloxTaskPhpDocumentorExternalTaskPhpLintTaskPHPUnitTaskPHPUnitReportrSTTaskS3PutTaskS3GetTaskScpTask

SshTaskSimpleTestTaskSvnCheckoutTaskSvnCommitTaskSvnCopyTaskSvnExportTaskSvnInfoTaskSvnLastRevisionTaskSvnListTaskSvnLogTaskSvnUpdateTaskSvnSwitchTaskSymfonyConsoleTaskSymlinkTaskTarTaskUntarTaskUnzipTaskVersionTaskWikiPublishTaskXmlLintTask

XmlPropertyTaskZendCodeAnalyzerTaskZendGuardEncodeTaskZendGuardLicenseTaskZipTask

Automating QA

PHPLint Task<target name="phplint"> <phplint haltonfailure="true" cachefile="${cache.dir}/lint.cache"> <fileset refid="php.files" /> </phplint></target>

PHPCodeSniffer Task<target name="phpcs"> <phpcodesniffer standard="PSR2"> <fileset refid="php.files" /> <formatter type="full" usefile="false" /> </phpcodesniffer></target>

PHPMD Task<target name="phpmd"> <phpmd> <fileset refid="php.files" /> </phpmd></target>

PHPUnit Task<target name="phpunit"> <exec command="phpunit -c ${src.dir}/Application/test/" passthru="true" checkreturn="true" /> <exec command="phpunit -c ${src.dir}/Album/test/" passthru="true" checkreturn="true" /></target>

<?xml version="1.0"?><project name="zf2" default="build"> <property name="build.dir" value="${project.basedir}/build" /> <property name="dist.dir" value="${build.dir}/dist" /> <property name="logs.dir" value="${build.dir}/logs" /> <property name="cache.dir" value="${build.dir}/cache" /> <property name="src.dir" value="${project.basedir}/module" /> <fileset id="php.files" dir="${src.dir}"> <include name="*/*.php" /> <include name="*/src/**/*.php" /> <include name="*/view/**/*.phtml" /> </fileset> <target name="build" /> <target name="phplint"> <phplint haltonfailure="true" cachefile="${cache.dir}/lint.cache"> <fileset refid="php.files" /> </phplint> </target> <target name="phpcs"> <phpcodesniffer standard="PSR2"> <fileset refid="php.files" /> <formatter type="full" usefile="false" /> </phpcodesniffer> </target> <target name="phpmd"> <phpmd> <fileset refid="php.files" /> </phpmd> </target> <target name="phpunit"> <exec command="phpunit -c ${src.dir}/Application/test/" passthru="true" checkreturn="true" /> <exec command="phpunit -c ${src.dir}/Album/test/" passthru="true" checkreturn="true" /> </target></project>

$ phingBuildfile: /var/www/zf2/build.xmlWarning: target 'build' has no tasks or dependencies

zf2 > build:

BUILD FINISHED

Total time: 0.0540 seconds

Dependencies<target name="build" depends="phplint, phpcs, phpmd, phpunit" />

$ phingBuildfile: /var/www/zf2/build.xml

zf2 > phplint:

BUILD FAILEDexception 'IOException' with message 'Unable to open /var/www/zf2/build/cache/lint.cache for writing: ' in /usr/share/php/phing/system/io/FileOutputStream.php:59Stack trace:#0 /usr/share/php/phing/system/io/FileWriter.php(38): FileOutputStream->__construct(Object(PhingFile), false)#1 /usr/share/php/phing/util/DataStore.php(146): FileWriter->__construct(Object(PhingFile))#2 /usr/share/php/phing/util/DataStore.php(107): DataStore->write()#3 /usr/share/php/phing/tasks/ext/PhpLintTask.php(198): DataStore->commit()#4 /usr/share/php/phing/UnknownElement.php(96): PhpLintTask->main()#5 /usr/share/php/phing/Task.php(260): UnknownElement->main()#6 /usr/share/php/phing/Target.php(297): Task->perform()#7 /usr/share/php/phing/Target.php(320): Target->main()#8 /usr/share/php/phing/Project.php(824): Target->performTasks()#9 /usr/share/php/phing/Project.php(797): Project->executeTarget('build')#10 /usr/share/php/phing/Phing.php(586): Project->executeTargets(Array)#11 /usr/share/php/phing/Phing.php(170): Phing->runBuild()#12 /usr/share/php/phing/Phing.php(278): Phing::start(Array, NULL)#13 /usr/share/php/phing.php(43): Phing::fire(Array)#14 {main}

Total time: 0.1397 seconds

<target name="prepare"> <mkdir dir="${build.dir}" /> <mkdir dir="${dist.dir}" /> <mkdir dir="${logs.dir}" /> <mkdir dir="${cache.dir}" /></target>

<target name="-prepare" hidden="true"> <mkdir dir="${build.dir}" /> <mkdir dir="${dist.dir}" /> <mkdir dir="${logs.dir}" /> <mkdir dir="${cache.dir}" /></target>

© Stephan Hochdörfer

<target name="phplint" depends="-prepare"> <!-- ... --></target>

<target name="phpcs" depends="-prepare"> <!-- ... --></target>

<target name="phpmd" depends="-prepare"> <!-- ... --></target>

<target name="phpunit" depends="-prepare"> <!-- ... --></target>

$ phingBuildfile: /var/www/zf2/build.xml

zf2 > -prepare:

zf2 > phplint:

zf2 > phpcs:

FILE: /var/www/zf2/module/Application/view/layout/layout.phtml--------------------------------------------------------------------------------FOUND 0 ERROR(S) AND 5 WARNING(S) AFFECTING 5 LINE(S)-------------------------------------------------------------------------------- 6 | WARNING | Line exceeds 120 characters; contains 127 characters 11 | WARNING | Line exceeds 120 characters; contains 154 characters 17 | WARNING | Line exceeds 120 characters; contains 137 characters 33 | WARNING | Line exceeds 120 characters; contains 125 characters 36 | WARNING | Line exceeds 120 characters; contains 123 characters--------------------------------------------------------------------------------

zf2 > phpmd:

[phpmd] Processing files...

/var/www/zf2/module/Album/src/Album/Form/AlbumForm.php:8 Avoid unused parameters such as '$name'./var/www/zf2/module/Album/src/Album/Model/Album.php:33 Avoid unused parameters such as '$inputFilter'. [phpmd] Finished processing files

zf2 > phpunit:

PHPUnit 4.0.14 by Sebastian Bergmann.

Configuration read from /var/www/zf2/module/Application/test/phpunit.xml.dist

.

Time: 42 ms, Memory: 5.75Mb

OK (1 test, 1 assertion)

PHPUnit 4.0.14 by Sebastian Bergmann.

Configuration read from /var/www/zf2/module/Album/test/phpunit.xml.dist

.............

Time: 72 ms, Memory: 8.50Mb

OK (13 tests, 22 assertions)

zf2 > build:

BUILD FINISHED

Logical tasksIfTask

ConditionTaskFailTask

ForeachTask

IfTask<property name="foo" value="bar" /><if> <equals arg1="${foo}" arg2="bar" /> <then> <echo message="The value of property foo is bar" /> </then> <else> <echo message="The value of property foo is not bar" /> </else></if>

ConditionTask<condition property="IsPhingRecursiveAcronym"> <contains string="PHing Is Not GNU make" substring="phing" casesensitive="false" /></condition><if> <istrue value="${IsPhingRecursiveAcronym}" /> <then> <echo message="It's recursive!" /> </then> <else> <echo message="It's not recursive!" /> </else></if>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-condition-task/build.xml

Example > build:

[echo] It's recursive!

BUILD FINISHED

Total time: 0.0487 seconds

<condition property="IsXmlRecursiveAcronym"> <contains string="Extensible Markup Language" substring="XML" casesensitive="false" /></condition><if> <istrue value="${IsXmlRecursiveAcronym}" /> <then> <echo message="It's recursive!" /> </then> <else> <echo message="It's not recursive!" /> </else></if>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-condition-task/build.xml

Example > build:

[echo] It's recursive!

BUILD FINISHED

Total time: 0.0524 seconds

<condition property="IsXmlRecursiveAcronym"> <contains string="Extensible Markup Language" substring="XML" casesensitive="false" /></condition><if> <isset property="IsXmlRecursiveAcronym" /> <then> <echo message="It's recursive!" /> </then> <else> <echo message="It's not recursive!" /> </else></if>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-condition-task/build.xml

Example > build:

[echo] It's not recursive!

BUILD FINISHED

Total time: 0.0468 seconds

FailTask<fail message="Failed for some reason!" />

<fail if="errorprop" message="Detected error!" />

<fail unless="dontfail" message="Detected error!" />

ForeachTask<fileset id="fruits" dir="."> <include name="fruits/*.xml" /> <include name="**/*.php" /></fileset>

<target name="build"> <foreach param="fruit" target="displayfruit"> <fileset refid="fruits" /> </foreach> <foreach list="apple;orange;pear;banana" target="displayfruit" param="fruit" delimiter=";" /></target>

<target name="displayfruit"> <echo message="${fruit}" /></target>

Interesting TasksPropertyPromptTask

PhpEvalTask

PropertyPromptTask<?xml version="1.0" encoding="UTF-8"?><project name="Example" default="build">

<propertyprompt propertyName="messages.name" promptText="Please enter your name" defaultValue="anonymous" />

<property name="messages.welcome" value="Hello, ${messages.name}!" />

<target name="build" description="Displays the project name and a personalized welcome message" <echo message="${phing.project.name}: ${messages.welcome}" /> </target>

</project>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-prompt/build.xml

Please enter your name [anonymous] ? Rick

Example > build:

[echo] Example: Hello, Rick!

BUILD FINISHED

Total time: 3.7389 seconds

PhpEvalTask<?xml version="1.0" encoding="UTF-8"?><project name="Example" default="build">

<target name="build"> <php expression="function increment($i) { return ++$i; }" /> <php function="increment" returnProperty="result"> <param>1</param> </php> <echo message="${result}" /> </target>

</project>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-php-eval/build.xml

Example > build:

[php] Evaluating PHP expression: function increment($i) { return ++$i; } [php] Calling PHP function: increment() [echo] 2

BUILD FINISHED

Total time: 0.0511 seconds

<?xml version="1.0"?><project name="Testing Framework" default="build"> <property name="haltOnFail" value="true" />

<target name="build"> <php function="ucfirst" returnProperty="result"> <param>phing</param> </php> <property name="expected" value="Phing" override="true" /> <phingcall target="test" />

<php expression="preg_replace('/php/', 'xml', 'PHP')" returnProperty="result" /> <property name="expected" value="xml" override="true" /> <phingcall target="test" /> </target>

<target name="test"> <if> <equals arg1="${result}" arg2="${expected}" casesensitive="true" /> <then> <echo>✔ </echo> </then> <else> <echo>✘</echo> <fail if="haltOnFail">Expected: ${expected}Result: ${result}</fail> </else> </if> </target></project>

$ phingBuildfile: /var/www/talk-phing/web/examples/phing-testing-framework/build.xml

Testing Framework > build:

[php] Calling PHP function: ucfirst()[phingcall] Calling Buildfile '/var/www/talk-phing/web/examples/phing-testing-framework/build.xml' with target 'test'

Testing Framework > test:

[echo] ✔ [php] Evaluating PHP expression: preg_replace('/php/', 'xml', 'PHP')[phingcall] Calling Buildfile '/var/www/talk-phing/web/examples/phing-testing-framework/build.xml' with target 'test'

Testing Framework > test:

[echo] ✘ [if] Error in IfTaskExecution of target "test" failed for the following reason: /var/www/talk-phing/web/examples/phing-testing-framework/build.xml:19:12: Error in IfTaskPrevious exception 'BuildException' with message '/var/www/talk-phing/web/examples/phing-testing-framework/build.xml:26:25: /var/www/talk-phing/web/examples/phing-testing-framework/build.xml:26:25:Expected: xmlResult: PHP

Extending our phpunit target<target name="phpunit" depends="-prepare"> <propertyprompt defaultValue="all" promptText="Which module would you like to run the tests for?" propertyName="module" /> <if> <equals arg1="${module}" arg2="all" /> <then> <phingcall target="-run-all-tests" /> </then> <else> <property name="absFile" value="${src.dir}/${module}/test/phpunit.xml.dist" /> <phingcall target="-run-test" /> </else> </if></target>

<target name="-run-all-tests" hidden="true"> <foreach param="file" absparam="absFile" target="-run-test"> <fileset dir="${src.dir}"> <include name="*/test/phpunit.xml*" /> </fileset> </foreach></target>

<target name="-run-test" hidden="true"> <php function="dirname" returnProperty="phpunitConfigDir"> <param>${absFile}</param> </php> <exec command="phpunit -c ${phpunitConfigDir}" passthru="true" checkreturn="true" /></target>

Create your own Task

VDDvar_dump driven development

XDebug or PHPDBG

VarDumpTaskAccept a filesetFind lines that contain var_dumpIgnore commentsShow the files and line numbers that matchHalt on match

<?php

require_once 'phing/Task.php';

class VarDumpTask extends Task{

public function main() {

}}

<?php

require_once 'phing/Task.php';include_once 'phing/types/FileSet.php';

class VarDumpTask extends Task{

protected $_fileSets = array();

public function main() {

}

public function createFileSet() { $num = array_push($this->_fileSets, new FileSet()); return $this->_fileSets[$num-1]; }}

<?php

require_once 'phing/Task.php';include_once 'phing/types/FileSet.php';

class VarDumpTask extends Task{

protected $_fileSets = array();

public function main() { if (!count($this->_fileSets)) { throw new BuildException("Missing a nested fileset"); } }

public function createFileSet() { $num = array_push($this->_fileSets, new FileSet()); return $this->_fileSets[$num-1]; }}

<?php

require_once 'phing/Task.php';include_once 'phing/types/FileSet.php';

class VarDumpTask extends Task{ const VAR_DUMP = 'var_dump(';

protected $_fileSets = array();

public function main() { if (!count($this->_fileSets)) { throw new BuildException("Missing a nested fileset"); }

$project = $this->getProject();

foreach ($this->_fileSets as $fs) {

$files = $fs->getDirectoryScanner($project)->getIncludedFiles(); $dir = $fs->getDir($this->project)->getPath();

foreach($files as &$file) { $fullfile = $dir . DIRECTORY_SEPARATOR . $file; if (($nr = $this->_grep($fullfile, self::VAR_DUMP, '//'))) { $this->log($fullfile . ':' . $nr); } } } }

public function createFileSet() { $num = array_push($this->_fileSets, new FileSet());

protected function _grep($file, $val, $ignoreLinesWith = null) { $lines = file($file);

foreach ($lines as $nr => $line) { if (strpos($line, $val) !== false) { if (!isset($ignoreLinesWith) || strpos($line, $ignoreLinesWith) === false) { return $nr; } } }

return false; }

protected $_haltOnMatch = false;

public function setHaltOnMatch($haltOnMatch = null) { if (isset($haltOnMatch)) { $this->_haltOnMatch = true; } }

public function main() { if (!count($this->_fileSets)) { throw new BuildException("Missing a nested fileset"); }

$project = $this->getProject(); $found = false;

foreach ($this->_fileSets as $fs) { $files = $fs->getDirectoryScanner($project)->getIncludedFiles(); $dir = $fs->getDir($project)->getPath();

foreach($files as &$file) { $fullfile = $dir . DIRECTORY_SEPARATOR . $file; if (($nr = $this->_grep($fullfile, self::VAR_DUMP, '//'))) { $this->log($fullfile . ':' . $nr); $found = true; } } }

if ($found && $this->_haltOnMatch) { throw new BuildException('Found traces of var_dump in filesets'); } }

Defining your taskAdhocTaskdefTask

TaskdefTask

AdhocTaskdefTask<adhoc-task name="foo"> <![CDATA[ class FooTest extends Task { private $bar;

function setBar($bar) { $this->bar = $bar; }

function main() { $this->log("In FooTest: " . $this->bar); } } ]]></adhoc-task>

TaskdefTask<taskdef name="vdd" classname="phing.tasks.VarDumpTask" />

Using our VarDumpTask<taskdef name="vdd" classname="phing.tasks.VarDumpTask" />

<target name="vdd" depends="-prepare"> <vdd haltOnMatch="true"> <fileset refid="php.files" /> </vdd></target>

$ phing vddBuildfile: /var/www/zf2/build.xml

zf2 > -prepare:

zf2 > vdd:

[vdd] /var/www/zf2/module/Album/Module.php:15Execution of target "vdd" failed for the following reason: /var/www/zf2/build.xml:48:25: Found traces of var_dump in filesets

BUILD FAILED/var/www/zf2/build.xml:48:25: Found traces of var_dump in filesetsTotal time: 0.0687 seconds

<?xml version="1.0"?><project name="zf2" default="build">

<taskdef name="vdd" classname="phing.tasks.VarDumpTask" />

<property name="build.dir" value="${project.basedir}/build" /> <property name="dist.dir" value="${build.dir}/dist" /> <property name="logs.dir" value="${build.dir}/logs" /> <property name="cache.dir" value="${build.dir}/cache" /> <property name="src.dir" value="${project.basedir}/module" />

<fileset id="php.files" dir="${src.dir}"> <include name="*/*.php" /> <include name="*/src/**/*.php" /> <include name="*/view/**/*.phtml" /> </fileset>

<target name="build" depends="phplint, phpcs, phpmd, phpunit, vdd" />

<target name="-prepare" hidden="true"> <mkdir dir="${build.dir}" /> <mkdir dir="${dist.dir}" /> <mkdir dir="${logs.dir}" /> <mkdir dir="${cache.dir}" /> </target>

<target name="phplint" depends="-prepare"> <phplint haltonfailure="true" cachefile="${cache.dir}/lint.cache"> <fileset refid="php.files" /> </phplint> </target>

<target name="phpcs" depends="-prepare"> <phpcodesniffer standard="PSR2"> <fileset refid="php.files" /> <formatter type="full" usefile="false" /> </phpcodesniffer> </target>

<target name="phpmd" depends="-prepare"> <phpmd> <fileset refid="php.files" /> </phpmd> </target>

<target name="vdd" depends="-prepare"> <vdd haltOnMatch="true"> <fileset refid="php.files" /> </vdd> </target>

<target name="phpunit" depends="-prepare"> <propertyprompt defaultValue="all" promptText="Which module would you like to run the tests for?" propertyName="module" /> <if> <equals arg1="${module}" arg2="all" /> <then> <phingcall target="-run-all-tests" /> </then> <else> <property name="absFile" value="${src.dir}/${module}/test/phpunit.xml.dist" /> <phingcall target="-run-test" /> </else> </if> </target>

<target name="-run-all-tests" hidden="true"> <foreach param="file" absparam="absFile" target="-run-test"> <fileset dir="${src.dir}"> <include name="*/test/phpunit.xml*" /> </fileset> </foreach> </target>

<target name="-run-test" hidden="true"> <php function="dirname" returnProperty="phpunitConfigDir"> <param>${absFile}</param> </php> <exec command="phpunit -c ${phpunitConfigDir}" passthru="true" checkreturn="true" /> </target>

</project>

Duplicate build file logicBuild file inheritance

Git submodules

phing/default.xml<?xml version="1.0"?><project name="zf2"> <taskdef name="vdd" classname="phing.tasks.VarDumpTask" />

<property name="build.dir" value="${project.basedir}/build" /> <property name="dist.dir" value="${build.dir}/dist" /> <property name="logs.dir" value="${build.dir}/logs" /> <property name="cache.dir" value="${build.dir}/cache" /> <property name="src.dir" value="${project.basedir}/module" />

<fileset id="php.files" dir="${src.dir}"> <include name="*/*.php" /> <include name="*/src/**/*.php" /> <include name="*/view/**/*.phtml" /> </fileset>

<target name="-prepare" hidden="true"> <mkdir dir="${build.dir}" /> <mkdir dir="${dist.dir}" /> <mkdir dir="${logs.dir}" /> <mkdir dir="${cache.dir}" /> </target>

<target name="phplint" depends="-prepare"> <phplint haltonfailure="true" cachefile="${cache.dir}/lint.cache"> <fileset refid="php.files" /> </phplint> </target>

<target name="phpcs" depends="-prepare"> <phpcodesniffer standard="PSR2"> <fileset refid="php.files" /> <formatter type="full" usefile="false" />

build.xml<?xml version="1.0"?><project name="zf2" default="build">

<import file="phing/default.xml" />

<target name="build" depends="phplint, phpcs, phpmd, phpunit, vdd" />

</project>

Documentationhttp://www.phing.info/docs/guide/stable/https://github.com/phingofficial/phing