buildframework/helium/doc/src/development/developer_guide.rst
changeset 628 7c4a911dc066
parent 588 c7c26511138f
child 645 b8d81fa19e7d
equal deleted inserted replaced
588:c7c26511138f 628:7c4a911dc066
    61     A number of subdirectories for each stage of the build. Each directory may contain Ant scripts and other tools and scripts related to that stage.
    61     A number of subdirectories for each stage of the build. Each directory may contain Ant scripts and other tools and scripts related to that stage.
    62 
    62 
    63 ``/tools/common``
    63 ``/tools/common``
    64     Common libraries for Java, Perl and Python and XML schemas.
    64     Common libraries for Java, Perl and Python and XML schemas.
    65     
    65     
       
    66 Anatomy of a library project
       
    67 ----------------------------
       
    68 
       
    69 ::
       
    70    
       
    71    + builder
       
    72       - build.xml
       
    73       - bld.bat
       
    74       - bld
       
    75       + antlibs
       
    76          Ant specific dependencies needed to execute ant properly
       
    77          e.g: Java checkstyle, Code coverage tools
       
    78          The jar in that folder will not be used as compilation dependencies
       
    79    + <layer>
       
    80        + doc
       
    81           General documentation of the project
       
    82        + settings
       
    83           + ivysettings.xml
       
    84        + deps
       
    85           + <org>
       
    86              + <name>
       
    87                 + <rev>
       
    88                    - <name>-<rev>.jar
       
    89           + ...
       
    90        + java
       
    91           + component1
       
    92           + componentn ...
       
    93        + python
       
    94           + component1
       
    95           + componentn ...
       
    96    + <layer> ...
    66 
    97 
    67 Ant script structure
    98 Ant script structure
    68 --------------------
    99 --------------------
    69 
   100 
    70 The ``helium.ant.xml`` file in the project root should be imported by each build configuration. This in turn imports the root files for each of the key build stages defined in the ``/tools`` directory. ``helium.ant.xml`` also defines a number of common Ant default properties.
   101 The ``helium.ant.xml`` file in the project root should be imported by each build configuration. This in turn imports the root files for each of the key build stages defined in the ``/tools`` directory. ``helium.ant.xml`` also defines a number of common Ant default properties.
    71 
   102 
    72 
   103 
    73 .. index::
   104 .. index::
    74   single: Custom Ant library
   105   single: Custom Ant libraries
    75 
   106 
    76 Custom Ant libraries
   107 Custom Ant libraries
    77 ====================
   108 ====================
    78 
   109 
    79 All custom Ant tasks, types and loggers should be added as new components under the ``/sf`` folder. If the component being created is Java-based, then add it inside the ``/java`` folder. The component directory must contain a ``build.xml`` file that imports ``${builder.dir}/java/macros.ant.xml``. Also the name of the project must be the name of the future JAR file e.g::
   110 All custom Ant tasks, types and loggers should be added as new components under the ``/sf`` folder. If the component being created is Java-based, then add it inside the ``/java`` folder. The component directory must contain a ``build.xml`` file that imports ``${builder.dir}/java/macros.ant.xml``. Also the name of the project must be the name of the future JAR file e.g::
    83        <import file="${builder.dir}/java/macros.ant.xml" />
   114        <import file="${builder.dir}/java/macros.ant.xml" />
    84    </project> 
   115    </project> 
    85 
   116 
    86 The component also need an Ivy file (``ivy.xml``) in order to be detected and built. The file must define the correct list of dependencies for the component so it get built in the correct order.
   117 The component also need an Ivy file (``ivy.xml``) in order to be detected and built. The file must define the correct list of dependencies for the component so it get built in the correct order.
    87 
   118 
       
   119 Structure
       
   120 ---------
       
   121 
       
   122 A component is a self contained structure which implements a set of feature related to a specific domain (e.g: Diamonds, SCM). The following diagram shows 
       
   123 the physical structure of a component.
       
   124 
       
   125 ::
       
   126    
       
   127    + <component_name>
       
   128          - build.xml
       
   129          - ivy.xml
       
   130          + src
       
   131             + com
       
   132                + nokia
       
   133                    + helium
       
   134                       + <component_name>
       
   135                           + ant
       
   136                              + taskdefs
       
   137                                source of the Ant tasks
       
   138                              + types
       
   139                                source of the Ant DataType 
       
   140                              + listeners
       
   141                                source of the Ant Listener
       
   142                              + conditions
       
   143                                source of the Ant Conditions
       
   144          + tests
       
   145            - build.xml
       
   146            - bld.bat
       
   147            - bld.sh
       
   148            + antunits
       
   149               - test_xxx.ant.xml* - Unittest implemented using AntUnit  
       
   150            + data
       
   151              data used for the the unittests.
       
   152            + src
       
   153              + com
       
   154                 + nokia
       
   155                    + helium
       
   156                       + <component_name>
       
   157                          + tests
       
   158                             source of junit unittests.
       
   159 
       
   160 build.xml file
       
   161 --------------
       
   162 
       
   163 This is the simplest file you must have at component level, ``<name of the component>`` is really important
       
   164 as it defines the future name of the JAR file.
       
   165 ::
       
   166    
       
   167    <project name="<name of the component>">
       
   168        <description>Component build file.</description>
       
   169        <import file="../../builder/java/macros.ant.xml"/>
       
   170    </project>
       
   171 
       
   172 ivy.xml file
       
   173 ------------
       
   174 
       
   175 The ``ivy.xml`` file is used to gather the relevant dependencies to build your component and to order
       
   176 the build of the components correctly::
       
   177     
       
   178    <?xml version="1.0" encoding="ISO-8859-1"?>
       
   179    <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       
   180           xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
       
   181        <info
       
   182           organisation="com.nokia.helium"
       
   183            module="<name of the component>"
       
   184            status="integration">
       
   185        </info>
       
   186        <dependencies>
       
   187           <dependency name="<name of an another component>" rev="latest.integration" conf="default" />
       
   188           <dependency org="dom4j" name="dom4j" rev="1.2.9" conf="default" />
       
   189        </dependencies>
       
   190    </ivy-module>
       
   191    
       
   192 More info about Ivy can be found from: http://ant.apache.org/ivy/
       
   193 
       
   194 AntUnit files
       
   195 -------------
       
   196 
       
   197 The builder will automatically test all the AntUnit files from ``<component>/tests/antunit``.
       
   198 Test must be written by keeping in mind that source tree must remain unmodified after the testing (please use the ``test.temp.dir``).
       
   199 
       
   200 Test file example::
       
   201    
       
   202    <project name="test-<component>-<feature>" xmlns:au="antlib:org.apache.ant.antunit" xmlns:hlm="http://www.nokia.com/helium">
       
   203       <description>Helium unittests.</description>
       
   204    
       
   205       <target name="setUp">
       
   206          <delete dir="${test.temp.dir}" failonerror="false" />
       
   207          <mkdir dir="${test.temp.dir}" />
       
   208       </target>
       
   209 
       
   210       <target name="tearDown">
       
   211          <delete dir="${test.temp.dir}" failonerror="false" />
       
   212          <mkdir dir="${test.temp.dir}" />
       
   213       </target>
       
   214       
       
   215       <target name="test-file-generation">
       
   216          <echo message="foo-bar" file="${test.temp.dir}/demo.txt" />
       
   217          <au:assertFileExists file="${test.temp.dir}/demo.txt" />
       
   218       </target>
       
   219    </project>
       
   220 
       
   221 Source code license
       
   222 -------------------
       
   223 
       
   224 Each file should include the following license header::
       
   225    
       
   226    /*
       
   227     * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
   228     * All rights reserved.
       
   229     * This component and the accompanying materials are made available
       
   230     * under the terms of the License "Eclipse Public License v1.0"
       
   231     * which accompanies this distribution, and is available
       
   232     * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
   233     *
       
   234     * Initial Contributors:
       
   235     * Nokia Corporation - initial contribution.
       
   236     *
       
   237     * Contributors:
       
   238     *
       
   239     * Description:  
       
   240     *
       
   241     */
       
   242 
       
   243 Documentation
       
   244 -------------
       
   245 
       
   246 All classes and methods must be documented.
       
   247 Ant facade classes like task or type must be doclet documented. This implies the javadoc
       
   248 to be user and not developer oriented, for instance examples of the task/type usage are really appreciated.
       
   249 Also all setter methods visible through Ant must be documented properly using *@ant.required* 
       
   250 or *@ant.not-required* javadoc style attributes.
       
   251 
       
   252 You can find more information on how to document Ant tasks using the doclet plugin on http://doclet.neuroning.com/. 
       
   253 
       
   254 General coding guidelines
       
   255 -------------------------
       
   256 
       
   257  * Java components must not use ``getProperty()`` with a hardcoded name coming from helium (e.g.: ``getProject().getProperty("helium.dir"))`` The only exceptions to this are:
       
   258     * Ant listeners (the name of the property must be linked to the listener not to Helium!)
       
   259     * Code under the legacy component.
       
   260  * It is forbidden to share unittest data between components (else it breaks the "self-contained" principle).
       
   261 
       
   262 
       
   263 Ant type and task guidelines
       
   264 ----------------------------
       
   265 
       
   266 In order to match as must as  configurability concepts, Helium custom types and tasks must follow  development guidelines as 
       
   267 much as possible. You can find then on http://.apache.org/_task_guidelines.html.
       
   268 
       
   269 Logging
       
   270 -------
       
   271 
       
   272 Developer must preferably use standard Ant logging for any user log output.
       
   273 Internal debug logging must be implemented using the log4j framework.
       
   274 
       
   275  * ANT Listeners must use log4j logging framework - using Ant logging system might cause some looping issues.
       
   276  * Ant ``Type`` and ``Task`` classes must use the Ant logging mechanism to report to the user.
       
   277  * Generic framework code (that which doesn't link to Ant directly) must use log4j. 
       
   278  * Usage of ``System.out.println()`` should be avoided.
       
   279  * All the unhandled exceptions should be considered as errors and should be reported as such:
       
   280     * use ``log("message", Project.MSG_ERR)`` under Ant.
       
   281     * ``log.error()`` otherwise.
       
   282     * Exceptions to this rule must be clearly commented under the code.
       
   283  * Debug information:
       
   284     * log4j framework (``log.debug()``) must be used to push information to the Helium debug log - so debug information is not
       
   285       directly visible by the user.
       
   286     * The Ant logging framework can also be used to log Type/Task debug info (but log4j is preferred).
       
   287     * The ``printStackTrace()`` method should be used on below scenarios:
       
   288        * At the time of an unknown exception.
       
   289        * Should be used with exceptions other than ``BuildException``.
       
   290        * In case it is difficult to debug the issue with ``Exception.getMessage()``.
       
   291        * Use when debugging complex issues (this doesn't mean the line should remain in the code after development).
       
   292        * When it is required to print the all the information about the occurring ``Exception``. 
       
   293 
       
   294 
       
   295 This is an example on how to use logging::
       
   296    
       
   297    import org.apache.log4j.Logger;
       
   298    
       
   299    class MyClass extends Task {
       
   300        private static Logger log = Logger.getLogger(MyClass.class);
       
   301        
       
   302        public void execute() {
       
   303            log("Executing...");
       
   304            log.debug("some useful debug information.");
       
   305        }
       
   306    }
       
   307 
       
   308 Please find more information on log4j from the online manual: http://logging.apache.org/log4j/1.2/manual.html.
       
   309 
       
   310 Debug log
       
   311 ``````````
       
   312 
       
   313 The log4j debug output is written to ``hlm_debug.log`` that is stored under ``HELIUM_CACHE_DIR``. This may be set one of these two values::
       
   314 
       
   315     %TEMP%\helium\%USERNAME%\%JOB_ID%
       
   316     %TEMP%\helium\%USERNAME%
       
   317     
       
   318 Ensure ``TEMP`` is set to a location that is visible to all so the file can be accessed from all accounts.
       
   319 
       
   320 Exceptions
       
   321 ----------
       
   322 
       
   323 Exceptional event reporting and handling is crutial in software development. Developer must make sure it is done accordingly
       
   324 to the framework it is currently using:
       
   325 
       
   326  * To report a build failure under Ant a ``BuildException`` must be used.
       
   327     But we have to keep in mind that a ``BuildException`` is not tracked because it derives from ``RuntimeException``.
       
   328     So we have to be careful with those and try to limit their puprose to the original usage: Ant build failure.
       
   329  * It is preferable to use a meaningful exception type like ``FileNotFoundException``.
       
   330  * Throwing or catching raw exceptions like ``Exception``, ``RuntimeException`` should be avoided.  
       
   331  
       
   332 Deprecation
       
   333 -----------
       
   334 
       
   335 Deprecation is an inevitable in involving software. The usage of deprecation implies most of the time the replacement of a feature 
       
   336 by an newer. To make sure it has the minimum impact on the user, we need to provide both features for at least one major release, so 
       
   337 the customer has time to do the relevant modification to migrate. In order to ease as much as possible the deployment and the migration
       
   338 to a newer version of any Ant object please follow this guidelines:
       
   339  
       
   340  * Ant attributes replacement
       
   341     * Use the @Deprecated annotation on the Java code to make sure this method is not in use anymore under our code.
       
   342     * Log a warning message to the user using Ant logging. Please use the following template:
       
   343         * The usage of the '<deprecated_attribute_name>' attribute is deprecated, please consider using the '<new_attribute_name>' attribute.
       
   344     * Try to keep the functionality by adapting the code inside the deprecated setter to use the newer API.
       
   345     
       
   346 Example of Ant attribute deprecation for a Java task::
       
   347    
       
   348    @Deprecated
       
   349    public void setDb(File database) {
       
   350        log("The usage of the 'db' attribute is deprecated, please consider using the 'database' attribute.", Project.MSG_WARN);
       
   351        this.database = database;
       
   352    }
       
   353 
       
   354  
    88 .. index::
   355 .. index::
    89   single: How to build the delivery?
   356   single: How to build the delivery?
    90 
   357 
    91 How to build the delivery?
   358 How to build the delivery?
    92 ==========================   
   359 ==========================   
   194     helium/config/ivy/modules/eggs-1.0.ivy.xml
   461     helium/config/ivy/modules/eggs-1.0.ivy.xml
   195     helium/config/ivy/modules/jars-1.0.ivy.xml
   462     helium/config/ivy/modules/jars-1.0.ivy.xml
   196     
   463     
   197 A new Ivy config file can be added for a non-jar or egg type file.
   464 A new Ivy config file can be added for a non-jar or egg type file.
   198 
   465 
       
   466 
       
   467 Feature enable Configuration
       
   468 ============================
       
   469 
       
   470 If we are adding new features (which are similar to diamonds, coverage toosl), then those feature needs to enabled in the build sequence using 'feature.enabled' property.
       
   471 
       
   472 Using feature.enabled property we need to set intermediate property and that intermidiate property should have the name pattern as internal.feature.enabled.
       
   473 
       
   474 Intermidiate properties should be set using ant <condition> task. Do not use antcontrib <if> task (avoid as much as possible).
       
   475 
       
   476 We need to trigger the targets using intermidiate property. 
       
   477 
       
   478 Target based feature testing
       
   479 ----------------------------
       
   480 
       
   481 And depending target should be called using intermediate property.
       
   482 
       
   483 Ex::
       
   484     
       
   485     feature.enabled = true
       
   486     
       
   487     <condition property="internal.feature.enabled">
       
   488         <istrue value="${feature.enabled}"/>
       
   489     </condition>
       
   490     
       
   491     <target name="xyz" if="internal.feature.enabled"/>
       
   492     
       
   493 If any property is deprecated then that should be documented in the respective .ant.xml.
       
   494 
       
   495 Ex::
       
   496 
       
   497     <!-- Set to true to enable feature - deprecated: Start using feature.enabled property
       
   498     @type boolean
       
   499     @editable required
       
   500     @scope public
       
   501     @deprecated since 11.0 
       
   502     -->
       
   503     <property name="old.feature" value="true"/>
       
   504     
       
   505     feature.enabled = true
       
   506     old.feature = false
       
   507     
       
   508     <condition property="internal.feature.enabled">
       
   509         <or>
       
   510             <istrue value="${feature.enabled}"/>
       
   511             <isset property="old.feature"/>
       
   512         </or>
       
   513     </condition>
       
   514     
       
   515     <target name="xyz" if="internal.feature.enabled"/>
       
   516         
       
   517 
       
   518 Task base feature testing
       
   519 -------------------------
       
   520 
       
   521 If the if task is used inside a target it is then preferable to use the feature.enabled property directly:
       
   522 
       
   523 ::
       
   524    
       
   525    <target name="target-name">
       
   526        ...
       
   527        <if>
       
   528           <or>
       
   529               <istrue value="${feature.enabled}"/>
       
   530               <isset property="old.feature"/>          
       
   531           </or>
       
   532           <then>
       
   533               ...
       
   534           </then>
       
   535           ...
       
   536        </if>
       
   537        ...
       
   538    </target>
       
   539    
       
   540 
       
   541 Of course the 'old.feature' will be kept for one major release and removed in the next one.
       
   542