All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tag_release.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 """
3 Small script to prepare the tags and the distribution special directory for a
4 release of Gaudi.
5 See https://twiki.cern.ch/twiki/bin/view/Gaudi/GaudiSVNRepository for a
6 description of the repository structure.
7 """
8 __author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>"
9 
10 import os, re, sys, tempfile, shutil
11 from subprocess import Popen, PIPE
12 
13 _req_version_pattern = re.compile(r"^\s*version\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*$")
15  """
16  Find the version number in a requirements file.
17  """
18  global _req_version_pattern
19  for l in open(f):
20  m = _req_version_pattern.match(l)
21  if m:
22  return m.group(1)
23  return None
24 
25 _use_pattern = re.compile(r"^\s*use\s*(\w+)\s*(v[0-9]+r[0-9]+(?:p[0-9]+)?)\s*(\w+)?\s*$")
27  global _use_pattern
28  versions = {}
29  for l in open(f):
30  m = _use_pattern.match(l)
31  if m:
32  versions[m.group(1)] = m.group(2)
33  return versions
34 
35 def svn(*args, **kwargs):
36  print "> svn", " ".join(args)
37  return apply(Popen, (["svn"] + list(args),), kwargs)
38 
39 def svn_ls(url):
40  return svn("ls", url, stdout = PIPE).communicate()[0].splitlines()
41 
42 def basename(url):
43  return url.rsplit("/", 1)[-1]
44 
45 def dirname(url):
46  return url.rsplit("/", 1)[1]
47 
48 def svn_exists(url):
49  d,b = url.rsplit("/", 1)
50  l = [x.rstrip("/") for x in svn_ls(d)]
51  return b in l
52 
53 def checkout_structure(url, proj, branch):
54  def checkout_level(base):
55  dirs = ["%s/%s" % (base, d) for d in svn_ls(base) if d.endswith("/")]
56  apply(svn, ["up", "-N"] + dirs).wait()
57  return dirs
58 
59  root = basename(url)
60  svn("co","-N", url, root).wait()
61  old_dir = os.getcwd()
62  os.chdir(root)
63  svn("up", "-N", proj).wait()
64  br = [proj] + branch.split("/")
65  for base in [ "/".join(br[:n+1]) for n in range(len(br))]:
66  checkout_level(base)
67  checkout_level(proj + "/tags")
68  os.chdir(old_dir)
69  return root
70 
71 def main():
72  from optparse import OptionParser
73  parser = OptionParser()
74  parser.add_option("--pre", action = "store_true",
75  help = "Create -pre tags instead of final tags.")
76  parser.add_option("-b", "--branch",
77  help = "Use the given (global) branch as source for the tags instead of the trunk")
78  opts, args = parser.parse_args()
79  if opts.branch:
80  opts.branch = "/".join(["branches", "GAUDI", opts.branch])
81  else:
82  opts.branch = "trunk"
83 
84  url = "svn+ssh://svn.cern.ch/reps/gaudi"
85  proj = "Gaudi"
86  container = "GaudiRelease"
87  packages = gather_new_versions("requirements")
88  packages[container] = extract_version("requirements")
89  tempdir = tempfile.mkdtemp()
90  try:
91  os.chdir(tempdir)
92  # prepare repository structure (and move to its top level)
93  os.chdir(checkout_structure(url, proj, opts.branch))
94 
95  # note that the project does not have "-pre"
96  pvers = "%s_%s" % (proj.upper(), packages[container])
97 
98  # prepare project tag
99  ptagdir = "%s/tags/%s/%s" % (proj, proj.upper(), pvers)
100  if not svn_exists(ptagdir):
101  svn('cp', '/'.join([proj, opts.branch]), ptagdir).wait()
102 
103  # prepare package tags
104  tag_re = re.compile(r"^v(\d+)r(\d+)(?:p(\d+))?$")
105  for p in packages:
106  tag = packages[p]
107  pktagdir = "%s/tags/%s/%s" % (proj, p, tag)
108  # I have to make the tag if it doesn't exist and (if we use -pre tags)
109  # neither the -pre tag exists.
110  no_tag = not svn_exists(pktagdir)
111  make_tag = no_tag or (opts.pre and no_tag and not svn_exists(pktagdir + "-pre"))
112  if make_tag:
113  if opts.pre:
114  pktagdir += "-pre"
115  svn("cp", "/".join([proj, opts.branch, p]), pktagdir).wait()
116  # Atlas type of tag
117  tagElements = tag_re.match(tag)
118  if tagElements:
119  tagElements = "-".join([ "%02d" % int(el or "0") for el in tagElements.groups() ])
120  pktagdir = "%s/tags/%s/%s-%s" % (proj, p, p, tagElements)
121  svn("cp", "/".join([proj, opts.branch, p]), pktagdir).wait()
122  else:
123  if not no_tag:
124  svn("up", "--depth=empty", pktagdir).wait() # needed for the copy in the global tag
125 
126  svn("ci").wait()
127 
128  finally:
129  shutil.rmtree(tempdir, ignore_errors = True)
130 
131  return 0
132 
133 if __name__ == '__main__':
134  sys.exit(main())
def checkout_structure
Definition: tag_release.py:53
def gather_new_versions
Definition: tag_release.py:26
def svn_exists
Definition: tag_release.py:48
def extract_version
Definition: tag_release.py:14
NamedRange_< CONTAINER > range(const CONTAINER &cnt, const std::string &name)
simple function to create the named range form arbitrary container
Definition: NamedRange.h:133