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