Botan 1.10.17

Functions
dist Namespace Reference

## Functions
def | check_subprocess_results (subproc, name)
def | datestamp (db, rev_id)
def | get_certs (db, rev_id)
def | gpg_sign (keyid, files)
def | main (args=None)
def | parse_args (args)
def | remove_file_if_exists (fspath)
def | run_monotone (db, args)

## Detailed Description

    Release script for botan (http://botan.randombit.net/)

    (C) 2011, 2012 Jack Lloyd

    Distributed under the terms of the Botan license

## Function Documentation

## ◆ check_subprocess_results()

def dist.check_subprocess_results | ( |  | subproc,
|  |  | name
| ) |  |

Definition at line 22 of file dist.py.

Referenced by gpg_sign(), and run_monotone().

22 def check_subprocess_results(subproc, name):
23 (stdout, stderr) = subproc.communicate()
24
25 stdout = stdout.strip()
26 stderr = stderr.strip()
27
28 if subproc.returncode != 0:
29 if stdout != '':
30 logging.error(stdout)
31 if stderr != '':
32 logging.error(stderr)
33 raise Exception('Running %s failed' % (name))
34 else:
35 if stderr != '':
36 logging.debug(stderr)
37
38 return stdout
39
dist.check_subprocess_results
def check_subprocess_results(subproc, name)
Definition: dist.py:22
Botan::Exception
std::runtime_error Exception
Definition: exceptn.h:19

## ◆ datestamp()

def dist.datestamp | ( |  | db,
|  |  | rev_id
| ) |  |

Definition at line 77 of file dist.py.

References get_certs().

Referenced by main().

77 def datestamp(db, rev_id):
78 certs = get_certs(db, rev_id)
79
80 if 'date' in certs:
81 return int(certs['date'].replace('-','')[0:8])
82
83 logging.info('Could not retreive date for %s' % (rev_id))
84 return 0
85
dist.get_certs
def get_certs(db, rev_id)
Definition: dist.py:47
dist.datestamp
def datestamp(db, rev_id)
Definition: dist.py:77

## ◆ get_certs()

def dist.get_certs | ( |  | db,
|  |  | rev_id
| ) |  |

Definition at line 47 of file dist.py.

References run_monotone().

Referenced by datestamp().

47 def get_certs(db, rev_id):
48 tokens = shlex.split(run_monotone(db, ['automate', 'certs', rev_id]))
49
50 def usable_cert(cert):
51 if 'signature' not in cert or cert['signature'] != 'ok':
52 return False
53 if 'trust' not in cert or cert['trust'] != 'trusted':
54 return False
55 if 'name' not in cert or 'value' not in cert:
56 return False
57 return True
58
59 def cert_builder(tokens):
60 pairs = zip(tokens[::2], tokens[1::2])
61 current_cert = {}
62 for pair in pairs:
63 if pair[0] == 'key':
64 if usable_cert(current_cert):
65 name = current_cert['name']
66 value = current_cert['value']
67 current_cert = {}
68
69 logging.debug('Cert %s "%s" for rev %s' % (name, value, rev_id))
70 yield (name, value)
71
72 current_cert[pair[0]] = pair[1]
73
74 certs = dict(cert_builder(tokens))
75 return certs
76
dist.run_monotone
def run_monotone(db, args)
Definition: dist.py:40
dist.get_certs
def get_certs(db, rev_id)
Definition: dist.py:47

## ◆ gpg_sign()

def dist.gpg_sign | ( |  | keyid,
|  |  | files
| ) |  |

Definition at line 86 of file dist.py.

References check_subprocess_results().

Referenced by main().

86 def gpg_sign(keyid, files):
87 for filename in files:
88 logging.info('Signing %s using PGP id %s' % (filename, keyid))
89
90 gpg = subprocess.Popen(['gpg', '--armor', '--detach-sign',
91 '--local-user', keyid, filename],
92 stdout=subprocess.PIPE,
93 stderr=subprocess.PIPE)
94
95 check_subprocess_results(gpg, 'gpg')
96
dist.check_subprocess_results
def check_subprocess_results(subproc, name)
Definition: dist.py:22
dist.gpg_sign
def gpg_sign(keyid, files)
Definition: dist.py:86

## ◆ main()

def dist.main | ( |  | args = `None` | ) |

Definition at line 123 of file dist.py.

References datestamp(), gpg_sign(), parse_args(), remove_file_if_exists(), and run_monotone().

123 def main(args = None):
124 if args is None:
125 args = sys.argv[1:]
126
127 (options, args) = parse_args(args)
128
129 def log_level():
130 if options.verbose:
131 return logging.DEBUG
132 return logging.INFO
133
134 logging.basicConfig(stream = sys.stdout,
135 format = '%(levelname) 7s: %(message)s',
136 level = log_level())
137
138 if options.mtn_db == '':
139 logging.error('No monotone db set (use --mtn-db)')
140 return 1
141
142 if not os.access(options.mtn_db, os.R_OK):
143 logging.error('Monotone db %s not found' % (options.mtn_db))
144 return 1
145
146 if len(args) != 1:
147 logging.error('Usage: %s version' % (sys.argv[0]))
148 return 1
149
150 version = args[0]
151
152 rev_id = run_monotone(options.mtn_db,
153 ['automate', 'select', 't:' + version])
154
155 if rev_id == '':
156 logging.error('No revision for %s found' % (version))
157 return 2
158
159 output_basename = os.path.join(options.output_dir, 'Botan-' + version)
160
161 output_tgz = output_basename + '.tgz'
162 output_tbz = output_basename + '.tbz'
163
164 logging.info('Found revision id %s' % (rev_id))
165
166 if os.access(output_basename, os.X_OK):
167 shutil.rmtree(output_basename)
168
169 run_monotone(options.mtn_db,
170 ['checkout', '-r', rev_id, output_basename])
171
172 shutil.rmtree(os.path.join(output_basename, '_MTN'))
173 remove_file_if_exists(os.path.join(output_basename, '.mtn-ignore'))
174
175 version_file = os.path.join(output_basename, 'botan_version.py')
176
177 if os.access(version_file, os.R_OK):
178 # rewrite botan_version.py
179
180 contents = open(version_file).readlines()
181
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))
188 else:
189 yield line
190
191 open(version_file, 'w').write(''.join(list(content_rewriter())))
192 else:
193 logging.error('Cannot find %s' % (version_file))
194 return 2
195
196 try:
197 os.makedirs(options.output_dir)
198 except OSError as e:
199 if e.errno != errno.EEXIST:
200 logging.error('Creating dir %s failed %s' % (options.output_dir, e))
201 return 2
202
203 remove_file_if_exists(output_tgz)
204 remove_file_if_exists(output_tgz + '.asc')
205 archive = tarfile.open(output_tgz, 'w:gz')
206 archive.add(output_basename)
207 archive.close()
208
209 remove_file_if_exists(output_tbz)
210 remove_file_if_exists(output_tbz + '.asc')
211 archive = tarfile.open(output_tbz, 'w:bz2')
212 archive.add(output_basename)
213 archive.close()
214
215 if options.pgp_key_id != '':
216 gpg_sign(options.pgp_key_id, [output_tbz, output_tgz])
217
218 shutil.rmtree(output_basename)
219
220 return 0
221
dist.run_monotone
def run_monotone(db, args)
Definition: dist.py:40
dist.gpg_sign
def gpg_sign(keyid, files)
Definition: dist.py:86
dist.datestamp
def datestamp(db, rev_id)
Definition: dist.py:77
dist.remove_file_if_exists
def remove_file_if_exists(fspath)
Definition: dist.py:116
dist.parse_args
def parse_args(args)
Definition: dist.py:97
dist.main
def main(args=None)
Definition: dist.py:123

