The Gaudi Framework  v29r0 (ff2e7097)
prepare_gaudi_release Namespace Reference

Functions

def checkGitVersion ()
 
def versionKey (x)
 
def findLatestTag ()
 
def releaseNotes (path=os.curdir, from_tag=None, branch=None)
 
def updateReleaseNotes (path, notes)
 
def tag_bar (pkg, version=None)
 
def main ()
 

Variables

 _VK_RE = re.compile(r'(\d+|\D+)')
 

Detailed Description

Script to prepare the release of Gaudi.

@author Marco Clemencic

Function Documentation

def prepare_gaudi_release.checkGitVersion ( )
Ensure we have a usable version of Git (>= 1.7.9.1).

See:
* https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/1.7.9.1.txt
* https://github.com/git/git/commit/36ed1913e1d5de0930e59db6eeec3ccb2bd58bd9

Definition at line 15 of file prepare_gaudi_release.py.

16  '''
17  Ensure we have a usable version of Git (>= 1.7.9.1).
18 
19  See:
20  * https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/1.7.9.1.txt
21  * https://github.com/git/git/commit/36ed1913e1d5de0930e59db6eeec3ccb2bd58bd9
22  '''
23  version = check_output(['git', '--version']).split()[-1]
24  if versionKey(version) < versionKey('1.7.9.1'):
25  raise RuntimeError(
26  'bad version of git found: %s (1.7.9.1 required)' % version)
27 
28 
def prepare_gaudi_release.findLatestTag ( )
Return the latest Gaudi tag (of the format "v*r*...").

Definition at line 42 of file prepare_gaudi_release.py.

43  '''
44  Return the latest Gaudi tag (of the format "v*r*...").
45  '''
46  logging.info('looking for latest tag')
47  cmd = ['git', 'tag']
48  logging.debug('using command %r', cmd)
49  output = check_output(cmd)
50  vers_exp = re.compile(r'^v\d+r\d+(p\d+)?$')
51  tags = [tag
52  for tag in output.splitlines()
53  if vers_exp.match(tag)]
54  if tags:
55  tags.sort(key=versionKey)
56  logging.info('found %s', tags[-1])
57  return tags[-1]
58  logging.info('no valid tag found')
59 
60 
def prepare_gaudi_release.main ( )

Definition at line 125 of file prepare_gaudi_release.py.

125 def main():
126  logging.basicConfig(level=logging.DEBUG)
127  os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
128  # Find the version of HEPTools (LCG)
129  for l in open('toolchain.cmake'):
130  m = re.match(r'^\s*set\(\s*heptools_version\s+(\S*)\s*\)', l)
131  if m:
132  HEPToolsVers = m.group(1)
133  print "Using HEPTools", HEPToolsVers
134  break
135  else:
136  logging.error('Cannot find HEPTools version')
137  sys.exit(1)
138 
139  # Collect all the packages in the project with their directory
140  def all_subdirs():
141  for dirpath, dirnames, filenames in os.walk(os.curdir):
142  if 'CMakeLists.txt' in filenames and dirpath != os.curdir:
143  dirnames[:] = []
144  yield dirpath
145  else:
146  dirnames[:] = [dirname for dirname in dirnames
147  if (not dirname.startswith('build.') and
148  dirname != 'cmake')]
149 
150  # Ask for the version of the project
151  latest_tag = findLatestTag()
152 
153  old_version = latest_tag.split('_')[-1]
154  new_version = raw_input(("The old version of the project is %s, "
155  "which is the new one? ") % old_version)
156 
157  release_notes = {}
158  # for each package in the project update the release.notes
159  for pkgdir in all_subdirs():
160  updateReleaseNotes(pkgdir,
161  tag_bar('Gaudi', new_version) + '\n\n' +
162  releaseNotes(pkgdir, latest_tag, 'master'))
163 
164  # update the global CMakeLists.txt
165  out = []
166  for l in open('CMakeLists.txt'):
167  if l.strip().startswith('gaudi_project'):
168  l = 'gaudi_project(Gaudi %s)\n' % new_version
169  out.append(l)
170  open('CMakeLists.txt', "w").writelines(out)
171 
172 
def releaseNotes(path=os.curdir, from_tag=None, branch=None)
def tag_bar(pkg, version=None)
def updateReleaseNotes(path, notes)
def prepare_gaudi_release.releaseNotes (   path = os.curdir,
  from_tag = None,
  branch = None 
)
Return the release notes (in the old LHCb format) extracted from git
commits for a given path.

