The Gaudi Framework  v32r2 (46d42edc)
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

◆ checkGitVersion()

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 16 of file prepare_gaudi_release.py.

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

◆ findLatestTag()

def prepare_gaudi_release.findLatestTag ( )
Return the latest Gaudi tag (of the format "v*r*...").

Definition at line 43 of file prepare_gaudi_release.py.

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

◆ main()

def prepare_gaudi_release.main ( )

Definition at line 131 of file prepare_gaudi_release.py.

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

◆ releaseNotes()

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 60 of file prepare_gaudi_release.py.

60 def releaseNotes(path=os.curdir, from_tag=None, branch=None):
61  '''
62  Return the release notes (in the old LHCb format) extracted from git
63  commits for a given path.
64  '''
65  cmd = [
66  'git', 'log', '--first-parent', '--date=short',
67  '--pretty=format:! %ad - commit %h%n%n%w(80,1,3)- %s%n%n%b%n'
68  ]
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(
85  check_output([
86  'git',
87  'log',
88  '--pretty=format:%aN',
89  '{0}^1..{0}^2'.format(match.group(1)),
90  ]).splitlines())
91  return ' - {0} (commit {1})'.format(', '.join(sorted(authors)),
92  match.group(1))
93  except CalledProcessError:
94  return match.group(0)
95 
96  out = re.sub(r' - commit ([0-9a-f]+)', add_contributors, out)
97  return out
98 
99 
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:109
def releaseNotes(path=os.curdir, from_tag=None, branch=None)

◆ tag_bar()

def prepare_gaudi_release.tag_bar (   pkg,
  version = None 
)

Definition at line 123 of file prepare_gaudi_release.py.

123 def tag_bar(pkg, version=None):
124  title = ' %s %s ' % (pkg, version)
125  letf_chars = (78 - len(title)) / 2
126  right_chars = 78 - letf_chars - len(title)
127  separator = ('=' * letf_chars) + title + ('=' * right_chars)
128  return separator
129 
130 
def tag_bar(pkg, version=None)

◆ updateReleaseNotes()

def prepare_gaudi_release.updateReleaseNotes (   path,
  notes 
)
Smartly prepend the content of notes to the release.notes file in path.

Definition at line 100 of file prepare_gaudi_release.py.

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

◆ versionKey()

def prepare_gaudi_release.versionKey (   x)
Key function to be passes to list.sort() to sort strings
as version numbers.

Definition at line 33 of file prepare_gaudi_release.py.

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

Variable Documentation

◆ _VK_RE

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

Definition at line 30 of file prepare_gaudi_release.py.