1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5from __future__ import absolute_import, print_function, unicode_literals
6
7from mozboot.base import BaseBootstrapper
8from mozboot.linux_common import LinuxBootstrapper
9
10import sys
11
12MERCURIAL_INSTALL_PROMPT = """
13Mercurial releases a new version every 3 months and your distro's package
14may become out of date. This may cause incompatibility with some
15Mercurial extensions that rely on new Mercurial features. As a result,
16you may not have an optimal version control experience.
17
18To have the best Mercurial experience possible, we recommend installing
19Mercurial via the "pip" Python packaging utility. This will likely result
20in files being placed in /usr/local/bin and /usr/local/lib.
21
22How would you like to continue?
23  1. Install a modern Mercurial via pip [default]
24  2. Install a legacy Mercurial via apt
25  3. Do not install Mercurial
26Your choice: """
27
28
29class DebianBootstrapper(LinuxBootstrapper, BaseBootstrapper):
30
31    # These are common packages for all Debian-derived distros (such as
32    # Ubuntu).
33    COMMON_PACKAGES = [
34        "build-essential",
35        "libpython3-dev",
36        "m4",
37        "nodejs",
38        "unzip",
39        "uuid",
40        "zip",
41    ]
42
43    # Ubuntu and Debian don't often differ, but they do for npm.
44    DEBIAN_PACKAGES = [
45        # Comment the npm package until Debian bring it back
46        # 'npm'
47    ]
48
49    # These are common packages for building Firefox for Desktop
50    # (browser) for all Debian-derived distros (such as Ubuntu).
51    BROWSER_COMMON_PACKAGES = [
52        "libasound2-dev",
53        "libcurl4-openssl-dev",
54        "libdbus-1-dev",
55        "libdbus-glib-1-dev",
56        "libdrm-dev",
57        "libgtk-3-dev",
58        "libpulse-dev",
59        "libx11-xcb-dev",
60        "libxt-dev",
61        "xvfb",
62    ]
63
64    # These are common packages for building Firefox for Android
65    # (mobile/android) for all Debian-derived distros (such as Ubuntu).
66    MOBILE_ANDROID_COMMON_PACKAGES = [
67        "openjdk-8-jdk-headless",  # Android's `sdkmanager` requires Java 1.8 exactly.
68        "wget",  # For downloading the Android SDK and NDK.
69    ]
70
71    def __init__(self, distro, version, dist_id, codename, **kwargs):
72        BaseBootstrapper.__init__(self, **kwargs)
73
74        self.distro = distro
75        self.version = version
76        self.dist_id = dist_id
77        self.codename = codename
78
79        self.packages = list(self.COMMON_PACKAGES)
80        if self.distro == "debian":
81            self.packages += self.DEBIAN_PACKAGES
82
83    def suggest_install_distutils(self):
84        print(
85            "HINT: Try installing distutils with "
86            "`apt-get install python3-distutils`.",
87            file=sys.stderr,
88        )
89
90    def suggest_install_pip3(self):
91        print(
92            "HINT: Try installing pip3 with `apt-get install python3-pip`.",
93            file=sys.stderr,
94        )
95
96    def install_system_packages(self):
97        self.apt_install(*self.packages)
98
99    def install_browser_packages(self, mozconfig_builder):
100        self.ensure_browser_packages()
101
102    def install_browser_artifact_mode_packages(self, mozconfig_builder):
103        self.ensure_browser_packages(artifact_mode=True)
104
105    def install_mobile_android_packages(self, mozconfig_builder):
106        self.ensure_mobile_android_packages(mozconfig_builder)
107
108    def install_mobile_android_artifact_mode_packages(self, mozconfig_builder):
109        self.ensure_mobile_android_packages(mozconfig_builder, artifact_mode=True)
110
111    def ensure_browser_packages(self, artifact_mode=False):
112        # TODO: Figure out what not to install for artifact mode
113        self.apt_install(*self.BROWSER_COMMON_PACKAGES)
114        modern = self.is_nasm_modern()
115        if not modern:
116            self.apt_install("nasm")
117
118    def ensure_mobile_android_packages(self, mozconfig_builder, artifact_mode=False):
119        # Multi-part process:
120        # 1. System packages.
121        # 2. Android SDK. Android NDK only if we are not in artifact mode. Android packages.
122        self.apt_install(*self.MOBILE_ANDROID_COMMON_PACKAGES)
123
124        # 2. Android pieces.
125        self.ensure_java(mozconfig_builder)
126        super().ensure_mobile_android_packages(artifact_mode=artifact_mode)
127
128    def _update_package_manager(self):
129        self.apt_update()
130
131    def upgrade_mercurial(self, current):
132        """Install Mercurial from pip because Debian packages typically lag."""
133        if self.no_interactive:
134            # Install via Apt in non-interactive mode because it is the more
135            # conservative option and less likely to make people upset.
136            self.apt_install("mercurial")
137            return
138
139        res = self.prompt_int(MERCURIAL_INSTALL_PROMPT, 1, 3)
140
141        # Apt.
142        if res == 2:
143            self.apt_install("mercurial")
144            return False
145
146        # No Mercurial.
147        if res == 3:
148            print("Not installing Mercurial.")
149            return False
150
151        # pip.
152        assert res == 1
153        self.run_as_root(["pip3", "install", "--upgrade", "Mercurial"])
154