Definition at line 61 of file prepare_gaudi_release.py.

61 def releaseNotes(path=os.curdir, from_tag=None, branch=None):
62  '''
63  Return the release notes (in the old LHCb format) extracted from git
64  commits for a given path.
65  '''
66  cmd = ['git', 'log',
67  '--first-parent', '--date=short',
68  '--pretty=format:! %ad - commit %h%n%n%w(80,1,3)- %s%n%n%b%n']
69  if from_tag:
70  cmd.append('{0}..{1}'.format(from_tag, branch or ''))
71  elif branch:
72  cmd.append(branch)
73  cmd.append('--')
74  cmd.append(path)
75  logging.info('preparing release notes for %s%s', path,
76  ' since ' + from_tag if from_tag else '')
77  logging.debug('using command %r', cmd)
78  # remove '\r' characters from commit messages
79  out = check_output(cmd).replace('\r', '')
80 
81  # replace ' - commit 123abc' with ' - Contributor Name (commit 123abc)'
82  def add_contributors(match):
83  try:
84  authors = set(check_output(['git', 'log', '--pretty=format:%aN',
85  '{0}^1..{0}^2'.format(match.group(1)),
86  ]).splitlines())
87  return ' - {0} (commit {1})'.format(', '.join(sorted(authors)),
88  match.group(1))
89  except CalledProcessError:
90  return match.group(0)
91  out = re.sub(r' - commit ([0-9a-f]+)', add_contributors, out)
92  return out
93 
94 
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
def releaseNotes(path=os.curdir, from_tag=None, branch=None)
def prepare_gaudi_release.tag_bar (   pkg,
  version = None 
)

Definition at line 117 of file prepare_gaudi_release.py.

117 def tag_bar(pkg, version=None):
118  title = ' %s %s ' % (pkg, version)
119  letf_chars = (78 - len(title)) / 2
120  right_chars = 78 - letf_chars - len(title)
121  separator = ('=' * letf_chars) + title + ('=' * right_chars)
122  return separator
123 
124 
def tag_bar(pkg, version=None)
def prepare_gaudi_release.updateReleaseNotes (   path,
  notes 
)
Smartly prepend the content of notes to the release.notes file in path.

Definition at line 95 of file prepare_gaudi_release.py.

95 def updateReleaseNotes(path, notes):
96  '''
97  Smartly prepend the content of notes to the release.notes file in path.
98  '''
99  notes_filename = os.path.join(path, 'doc', 'release.notes')
100  logging.info('updating %s', notes_filename)
101  from itertools import takewhile, dropwhile
102 
103  def dropuntil(predicate, iterable):
104  return dropwhile(lambda x: not predicate(x), iterable)
105  with open(notes_filename) as notes_file:
106  orig_data = iter(list(notes_file))
107  header = takewhile(str.strip, orig_data)
108  with open(notes_filename, 'w') as notes_file:
109  notes_file.writelines(header)
110  notes_file.write('\n')
111  notes_file.writelines(l.rstrip() + '\n' for l in notes.splitlines())
112  notes_file.write('\n')
113  notes_file.writelines(
114  dropuntil(re.compile(r'^!?============').match, orig_data))
115 
116 
def updateReleaseNotes(path, notes)
def prepare_gaudi_release.versionKey (   x)
Key function to be passes to list.sort() to sort strings
as version numbers.

Definition at line 32 of file prepare_gaudi_release.py.

32 def versionKey(x):
33  '''
34  Key function to be passes to list.sort() to sort strings
35  as version numbers.
36  '''
37  return [int(i) if i[0] in '0123456789' else i
38  for i in _VK_RE.split(x)
39  if i]
40 
41 

Variable Documentation

prepare_gaudi_release._VK_RE = re.compile(r'(\d+|\D+)')
private

Definition at line 29 of file prepare_gaudi_release.py.