<?xml version="1.0" encoding="UTF-8"?>
<project name="php-automate-build-ant" default="full-build" basedir=".">
    <!-- By default the tools are managed by Composer in ${project.basedir}/vendor/bin -->
    <property name="url.composer.download" value="https://getcomposer.org/download/2.2.6/composer.phar"/>
    <property name="url.phpdocumentor.download" value="https://phpdoc.org/phpDocumentor.phar"/>
    <property name="composer" value="${project.basedir}/composer.phar"/>
    <property name="phpdocumentor" value="${project.basedir}/phpDocumentor.phar"/>
    <property name="pdepend" value="${project.basedir}/vendor/bin/pdepend"/>
    <property name="phpcpd" value="${project.basedir}/vendor/bin/phpcpd"/>
    <property name="phpcs" value="${project.basedir}/vendor/bin/phpcs"/>
    <property name="phploc" value="${project.basedir}/vendor/bin/phploc"/>
    <property name="phpmd" value="${project.basedir}/vendor/bin/phpmd"/>
    <property name="phpunit" value="${project.basedir}/vendor/bin/phpunit"/>
    <property name="phpstan" value="${project.basedir}/vendor/bin/phpstan"/>
    <property name="git" value="/usr/bin/git"/>
    <target name="clean" unless="clean.done" description="Cleanup build artifacts.">
        <delete dir="${project.basedir}/build/builddoc"/>
        <delete dir="${project.basedir}/build/cache"/>
        <delete dir="${project.basedir}/build/doc"/>
        <delete dir="${project.basedir}/build/coverage"/>
        <delete dir="${project.basedir}/build/logs"/>
        <delete dir="${project.basedir}/build/pdepend"/>
        <delete dir="${project.basedir}/build/dist"/>
        <delete dir="${project.basedir}/build/phpdoc"/>
        <property name="clean.done" value="true"/>
    </target>
    <target name="composer" description="Install composer packages including require-dev.">
        <exec executable="wget">
            <arg path="${url.composer.download}"/>
            <arg value="-O"/>
            <arg path="${composer}"/>
        </exec>
        <exec executable="chmod">
            <arg value="+x"/>
            <arg path="${composer}"/>
        </exec>
        <exec executable="php">
            <arg path="${composer}"/>
            <arg value="install"/>
            <arg value="--prefer-dist"/>
            <arg value="--no-progress"/>
        </exec>
        <exec executable="php">
            <arg path="${composer}"/>
            <arg value="update"/>
        </exec>
    </target>
    <target name="downloadphpdocumentor" description="Install phpdocumentor">
        <exec executable="wget">
            <arg path="${url.phpdocumentor.download}"/>
            <arg value="-O"/>
            <arg path="${phpdocumentor}"/>
        </exec>
        <exec executable="chmod">
            <arg value="+x"/>
            <arg path="${phpdocumentor}"/>
        </exec>
    </target>
    <target name="full-build" depends="prepare,composer,static-analysis,phpunit,-check-failure,projectdoc,deploy" description="Perform static analysis, run tests, and generate project documentation.">
        <echo message="Built"/>
    </target>
    <target name="lint" unless="lint.done" description="Perform syntax check of PHP sourcecode files.">
        <apply executable="php" taskname="lint">
            <arg value="-l"/>
            <fileset dir="${project.basedir}/src">
                <include name="**/*.php"/>
            </fileset>
            <fileset dir="${project.basedir}/tests">
                <include name="**/*.php"/>
            </fileset>
        </apply>
        <property name="lint.done" value="true"/>
    </target>
    <target name="pdepend" unless="pdepend.done" depends="prepare" description="Calculate software metrics using PHP_Depend and log result in XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${pdepend}" taskname="pdepend">
            <arg value="--jdepend-xml=${project.basedir}/build/logs/jdepend.xml"/>
            <arg value="--jdepend-chart=${project.basedir}/build/pdepend/dependencies.svg"/>
            <arg value="--overview-pyramid=${project.basedir}/build/pdepend/overview-pyramid.svg"/>
            <arg path="${project.basedir}/src"/>
        </exec>
        <property name="pdepend.done" value="true"/>
    </target>
    <target name="phpcpd" unless="phpcpd.done" description="Find duplicate code using PHPCPD and print human readable output. Intended for usage on the command line before committing.">
        <exec executable="${phpcpd}" taskname="phpcpd">
            <arg value="--exclude"/>
            <arg path="${project.basedir}/src/entities/"/>
            <arg path="${project.basedir}/src"/>
        </exec>
        <property name="phpcpd.done" value="true"/>
    </target>
    <target name="phpcpd-ci" unless="phpcpd.done" depends="prepare" description="Find duplicate code using PHPCPD and log result in XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${phpcpd}" taskname="phpcpd">
            <arg value="--log-pmd"/>
            <arg path="${project.basedir}/build/logs/pmd-cpd.xml"/>
            <arg value="--exclude"/>
            <arg path="${project.basedir}/src/entities/"/>
            <arg path="${project.basedir}/src"/>
        </exec>
        <property name="phpcpd.done" value="true"/>
    </target>
    <target name="phpcs" unless="phpcs.done" description="Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing.">
        <exec executable="${phpcs}" taskname="phpcs">
            <arg value="--standard=${project.basedir}/build/phpcsrules.xml"/>
            <arg value="--extensions=php"/>
            <arg value="--ignore=autoload.php"/>
            <arg path="${project.basedir}/src"/>
            <arg path="${project.basedir}/tests"/>
        </exec>
        <property name="phpcs.done" value="true"/>
    </target>
    <target name="phpcs-ci" unless="phpcs.done" depends="prepare" description="Find coding standard violations using PHP_CodeSniffer and log result in XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${phpcs}" output="/dev/null" taskname="phpcs">
            <arg value="--report=checkstyle"/>
            <arg value="--report-file=${project.basedir}/build/logs/checkstyle.xml"/>
            <arg value="--standard=${project.basedir}/build/phpcsrules.xml"/>
            <arg value="--extensions=php"/>
            <arg value="--ignore=autoload.php"/>
            <arg path="${project.basedir}/src"/>
            <arg path="${project.basedir}/tests"/>
        </exec>
        <property name="phpcs.done" value="true"/>
    </target>
    <target name="phpstan" unless="phpstan.done" description="Find coding standard violations using PHPStan and print human readable output. Intended for usage on the command line before committing.">
        <exec executable="${phpstan}" taskname="phpstan" passthru="true">
            <arg value="analyze"/>
            <arg value="-c"/>
            <arg path="${project.basedir}/build/phpstan.neon"/>
            <arg value="--autoload-file=${project.basedir}/vendor/autoload.php"/>
            <arg value="--no-interaction"/>
            <arg value="--no-progress"/>
            <arg value="--error-format=table"/>
        </exec>
        <property name="phpstan.done" value="true"/>
    </target>
    <target name="phpstan-ci" unless="phpstan.done" depends="prepare" description="Find coding standard violations using PHPStan and log result in XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${phpstan}" taskname="phpstan" outputProperty="phpstan.output">
            <arg value="analyze"/>
            <arg value="-c"/>
            <arg path="${project.basedir}/build/phpstan.neon"/>
            <arg value="--autoload-file=${project.basedir}/vendor/autoload.php"/>
            <arg value="--no-interaction"/>
            <arg value="--no-progress"/>
            <arg value="--error-format=checkstyle"/>
        </exec>
        <echo message="${phpstan.output}" file="${project.basedir}/build/logs/checkstyle_phpstan.xml"/>
        <property name="phpstan.done" value="true"/>
    </target>
    <target name="phploc" unless="phploc.done" description="Measure project size using PHPLOC and print human readable output. Intended for usage on the command line.">
        <exec executable="${phploc}" taskname="phploc">
            <arg value="--count-tests"/>
            <arg path="${project.basedir}/src"/>
            <arg path="${project.basedir}/tests"/>
        </exec>
        <property name="phploc.done" value="true"/>
    </target>
    <target name="phploc-ci" unless="phploc.done" depends="prepare" description="Measure project size using PHPLOC and log result in CSV and XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${phploc}" taskname="phploc">
            <arg value="--count-tests"/>
            <arg value="--log-csv"/>
            <arg path="${project.basedir}/build/logs/phploc.csv"/>
            <arg value="--log-xml"/>
            <arg path="${project.basedir}/build/logs/phploc.xml"/>
            <arg path="${project.basedir}/src"/>
            <arg path="${project.basedir}/tests"/>
        </exec>
        <property name="phploc.done" value="true"/>
    </target>
    <target name="phpmd" unless="phpmd.done" description="Perform project mess detection using PHPMD and print human readable output. Intended for usage on the command line before committing.">
        <exec executable="${phpmd}" taskname="phpmd">
            <arg path="${project.basedir}/src"/>
            <arg value="text"/>
            <arg path="${project.basedir}/build/phpmd.xml"/>
            <arg value="--exclude"/>
            <arg path="${project.basedir}/src/entities/"/>
        </exec>
        <property name="phpmd.done" value="true"/>
    </target>
    <target name="phpmd-ci" unless="phpmd.done" depends="prepare" description="Perform project mess detection using PHPMD and log result in XML format. Intended for usage within a continuous integration environment.">
        <exec executable="${phpmd}" taskname="phpmd">
            <arg path="${project.basedir}/src"/>
            <arg value="xml"/>
            <arg path="${project.basedir}/build/phpmd.xml"/>
            <arg value="--reportfile"/>
            <arg path="${project.basedir}/build/logs/pmd.xml"/>
            <arg value="--exclude"/>
            <arg path="${project.basedir}/src/entities/"/>
        </exec>
        <exec executable="${phpmd}" taskname="phpmd">
            <arg path="${project.basedir}/src"/>
            <arg value="html"/>
            <arg path="${project.basedir}/build/phpmd.xml"/>
            <arg value="--reportfile"/>
            <arg path="${project.basedir}/build/logs/pmd.html"/>
            <arg value="--exclude"/>
            <arg path="${project.basedir}/src/entities/"/>
        </exec>
        <property name="phpmd.done" value="true"/>
    </target>
    <target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit.">
        <exec executable="${phpunit}" returnProperty="result.phpunit" taskname="phpunit">
            <arg value="--configuration"/>
            <arg path="${project.basedir}/build/phpunit.xml"/>
        </exec>
        <property name="phpunit.done" value="true"/>
    </target>
    <target name="phpunit-no-coverage" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit without generating code coverage reports.">
        <exec executable="${phpunit}" taskname="phpunit">
            <arg value="--configuration"/>
            <arg path="${project.basedir}/build/phpunit.xml"/>
            <arg path="tests"/>
            <arg value="--no-coverage"/>
        </exec>
        <property name="phpunit.done" value="true"/>
    </target>
    <target name="prepare" unless="prepare.done" depends="clean" description="Prepare for build.">
        <mkdir dir="${project.basedir}/build/builddoc"/>
        <mkdir dir="${project.basedir}/build/cache"/>
        <mkdir dir="${project.basedir}/build/doc"/>
        <mkdir dir="${project.basedir}/build/coverage"/>
        <mkdir dir="${project.basedir}/build/logs"/>
        <mkdir dir="${project.basedir}/build/pdepend"/>
        <mkdir dir="${project.basedir}/build/dist"/>
        <mkdir dir="${project.basedir}/build/phpdoc"/>
        <property name="prepare.done" value="true"/>
    </target>
    <target name="quick-build" depends="prepare,composer,lint,phpunit-no-coverage" description="Perform lint check and run tests without generating code coverage reports.">
        <echo message="Built"/>
    </target>
    <target name="static-analysis" depends="lint,phploc-ci,pdepend,phpmd-ci,phpcs-ci,phpstan-ci,phpcpd-ci" description="Perform static analysis.">
        <echo message="Done"/>
    </target>
    <target name="-check-failure">
        <fail message="PHPUnit did not finish successfully">
            <condition>
                <not>
                    <equals arg1="${result.phpunit}" arg2="0"/>
                </not>
            </condition>
        </fail>
        <echo message="Checked failure"/>
    </target>
    <target name="deploy" description="Deplay build">
        <zip destfile="${project.basedir}/build/dist/doc.zip">
            <fileset dir="${project.basedir}/build/doc">
                <include name="**/*.*"/>
            </fileset>
        </zip>
        <zip destfile="${project.basedir}/build/dist/src.zip">
            <fileset dir="${project.basedir}/src">
                <include name="**/*.*"/>
            </fileset>
        </zip>
        <zip destfile="${project.basedir}/build/dist/builddoc.zip">
            <fileset dir="${project.basedir}/build">
                <include name="builddoc/**/*.*"/>
                <include name="coverage/**/*.*"/>
                <include name="coverage-html/**/*.*"/>
                <include name="logs/**/*.*"/>
                <include name="pdepend/**/*.*"/>
                <exclude name="phpdoc/**/*.*"/>
            </fileset>
        </zip>
    </target>
    <target name="projectdoc" description="Generate documentation">
        <if>
            <versioncompare version="${php.version}" desiredVersion="7.4" operator=">=" />
            <then>
                <phingcall target="clean" />
                <phingcall target="downloadphpdocumentor" />
                <exec executable="php" dir="${project.basedir}/build">
                    <arg path="${phpdocumentor}"/>
                </exec>
                <delete file="${phpdocumentor}"/>
                <phingcall target="clean" />
            </then>
            <else>
                <echo message="Build documentation only on PHP7.4 or higher" />
            </else>
        </if>
    </target>
</project>
