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 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
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
00069 if state == "searching":
00070 if changelog_entry.match(l):
00071 state = "found"
00072
00073 if state == "found":
00074 if not separator_entry.match(l):
00075 notes.append(l)
00076 else:
00077 break
00078
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
00092 if not found:
00093 if changelog_entry.match(l):
00094 out.append(separator)
00095 found = True
00096
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
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
00115
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
00125 special_packages = ["Gaudi", "GaudiExamples", "GaudiSys", "GaudiRelease"]
00126
00127
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
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):
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
00151 if new_versions[pkg] != old_versions[pkg]:
00152 change_version(all_packages[pkg], new_versions[pkg])
00153 if os.path.exists(relnotefile):
00154 add_release_separator_bar(relnotefile, pkg, new_versions[pkg])
00155 print "=" * 80
00156
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
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('&','&') \
00183 .replace('<','<') \
00184 .replace('>','>') + "</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()