3 Simple script for automatic validation of a patch.
6 validate_patch.py <savannah patch id>
7 validate_patch.py file.patch
10 __author__ =
"Marco Clemencic <marco.clemencic@cern.ch>"
14 from shutil
import rmtree
15 from tempfile
import mkdtemp
16 from subprocess
import Popen, PIPE
18 from HTMLParser
import HTMLParser
19 from urllib
import urlopen
22 def __init__(self, id = None, title = None, files = None):
28 r = self.__class__.__name__ +
"("
30 if self.
id is not None:
31 fields.append(
"id=%r" % self.
id)
32 if self.
title is not None:
33 fields.append(
"title=%r" % self.
title)
35 fields.append(
"files=%r" % self.
files)
36 return "%s(%s)" % (self.__class__.__name__,
",".join(fields))
40 __attachments_id__ =
"hidsubpartcontentattached"
42 HTMLParser.__init__(self)
65 and "file_id=" in attrs.get(
"href",
"")):
72 filename = self._currentFileData.split(
":")[-1].strip()
80 data = data.replace(
" ",
" ")
85 server =
"savannah.cern.ch"
86 path =
"/patch/?%d" % patch
87 conn = httplib.HTTPSConnection(server)
88 conn.request(
"GET", path)
89 r = conn.getresponse()
93 raise RuntimeError(r.status, r.reason,
"https://" + server + path)
103 parser.feed(urlopen(
"https://savannah.cern.ch/patch/?%d" % patch).read())
108 file_id = int(file_id)
109 return urlopen(
"https://savannah.cern.ch/patch/download.php?file_id=%d" % file_id).read()
112 """Class to create a temporary directory."""
113 def __init__(self, suffix="", prefix="tmp", dir=None, keep_var="KEEPTEMPDIR"):
116 'keep_var' is used to define which environment variable will prevent the
117 deletion of the directory.
119 The other arguments are the same as tempfile.mkdtemp.
122 self.
_name = mkdtemp(suffix, prefix, dir)
125 """Returns the name of the temporary directory"""
129 """Convert to string."""
135 Remove the temporary directory.
139 logging.info(
"%s set: I do not remove the temporary directory '%s'",
145 return Popen([
"svn",
"co",
"http://svnweb.cern.ch/guest/gaudi/Gaudi/trunk", os.path.join(path,
"Gaudi")]).wait()
148 proc = Popen([
"patch",
"-p0",
"--batch"], cwd = path, stdin = PIPE)
149 proc.communicate(patch_data)
150 return proc.returncode
153 return Popen(
" ".join([
"cmt",
"show",
"projects"]), shell =
True, cwd = path).wait()
156 if "LBCONFIGURATIONROOT" in os.environ:
158 "-f", os.path.join(os.environ[
"LBCONFIGURATIONROOT"],
"data",
"Makefile")]
159 if "use-distcc" in os.environ.get(
"CMTEXTRATAGS",
""):
162 cmd = [
"cmt",
"-pack=GaudiRelease",
"broadcast",
"cmt",
"make",
"all_groups"]
163 return Popen(
" ".join(cmd),
167 cmd = [
"cmt",
"-pack=GaudiRelease",
"TestProject"]
168 proc = Popen(
" ".join(cmd),
173 while proc.poll()
is None:
174 chunk = proc.stdout.read(256)
176 sys.stdout.write(chunk)
178 chunk = proc.stdout.read(256)
180 sys.stdout.write(chunk)
184 return proc.returncode
186 output = (
"".join(output)).splitlines()
189 if ": FAIL" in l
or ": ERROR" in l:
194 logging.basicConfig()
195 if len(sys.argv) != 2:
197 validate_patch.py <savannah patch id>
198 validate_patch.py file.patch
201 patch_id = sys.argv[1]
202 if os.path.isfile(patch_id):
203 patch_data = open(patch_id,
"rb").read()
206 patch_file_id = patch.files[0][1]
209 td =
TempDir(prefix = patch_id +
"-")
211 print "Sorry, problems checking out Gaudi. Try again."
213 top_dir = os.path.join(str(td),
"Gaudi")
214 open(os.path.join(top_dir, patch_id) ,
"wb").write(patch_data)
217 for l
in Popen([
"svn",
"info", top_dir], stdout = PIPE).communicate()[0].splitlines():
218 if l.startswith(
"Revision:"):
219 revision = int(l.split()[-1])
222 actions = [(
lambda path:
apply_patch(patch_data, path),
"application of the patch"),
223 (check,
"check of the configuration"),
228 for action, title
in actions:
234 print "*** Patch %s failed during %s (using revision r%d) ***" % (patch_id, failure, revision)
237 print "*** Patch %s succeeded (using revision r%d) ***" % (patch_id, revision)
240 if __name__ ==
"__main__":
string __attachments_id__