#!/usr/bin/env python import argparse import contextlib import errno import os import shutil import subprocess import sys import tempfile import urllib2 import zipfile SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) class ProgramError(Exception): pass def main(): try: args = parse_args() commit = head_commit() download_if_needed(args.path, args.url, commit, force=args.force) except ProgramError as e: return e.message def parse_args(): parser = argparse.ArgumentParser(description='Download and extract ' 'atom-shell') parser.add_argument('-f', '--force', action='store_true', help='Overwrite destination if it already exists.') parser.add_argument('url', help='The base URL from which to download ' '(i.e., the URL you passed to script/upload)') parser.add_argument('path', help='The path to extract to') return parser.parse_args() def head_commit(): args = [ 'git', '--git-dir', os.path.join(SOURCE_ROOT, '.git'), 'rev-parse', 'HEAD', ] return subprocess.check_output(args).strip() def download_if_needed(destination, base_url, commit, force): version_file = os.path.join(destination, '.version') existing_version = '' try: with open(version_file, 'r') as f: existing_version = f.readline().strip() except IOError as e: if e.errno != errno.ENOENT: raise if existing_version == commit: return if force: rm_rf(destination) elif os.path.exists(destination): raise ProgramError('Error: {0} already exists. Pass --force if you ' 'want to overwrite it.'.format(destination)) sys.stderr.write('Downloading atom-shell {0}...\n'.format(commit)) sys.stderr.flush() download_and_extract(destination, '{0}/{1}/atom-shell.zip'.format(base_url, commit)) with open(version_file, 'w') as f: f.write('{0}\n'.format(commit)) def download_and_extract(destination, url): print url with tempfile.TemporaryFile() as t: with contextlib.closing(urllib2.urlopen(url)) as u: while True: chunk = u.read(1024*1024) if not len(chunk): break sys.stderr.write('.') sys.stderr.flush() t.write(chunk) sys.stderr.write('\nExtracting...\n') sys.stderr.flush() with zipfile.ZipFile(t) as z: z.extractall(destination) def rm_rf(path): try: shutil.rmtree(path) except OSError as e: if e.errno != errno.ENOENT: raise if __name__ == '__main__': sys.exit(main())