00001
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
00009
00010
00011 _req_version_pattern = re.compile(r"^\s*version\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*$")
00012 _cml_version_pattern = re.compile(r"^\s*gaudi_subdir\s*\(\s*\S+\s+(v[0-9]+r[0-9]+(?:p[0-9]+)?)\)\s*$")
00013 def extract_version(f):
00014 """
00015 Find the version number in a requirements file.
00016 """
00017 global _req_version_pattern
00018 for l in open(f):
00019 m = _req_version_pattern.match(l)
00020 if m:
00021 return m.group(1)
00022 return None
00023
00024 def change_cml_version(cml, newversion):
00025 if os.path.exists(cml):
00026 out = []
00027 changed = False
00028 for l in open(cml):
00029 m = _cml_version_pattern.match(l)
00030 if m and m.group(1) != newversion:
00031 print "%s: %s -> %s"%(cml, m.group(1), newversion)
00032 l = l.replace(m.group(1), newversion)
00033 changed = True
00034 out.append(l)
00035 if changed:
00036 open(cml, "w").writelines(out)
00037
00038 def change_version(packagedir, newversion):
00039 """
00040 Compare the version of the package with the new one and update the package if
00041 needed.
00042
00043 Returns true if the package have been modified.
00044 """
00045 global _req_version_pattern
00046 changed = False
00047 out = []
00048 req = os.path.join(packagedir,"requirements")
00049 for l in open(req):
00050 m = _req_version_pattern.match(l)
00051 if m:
00052 if m.group(1) != newversion:
00053 print "%s: %s -> %s"%(packagedir,m.group(1),newversion)
00054 l = l.replace(m.group(1),newversion)
00055 changed = True
00056 out.append(l)
00057 if changed:
00058 open(req,"w").writelines(out)
00059
00060 ver = os.path.join(packagedir,"version.cmt")
00061 if os.path.exists(ver):
00062 current = open(ver).read().strip()
00063 if current != newversion:
00064 open(ver,"w").write(newversion + "\n")
00065
00066 cml = os.path.normpath(os.path.join(packagedir, "..", "CMakeLists.txt"))
00067 change_cml_version(cml, newversion)
00068 if "GaudiKernel" in packagedir:
00069 cml = os.path.normpath(os.path.join(packagedir, "..", "src", "Util", "CMakeLists.txt"))
00070 change_cml_version(cml, newversion)
00071 return changed
00072
00073 _use_pattern = re.compile(r"^\s*use\s*(\w+)\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*(\w+)?\s*$")
00074 def gather_new_versions(f):
00075 global _use_pattern
00076 versions = {}
00077 for l in open(f):
00078 m = _use_pattern.match(l)
00079 if m:
00080 versions[m.group(1)] = m.group(2)
00081 return versions
00082
00083 def extract_recent_rel_notes(filename):
00084 changelog_entry = re.compile(r'^(! [0-9]{4}-[0-9]{2}-[0-9]{2} -)|============')
00085 separator_entry = re.compile(r'^!?============')
00086 notes = []
00087 state = "searching"
00088 for l in open(filename):
00089
00090 if state == "searching":
00091 if changelog_entry.match(l):
00092 state = "found"
00093
00094 if state == "found":
00095 if not separator_entry.match(l):
00096 notes.append(l)
00097 else:
00098 break
00099
00100 while notes and not notes[-1].strip(): notes.pop()
00101 return "".join(notes)
00102
00103 def add_release_separator_bar(filename, pkg, version):
00104 changelog_entry = re.compile(r'^(! [0-9]{4}-[0-9]{2}-[0-9]{2} -)|============')
00105 title = " %s %s " % (pkg, version)
00106 letf_chars = (78 - len(title)) / 2
00107 right_chars = 78 - letf_chars - len(title)
00108 separator = ("=" * letf_chars) + title + ("=" * right_chars) + "\n"
00109 out = []
00110 found = False
00111 for l in open(filename):
00112
00113 if not found:
00114 if changelog_entry.match(l):
00115 out.append(separator)
00116 found = True
00117
00118 out.append(l)
00119 if found:
00120 open(filename,"w").writelines(out)
00121 else:
00122 print "Warning: could not update release.notes in %s" % pkg
00123
00124 def main():
00125
00126
00127 m = re.search("use\s*LCGCMT\s*LCGCMT_(\S*)",open(os.path.join("..","..","cmt","project.cmt")).read())
00128 if m:
00129 LCGCMTVers = m.group(1)
00130 print "Using LCGCMT", LCGCMTVers
00131 else:
00132 print "Cannot find LCGCMT version"
00133 sys.exit(1)
00134
00135
00136
00137 all_packages_tmp = []
00138 exec(os.popen(r"""cmt broadcast 'echo "all_packages_tmp.append((\"<package>\"", \"$PWD\""))"'""","r").read())
00139 all_packages_names = []
00140 all_packages = {}
00141 for k,v in all_packages_tmp:
00142 all_packages_names.append(k)
00143 all_packages[k] = v
00144
00145
00146 special_packages = ["Gaudi", "GaudiExamples", "GaudiSys", "GaudiRelease"]
00147
00148
00149 old_version = extract_version("requirements")
00150 new_version = raw_input("The old version of the project is %s, which is the new one? " % old_version)
00151
00152 old_versions = {}
00153 release_notes = {}
00154 new_versions = {}
00155
00156 for pkg in all_packages_names:
00157 reqfile = os.path.join(all_packages[pkg], "requirements")
00158 relnotefile = os.path.join(all_packages[pkg], "..", "doc", "release.notes")
00159 old_versions[pkg] = extract_version(reqfile)
00160 if os.path.exists(relnotefile):
00161 release_notes[pkg] = extract_recent_rel_notes(relnotefile)
00162 else:
00163 release_notes[pkg] = ""
00164 if pkg in special_packages:
00165 new_versions[pkg] = new_version
00166 else:
00167 if release_notes[pkg]:
00168 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]))
00169 else:
00170 new_versions[pkg] = old_versions[pkg]
00171
00172 if new_versions[pkg] != old_versions[pkg]:
00173 change_version(all_packages[pkg], new_versions[pkg])
00174 if os.path.exists(relnotefile):
00175 add_release_separator_bar(relnotefile, pkg, new_versions[pkg])
00176 print "=" * 80
00177
00178 reqfile = os.path.join(all_packages["GaudiRelease"], "requirements")
00179 out = []
00180 for l in open(reqfile):
00181 sl = l.strip().split()
00182 if sl and sl[0] == "use":
00183 if sl[1] in new_versions:
00184 if sl[2] != new_versions[sl[1]]:
00185 l = l.replace(sl[2], new_versions[sl[1]])
00186 out.append(l)
00187 open(reqfile, "w").writelines(out)
00188
00189
00190 new_lines = []
00191 new_lines.append("<!-- ====================================================================== -->")
00192 data = { "vers": new_version, "date": time.strftime("%Y-%m-%d") }
00193 new_lines.append('<h2><a name="%(vers)s">Gaudi %(vers)s</a> (%(date)s)</h2>' % data)
00194 data = { "vers": LCGCMTVers }
00195 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)
00196 new_lines.append("<h3>General Changes</h3>")
00197 new_lines.append('<ul>\n<li><br/>\n (<span class="author"></span>)</li>\n</ul>')
00198 new_lines.append("<h3>Packages Changes</h3>")
00199 new_lines.append("<ul>")
00200 for pkg in all_packages_names:
00201 if release_notes[pkg]:
00202 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]))
00203 new_lines.append(release_notes[pkg].replace('&','&') \
00204 .replace('<','<') \
00205 .replace('>','>') + "</pre>")
00206 new_lines.append("</li>")
00207 new_lines.append("</ul>")
00208
00209 global_rel_notes = os.path.join("..", "doc", "release.notes.html")
00210 out = []
00211 separator = re.compile("<!-- =+ -->")
00212 block_added = False
00213 for l in open(global_rel_notes):
00214 if not block_added and separator.match(l.strip()):
00215 out.append("\n".join(new_lines) + "\n")
00216 block_added = True
00217 out.append(l)
00218 open(global_rel_notes, "w").writelines(out)
00219
00220 if __name__ == '__main__':
00221 main()