The Gaudi Framework  v33r0 (d5ea422b)
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+)')
 

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

26 def checkGitVersion():
27  '''
28  Ensure we have a usable version of Git (>= 1.7.9.1).
29 
30  See:
31  * https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/1.7.9.1.txt
32  * https://github.com/git/git/commit/36ed1913e1d5de0930e59db6eeec3ccb2bd58bd9
33  '''
34  version = check_output(['git', '--version']).split()[-1]
35  if versionKey(version) < versionKey('1.7.9.1'):
36  raise RuntimeError(
37  'bad version of git found: %s (1.7.9.1 required)' % version)
38 
39 

◆ findLatestTag()

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

Definition at line 53 of file prepare_gaudi_release.py.

53 def findLatestTag():
54  '''
55  Return the latest Gaudi tag (of the format "v*r*...").
56  '''
57  logging.info('looking for latest tag')
58  cmd = ['git', 'tag']
59  logging.debug('using command %r', cmd)
60  output = check_output(cmd)
61  vers_exp = re.compile(r'^v\d+r\d+(p\d+)?$')
62  tags = [tag for tag in output.splitlines() if vers_exp.match(tag)]
63  if tags:
64  tags.sort(key=versionKey)
65  logging.info('found %s', tags[-1])
66  return tags[-1]
67  logging.info('no valid tag found')
68 
69 

◆ main()

def prepare_gaudi_release.main ( )

Definition at line 141 of file prepare_gaudi_release.py.

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

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

◆ tag_bar()

def prepare_gaudi_release.tag_bar (   pkg,
  version = None 
)

Definition at line 133 of file prepare_gaudi_release.py.

133 def tag_bar(pkg, version=None):
134  title = ' %s %s ' % (pkg, version)
135  letf_chars = (78 - len(title)) / 2
136  right_chars = 78 - letf_chars - len(title)
137  separator = ('=' * letf_chars) + title + ('=' * right_chars)
138  return separator
139 
140 
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 110 of file prepare_gaudi_release.py.

110 def updateReleaseNotes(path, notes):
111  '''
112  Smartly prepend the content of notes to the release.notes file in path.
113  '''
114  notes_filename = os.path.join(path, 'doc', 'release.notes')
115  logging.info('updating %s', notes_filename)
116  from itertools import takewhile, dropwhile
117 
118  def dropuntil(predicate, iterable):
119  return dropwhile(lambda x: not predicate(x), iterable)
120 
121  with open(notes_filename) as notes_file:
122  orig_data = iter(list(notes_file))
123  header = takewhile(str.strip, orig_data)
124  with open(notes_filename, 'w') as notes_file:
125  notes_file.writelines(header)
126  notes_file.write('\n')
127  notes_file.writelines(l.rstrip() + '\n' for l in notes.splitlines())
128  notes_file.write('\n')
129  notes_file.writelines(
130  dropuntil(re.compile(r'^!?============').match, orig_data))
131 
132 
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 43 of file prepare_gaudi_release.py.

43 def versionKey(x):
44  '''
45  Key function to be passes to list.sort() to sort strings
46  as version numbers.
47  '''
48  return [
49  int(i) if i[0] in '0123456789' else i for i in _VK_RE.split(x) if i
50  ]
51 
52 

Variable Documentation

◆ _VK_RE

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

Definition at line 40 of file prepare_gaudi_release.py.