Actions

Difference between revisions of "Joomla Ant build files"

From Joomla! Documentation

m (Installing Ant)
 
(4 intermediate revisions by one user not shown)
Line 16: Line 16:
 
If Eclipse complain something like "No grammar constraints (DTD or XML schema) detected for the document.", then you will need to add minimal DTD. For example; <!DOCTYPE project> [http://stackoverflow.com/questions/363768/disable-dtd-warning-for-ant-scripts-in-eclipse/483260#483260 reference]
 
If Eclipse complain something like "No grammar constraints (DTD or XML schema) detected for the document.", then you will need to add minimal DTD. For example; <!DOCTYPE project> [http://stackoverflow.com/questions/363768/disable-dtd-warning-for-ant-scripts-in-eclipse/483260#483260 reference]
  
== Example Build File ==
+
== Example Build Files ==
 +
=== Example 1 ===
 
<source lang="xml">
 
<source lang="xml">
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
Line 149: Line 150:
 
</source>
 
</source>
  
=== Config File to Accompany Build File ===
+
==== Config File to Accompany Build File ====
 
<source lang="text">
 
<source lang="text">
 
cfg.name=uncleocho
 
cfg.name=uncleocho
Line 162: Line 163:
 
ftp.dir=
 
ftp.dir=
 
</source>
 
</source>
 +
 +
=== Example 2 ===
 +
Anohter one, a bit less and a bit more.
 +
<source lang="xml">
 +
<!DOCTYPE project> <!-- For Eclipse -->
 +
<project name="People Actions" default="update_local" basedir=".">
 +
    <description>Ant Build File for Joomla! extensions</description>
 +
 
 +
    <!-- The name of your extension's main XML file -->
 +
    <property name="cfg.name" value="peopleactions" />
 +
    <!-- Prefix, eg com, bot, mod, or a brand name (or empty) -->
 +
    <property name="cfg.prefix" value="com_" />
 +
    <!-- Relative path to your project -->
 +
    <property name="cfg.dir" value="../trunk/component" />
 +
    <!-- Relative path to store the packages -->
 +
    <property name="cfg.packages" value="../packages" />
 +
    <!-- Absolute path to local server -->
 +
    <property name="cfg.serverpath" value="C:\Users\Ruben\Documents\Dev\Projects\Joomla\joomla-base\2.5" />
 +
 +
    <target name="init" >
 +
        <xmlproperty file="${cfg.dir}/${cfg.name}.xml" collapseAttributes="true" prefix="xml" keepRoot="false" />
 +
        <buildnumber/>
 +
        <tstamp>
 +
            <format property="TODAY" pattern="yyyy-MM-dd"/>
 +
        </tstamp>
 +
 +
        <property name="str.version" value="_v${xml.version}.${build.number}" />
 +
        <property name="str.destfile" value="${cfg.packages}/${cfg.prefix}${cfg.name}${str.version}_${TODAY}" />
 +
        <property name="str.sitetrunkpath" value="${cfg.dir}/site" />
 +
        <property name="str.admintrunkpath" value="${cfg.dir}/admin" />
 +
        <property name="str.xmlfile" value="${cfg.dir}/${cfg.name}test.xml" />
 +
    </target>
 +
 +
    <target name="info" depends="init" description="prints information">
 +
        <echo message="${cfg.name} - ${str.version} - ${ant.version}" />
 +
    </target>
 +
 
 +
    <target name="update_local" depends="info, init" description="attemps to update files on localhost server">
 +
        <copy todir="${cfg.serverpath}/components/${cfg.prefix}${cfg.name}">
 +
            <fileset dir="${str.sitetrunkpath}" excludes="/language/" />
 +
        </copy>
 +
        <copy todir="${cfg.serverpath}/language/">
 +
            <fileset dir="${str.sitetrunkpath}/language/" />
 +
        </copy>
 +
        <copy todir="${cfg.serverpath}/administrator/components/${cfg.prefix}${cfg.name}">
 +
            <fileset file="${cfg.dir}/${cfg.name}.xml" />
 +
            <fileset dir="${str.admintrunkpath}" excludes="/language/" />
 +
        </copy>
 +
        <copy todir="${cfg.serverpath}/administrator/language/">
 +
            <fileset dir="${str.admintrunkpath}/language/" />
 +
        </copy>
 +
        <copy todir="${cfg.serverpath}/media/${cfg.prefix}${cfg.name}/">
 +
    <fileset dir="${cfg.dir}/media/" />
 +
        </copy>
 +
    </target>
 +
 +
    <target name="zip" depends="info" description="Makes an uploadable zip package">
 +
        <mkdir dir="${cfg.packages}" />
 +
        <zip
 +
            destfile="${str.destfile}.zip"
 +
            basedir="${cfg.dir}" />
 +
    </target>
 +
 
 +
 +
    <target name="build_xml" depends="info" description="builds an xml listing of all the files in trunk">
 +
        <fileset id="site" dir="${str.sitetrunkpath}" />
 +
        <echo message="${line.separator}&lt;files folder=&quot;site&quot;&gt;${line.separator}&lt;filename&gt;" file="${str.xmlfile}" append="false" />
 +
        <echo-fileset filesetref="site" />
 +
        <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${str.xmlfile}" append="true" />
 +
 +
        <fileset id="admin" dir="${str.admintrunkpath}" />
 +
        <echo message="${line.separator}&lt;files folder=&quot;admin&quot;&gt;${line.separator}&lt;filename&gt;" file="${str.xmlfile}" append="true" />
 +
        <echo-fileset filesetref="admin" />
 +
        <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${str.xmlfile}" append="true" />
 +
 +
        <replace file="${str.xmlfile}" token="${str.sitetrunkpath}/" value="" />
 +
        <replace file="${str.xmlfile}" token="${str.admintrunkpath}/" value="" />
 +
    </target>
 +
 +
 +
    <macrodef name="echo-fileset" description="creates a printable directory listing">
 +
        <attribute name="filesetref" />
 +
        <sequential>
 +
            <pathconvert pathsep="&lt;/filename&gt;${line.separator}&lt;filename&gt;" property="@{filesetref}.echopath">
 +
                <path>
 +
                    <fileset refid="@{filesetref}" />
 +
                </path>
 +
            </pathconvert>
 +
            <echo message="${@{filesetref}.echopath}" file="${str.xmlfile}" append="true" />
 +
        </sequential>
 +
    </macrodef>
 +
 +
</project>
 +
</source>
 +
 +
[[Category:Development]]

Latest revision as of 06:10, 23 May 2013

Contents

Introduction

When software projects become large its is often helpful for developers to create build or make file that assists the developer to quickly "compile" new code. Although designed for Java the Apache Ant system can be used to create build files for Joomla developers, it is especially useful because it is installed by default in Eclipse, which is an IDE often used by Joomla! extension developers. Creating an Ant build file for your projects will greatly expedite the following frequent tasks.

Common tasks that can be scripted by an Ant build file

  1. Creating accurate xml manifest file lists
  2. Generating new Joomla install archives
  3. Updating development/debug server files
  4. Uploading new archives to release sites

Installing Ant

Ant is high portable software and can be installed on most systems. Please follow the instructions on the Apache Ant homepage. As mentioned previously if you are working in Eclipse Ant is installed by default.

For those who have Eclipse PDT Ganymede without ANT, should download the Java Development Tools (JDT) plugin. The JDT plugin could be downloaded by clicking Help > Software Updates > Ganymede Update Site > Java Development > Eclipse Java Development Tool and then Install button at right hand. Once its downloaded, restart Eclipse and then verify if ANT is properly installed by clicking Window > Preferences. If you see ANT (under General), it means ANT is successfully installed over Eclipse.

If Eclipse complain something like "No grammar constraints (DTD or XML schema) detected for the document.", then you will need to add minimal DTD. For example; <!DOCTYPE project> reference

Example Build Files

Example 1

<?xml version="1.0" encoding="UTF-8"?>
<project name="uncleocho" default="build" basedir=".">
        <description>Ant Build File for Joomla by Evan Fillman (mole84)</description>
 
        <!-- load variables from config file -->
        <property name="cfg.configFile" location="antconfig.txt" />
        <loadproperties srcfile="${cfg.configFile}" />
 
        <!--config file values
        cfg.name=paket
        cfg.versionDir=v1_50
        cfg.buildDir=packages
        cfg.localhostRoot=../../www
        cfg.xmlfile=files.txt
 
        ftp.server=
        ftp.user=
        ftp.password=
        ftp.dir=        
        -->
 
        <!-- auto values but should be checked -->
        <property name="cfg.comName" value="com_${cfg.name}" />
        <property name="cfg.comDir" value="${basedir}/${cfg.versionDir}/${cfg.comName}" />
        <property name="cfg.buildVersionDir" value="${cfg.buildDir}/${cfg.versionDir}" />
        <property name="cfg.adminFilesDir" location="${cfg.comDir}/admin" />
        <property name="cfg.siteFilesDir" location="${cfg.comDir}/site" />
        <property name="cfg.extensionsDir" location="${cfg.adminFilesDir}/extensions" />
 
        <target name="build" depends="clean, init, build_component, info" />
 
        <target name="init" description="creates nessecary directory to build with">
                <mkdir dir="${cfg.buildVersionDir}" />
                <mkdir dir="${cfg.buildVersionDir}/plugins" />
                <mkdir dir="${cfg.buildVersionDir}/modules" />
                <mkdir dir="${cfg.buildVersionDir}/components" />
                <mkdir dir="${cfg.extensionsDir}" />
        </target>
 
        <target name="build_component" depends="update_extensions" description="packages the finaly component file">
                <zip destfile="${cfg.buildVersionDir}/components/${cfg.comName}.zip" basedir="${cfg.comDir}" />
        </target>
 
        <target name="build_plugins" description="packages any plugins">
                <!-- add all plugin directories here -->
                <zip destfile="${cfg.buildVersionDir}/plugins/plg_uncleocho.zip" basedir="${cfg.versionDir}/plg_uncleocho" />
        </target>
 
        <target name="build_modules" description="packages any modules">
                <!-- add all module directories here -->
                <zip destfile="${cfg.buildVersionDir}/modules/mod_uncleocho.zip" basedir="${cfg.versionDir}/mod_uncleocho" />
        </target>
 
        <target name="build_debug" description="builds any debug plugins or code">
                <zip destfile="${cfg.buildVersionDir}/plugins/billets_plugin_toolbox.zip" basedir="${cfg.versionDir}/billets_plugin_toolbox" />
                <zip destfile="${cfg.buildVersionDir}/plugins/billets_plugin_debug.zip" basedir="${cfg.versionDir}/billets_plugin_debug" />
        </target>
 
        <target name="update_extensions" depends="build_plugins, build_modules" description="copies fresh builds of plugins and extensions to the admin/extensions folder">
                <copy todir="${cfg.extensionsDir}" overwrite="true">
                        <fileset dir="${cfg.buildVersionDir}/plugins" />
                </copy>
                <copy todir="${cfg.extensionsDir}" overwrite="true">
                        <fileset dir="${cfg.buildVersionDir}/modules" />
                </copy>
        </target>
 
        <target name="info" description="prints information">
                <echo message="Project:                 ${cfg.name}" />
                <tstamp>
                        <format property="buildtime" pattern="yyyy-MM-dd'T'HH:mm:ss" />
                </tstamp>
                <echo message="Buildtime:       ${buildtime}" />
        </target>
 
        <target name="clean" description="Destroys all generated files and dirs.">
                <delete dir="${cfg.buildVersionDir}" />
                <delete dir="packages" />
                <delete dir="${cfg.extensionsDir}" />
                <delete file="${cfg.xmlfile}" />
        </target>
 
        <target name="update_localhost" depends="info" description="attemps to update files on localhost server with files from working directory">
                <copy todir="${cfg.localhostRoot}/administrator/components/${cfg.comName}" overwrite="true">
                        <fileset dir="${cfg.adminFilesDir}" />
                </copy>
                <copy todir="${cfg.localhostRoot}/components/${cfg.comName}" overwrite="true">
                        <fileset dir="${cfg.siteFilesDir}" />
                </copy>
        </target>
 
        <target name="upload" description="attempts to upload build file to ftp server">
                <fileset id="ftp.upload.fileset" dir="${cfg.buildVersionDir}/components">
                        <include name="*.zip" />
                </fileset>
 
                <echo>FTP target is ${ftp.server}</echo>
                <ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.password}" action="put" remotedir="${ftp.dir}">
                        <fileset refid="ftp.upload.fileset" />
                </ftp>
        </target>
 
        <target name="build_xml" description="builds an xml listing of all the files in the working copy">
                <fileset id="site" dir="${cfg.siteFilesDir}" />
                <echo message="${line.separator}&lt;files folder=&quot;site&quot;&gt;${line.separator}&lt;filename&gt;" file="${cfg.xmlfile}" append="false" />
                <echo-fileset filesetref="site" />
                <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${cfg.xmlfile}" append="true" />
 
                <fileset id="admin" dir="${cfg.adminFilesDir}" />
                <echo message="${line.separator}&lt;files folder=&quot;admin&quot;&gt;${line.separator}&lt;filename&gt;" file="${cfg.xmlfile}" append="true" />
                <echo-fileset filesetref="admin" />
                <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${cfg.xmlfile}" append="true" />
 
                <replace file="${cfg.xmlfile}" token="${cfg.siteFilesDir}/" value="" />
                <replace file="${cfg.xmlfile}" token="${cfg.adminFilesDir}/" value="" />
        </target>
 
        <macrodef name="echo-fileset" description="creates a printable directory listing">
                <attribute name="filesetref" />
                <sequential>
                        <pathconvert pathsep="&lt;/filename&gt;${line.separator}&lt;filename&gt;" property="@{filesetref}.echopath">
                                <path>
                                        <fileset refid="@{filesetref}" />
                                </path>
                        </pathconvert>
                        <echo message="${@{filesetref}.echopath}" file="${cfg.xmlfile}" append="true" />
                </sequential>
        </macrodef>
</project>

Config File to Accompany Build File

cfg.name=uncleocho
cfg.versionDir=v1_50
cfg.buildDir=packages
cfg.localhostRoot=../../www
cfg.xmlfile=files.txt
 
ftp.server=
ftp.user=
ftp.password=
ftp.dir=

Example 2

Anohter one, a bit less and a bit more.

<!DOCTYPE project> <!-- For Eclipse -->
<project name="People Actions" default="update_local" basedir=".">
    <description>Ant Build File for Joomla! extensions</description>
 
    <!-- The name of your extension's main XML file -->
    <property name="cfg.name" value="peopleactions" />
    <!-- Prefix, eg com, bot, mod, or a brand name (or empty) -->
    <property name="cfg.prefix" value="com_" />
    <!-- Relative path to your project -->
    <property name="cfg.dir" value="../trunk/component" />
    <!-- Relative path to store the packages -->
    <property name="cfg.packages" value="../packages" />
    <!-- Absolute path to local server -->
    <property name="cfg.serverpath" value="C:\Users\Ruben\Documents\Dev\Projects\Joomla\joomla-base\2.5" />
 
    <target name="init" >
        <xmlproperty file="${cfg.dir}/${cfg.name}.xml" collapseAttributes="true" prefix="xml" keepRoot="false" />
        <buildnumber/>
        <tstamp>
            <format property="TODAY" pattern="yyyy-MM-dd"/>
        </tstamp>
 
        <property name="str.version" value="_v${xml.version}.${build.number}" />
        <property name="str.destfile" value="${cfg.packages}/${cfg.prefix}${cfg.name}${str.version}_${TODAY}" />
        <property name="str.sitetrunkpath" value="${cfg.dir}/site" />
        <property name="str.admintrunkpath" value="${cfg.dir}/admin" />
        <property name="str.xmlfile" value="${cfg.dir}/${cfg.name}test.xml" />
    </target>
 
    <target name="info" depends="init" description="prints information">
        <echo message="${cfg.name} - ${str.version} - ${ant.version}" />
    </target>
 
    <target name="update_local" depends="info, init" description="attemps to update files on localhost server">
        <copy todir="${cfg.serverpath}/components/${cfg.prefix}${cfg.name}">
            <fileset dir="${str.sitetrunkpath}" excludes="/language/" />
        </copy>
        <copy todir="${cfg.serverpath}/language/">
            <fileset dir="${str.sitetrunkpath}/language/" />
        </copy>
        <copy todir="${cfg.serverpath}/administrator/components/${cfg.prefix}${cfg.name}">
            <fileset file="${cfg.dir}/${cfg.name}.xml" />
            <fileset dir="${str.admintrunkpath}" excludes="/language/" />
        </copy>
        <copy todir="${cfg.serverpath}/administrator/language/">
            <fileset dir="${str.admintrunkpath}/language/" />
        </copy>
        <copy todir="${cfg.serverpath}/media/${cfg.prefix}${cfg.name}/">
    <fileset dir="${cfg.dir}/media/" />
        </copy>
    </target>
 
    <target name="zip" depends="info" description="Makes an uploadable zip package">
        <mkdir dir="${cfg.packages}" />
        <zip
            destfile="${str.destfile}.zip"
            basedir="${cfg.dir}" />
    </target>
 
 
    <target name="build_xml" depends="info" description="builds an xml listing of all the files in trunk">
        <fileset id="site" dir="${str.sitetrunkpath}" />
        <echo message="${line.separator}&lt;files folder=&quot;site&quot;&gt;${line.separator}&lt;filename&gt;" file="${str.xmlfile}" append="false" />
        <echo-fileset filesetref="site" />
        <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${str.xmlfile}" append="true" />
 
        <fileset id="admin" dir="${str.admintrunkpath}" />
        <echo message="${line.separator}&lt;files folder=&quot;admin&quot;&gt;${line.separator}&lt;filename&gt;" file="${str.xmlfile}" append="true" />
        <echo-fileset filesetref="admin" />
        <echo message="&lt;/filename&gt;${line.separator}&lt;/files&gt;${line.separator}" file="${str.xmlfile}" append="true" />
 
        <replace file="${str.xmlfile}" token="${str.sitetrunkpath}/" value="" />
        <replace file="${str.xmlfile}" token="${str.admintrunkpath}/" value="" />
    </target>
 
 
    <macrodef name="echo-fileset" description="creates a printable directory listing">
        <attribute name="filesetref" />
        <sequential>
            <pathconvert pathsep="&lt;/filename&gt;${line.separator}&lt;filename&gt;" property="@{filesetref}.echopath">
                <path>
                    <fileset refid="@{filesetref}" />
                </path>
            </pathconvert>
            <echo message="${@{filesetref}.echopath}" file="${str.xmlfile}" append="true" />
        </sequential>
    </macrodef>
 
</project>