## ◆ parse_args()

def dist.parse_args | ( |  | args | ) |

Definition at line 97 of file dist.py.

Referenced by main().

97 def parse_args(args):
98 parser = optparse.OptionParser()
99 parser.add_option('--verbose', action='store_true',
100 default=False, help='Extra debug output')
101
102 parser.add_option('--output-dir', metavar='DIR',
103 default='.',
104 help='Where to place output (default %default)')
105
106 parser.add_option('--mtn-db', metavar='DB',
107 default=os.getenv('BOTAN_MTN_DB', ''),
108 help='Set monotone db (default \'%default\')')
109
110 parser.add_option('--pgp-key-id', metavar='KEYID',
111 default='EFBADFBC',
112 help='PGP signing key (default %default)')
113
114 return parser.parse_args(args)
115
dist.parse_args
def parse_args(args)
Definition: dist.py:97

## ◆ remove_file_if_exists()

def dist.remove_file_if_exists | ( |  | fspath | ) |

Definition at line 116 of file dist.py.

Referenced by main().

116 def remove_file_if_exists(fspath):
117 try:
118 os.unlink(fspath)
119 except OSError as e:
120 if e.errno != errno.ENOENT:
121 raise
122
dist.remove_file_if_exists
def remove_file_if_exists(fspath)
Definition: dist.py:116

## ◆ run_monotone()

def dist.run_monotone | ( |  | db,
|  |  | args
| ) |  |

Definition at line 40 of file dist.py.

References check_subprocess_results().

Referenced by get_certs(), and main().

40 def run_monotone(db, args):
41 mtn = subprocess.Popen(['mtn', '--db', db] + args,
42 stdout=subprocess.PIPE,
43 stderr=subprocess.PIPE)
44
45 return check_subprocess_results(mtn, 'mtn')
46
dist.check_subprocess_results
def check_subprocess_results(subproc, name)
Definition: dist.py:22
dist.run_monotone
def run_monotone(db, args)
Definition: dist.py:40