ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Matt Lyon" <m...@stargus.com>
Subject RE: Automated source config model?
Date Wed, 04 Sep 2002 21:18:44 GMT
Matt,
 
Thanks for the information. What I don't understand about your approach is how the foreach
task in your checkout target can pass a param to the propertycopy task to define the value
which it is supposed to then associate with the matching property value in from the propfile
to create a new property. Specifically, I'm referring to
 
  <!-- targets to check out the souce code from cvs --> 
  <target name="checkout" depends="init" 
          description="checks out tagged directories listed in the propfile"> 
    <record name="${cvslogfile}" append="true" action="start"/> 
    <foreach list="${components}" target="checkout-dirs" param="component"/>
                                                                                         
                                     ^
    <antcall target="checkout-build" inheritAll="true"/> 
    <record name="${cvslogfile}" action="stop"/> 
  </target> 
 
and 

  <target name="checkout-dirs"> 
    <propertycopy name="complist" from="${component}.dirs"/>
                                                         ^
    <propertycopy name="comptag" from="${component}.tag" silent="true"/> 
    <foreach list="${complist}" target="checkout-dir" param="ckout.pkg"/> 
  </target> 
 
There's probably a really simple explanation, but I'm missing something conceptually here.
If I try something similar my build bombs out because the value of ${component.dirs} is not
defined for the checkout-dirs target. Is this due to property immutability holes being plugged
in Ant 1.5?
 
Matt

-----Original Message-----
From: McHenry, Matt [mailto:mmchenry@carnegielearning.com]
Sent: Tuesday, September 03, 2002 5:07 PM
To: Matt Lyon
Cc: Ant Users List
Subject: RE: Automated source config model?



> Thanks for the information. I would be interested in seeing how you implemented what
you have if > you can give me a high level view without ruffling any feathers. Thanks.

        Okay, here's an example java properties file that defines a set of deliverables built
from several components, each checked out from CVS with a different tag.

        (This is a bit more than what you want, as it's geared towards checking out into a
sandbox directory where the build happens, then collecting all the deliverables into a holding
directory so that the installer project can find them.)


#the deliverable files 
deliverables.files=dist/lib1.jar,dist/lib2.jar 

#you can also specify entire directories 
#deliverables.dirs 

#the list of components -- details of each are specified below 
components=platform,ui,content 

#the buildfile 
build.file=build.xml 
build.file.tag=BUILDFILE_03 
build.dir=src 
build.target=jars 

#the tag for the 'platform' component 
platform.tag=PLATFORM_17 
#the directories under CVS covered by that tag 
platform.dirs=src/platform,src/foo 

#the tag for the 'ui' component 
ui.tag=UI_08 
#the directories under CVS covered by that tag 
ui.dirs=src/ui,src/util 

#leave the tag undefined to check out 
#to the edge of the main trunk 
#content.tag= 
content.dirs=content/site1,content/site1,content/site3 

        The following ant project will process this sort of properties file.  You can just
use the 'checkout' target to pull stuff from CVS, or if you also want to build according to
the build.* properties, you can use the 'call-build' or 'copy-delivs' targets.


