Mercurial > treepkg
comparison test/mocksudopbuilder.py @ 84:98a7d70746a9
Make BinaryPackager remove all files that do not belong to the binary
package from the pkg/<rev>/binary directory after pbuilder finished.
Also, add tests for this and some corresponding test support code.
author | Bernhard Herzog <bh@intevation.de> |
---|---|
date | Mon, 10 Sep 2007 17:13:33 +0000 |
parents | |
children | c0ea6cbb0fd2 |
comparison
equal
deleted
inserted
replaced
83:83e48a76f759 | 84:98a7d70746a9 |
---|---|
1 #! /usr/bin/env python | |
2 # Copyright (C) 2007 by Intevation GmbH | |
3 # Authors: | |
4 # Bernhard Herzog <bh@intevation.de> | |
5 # | |
6 # This program is free software under the GPL (>=v2) | |
7 # Read the file COPYING coming with the software for details. | |
8 | |
9 """ | |
10 Mock sudo that mimics some aspects of sudo pbuilder invocations for test cases | |
11 """ | |
12 | |
13 import sys | |
14 import os | |
15 import shutil | |
16 import tempfile | |
17 import re | |
18 | |
19 from optparse import OptionParser | |
20 | |
21 sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) | |
22 | |
23 from treepkg.util import extract_value_for_key, writefile | |
24 from treepkg.run import call | |
25 from treepkg.cmdexpand import cmdexpand | |
26 | |
27 | |
28 def parse_command_line(args): | |
29 if len(args) < 2: | |
30 raise RuntimeError("mocksudopbuilder must be called with at least" | |
31 " two parameters") | |
32 if args[0] != "/usr/sbin/pbuilder": | |
33 raise RuntimeError("mocksudopbuilder must be called with" | |
34 " /usr/sbin/pbuilder as first argument") | |
35 | |
36 cmd = args[1] | |
37 if cmd != "build": | |
38 raise RuntimeError("mocksudopbuilder only supports the pbuilder build" | |
39 " command") | |
40 | |
41 args = args[2:] | |
42 | |
43 parser = OptionParser() | |
44 parser.add_option("--configfile") | |
45 parser.add_option("--logfile") | |
46 parser.add_option("--buildresult") | |
47 | |
48 opts, rest = parser.parse_args(args) | |
49 return opts, rest | |
50 | |
51 | |
52 class DSC(object): | |
53 | |
54 def __init__(self, filename): | |
55 self.filename = os.path.abspath(filename) | |
56 self.parse_dsc_file() | |
57 | |
58 def parse_dsc_file(self): | |
59 lines = open(self.filename).readlines() | |
60 | |
61 self.source_package = extract_value_for_key(lines, "Source:") | |
62 | |
63 raw_binaries = extract_value_for_key(lines, "Binary:") | |
64 self.binaries = [name.strip() for name in raw_binaries.split(",")] | |
65 | |
66 version = extract_value_for_key(lines, "Version:") | |
67 match = re.match(r"\d+:", version) | |
68 if match: | |
69 version = version[match.end(0):] | |
70 self.version = version | |
71 match = re.search("-([^-]+)$", version) | |
72 if match: | |
73 self.base_version = version[:match.start(0)] | |
74 self.revision = match.group(1) | |
75 else: | |
76 self.base_version = version | |
77 self.revision = "" | |
78 | |
79 self.files = [] | |
80 for i in range(len(lines) - 1, -1, -1): | |
81 line = lines[i] | |
82 if line[0] != " ": | |
83 break | |
84 self.files.append(line.split()[-1]) | |
85 | |
86 def unpack_source_pkg(dsc): | |
87 tempdir = tempfile.mkdtemp() | |
88 call(cmdexpand("dpkg-source -x $filename", filename=dsc.filename), | |
89 cwd=tempdir, stdout=sys.stdout) | |
90 return os.path.join(tempdir, dsc.source_package + "-" + dsc.base_version) | |
91 | |
92 def parse_debian_control(filename): | |
93 packages = [] | |
94 lines = [line.strip() for line in open(filename).readlines()] | |
95 while lines: | |
96 try: | |
97 empty_line = lines.index("") | |
98 except ValueError: | |
99 empty_line = len(lines) | |
100 paragraph = lines[:empty_line] | |
101 lines = lines[empty_line + 1:] | |
102 | |
103 package_name = extract_value_for_key(paragraph, "Package:") | |
104 arch = extract_value_for_key(paragraph, "Architecture:") | |
105 if package_name is not None: | |
106 packages.append((package_name, arch)) | |
107 return packages | |
108 | |
109 def create_binary_results(buildresult, dsc, packages): | |
110 for name, arch in packages: | |
111 if arch == "any": | |
112 arch = "i386" | |
113 writefile(os.path.join(buildresult, | |
114 "%s_%s_%s.deb" % (name, dsc.version, arch)), | |
115 "") | |
116 | |
117 basename = os.path.splitext(os.path.basename(dsc.filename))[0] | |
118 writefile(os.path.join(buildresult, basename + "_i386.changes"), "") | |
119 | |
120 def create_source_results(buildresult, dsc): | |
121 dscdir = os.path.dirname(dsc.filename) | |
122 shutil.copy(dsc.filename, buildresult) | |
123 for name in dsc.files: | |
124 shutil.copy(os.path.join(dscdir, name), buildresult) | |
125 | |
126 def mock_pbuilder_build(opts, dscfilename): | |
127 dsc = DSC(dscfilename) | |
128 print "unpacking source package" | |
129 unpacked_dir = unpack_source_pkg(dsc) | |
130 try: | |
131 packages = parse_debian_control(os.path.join(unpacked_dir, "debian", | |
132 "control")) | |
133 create_binary_results(opts.buildresult, dsc, packages) | |
134 create_source_results(opts.buildresult, dsc) | |
135 finally: | |
136 print "removing tempdir", repr(os.path.dirname(unpacked_dir)) | |
137 shutil.rmtree(os.path.dirname(unpacked_dir)) | |
138 | |
139 def main(): | |
140 opts, rest = parse_command_line(sys.argv[1:]) | |
141 for optname in ["buildresult"]: | |
142 if getattr(opts, optname) is None: | |
143 raise RuntimeError("Missing required option %r" % optname) | |
144 if len(rest) != 1: | |
145 raise RuntimeError("Missing required argument for .dsc file") | |
146 if opts.logfile: | |
147 sys.stdout = open(opts.logfile, "w", 1) | |
148 mock_pbuilder_build(opts, rest[0]) | |
149 | |
150 main() |