michael@0: #!/usr/bin/env python michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: # You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: # This script provides one-line bootstrap support to configure systems to build michael@0: # the tree. michael@0: # michael@0: # The role of this script is to load the Python modules containing actual michael@0: # bootstrap support. It does this through various means, including fetching michael@0: # content from the upstream source repository. michael@0: michael@0: # If we add unicode_literals, optparse breaks on Python 2.6.1 (which is needed michael@0: # to support OS X 10.6). michael@0: from __future__ import print_function michael@0: michael@0: import os michael@0: import shutil michael@0: import sys michael@0: import tempfile michael@0: try: michael@0: from urllib2 import urlopen michael@0: except ImportError: michael@0: from urllib.request import urlopen michael@0: michael@0: from optparse import OptionParser michael@0: michael@0: # The next two variables define where in the repository the Python files michael@0: # reside. This is used to remotely download file content when it isn't michael@0: # available locally. michael@0: REPOSITORY_PATH_PREFIX = 'python/mozboot' michael@0: michael@0: REPOSITORY_PATHS = [ michael@0: 'mozboot/__init__.py', michael@0: 'mozboot/base.py', michael@0: 'mozboot/bootstrap.py', michael@0: 'mozboot/centos.py', michael@0: 'mozboot/debian.py', michael@0: 'mozboot/fedora.py', michael@0: 'mozboot/freebsd.py', michael@0: 'mozboot/gentoo.py', michael@0: 'mozboot/openbsd.py', michael@0: 'mozboot/osx.py', michael@0: 'mozboot/ubuntu.py', michael@0: ] michael@0: michael@0: TEMPDIR = None michael@0: michael@0: def setup_proxy(): michael@0: # Some Linux environments define ALL_PROXY, which is a SOCKS proxy michael@0: # intended for all protocols. Python doesn't currently automatically michael@0: # detect this like it does for http_proxy and https_proxy. michael@0: if 'ALL_PROXY' in os.environ and 'https_proxy' not in os.environ: michael@0: os.environ['https_proxy'] = os.environ['ALL_PROXY'] michael@0: if 'ALL_PROXY' in os.environ and 'http_proxy' not in os.environ: michael@0: os.environ['http_proxy'] = os.environ['ALL_PROXY'] michael@0: michael@0: def fetch_files(repo_url, repo_type): michael@0: setup_proxy() michael@0: repo_url = repo_url.rstrip('/') michael@0: michael@0: files = {} michael@0: michael@0: if repo_type == 'hgweb': michael@0: for path in REPOSITORY_PATHS: michael@0: url = repo_url + '/raw-file/default/python/mozboot/' + path michael@0: michael@0: req = urlopen(url=url, timeout=30) michael@0: files[path] = req.read() michael@0: else: michael@0: raise NotImplementedError('Not sure how to handle repo type.', repo_type) michael@0: michael@0: return files michael@0: michael@0: def ensure_environment(repo_url=None, repo_type=None): michael@0: """Ensure we can load the Python modules necessary to perform bootstrap.""" michael@0: michael@0: try: michael@0: from mozboot.bootstrap import Bootstrapper michael@0: return Bootstrapper michael@0: except ImportError: michael@0: # The first fallback is to assume we are running from a tree checkout michael@0: # and have the files in a sibling directory. michael@0: pardir = os.path.join(os.path.dirname(__file__), os.path.pardir) michael@0: include = os.path.normpath(pardir) michael@0: michael@0: sys.path.append(include) michael@0: try: michael@0: from mozboot.bootstrap import Bootstrapper michael@0: return Bootstrapper michael@0: except ImportError: michael@0: sys.path.pop() michael@0: michael@0: # The next fallback is to download the files from the source michael@0: # repository. michael@0: files = fetch_files(repo_url, repo_type) michael@0: michael@0: # Install them into a temporary location. They will be deleted michael@0: # after this script has finished executing. michael@0: global TEMPDIR michael@0: TEMPDIR = tempfile.mkdtemp() michael@0: michael@0: for relpath in files.keys(): michael@0: destpath = os.path.join(TEMPDIR, relpath) michael@0: destdir = os.path.dirname(destpath) michael@0: michael@0: if not os.path.exists(destdir): michael@0: os.makedirs(destdir) michael@0: michael@0: with open(destpath, 'wb') as fh: michael@0: fh.write(files[relpath]) michael@0: michael@0: # This should always work. michael@0: sys.path.append(TEMPDIR) michael@0: from mozboot.bootstrap import Bootstrapper michael@0: return Bootstrapper michael@0: michael@0: def main(args): michael@0: parser = OptionParser() michael@0: parser.add_option('-r', '--repo-url', dest='repo_url', michael@0: default='https://hg.mozilla.org/mozilla-central/', michael@0: help='Base URL of source control repository where bootstrap files can ' michael@0: 'be downloaded.') michael@0: michael@0: parser.add_option('--repo-type', dest='repo_type', michael@0: default='hgweb', michael@0: help='The type of the repository. This defines how we fetch file ' michael@0: 'content. Like --repo, you should not need to set this.') michael@0: michael@0: options, leftover = parser.parse_args(args) michael@0: michael@0: try: michael@0: try: michael@0: cls = ensure_environment(options.repo_url, options.repo_type) michael@0: except Exception as e: michael@0: print('Could not load the bootstrap Python environment.\n') michael@0: print('This should never happen. Consider filing a bug.\n') michael@0: print('\n') michael@0: print(e) michael@0: return 1 michael@0: michael@0: dasboot = cls() michael@0: dasboot.bootstrap() michael@0: michael@0: return 0 michael@0: finally: michael@0: if TEMPDIR is not None: michael@0: shutil.rmtree(TEMPDIR) michael@0: michael@0: michael@0: if __name__ == '__main__': michael@0: sys.exit(main(sys.argv))