<project name="cvsbuild" default="copy-delivs" basedir="."> 

  <!-- This ant file defines targets used to check out code and a 
  build file from CVS, call a target in that build file, and copy the 
  deliverables created by that build file into a deliverables 
  directory.  The build file can also be left out if all of the 
  deliverables are retrieved directly from CVS.  This is useful for 
  e.g. straight text files, or third-party binaries. 

  When using this ant file, the property 'propfile' must be defined on 
  the command line (e.g. ant -Dpropfile=java-tags.txt).  This property 
  is the name of an ant properties file.  The propfile is basically a 
  list of CVS modules, and tags corresponding to one or more of the 
  modules. 

  For a given tagged module, two properties should be defined: 
   <module>.tag: the cvs tag for this module 
   <module>.dirs: a comma-separated list of directories which make up 
                  this module 
  The <module>.tag property may be left undefined, in which case the 
  module will be checked out to the edge of the tree. 

  The propfile must define the following special property: 
   components: a comma-separated list of the <module> tags to be used 
               in the build. 

  At least one of these two properties must be defined as well: 
   deliverables.files: a comma-separated list of paths to individual 
                       deliverable files (typically .zip files) 
   deliverables.dirs: a comma-separated list of paths to deliverable 
                      directories.  This is used to pull an entire 
                      directory out of CVS into the deliverables 
                      directory. 

  If the deliverables must be constructed via a buildfile, the 
  propfile should define the following four special properties: 
   build.file: the name of the ant build file for this project.  The 
               path to this file is constructed as 
               ${build.dir}/${build.file}. 
   build.dir: the base directory to use when calling ant using 
              ${build.file}. 
   build.target: the name of the target (defined in ${build.file}) to 
                 build 
   build.file.tag: the cvs tag to use when checking out the build 
                   file. 
  The build.file.tag property may be left undefined, in which case the 
  build file will be checked out to the edge of the tree. 

  This ant file also defines a target to tag the modules listed in a 
  propfile.  Typically this is used once a build (the copy-delivs 
  target) has succeeded to mark the source code as stable & as part of 
  whatever release is being built. 

  --> 

  <taskdef name="foreach" 
           classname="org.apache.tools.ant.taskdefs.optional.ForEach"/> 
  <taskdef name="propertycopy" 
           classname="org.apache.tools.ant.taskdefs.optional.PropertyCopy"/> 

  <!-- the temporary directory where we'll check out the modules --> 
  <property name="cvstree" value="${basedir}/cvstree"/> 

  <!-- the directory where the deliverables will be stored --> 
  <property name="deliv.dir" value="${basedir}/deliv"/> 

  <!-- file where cvs actions are logged --> 
  <property name="cvslogfile" value="cvslog"/> 

  <!-- file where the results of building target ${build.target} in 
  ${build.file} are logged --> 
  <property name="buildlogfile" value="buildlog"/> 

  <!-- load in the properties from the propfile --> 
  <property file="${propfile}"/> 


  <target name="check-for-tagname" unless="tagname" 
          description="checks that the 'tagname' property has been defined"> 
    <echo message="You must define the 'tagname' property on the command line.  For example:"/>

    <echo message="   ant -Dtagname=STABLE_2002"/> 
    <fail message="The 'tagname' property has not been defined."/> 
  </target> 

  <target name="check-for-propfile" 
          description="checks that the file 'propfile' exists"> 
    <available file="${propfile}" type="file" property="propfile-ok"/> 
    <antcall target="fail-no-propfile"/> 
  </target> 

  <target name="fail-no-propfile" unless="propfile-ok" 
          description="presents an error message to the user if 'propfile' is invalid">

    <echo message="You must define the 'propfile' property on the command line.  For example:"/>

    <echo message="   ant -Dpropfile=tags.txt"/> 
    <echo message="will build according to the tags in the file tags.txt"/> 
    <fail message="The 'propfile' property has not been defined, or points to a non-existent
file."/> 
  </target> 

  <target name="init" depends="check-for-propfile"> 
    <mkdir dir="${cvstree}"/> 
  </target> 


  <!-- targets to check out the souce code from cvs --> 
  <target name="checkout" depends="init" 
          description="checks out tagged directories listed in the propfile"> 
    <record name="${cvslogfile}" append="true" action="start"/> 
    <foreach list="${components}" target="checkout-dirs" param="component"/> 
    <antcall target="checkout-build" inheritAll="true"/> 
    <record name="${cvslogfile}" action="stop"/> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the checkout wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="checkout-build" if="build.file"> 
    <propertycopy name="comptag" from="build.file.tag" silent="true"/> 
    <antcall target="checkout-dir" inheritAll="true"> 
      <param name="ckout.pkg" value="${build.dir}/${build.file}"/> 
    </antcall> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the checkout wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="checkout-dirs"> 
    <propertycopy name="complist" from="${component}.dirs"/> 
    <propertycopy name="comptag" from="${component}.tag" silent="true"/> 
    <foreach list="${complist}" target="checkout-dir" param="ckout.pkg"/> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the checkout-dirs wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="checkout-dir-tag" if="comptag"> 
    <echo message="checking out ${ckout.pkg} with tag ${comptag}"/> 
    <cvs dest="${cvstree}" quiet="true" failonerror="true" 
         command="checkout -P -r ${comptag} &quot;${ckout.pkg}&quot;"/> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the checkout-dirs wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="checkout-dir-notag" unless="comptag"> 
    <echo message="NOTE: no tag defined for ${ckout.pkg}; checking out to edge of tree"/>

    <cvs dest="${cvstree}" quiet="true" failonerror="true" 
         command="checkout -PA &quot;${ckout.pkg}&quot;"/> 
  </target> 

  <target name="checkout-dir" depends="checkout-dir-tag,checkout-dir-notag"/> 


  <!-- targets to tag the souce code in cvs --> 
  <target name="tag" depends="init,check-for-tagname" 
          description="tags directories listed in the propfile"> 
    <record name="${cvslogfile}" append="true" action="start"/> 
    <foreach list="${components}" target="tag-dirs" param="component"/> 
    <antcall target="tag-build" inheritAll="true"/> 
    <record name="${cvslogfile}" action="stop"/> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the tag wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="tag-build" if="build.file"> 
    <antcall target="tag-dir" inheritAll="true"> 
      <param name="ckout.pkg" value="${build.dir}/${build.file}"/> 
    </antcall> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the tag wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="tag-dirs"> 
    <propertycopy name="complist" from="${component}.dirs"/> 
    <foreach list="${complist}" target="tag-dir" param="ckout.pkg"/> 
  </target> 

  <!-- WARNING: this depends on init, but it should only be called by 
  the tag-dirs wrapper task, so we're going to leave the explicit 
  dependency off for efficiency --> 
  <target name="tag-dir"> 
    <echo message="tagging ${ckout.pkg} with tag ${tagname}"/> 
    <cvs dest="${cvstree}" quiet="true" failonerror="true" 
         command="tag -F ${tagname} &quot;${ckout.pkg}&quot;"/> 
  </target> 


  <!-- a target to call out to the build.xml we've gotten out of CVS --> 
  <target name="call-build-bf" depends="init,checkout" if="build.file" 
          description="executes the selected target on the checked-out build file"> 
    <record name="${buildlogfile}" append="true" action="start"/> 
    <echo message="calling target ${build.target} in buildfile ${build.dir}/${build.file}"/>

    <ant antfile="${build.file}" dir="${cvstree}/${build.dir}" target="${build.target}"
