00001
00002 """
00003 Small script to prepare the tags and the distribution special directory for a
00004 release of Gaudi.
00005 See https://twiki.cern.ch/twiki/bin/view/Gaudi/GaudiSVNRepository for a
00006 description of the repository structure.
00007 """
00008 __author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>"
00009
00010 import os, re, sys, tempfile, shutil
00011 from subprocess import Popen, PIPE
00012
00013 _req_version_pattern = re.compile(r"^\s*version\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*$")
00014 def extract_version(f):
00015 """
00016 Find the version number in a requirements file.
00017 """
00018 global _req_version_pattern
00019 for l in open(f):
00020 m = _req_version_pattern.match(l)
00021 if m:
00022 return m.group(1)
00023 return None
00024
00025 _use_pattern = re.compile(r"^\s*use\s*(\w+)\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*(\w+)?\s*$")
00026 def gather_new_versions(f):
00027 global _use_pattern
00028 versions = {}
00029 for l in open(f):
00030 m = _use_pattern.match(l)
00031 if m:
00032 versions[m.group(1)] = m.group(2)
00033 return versions
00034
00035 def svn(*args, **kwargs):
00036 print "> svn", " ".join(args)
00037 return apply(Popen, (["svn"] + list(args),), kwargs)
00038
00039 def svn_ls(url):
00040 return svn("ls", url, stdout = PIPE).communicate()[0].splitlines()
00041
00042 def basename(url):
00043 return url.rsplit("/", 1)[-1]
00044
00045 def dirname(url):
00046 return url.rsplit("/", 1)[1]
00047
00048 def svn_exists(url):
00049 d,b = url.rsplit("/", 1)
00050 l = [x.rstrip("/") for x in svn_ls(d)]
00051 return b in l
00052
00053 def checkout_structure(url, proj, branch):
00054 def checkout_level(base):
00055 dirs = ["%s/%s" % (base, d) for d in svn_ls(base) if d.endswith("/")]
00056 apply(svn, ["up", "-N"] + dirs).wait()
00057 return dirs
00058
00059 root = basename(url)
00060 svn("co","-N", url, root).wait()
00061 old_dir = os.getcwd()
00062 os.chdir(root)
00063 svn("up", "-N", proj).wait()
00064 br = [proj] + branch.split("/")
00065 for base in [ "/".join(br[:n+1]) for n in range(len(br))]:
00066 checkout_level(base)
00067 checkout_level(proj + "/tags")
00068 os.chdir(old_dir)
00069 return root
00070
00071 def main():
00072 from optparse import OptionParser
00073 parser = OptionParser()
00074 parser.add_option("--pre", action = "store_true",
00075 help = "Create -pre tags instead of final tags.")
00076 parser.add_option("-b", "--branch",
00077 help = "Use the given (global) branch as source for the tags instead of the trunk")
00078 opts, args = parser.parse_args()
00079 if opts.branch:
00080 opts.branch = "/".join(["branches", "GAUDI", opts.branch])
00081 else:
00082 opts.branch = "trunk"
00083
00084 url = "svn+ssh://svn.cern.ch/reps/gaudi"
00085 proj = "Gaudi"
00086 container = "GaudiRelease"
00087 packages = gather_new_versions("requirements")
00088 packages[container] = extract_version("requirements")
00089 tempdir = tempfile.mkdtemp()
00090 try:
00091 os.chdir(tempdir)
00092
00093 os.chdir(checkout_structure(url, proj, opts.branch))
00094
00095
00096 pvers = "%s_%s" % (proj.upper(), packages[container])
00097
00098
00099 ptagdir = "%s/tags/%s/%s" % (proj, proj.upper(), pvers)
00100 if not svn_exists(ptagdir):
00101 svn("mkdir", ptagdir).wait()
00102 for f in ["cmt", "Makefile.cmt", "configure", "cmake", "CMakeLists.txt"]:
00103 svn("cp", "/".join([proj, opts.branch, f]), "/".join([ptagdir, f])).wait()
00104
00105
00106 tag_re = re.compile(r"^v(\d+)r(\d+)(?:p(\d+))?$")
00107 for p in packages:
00108 tag = packages[p]
00109 pktagdir = "%s/tags/%s/%s" % (proj, p, tag)
00110
00111
00112 no_tag = not svn_exists(pktagdir)
00113 make_tag = no_tag or (opts.pre and no_tag and not svn_exists(pktagdir + "-pre"))
00114 if make_tag:
00115 if opts.pre:
00116 pktagdir += "-pre"
00117 svn("cp", "/".join([proj, opts.branch, p]), pktagdir).wait()
00118
00119 tagElements = tag_re.match(tag)
00120 if tagElements:
00121 tagElements = "-".join([ "%02d" % int(el or "0") for el in tagElements.groups() ])
00122 pktagdir = "%s/tags/%s/%s-%s" % (proj, p, p, tagElements)
00123 svn("cp", "/".join([proj, opts.branch, p]), pktagdir).wait()
00124 else:
00125 if not no_tag:
00126 svn("up", "-N", pktagdir).wait()
00127
00128 if not opts.pre:
00129
00130 for p in packages:
00131 tag = packages[p]
00132 pktagdir = "%s/tags/%s/%s" % (proj, p, tag)
00133 svn("cp", pktagdir, "%s/%s" % (ptagdir, p)).wait()
00134
00135 svn("ci").wait()
00136
00137 finally:
00138 shutil.rmtree(tempdir, ignore_errors = True)
00139
00140 return 0
00141
00142 if __name__ == '__main__':
00143 sys.exit(main())