blob: 1920ec7312a88941265a8a00dbaef58ee6ea2be8 [file] [log] [blame]
#!/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/android.py',
'mozboot/archlinux.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',
]
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.')
parser.add_option('--application-choice', dest='application_choice',
help='Pass in an application choice (desktop/android) instead of using the '
'default interactive prompt.')
parser.add_option('--no-interactive', dest='no_interactive', action='store_true',
help='Answer yes to any (Y/n) interactive prompts.')
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(choice=options.application_choice, no_interactive=options.no_interactive)
dasboot.bootstrap()
return 0
finally:
if TEMPDIR is not None:
shutil.rmtree(TEMPDIR)
if __name__ == '__main__':
sys.exit(main(sys.argv))