inheritAll="false"/> 
    <record name="${buildlogfile}" action="stop"/> 
  </target> 

  <target name="call-build-nobf" unless="build.file" 
          description="makes a note in the log file that no build file is being called">

    <echo message="NOTE: No build file is defined, so no call to it is being made."/>

    <echo message="      Deliverables are assumed to have been checked out directly from
CVS."/> 
  </target> 

  <target name="call-build" depends="call-build-bf,call-build-nobf" 
          description="meta-target to call out to a build file, if one is defined"/> 

  <!-- targets to copy the deliverables to where they belong --> 
  <target name="init-deliv" description="creates the 'deliv.dir' directory"> 
    <mkdir dir="${deliv.dir}"/> 
  </target> 

  <target name="copy-delivs" depends="call-build,init-deliv,copy-deliv-files,copy-deliv-dirs"

          description="meta-target to copy the deliverables"/> 

  <target name="copy-deliv-files" if="deliverables.files" 
          description="copies each of the deliverable files"> 
    <foreach list="${deliverables.files}" target="copy-deliv-file" param="deliv"/> 
  </target> 

  <target name="copy-deliv-dirs" if="deliverables.dirs" 
          description="copies each of the deliverable directories"> 
    <foreach list="${deliverables.dirs}" target="copy-deliv-dir" param="deliv"/> 
  </target> 

  <target name="copy-deliv-file"> 
    <echo message="copying deliverable file(s): ${deliv}"/> 
    <copy todir="${deliv.dir}" flatten="true"> 
      <fileset dir="${cvstree}"> 
        <include name="${deliv}"/> 
      </fileset> 
    </copy> 
  </target> 

  <target name="copy-deliv-dir"> 
    <echo message="copying deliverable dir(s): ${deliv}"/> 
    <copy todir="${deliv.dir}/${deliv}" flatten="false"> 
      <fileset dir="${cvstree}/${deliv}"/> 
    </copy> 
  </target> 


  <!-- housekeeping targets --> 
  <target name="clean-comps" depends="init" 
          description="removes all checked-out components from the temporary cvs tree, including
the build file"> 
    <foreach list="${components}" target="clean-dirs" param="component"/> 
    <antcall target="clean-buildfile" inheritAll="true"/> 
  </target> 

  <target name="clean-buildfile" 
          description="removes the checked-out build file"> 
    <echo message="deleting file ${build.dir}/${build.file}"/> 
    <delete file="${cvstree}/${build.dir}/${build.file}"/> 
  </target> 

  <target name="clean-dirs"> 
    <propertycopy name="complist" from="${component}.dirs"/> 
    <foreach list="${complist}" target="clean-dir-or-file" param="clean.pkg"/> 
  </target> 

  <target name="decide-dir-or-file"> 
    <available file="${cvstree}/${clean.pkg}" type="dir" property="tgt-is-dir"/> 
  </target> 

  <target name="clean-dir" if="tgt-is-dir"> 
    <echo message="deleting directory ${clean.pkg}"/> 
    <delete dir="${cvstree}/${clean.pkg}"/> 
  </target> 

  <target name="clean-file" unless="tgt-is-dir"> 
    <echo message="deleting file ${clean.pkg}"/> 
    <delete file="${cvstree}/${clean.pkg}"/> 
  </target> 

  <target name="clean-dir-or-file" depends="decide-dir-or-file,clean-dir,clean-file"/>


  <target name="clean-delivs-dirs" if="deliverables.dirs"> 
    <foreach list="${deliverables.dirs}" target="clean-delivs-dir" param="dir"/> 
  </target> 

  <target name="clean-delivs-dir"> 
    <echo message="deleting dir ${dir}"/> 
    <delete dir="${cvstree}/${dir}"/> 
  </target> 

  <target name="clean-delivs-files" if="deliverables.files"> 
    <foreach list="${deliverables.files}" target="clean-delivs-file" param="file"/>

  </target> 

  <target name="clean-delivs-file"> 
    <echo message="deleting file ${file}"/> 
    <delete dir="${cvstree}/${file}"/> 
  </target> 

  <target name="clean-delivs" depends="init,clean-delivs-dirs,clean-delivs-files" 
          description="removes all deliverables from the temporary cvs tree"/> 

  <target name="clean" description="removes the entire temp cvs tree"> 
    <delete dir="${cvstree}"/> 
  </target> 

</project> 


Matt McHenry 
Software Developer 
Carnegie Learning 
(412)690-2442 x150 


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message