| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# update_versions.py

Go to the documentation of this file.

    00001 #!/usr/bin/env python
    00002
    00003 __author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>"
    00004 __version__ = "$Id: update_versions.py,v 1.3 2008/11/10 19:43:31 marcocle Exp $"
    00005
    00006 import os, re, sys, time
    00007
    00008 # special_packages = [ "Gaudi", "GaudiSys", "GaudiExamples" ]
    00009
    00010 # guess current version
    00011 _req_version_pattern = re.compile(r"^\s*version\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*$")
    00012 def extract_version(f):
    00013     """
    00014     Find the version number in a requirements file.
    00015     """
    00016     global _req_version_pattern
    00017     for l in open(f):
    00018         m = _req_version_pattern.match(l)
    00019         if m:
    00020             return m.group(1)
    00021     return None
    00022
    00023 def change_version(packagedir, newversion):
    00024     """
    00025     Compare the version of the package with the new one and update the package if
    00026     needed.
    00027
    00028     Returns true if the package have been modified.
    00029     """
    00030     global _req_version_pattern
    00031     changed = False
    00032     out = []
    00033     req = os.path.join(packagedir,"requirements")
    00034     for l in open(req):
    00035         m = _req_version_pattern.match(l)
    00036         if m:
    00037             if m.group(1) != newversion:
    00038                 print "%s: %s -> %s"%(packagedir,m.group(1),newversion)
    00039                 l = l.replace(m.group(1),newversion)
    00040                 changed = True
    00041         out.append(l)
    00042     if changed:
    00043         open(req,"w").writelines(out)
    00044     # verify the version.cmt file
    00045     ver = os.path.join(packagedir,"version.cmt")
    00046     if os.path.exists(ver):
    00047         current = open(ver).read().strip()
    00048         if current != newversion:
    00049             open(ver,"w").write(newversion + "\n")
    00050     return changed
    00051
    00052 _use_pattern = re.compile(r"^\s*use\s*(\w+)\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*(\w+)?\s*$")
    00053 def gather_new_versions(f):
    00054     global _use_pattern
    00055     versions = {}
    00056     for l in open(f):
    00057         m = _use_pattern.match(l)
    00058         if m:
    00059             versions[m.group(1)] = m.group(2)
    00060     return versions
    00061
    00062 def extract_recent_rel_notes(filename):
    00063     changelog_entry = re.compile(r'^(! [0-9]{4}-[0-9]{2}-[0-9]{2} -)|============')
    00064     separator_entry = re.compile(r'^============')
    00065     notes = []
    00066     state = "searching"
    00067     for l in open(filename):
    00068         # looking for the first changelog entry
    00069         if state == "searching":
    00070             if changelog_entry.match(l):
    00071                 state = "found"
    00072         # when found, we start collecting lines until the next separator
    00073         if state == "found":
    00074             if not separator_entry.match(l):
    00075                 notes.append(l)
    00076             else:
    00077                 break
    00078     # remove trailing empty lines
    00079     while notes and not notes[-1].strip(): notes.pop()
    00080     return "".join(notes)
    00081
    00082 def add_release_separator_bar(filename, pkg, version):
    00083     changelog_entry = re.compile(r'^(! [0-9]{4}-[0-9]{2}-[0-9]{2} -)|============')
    00084     title = " %s %s " % (pkg, version)
    00085     letf_chars = (78 - len(title)) / 2
    00086     right_chars = 78 - letf_chars - len(title)
    00087     separator = ("=" * letf_chars) + title + ("=" * right_chars) + "\n"
    00088     out = []
    00089     found = False
    00090     for l in open(filename):
    00091         # looking for the first changelog entry
    00092         if not found:
    00093             if changelog_entry.match(l):
    00094                 out.append(separator)
    00095                 found = True
    00096         # if found, just go on appending lines
    00097         out.append(l)
    00098     if found:
    00099         open(filename,"w").writelines(out)
    00100     else:
    00101         print "Warning: could not update release.notes in %s" % pkg
    00102
    00103 def main():
    00104
    00105     # Find the version of LCGCMT
    00106     m = re.search("use\s*LCGCMT\s*LCGCMT_(\S*)",open(os.path.join("..","..","cmt","project.cmt")).read())
    00107     if m:
    00108         LCGCMTVers = m.group(1)
    00109         print "Using LCGCMT", LCGCMTVers
    00110     else:
    00111         print "Cannot find LCGCMT version"
    00112         sys.exit(1)
    00113
    00114     # Collect all the packages in the project with their directory
    00115     # (I want to preserve the order that cmt broadcast gives)
    00116     all_packages_tmp = []
    00117     exec(os.popen(r"""cmt broadcast 'echo "all_packages_tmp.append((\"<package>\"", \"$PWD\""))"'""","r").read())
    00118     all_packages_names = []
    00119     all_packages = {}
    00120     for k,v in all_packages_tmp:
    00121         all_packages_names.append(k)
    00122         all_packages[k] = v
    00123
    00124     # Packages which version must match the version of the project
    00125     special_packages = ["Gaudi", "GaudiExamples", "GaudiSys", "GaudiRelease"]
    00126
    00127     # Ask for the version of the project
    00128     old_version = extract_version("requirements")
    00129     new_version = raw_input("The old version of the project is %s, which is the new one? " % old_version)
    00130
    00131     old_versions = {}
    00132     release_notes = {}
    00133     new_versions = {}
    00134     # for each package in the project check if there were changes and ask for the new version number
    00135     for pkg in all_packages_names:
    00136         reqfile = os.path.join(all_packages[pkg], "requirements")
    00137         relnotefile = os.path.join(all_packages[pkg], "..", "doc", "release.notes")
    00138         old_versions[pkg] = extract_version(reqfile)
    00139         if os.path.exists(relnotefile): # ignore missing release.notes
    00140             release_notes[pkg] = extract_recent_rel_notes(relnotefile)
    00141         else:
    00142             release_notes[pkg] = ""
    00143         if pkg in special_packages:
    00144             new_versions[pkg] = new_version
    00145         else:
    00146             if release_notes[pkg]:
    00147                 new_versions[pkg] = raw_input("\nThe old version of %s is %s, this are the changes:\n%s\nWhich version you want (old is %s)? " % (pkg, old_versions[pkg], release_notes[pkg], old_versions[pkg]))
    00148             else:
    00149                 new_versions[pkg] = old_versions[pkg]
    00150         # update infos
    00151         if new_versions[pkg] != old_versions[pkg]:
    00152             change_version(all_packages[pkg], new_versions[pkg])
    00153             if pkg != "GaudiRelease":
    00154                 add_release_separator_bar(relnotefile, pkg, new_versions[pkg])
    00155         print "=" * 80
    00156     # The changes in the GaudiRelease requirements for the other packages can be postponed to now
    00157     reqfile = os.path.join(all_packages["GaudiRelease"], "requirements")
    00158     out = []
    00159     for l in open(reqfile):
    00160         sl = l.strip().split()
    00161         if sl and sl[0] == "use":
    00162             if sl[1] in new_versions:
    00163                 if sl[2] != new_versions[sl[1]]:
    00164                     l = l.replace(sl[2], new_versions[sl[1]])
    00165         out.append(l)
    00166     open(reqfile, "w").writelines(out)
    00167
    00168     # update the global release notes
    00169     new_lines = []
    00170     new_lines.append("<!-- ====================================================================== -->")
    00171     data = { "vers": new_version, "date": time.strftime("%Y-%m-%d") }
    00172     new_lines.append('<h2><a name="%(vers)s">Gaudi %(vers)s</a> (%(date)s)</h2>' % data)
    00173     data = { "vers": LCGCMTVers }
    00174     new_lines.append('<h3>Externals version: <a href="http://lcgsoft.cern.ch/index.py?page=cfg_overview&cfg=%(vers)s">LCGCMT_%(vers)s</a></h3>' % data)
    00175     new_lines.append("<h3>General Changes</h3>")
    00176     new_lines.append('<ul>\n<li><br/>\n    (<span class="author"></span>)</li>\n</ul>')
    00177     new_lines.append("<h3>Packages Changes</h3>")
    00178     new_lines.append("<ul>")
    00179     for pkg in all_packages_names:
    00180         if release_notes[pkg]:
    00181             new_lines.append('<li>%s (%s):\n<ul>\n<li><br/>\n    (<span class="author"></span>)</li>\n</ul>\n<pre>'%(pkg,new_versions[pkg]))
    00182             new_lines.append(release_notes[pkg].replace('&','&amp;') \
    00183                                                .replace('<','&lt;') \
    00184                                                .replace('>','&gt;') + "</pre>")
    00185             new_lines.append("</li>")
    00186     new_lines.append("</ul>")
    00187
    00188     global_rel_notes = os.path.join("..", "doc", "release.notes.html")
    00189     out = []
    00190     separator = re.compile("<!-- =+ -->")
    00191     block_added = False
    00192     for l in open(global_rel_notes):
    00193         if not block_added and separator.match(l.strip()):
    00194             out.append("\n".join(new_lines) + "\n")
    00195             block_added = True
    00196         out.append(l)
    00197     open(global_rel_notes, "w").writelines(out)
    00198
    00199 if __name__ == '__main__':
    00200     main()