# HG changeset patch # User cmlenz # Date 1130285008 0 # Node ID 5f84af72d17f315ed4377dd74bc965e227692570 # Parent cb9af0adb3659f5fc29a4a8a9c3fcaa69736de9b * Store executable bit in ZIP archives (from `svn:executable`). * Remove some unused imports etc. diff --git a/bitten/queue.py b/bitten/queue.py --- a/bitten/queue.py +++ b/bitten/queue.py @@ -9,7 +9,6 @@ from itertools import ifilter import logging -import os import re from bitten.model import BuildConfig, TargetPlatform, Build, BuildStep diff --git a/bitten/recipe.py b/bitten/recipe.py --- a/bitten/recipe.py +++ b/bitten/recipe.py @@ -10,7 +10,6 @@ import keyword import logging import os -import re try: set except NameError: diff --git a/bitten/slave.py b/bitten/slave.py --- a/bitten/slave.py +++ b/bitten/slave.py @@ -7,7 +7,6 @@ # you should have received as part of this distribution. The terms # are also available at http://bitten.cmlenz.net/wiki/License. -from ConfigParser import ConfigParser from datetime import datetime import logging import os @@ -137,19 +136,14 @@ try: zip_file = zipfile.ZipFile(path, 'r') try: - badfile = zip_file.testzip() - if badfile: - log.error('Bad CRC for file %s in ZIP archive at %s', - badfile, path) - raise beep.ProtocolError(550, 'Corrupt snapshot archive') - names = [] for name in zip_file.namelist(): if name.startswith('/') or '..' in name: continue names.append(os.path.normpath(name)) + info = zip_file.getinfo(name) fullpath = os.path.join(project_dir, name) - if name.endswith('/'): + if name.endswith('/') or info.external_attr & 0x10: os.makedirs(fullpath) else: dirname = os.path.dirname(fullpath) @@ -157,9 +151,17 @@ os.makedirs(dirname) fileobj = file(fullpath, 'wb') try: - fileobj.write(zip_file.read(name)) + try: + fileobj.write(zip_file.read(name)) + except zipfile.BadZipFile: + log.error('Bad CRC for file %s', name, path) + raise beep.ProtocolError(550, 'Corrupt ' + 'snapshot archive') finally: fileobj.close() + mode = (info.external_attr >> 16) & 0777 + if mode: + os.chmod(fullpath, mode) finally: zip_file.close() diff --git a/bitten/snapshot.py b/bitten/snapshot.py --- a/bitten/snapshot.py +++ b/bitten/snapshot.py @@ -171,7 +171,7 @@ """ log.debug('Preparing snapshot archive for %s@%s', root.path, root.rev) - zip = zipfile.ZipFile(filepath, 'w', zipfile.ZIP_DEFLATED) + zip_file = zipfile.ZipFile(filepath, 'w', zipfile.ZIP_DEFLATED) def _add_entry(node): name = node.path[len(self.config.path):] if name.startswith('/'): @@ -179,22 +179,33 @@ if node.isdir: path = os.path.join(prefix, name).rstrip('/\\') + '/' info = zipfile.ZipInfo(path) - zip.writestr(info, '') - log.debug('Adding directory %s to archive' % name) + info.create_system = 3 + info.external_attr = 040755 << 16L | 0x10 + zip_file.writestr(info, '') + log.debug('Adding directory %s to archive', name) for entry in node.get_entries(): _add_entry(entry) time.sleep(.1) # be nice else: path = os.path.join(prefix, name) info = zipfile.ZipInfo(path) + info.create_system = 3 info.compress_type = zipfile.ZIP_DEFLATED info.date_time = time.gmtime(node.last_modified)[:6] info.file_size = node.content_length - zip.writestr(info, node.get_content().read()) + + # FIXME: Subversion specific! This should really be an + # executable flag provided by Trac's versioncontrol API + if 'svn:executable' in node.get_properties(): + info.external_attr = 0100755 << 16L + else: + info.external_attr = 0100644 << 16L + + zip_file.writestr(info, node.get_content().read()) try: _add_entry(root) finally: - zip.close() + zip_file.close() # Create MD5 checksum file md5sum.write(filepath) diff --git a/bitten/trac_ext/web_ui.py b/bitten/trac_ext/web_ui.py --- a/bitten/trac_ext/web_ui.py +++ b/bitten/trac_ext/web_ui.py @@ -7,7 +7,7 @@ # you should have received as part of this distribution. The terms # are also available at http://bitten.cmlenz.net/wiki/License. -from datetime import datetime, timedelta +from datetime import datetime import posixpath import re try: @@ -19,8 +19,7 @@ import pkg_resources from trac.core import * from trac.Timeline import ITimelineEventProvider -from trac.util import escape, pretty_timedelta, format_date, format_datetime, \ - shorten_line +from trac.util import escape, pretty_timedelta, format_datetime, shorten_line from trac.web import IRequestHandler from trac.web.chrome import INavigationContributor, ITemplateProvider, \ add_link, add_stylesheet diff --git a/bitten/util/beep.py b/bitten/util/beep.py --- a/bitten/util/beep.py +++ b/bitten/util/beep.py @@ -180,7 +180,7 @@ def handle_error(channelno, code, message): log.error('Failed to close channel %d', channelno) log.debug('Closing session with %s', session.addr) - session.terminate(handle_ok=handle_ok) + session.terminate(handle_ok=handle_ok, handle_error=handle_error) self.schedule(0, terminate_next_session) self.run(.5) diff --git a/bitten/util/testrunner.py b/bitten/util/testrunner.py --- a/bitten/util/testrunner.py +++ b/bitten/util/testrunner.py @@ -164,7 +164,7 @@ raise DistutilsExecError, 'unit tests failed' -def main(argv): +def main(): from distutils.dist import Distribution from optparse import OptionParser