summaryrefslogtreecommitdiffstats
path: root/python/mozboot/bin/bootstrap.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozboot/bin/bootstrap.py')
-rwxr-xr-xpython/mozboot/bin/bootstrap.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/python/mozboot/bin/bootstrap.py b/python/mozboot/bin/bootstrap.py
new file mode 100755
index 000000000..d916351e7
--- /dev/null
+++ b/python/mozboot/bin/bootstrap.py
@@ -0,0 +1,170 @@
+#!/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
+
+WRONG_PYTHON_VERSION_MESSAGE = '''
+Bootstrap currently only runs on Python 2.7 or Python 2.6. Please try re-running with python2.7 or python2.6.
+
+If these aren't available on your system, you may need to install them. Look for a "python2" or "python27" package in your package manager.
+'''
+
+import sys
+if sys.version_info[:2] not in [(2, 6), (2, 7)]:
+ print(WRONG_PYTHON_VERSION_MESSAGE)
+ sys.exit(1)
+
+import os
+import shutil
+from StringIO import StringIO
+import tempfile
+try:
+ from urllib2 import urlopen
+except ImportError:
+ from urllib.request import urlopen
+import zipfile
+
+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/'
+
+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':
+ url = repo_url + '/archive/default.zip/python/mozboot'
+ req = urlopen(url=url, timeout=30)
+ data = StringIO(req.read())
+ data.seek(0)
+ zip = zipfile.ZipFile(data, 'r')
+ for f in zip.infolist():
+ # The paths are prefixed with the repo and revision name before the
+ # directory name.
+ offset = f.filename.find(REPOSITORY_PATH_PREFIX) + len(REPOSITORY_PATH_PREFIX)
+ name = f.filename[offset:]
+
+ # We only care about the Python modules.
+ if not name.startswith('mozboot/'):
+ continue
+
+ files[name] = zip.read(f)
+ 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))