buildframework/helium/tools/relnotes/relnotes.ant.xml
changeset 307 22ecbfc20eb4
parent 217 0f5e3a7fb6af
child 587 85df38eb4012
equal deleted inserted replaced
215:b61c19d4168d 307:22ecbfc20eb4
    18 
    18 
    19 Description:
    19 Description:
    20 
    20 
    21 ============================================================================
    21 ============================================================================
    22 -->
    22 -->
       
    23 <!--* @package releases -->
    23 <project name="relnotes" default="release-notes" xmlns:hlm="http://www.nokia.com/helium">
    24 <project name="relnotes" default="release-notes" xmlns:hlm="http://www.nokia.com/helium">
    24     <description>
    25     <description>
    25     Generates a release note by modifying a template (that you can edit yourself) with
    26     Generates a release note by modifying a template (that you can edit yourself) with
    26     values from the build and Synergy.
    27     values from the build and Synergy.
    27     
    28     
    28     * Modifies a RTF template with values from build
    29     * Modifies a RTF template with values from build
    29     * Adds table of errors and warnings
    30     * Adds table of errors and warnings
    30     * Generates list of baselines, projects and tasks used
    31     * Generates list of baselines, projects and tasks used
    31     </description>
    32     </description>
    32 
    33     
       
    34     <!--* @property product.printname
       
    35     A printable name for a product used in release notes.
       
    36     @type string
       
    37     @editable required
       
    38     @scope public
       
    39     -->
       
    40     
       
    41     <!--* @property product.type
       
    42     Project ID in release notes.
       
    43     @type string
       
    44     @editable required
       
    45     @scope public
       
    46     -->
       
    47     
       
    48     <!--* @property relnotes.config.dir
       
    49     Defines the directory that contains release notes creation configuration files.
       
    50     @type string
       
    51     @editable required
       
    52     @scope public
       
    53     -->
       
    54 
       
    55     <!-- Defines the directory that will contain the output of release notes creation.
       
    56     @type string
       
    57     @scope private
       
    58     -->
    33     <property name="releasenotes.output.dir" value="${build.output.dir}/relnotes"/>
    59     <property name="releasenotes.output.dir" value="${build.output.dir}/relnotes"/>
       
    60     <!-- Defines the logo image file which will be used in release notes.
       
    61     @type string
       
    62     @scope private
       
    63     -->
    34     <property name="releasenotes.logo" value="${relnotes.config.dir}/logo.png"/>
    64     <property name="releasenotes.logo" value="${relnotes.config.dir}/logo.png"/>
       
    65     <!-- Property file with customer values
       
    66     @type string
       
    67     @scope private
       
    68     -->
    35     <property name="releasenotes.props" value="${relnotes.config.dir}/relnotes.properties"/>
    69     <property name="releasenotes.props" value="${relnotes.config.dir}/relnotes.properties"/>
       
    70     <!-- Temp file
       
    71     @type string
       
    72     @scope private
       
    73     -->
    36     <property name="releasenotes.temp.props" value="${temp.build.dir}/relnotes.properties"/>
    74     <property name="releasenotes.temp.props" value="${temp.build.dir}/relnotes.properties"/>
       
    75     <!-- Temp file
       
    76     @type string
       
    77     @scope private
       
    78     -->
    37     <property name="releasenotes.temp.props2" value="${temp.build.dir}/relnotes2.properties"/>
    79     <property name="releasenotes.temp.props2" value="${temp.build.dir}/relnotes2.properties"/>
       
    80     <!-- Defines the name of the release note template used.
       
    81     @type string
       
    82     @scope private
       
    83     -->
    38     <property name="releasenotes.template" value="${relnotes.config.dir}/template.rtf"/>
    84     <property name="releasenotes.template" value="${relnotes.config.dir}/template.rtf"/>
       
    85     <!-- Location of output rtf file
       
    86     @type string
       
    87     @scope private
       
    88     -->
    39     <property name="releasenotes.output" value="${releasenotes.output.dir}/${build.id}_relnotes.rtf"/>
    89     <property name="releasenotes.output" value="${releasenotes.output.dir}/${build.id}_relnotes.rtf"/>
       
    90     <!-- Temp file
       
    91     @type string
       
    92     @scope private
       
    93     -->
    40     <property name="releasenotes.temp.errors" value="${temp.build.dir}/errors.csv"/>
    94     <property name="releasenotes.temp.errors" value="${temp.build.dir}/errors.csv"/>
       
    95     <!-- Temp file
       
    96     @type string
       
    97     @scope private
       
    98     -->
    41     <property name="releasenotes.temp.output" value="${temp.build.dir}/tempDocument.rtf"/>
    99     <property name="releasenotes.temp.output" value="${temp.build.dir}/tempDocument.rtf"/>
       
   100     <!-- Location of scan2log HTML file
       
   101     @type string
       
   102     @scope private
       
   103     -->
    42     <property name="releasenotes.scan2log" value="${build.log.dir}/${build.id}.${product.family}_scan2.html"/>
   104     <property name="releasenotes.scan2log" value="${build.log.dir}/${build.id}.${product.family}_scan2.html"/>
    43     
   105     
    44     <import file="${relnotes.config.dir}/relnotes_properties.ant.xml" optional="true"/>
   106     <import file="${relnotes.config.dir}/relnotes_properties.ant.xml" optional="true"/>
    45     
   107     
    46     <!-- Private: -->
   108     <!-- @scope private -->
    47     <target name="release-notes-variant-configuration" depends="rombuild-prepare-input">
   109     <target name="release-notes-variant-configuration" depends="imaker-merge-rom-xml">
    48         
       
    49         <script language="jython" setbeans="false">
   110         <script language="jython" setbeans="false">
    50 tagnames = ""
   111 tagnames = ""
    51 for product in project.getProperty("product.list").split(","):
   112 for product in project.getProperty("product.list").split(","):
    52     tagnames += "Type%sVariantTableHere\n" %  product 
   113     tagnames += "Type%sVariantTableHere\n" %  product 
    53 project.setProperty("variant.product.tagnames", tagnames)
   114 project.setProperty("variant.product.tagnames", tagnames)
    54         </script>
   115         </script>
    55         <replace file="${releasenotes.output}" token="TypeVariantTableHere" value="${variant.product.tagnames}" summary="true"/>
   116         <replace file="${releasenotes.output}" token="TypeVariantTableHere" value="${variant.product.tagnames}" summary="true"/>
    56         <for list="${product.list}" delimiter="," param="product.name" >
   117         <for list="${product.list}" delimiter="," param="product.name" >
    57             <sequential>            
   118             <sequential>            
    58                 <exec executable="python" dir="${helium.dir}/tools/relnotes" failonerror="${failonerror}">
   119                 <exec executable="python" failonerror="${failonerror}">
    59                     <arg value="getVariantConfiguration.py"/>
   120                     <arg line="-m getVariantConfiguration"/>
    60                     <arg value="@{product.name}"/>
   121                     <arg value="@{product.name}"/>
    61                     <arg value="${localisation.language.file}"/>
       
    62                     <arg value="${rombuild.config.file.parsed}"/>
   122                     <arg value="${rombuild.config.file.parsed}"/>
    63                     <arg value="${temp.build.dir}/variant_@{product.name}.csv"/>
   123                     <arg value="${temp.build.dir}/variant_@{product.name}.csv"/>
    64                 </exec>
   124                 </exec>
    65                 <hlm:python>
   125                 <hlm:python>
    66 import ant
   126 import ant
    73                 <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
   133                 <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
    74             </sequential>
   134             </sequential>
    75         </for>
   135         </for>
    76     </target>
   136     </target>
    77     
   137     
    78     <!-- Private: Create error list in release notes -->
   138     <!-- Create error list in release notes
       
   139     @scope private    
       
   140     -->
    79     <target name="release-notes-error-summary">
   141     <target name="release-notes-error-summary">
    80         <exec executable="python" dir="${helium.dir}/tools/relnotes" failonerror="${failonerror}">
   142         <fmpp sourceFile="${helium.dir}/tools/relnotes/templates/errors.csv.ftl"
    81             <arg value="readHTML.py"/>
   143                      outputfile="${releasenotes.temp.errors}">
    82             <arg value="${releasenotes.scan2log}"/>
   144             <freemarkerLinks expandProperties="yes">
    83             <arg value="${releasenotes.temp.errors}"/>
   145                 macro: ${helium.dir}/tools/common/templates/macro
    84         </exec>
   146             </freemarkerLinks>
       
   147             <data expandProperties="yes">
       
   148                 dbPath: ${metadata.dbfile}
       
   149                 ant: antProperties()
       
   150             </data>
       
   151         </fmpp>
    85         <hlm:python>
   152         <hlm:python>
    86 import ant
   153 import ant
    87 import rtfutils
   154 import rtfutils
    88 rn = rtfutils.RTFUtils(ant.get_property(r'${releasenotes.output}'))
   155 rn = rtfutils.RTFUtils(ant.get_property(r'${releasenotes.output}'))
    89 rn.rtftable(ant.get_property(r'${releasenotes.temp.errors}'), ant.get_property(r'${releasenotes.temp.output}'), 'TypeErrorTableSummaryHere')
   156 rn.rtftable(ant.get_property(r'${releasenotes.temp.errors}'), ant.get_property(r'${releasenotes.temp.output}'), 'TypeErrorTableSummaryHere')
    90         </hlm:python>
   157         </hlm:python>
    91         <delete file="${releasenotes.output}"/>
   158         <delete file="${releasenotes.output}"/>
    92         <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
   159         <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
    93     </target>
   160     </target>
    94     
   161     
    95     <!-- Private: Add logo to release notes -->
   162     <!--  Add logo to release notes. @scope private -->
    96     <target name="release-notes-logo">
   163     <target name="release-notes-logo">
    97         <hlm:python>
   164         <hlm:python>
    98 import ant
   165 import ant
    99 import rtfutils
   166 import rtfutils
   100 rn = rtfutils.RTFUtils(ant.get_property(r'${releasenotes.output}'))
   167 rn = rtfutils.RTFUtils(ant.get_property(r'${releasenotes.output}'))
   101 rn.rtfimage(ant.get_property(r'${releasenotes.logo}'), ant.get_property(r'${releasenotes.temp.output}'), 'AddProductImageHere')
   168 rn.rtfimage(ant.get_property(r'${releasenotes.logo}'), ant.get_property(r'${releasenotes.temp.output}'), 'AddProductImageHere')
   102         </hlm:python>
   169         </hlm:python>
   103         <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
   170         <move file="${releasenotes.temp.output}" tofile="${releasenotes.output}"/>
   104     </target>
   171     </target>
   105     
   172     
   106     <!-- Private: Find project and baseline of what is running helium -->
   173     <!-- Find project and baseline of what is running helium
       
   174     @scope private    
       
   175     -->
   107     <target name="release-notes-getcmprojectname">
   176     <target name="release-notes-getcmprojectname">
   108         <script language="jython" setbeans="false">
   177         <if>
   109 import nokia.nokiaccm
   178             <istrue value="${ccm.enabled}" />
       
   179             <then>
       
   180                 <script language="jython" setbeans="false">
   110 import ccm.extra
   181 import ccm.extra
   111 import traceback
   182 import traceback
   112 import os
   183 import os
   113 import logging
   184 import logging
       
   185 import ccmutil
       
   186 
   114 #logging.basicConfig(level=logging.DEBUG)
   187 #logging.basicConfig(level=logging.DEBUG)
   115 session = None
   188 session = None
   116 try:
   189 try:
   117     database = project.getProperty('ccm.database')
   190     database = project.getProperty('ccm.database')
   118     username = project.getProperty('ccm.user.login')
   191     username = project.getProperty('ccm.user.login')
   119     password = project.getProperty('ccm.user.password')
   192     password = project.getProperty('ccm.user.password')
   120     engine = project.getProperty('ccm.engine.host')
   193     engine = project.getProperty('ccm.engine.host')
   121     dbpath = project.getProperty('ccm.database.path')     
   194     dbpath = project.getProperty('ccm.database.path')     
   122     waroot = project.getProperty('create.bom.workarea.root')
   195     waroot = project.getProperty('create.bom.workarea.root')
   123     if database != None:
   196     
   124         session = nokia.nokiaccm.open_session(username, password, database=database)
   197     session = ccmutil.get_session(database, username, password, engine, dbpath)
   125     else:
       
   126         session = nokia.nokiaccm.open_session(username, password, engine, dbpath)
       
   127         
       
   128     cmproject = ccm.extra.get_toplevel_project(session, waroot)
   198     cmproject = ccm.extra.get_toplevel_project(session, waroot)
       
   199     
   129     if cmproject == None:
   200     if cmproject == None:
   130         print 'Error: ' + waroot + ' must be a synergy project and still be in database'
   201         print 'Error: ' + waroot + ' must be a synergy project and still be in database'
   131     else:
   202     else:
   132         project.setProperty("ccm.toplevel.project", str(cmproject))
   203         project.setProperty("ccm.toplevel.project", str(cmproject))
   133     session.close()
   204     session.close()
   134 except Exception, ex:
   205 except Exception, ex:
   135     print 'Caught exception: ' + str(ex)
   206     print 'Caught exception: ' + str(ex)
   136     traceback.print_exc()
   207     traceback.print_exc()
   137         </script>
   208     if session:
   138         
   209         session.close()
   139         <hlm:python outputproperty="ccm.toplevel.baseline">
   210                 </script>
   140 import nokia.nokiaccm
   211                 <hlm:python outputproperty="ccm.toplevel.baseline">
   141 import traceback
   212 import traceback
   142 import ant
   213 import ant
   143 import logging
   214 import logging
       
   215 import ccmutil
   144 logging.disable(logging.INFO)
   216 logging.disable(logging.INFO)
   145 session = None
   217 session = None
   146 try:
   218 try:
   147     database = ant.get_property(r'${ccm.database}')
   219     database = ant.get_property(r'${ccm.database}')
   148     username = ant.get_property(r'${ccm.user.login}')
   220     username = ant.get_property(r'${ccm.user.login}')
   149     password = ant.get_property(r'${ccm.user.password}')
   221     password = ant.get_property(r'${ccm.user.password}')
   150     engine = ant.get_property(r'${ccm.engine.host}')
   222     engine = ant.get_property(r'${ccm.engine.host}')
   151     dbpath = ant.get_property(r'${ccm.database.path}')
   223     dbpath = ant.get_property(r'${ccm.database.path}')
   152     if database != None:
   224     session = ccmutil.get_session(database, username, password, engine, dbpath)
   153         session = nokia.nokiaccm.open_session(username, password, database=database)
       
   154     else:
       
   155         session = nokia.nokiaccm.open_session(username, password, engine, dbpath)
       
   156         
       
   157     cmproject = session.create(ant.get_property(r'${ccm.toplevel.project}'))
   225     cmproject = session.create(ant.get_property(r'${ccm.toplevel.project}'))
   158     print cmproject.baseline
   226     print cmproject.baseline
   159     session.close()
   227     session.close()
   160 except Exception, ex:
   228 except Exception, ex:
   161     print 'Caught exception: ' + str(ex)
   229     print 'Caught exception: ' + str(ex)
   162     traceback.print_exc()
   230     traceback.print_exc()
   163         </hlm:python>
   231     if session:
   164     </target>
   232         session.close()
   165     
   233                 </hlm:python>
   166     <!-- Private: 
   234             </then>
   167     Look at property 'project.startswith' and find complete CM name
   235         </if>
   168     Output property: '${project.startswith}.project'
   236     </target>
   169     -->
   237     
   170     <target name="release-notes-getprojectname">
   238     <!--
   171         <hlm:python outputproperty="release.notes.temp">
   239     Look 'startsWith' and find complete CM name
       
   240     Output property: '{startsWith}.project'.
       
   241         
       
   242     @scope private
       
   243     -->
       
   244     <macrodef name="releaseNotesGetProjectName" uri="http://www.nokia.com/helium">
       
   245         <attribute name="startsWith" />
       
   246         <sequential>
       
   247             <if>
       
   248                 <available file="${build.log.dir}/${build.id}_bom.xml" />
       
   249                 <then>
       
   250                     <hlm:python outputproperty="@{startsWith}.project">
   172 import amara
   251 import amara
   173 import ant
   252 import ant
   174 
   253 
   175 bomfile = open(r"${build.log.dir}/${build.id}_BOM.xml")
   254 bomfile = open(r"${build.log.dir}/${build.id}_bom.xml")
   176 bom = amara.parse(bomfile)
   255 bom = amara.parse(bomfile)
   177 
   256 
   178 for p in bom.bom.content.project:
   257 for p in bom.bom.content.project:
   179     if (str(p.name).startswith(ant.get_property(r'${project.startswith}'))):
   258     if (str(p.name).startswith(ant.get_property(r'@{startsWith}'))):
   180         print str(p.name)
   259         print str(p.name)
   181 bomfile.close()
   260 bomfile.close()
   182         </hlm:python>
   261                     </hlm:python>
   183         <script language="jython" setbeans="false">
   262                 </then>
   184 project.setProperty(project.getProperty('project.startswith') + '.project', project.getProperty('release.notes.temp'))
   263             </if>
   185         </script>
   264         </sequential>
   186         
   265     </macrodef>
   187     </target>
   266     
   188     
   267     <!-- Write projects, baselines and task list for MC and IBUSAL
   189     <!-- Private: Write projects, baselines and task list for MC and IBUSAL -->
   268     @scope private    
       
   269     -->
   190     <target name="release-notes-ccm" depends="get-ccm-password,release-notes-getcmprojectname,create-bom">
   270     <target name="release-notes-ccm" depends="get-ccm-password,release-notes-getcmprojectname,create-bom">
   191         
   271         <if>
   192         <hlm:python>
   272             <and>
       
   273                 <istrue value="${ccm.enabled}" />
       
   274                 <available file="${build.log.dir}/${build.id}_bom.xml" />
       
   275             </and>
       
   276             <then>
       
   277                 <hlm:python>
   193 import amara
   278 import amara
   194 import nokia.nokiaccm
   279 import ant
   195 import ant
   280 import bomtofile
   196 
   281 import ccmutil
   197 class BOMToFile(object):
   282 
   198     """
   283 bomfile = open(r"${build.log.dir}/${build.id}_bom.xml")
   199     Read BOM and output in text
       
   200     """
       
   201     def __init__(self, session, project_name, project, output_dir):
       
   202         self.project_name = project_name
       
   203         self.project = project
       
   204         self.output_dir = output_dir
       
   205         self.session = session
       
   206       
       
   207     def writeprojects(self):
       
   208         fileout = file(self.output_dir + '/' + self.project_name + '_projects.txt', 'w')
       
   209         
       
   210         i = 1
       
   211         for project in self.project.baseline:
       
   212             fileout.write(str(i) + ") " + str(project) + "\n")
       
   213             
       
   214             i += 1
       
   215         fileout.close()
       
   216         
       
   217     def writebaselines(self):
       
   218         fileout = file(self.output_dir + '/' + self.project_name + '_baselines.txt', 'w')    
       
   219         
       
   220         i = 1
       
   221         for project in self.project.baseline:
       
   222             fileout.write(str(i) + ") " + str(project) + "\n")
       
   223             
       
   224             cmproject = self.session.create(str(project))
       
   225             
       
   226             try:
       
   227                 baseline = str(cmproject.baseline).strip()
       
   228                 if baseline == "None":
       
   229                     fileout.write(str(i) + ") " + str(project) + "\n")
       
   230                 else:
       
   231                     fileout.write(str(i) + ") " + baseline + "\n")
       
   232                 i += 1
       
   233             except Exception, ex:
       
   234                 print ex
       
   235         fileout.close()
       
   236             
       
   237     def writetasks(self):
       
   238         if self.project.xml_properties.has_key("task"):
       
   239             fileout = file(self.output_dir + '/' + self.project_name + '_tasks.txt', 'w')
       
   240             
       
   241             i = 1
       
   242             for task in self.project.task:
       
   243                 fileout.write(str(i) + ") Task " + str(task) + "\n")
       
   244                 i += 1
       
   245             fileout.close()
       
   246 
       
   247 bomfile = open(r"${build.log.dir}/${build.id}_BOM.xml")
       
   248 bom = amara.parse(bomfile)
   284 bom = amara.parse(bomfile)
   249 database = ant.get_property(r'${ccm.database}')
       
   250 username = ant.get_property(r'${ccm.user.login}')
       
   251 password = ant.get_property(r'${ccm.user.password}')
   285 password = ant.get_property(r'${ccm.user.password}')
   252 engine = ant.get_property(r'${ccm.engine.host}')
   286 session = ccmutil.get_session(ant.get_property(r'${ccm.database}'), ant.get_property(r'${ccm.user.login}'), password, ant.get_property(r'${ccm.engine.host}'), ant.get_property(r'${ccm.database.path}'))
   253 dbpath = ant.get_property(r'${ccm.database.path}')
       
   254 if database != None:
       
   255     session = nokia.nokiaccm.open_session(username, password, database=database)
       
   256 else:
       
   257     session = nokia.nokiaccm.open_session(username, password, engine, dbpath)
       
   258 
       
   259 for p in bom.bom.content.project:
   287 for p in bom.bom.content.project:
   260     if p.name == ant.get_property(r'${ccm.toplevel.project}'):
   288     if p.name == ant.get_property(r'${ccm.toplevel.project}'):
   261         btof = BOMToFile(session, 'MC', p, ant.get_property(r'${releasenotes.output.dir}'))
   289         bomwriter = bomtofile.BOMWriter(session, 'MC', p, ant.get_property(r'${releasenotes.output.dir}'))
   262         
   290         bomwriter.writeprojects()
   263         btof.writeprojects()
   291         bomwriter.writebaselines()
   264         btof.writebaselines()
   292         bomwriter.writetasks()
   265             
       
   266         btof.writetasks()
       
   267             
   293             
   268     if (str(p.name).startswith('IBUSAL')):
   294     if (str(p.name).startswith('IBUSAL')):
   269         btof = BOMToFile(session, 'IBUSAL', p, ant.get_property(r'${releasenotes.output.dir}'))
   295         bomwriter = bomtofile.BOMWriter(session, 'IBUSAL', p, ant.get_property(r'${releasenotes.output.dir}'))
   270         
   296         bomwriter.writeprojects()
   271         btof.writeprojects()
   297         bomwriter.writetasks()
   272             
       
   273         btof.writetasks()
       
   274             
       
   275 session.close()
   298 session.close()
   276 bomfile.close()
   299 bomfile.close()
   277 
   300                 </hlm:python>
   278         </hlm:python>
   301             </then>
   279     </target>
   302         </if>
   280     
   303     </target>
   281     <!-- Private: Read BOM and write ICF list -->
   304     
       
   305     <!-- Read BOM and write ICF list
       
   306     @scope private
       
   307     -->
   282     <target name="release-notes-icfs" depends="create-bom">
   308     <target name="release-notes-icfs" depends="create-bom">
   283         <exec executable="python" dir="${helium.dir}/tools/relnotes" failonerror="${failonerror}">
   309         <exec executable="python" failonerror="${failonerror}">
   284             <arg value="icf2txt.py"/>
   310             <arg line="-m icf2txt"/>
   285             <arg value="${build.log.dir}/${build.id}_BOM.xml"/>            
   311             <arg value="${temp.build.dir}/${build.id}_BOM.xml"/>            
   286             <arg value="${releasenotes.output.dir}/icdicf.txt"/>
   312             <arg value="${releasenotes.output.dir}/icdicf.txt"/>
   287         </exec>
   313         </exec>
   288     </target>
   314     </target>
   289     
   315     
   290     <!-- Private: -->
   316     <!-- @scope private -->
   291     <target name="release-notes-test" if="hlm.enable.asserts">
   317     <target name="release-notes-test" if="hlm.enable.asserts">
   292         <hlm:python>
   318         <if>
       
   319             <istrue value="${ccm.enabled}" />
       
   320             <then>
       
   321                 <hlm:python>
   293 import ccm
   322 import ccm
   294 #check for ccm session leaks
   323 #check for ccm session leaks
   295 assert (len(ccm.running_sessions()) == 0)
   324 assert (len(ccm.running_sessions()) == 0)
   296         </hlm:python>
   325                 </hlm:python>
       
   326             </then>
       
   327         </if>
   297     </target>
   328     </target>
   298         
   329         
   299     <!-- 
   330     <!-- 
   300     Generates a product release note based on a template in config dir
   331     Generates a product release note based on a template in config dir
   301     -->
   332     -->