| The Gaudi Framework v28r2p1 (f1a77ff4)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

prepare_gaudi_release.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 '''
3 Script to prepare the release of Gaudi.
4
5 @author Marco Clemencic
6 '''
7
8 import os
9 import sys
10 import logging
11 import re
12 from subprocess import check_output, CalledProcessError
13
14 def checkGitVersion():
15 '''
16 Ensure we have a usable version of Git (>= 1.7.9.1).
17
18 See:
19 * https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/1.7.9.1.txt
20 * https://github.com/git/git/commit/36ed1913e1d5de0930e59db6eeec3ccb2bd58bd9
21 '''
22 version = check_output(['git', '--version']).split()[-1]
23 if versionKey(version) < versionKey('1.7.9.1'):
24 raise RuntimeError('bad version of git found: %s (1.7.9.1 required)' % version)
25
26 _VK_RE = re.compile(r'(\d+|\D+)')
27 def versionKey(x):
28 '''
29 Key function to be passes to list.sort() to sort strings
30 as version numbers.
31 '''
32 return [int(i) if i[0] in '0123456789' else i
33 for i in _VK_RE.split(x)
34 if i]
35
36 def findLatestTag():
37 '''
38 Return the latest Gaudi tag (of the format "v*r*...").
39 '''
40 logging.info('looking for latest tag')
41 cmd = ['git', 'tag']
42 logging.debug('using command %r', cmd)
43 output = check_output(cmd)
44 vers_exp = re.compile(r'^v\d+r\d+(p\d+)?$')
45 tags = [tag
46 for tag in output.splitlines()
47 if vers_exp.match(tag)]
48 if tags:
49 tags.sort(key=versionKey)
50 logging.info('found %s', tags[-1])
51 return tags[-1]
52 logging.info('no valid tag found')
53
54 def releaseNotes(path=os.curdir, from_tag=None, branch=None):
55 '''
56 Return the release notes (in the old LHCb format) extracted from git
57 commits for a given path.
58 '''
59 cmd = ['git', 'log',
60 '--first-parent', '--date=short',
61 '--pretty=format:! %ad - commit %h%n%n%w(80,1,3)- %s%n%n%b%n']
62 if from_tag:
63 cmd.append('{0}..{1}'.format(from_tag, branch or ''))
64 elif branch:
65 cmd.append(branch)
66 cmd.append('--')
67 cmd.append(path)
68 logging.info('preparing release notes for %s%s', path,
69 ' since ' + from_tag if from_tag else '')
70 logging.debug('using command %r', cmd)
71 # remove '\r' characters from commit messages
72 out = check_output(cmd).replace('\r', '')
73
74 # replace ' - commit 123abc' with ' - Contributor Name (commit 123abc)'
75 def add_contributors(match):
76 try:
77 authors = set(check_output(['git', 'log', '--pretty=format:%aN',
78 '{0}^1..{0}^2'.format(match.group(1)),
79 ]).splitlines())
80 return ' - {0} (commit {1})'.format(', '.join(sorted(authors)),
81 match.group(1))
82 except CalledProcessError:
83 return match.group(0)
84 out = re.sub(r' - commit ([0-9a-f]+)', add_contributors, out)
85 return out
86
87 def updateReleaseNotes(path, notes):
88 '''
89 Smartly prepend the content of notes to the release.notes file in path.
90 '''
91 notes_filename = os.path.join(path, 'doc', 'release.notes')
92 logging.info('updating %s', notes_filename)
93 from itertools import takewhile, dropwhile
94 def dropuntil(predicate, iterable):
95 return dropwhile(lambda x: not predicate(x), iterable)
96 with open(notes_filename) as notes_file:
97 orig_data = iter(list(notes_file))
98 header = takewhile(str.strip, orig_data)
99 with open(notes_filename, 'w') as notes_file:
100 notes_file.writelines(header)
101 notes_file.write('\n')
102 notes_file.writelines(l.rstrip() + '\n' for l in notes.splitlines())
103 notes_file.write('\n')
104 notes_file.writelines(dropuntil(re.compile(r'^!?============').match, orig_data))
105
106
107 def tag_bar(pkg, version=None):
108 title = ' %s %s ' % (pkg, version)
109 letf_chars = (78 - len(title)) / 2
110 right_chars = 78 - letf_chars - len(title)
111 separator = ('=' * letf_chars) + title + ('=' * right_chars)
112 return separator
113
114
115 def main():
116 logging.basicConfig(level=logging.DEBUG)
117 os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
118 # Find the version of HEPTools (LCG)
119 for l in open('toolchain.cmake'):
120 m = re.match(r'^\s*set\(\s*heptools_version\s+(\S*)\s*\)', l)
121 if m:
122 HEPToolsVers = m.group(1)
123 print "Using HEPTools", HEPToolsVers
124 break
125 else:
126 logging.error('Cannot find HEPTools version')
127 sys.exit(1)
128
129 # Collect all the packages in the project with their directory
130 def all_subdirs():
131 for dirpath, dirnames, filenames in os.walk(os.curdir):
132 if 'CMakeLists.txt' in filenames and dirpath != os.curdir:
133 dirnames[:] = []
134 yield dirpath
135 else:
136 dirnames[:] = [dirname for dirname in dirnames
137 if (not dirname.startswith('build.') and
138 dirname != 'cmake')]
139
140 # Ask for the version of the project
141 latest_tag = findLatestTag()
142
143 old_version = latest_tag.split('_')[-1]
144 new_version = raw_input(("The old version of the project is %s, "
145 "which is the new one? ") % old_version)
146
147 release_notes = {}
148 # for each package in the project update the release.notes
149 for pkgdir in all_subdirs():
150 updateReleaseNotes(pkgdir,
151 tag_bar('Gaudi', new_version) + '\n\n' +
152 releaseNotes(pkgdir, latest_tag, 'master'))
153
154 # update the global CMakeLists.txt
155 out = []
156 for l in open('CMakeLists.txt'):
157 if l.strip().startswith('gaudi_project'):
158 l = 'gaudi_project(Gaudi %s)\n' % new_version
159 out.append(l)
160 open('CMakeLists.txt', "w").writelines(out)
161
162
163 if __name__ == '__main__':
164 checkGitVersion()
165 main()
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
prepare_gaudi_release.releaseNotes
def releaseNotes(path=os.curdir, from_tag=None, branch=None)
Definition: prepare_gaudi_release.py:54
prepare_gaudi_release.findLatestTag
def findLatestTag()
Definition: prepare_gaudi_release.py:36
prepare_gaudi_release.main
def main()
Definition: prepare_gaudi_release.py:115
prepare_gaudi_release.tag_bar
def tag_bar(pkg, version=None)
Definition: prepare_gaudi_release.py:107
prepare_gaudi_release.updateReleaseNotes
def updateReleaseNotes(path, notes)
Definition: prepare_gaudi_release.py:87
prepare_gaudi_release.versionKey
def versionKey(x)
Definition: prepare_gaudi_release.py:27
prepare_gaudi_release.checkGitVersion
def checkGitVersion()
Definition: prepare_gaudi_release.py:14