4 Release script for botan (http://botan.randombit.net/)
6 (C) 2011, 2012 Jack Lloyd
8 Distributed under the terms of the Botan license
23 (stdout, stderr) = subproc.communicate()
25 stdout = stdout.strip()
26 stderr = stderr.strip()
28 if subproc.returncode != 0:
33 raise Exception(
'Running %s failed' % (name))
41 mtn = subprocess.Popen([
'mtn',
'--db', db] + args,
42 stdout=subprocess.PIPE,
43 stderr=subprocess.PIPE)
48 tokens = shlex.split(
run_monotone(db, [
'automate',
'certs', rev_id]))
50 def usable_cert(cert):
51 if 'signature' not in cert
or cert[
'signature'] !=
'ok':
53 if 'trust' not in cert
or cert[
'trust'] !=
'trusted':
55 if 'name' not in cert
or 'value' not in cert:
59 def cert_builder(tokens):
60 pairs = zip(tokens[::2], tokens[1::2])
64 if usable_cert(current_cert):
65 name = current_cert[
'name']
66 value = current_cert[
'value']
69 logging.debug(
'Cert %s "%s" for rev %s' % (name, value, rev_id))
72 current_cert[pair[0]] = pair[1]
74 certs = dict(cert_builder(tokens))
81 return int(certs[
'date'].replace(
'-',
'')[0:8])
83 logging.info(
'Could not retreive date for %s' % (rev_id))
87 for filename
in files:
88 logging.info(
'Signing %s using PGP id %s' % (filename, keyid))
90 gpg = subprocess.Popen([
'gpg',
'--armor',
'--detach-sign',
91 '--local-user', keyid, filename],
92 stdout=subprocess.PIPE,
93 stderr=subprocess.PIPE)
98 parser = optparse.OptionParser()
99 parser.add_option(
'--verbose', action=
'store_true',
100 default=
False, help=
'Extra debug output')
102 parser.add_option(
'--output-dir', metavar=
'DIR',
104 help=
'Where to place output (default %default)')
106 parser.add_option(
'--mtn-db', metavar=
'DB',
107 default=os.getenv(
'BOTAN_MTN_DB',
''),
108 help=
'Set monotone db (default \'%default\')')
110 parser.add_option(
'--pgp-key-id', metavar=
'KEYID',
112 help=
'PGP signing key (default %default)')
114 return parser.parse_args(args)
120 if e.errno != errno.ENOENT:
134 logging.basicConfig(stream = sys.stdout,
135 format =
'%(levelname) 7s: %(message)s',
138 if options.mtn_db ==
'':
139 logging.error(
'No monotone db set (use --mtn-db)')
142 if not os.access(options.mtn_db, os.R_OK):
143 logging.error(
'Monotone db %s not found' % (options.mtn_db))
147 logging.error(
'Usage: %s version' % (sys.argv[0]))
153 [
'automate',
'select',
't:' + version])
156 logging.error(
'No revision for %s found' % (version))
159 output_basename = os.path.join(options.output_dir,
'Botan-' + version)
161 output_tgz = output_basename +
'.tgz'
162 output_tbz = output_basename +
'.tbz'
164 logging.info(
'Found revision id %s' % (rev_id))
166 if os.access(output_basename, os.X_OK):
167 shutil.rmtree(output_basename)
170 [
'checkout',
'-r', rev_id, output_basename])
172 shutil.rmtree(os.path.join(output_basename,
'_MTN'))
175 version_file = os.path.join(output_basename,
'botan_version.py')
177 if os.access(version_file, os.R_OK):
180 contents = open(version_file).readlines()
182 def content_rewriter():
183 for line
in contents:
184 if line ==
'release_vc_rev = None\n':
185 yield 'release_vc_rev = \'mtn:%s\'\n' % (rev_id)
186 elif line ==
'release_datestamp = 0\n':
187 yield 'release_datestamp = %d\n' % (
datestamp(options.mtn_db, rev_id))
191 open(version_file,
'w').write(
''.join(list(content_rewriter())))
193 logging.error(
'Cannot find %s' % (version_file))
197 os.makedirs(options.output_dir)
199 if e.errno != errno.EEXIST:
200 logging.error(
'Creating dir %s failed %s' % (options.output_dir, e))
205 archive = tarfile.open(output_tgz,
'w:gz')
206 archive.add(output_basename)
211 archive = tarfile.open(output_tbz,
'w:bz2')
212 archive.add(output_basename)
215 if options.pgp_key_id !=
'':
216 gpg_sign(options.pgp_key_id, [output_tbz, output_tgz])
218 shutil.rmtree(output_basename)
222 if __name__ ==
'__main__':
225 except Exception
as e:
228 logging.info(traceback.format_exc())
def check_subprocess_results(subproc, name)
def run_monotone(db, args)
def gpg_sign(keyid, files)
def get_certs(db, rev_id)
def datestamp(db, rev_id)
std::runtime_error Exception
def remove_file_if_exists(fspath)