Bug 1174037 - Support installing Mercurial from pip; r=glandium
Previously, we used a PPA on Ubuntu to install Mercurial. The PPA has proved to be unreliable. Furthermore, we didn't have a mechanism for installing a modern Mercurial on Debian and other derived distros. In this commit, we remove the PPA from Ubuntu. We add the ability to install Mercurial from pip to the Debian bootstrapper. However, since some people may not want <not apt> installing package-like things, we add a prompt explaining the situation and giving users a choice. We recommend installing a modern Mercurial via pip. But we also given the option to install a likely legacy version via apt. And, for Git users, we give the option to not install Mercurial at all. Since the new version of the Ubuntu bootstrapper is empty, it doesn't need to exist, so it has been removed. DONTBUILD (NPOTB)
This commit is contained in:
@@ -44,7 +44,6 @@ REPOSITORY_PATHS = [
|
||||
'mozboot/gentoo.py',
|
||||
'mozboot/openbsd.py',
|
||||
'mozboot/osx.py',
|
||||
'mozboot/ubuntu.py',
|
||||
]
|
||||
|
||||
TEMPDIR = None
|
||||
|
||||
@@ -296,13 +296,21 @@ class BaseBootstrapper(object):
|
||||
def ensure_mercurial_modern(self):
|
||||
installed, modern, version = self.is_mercurial_modern()
|
||||
|
||||
if not installed or modern:
|
||||
if modern:
|
||||
print('Your version of Mercurial (%s) is sufficiently modern.' %
|
||||
version)
|
||||
return
|
||||
|
||||
self._ensure_package_manager_updated()
|
||||
self.upgrade_mercurial(version)
|
||||
|
||||
if installed:
|
||||
print('Your version of Mercurial (%s) is not modern enough.' %
|
||||
version)
|
||||
else:
|
||||
print('You do not have Mercurial installed')
|
||||
|
||||
if self.upgrade_mercurial(version) is False:
|
||||
return
|
||||
|
||||
installed, modern, after = self.is_mercurial_modern()
|
||||
|
||||
@@ -313,6 +321,9 @@ class BaseBootstrapper(object):
|
||||
"""Upgrade Mercurial.
|
||||
|
||||
Child classes should reimplement this.
|
||||
|
||||
Return False to not perform a version check after the upgrade is
|
||||
performed.
|
||||
"""
|
||||
print(MERCURIAL_UNABLE_UPGRADE % (current, MODERN_MERCURIAL_VERSION))
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ from mozboot.freebsd import FreeBSDBootstrapper
|
||||
from mozboot.gentoo import GentooBootstrapper
|
||||
from mozboot.osx import OSXBootstrapper
|
||||
from mozboot.openbsd import OpenBSDBootstrapper
|
||||
from mozboot.ubuntu import UbuntuBootstrapper
|
||||
from mozboot.archlinux import ArchlinuxBootstrapper
|
||||
|
||||
APPLICATION_CHOICE = '''
|
||||
@@ -50,6 +49,21 @@ Or, if you prefer Git:
|
||||
git clone https://git.mozilla.org/integration/gecko-dev.git
|
||||
'''
|
||||
|
||||
DEBIAN_DISTROS = (
|
||||
'Debian',
|
||||
'debian',
|
||||
'Ubuntu',
|
||||
# Most Linux Mint editions are based on Ubuntu. One is based on Debian.
|
||||
# The difference is reported in dist_id from platform.linux_distribution.
|
||||
# But it doesn't matter since we share a bootstrapper between Debian and
|
||||
# Ubuntu.
|
||||
'Mint',
|
||||
'LinuxMint',
|
||||
'Elementary OS',
|
||||
'Elementary',
|
||||
'"elementary OS"',
|
||||
)
|
||||
|
||||
|
||||
class Bootstrapper(object):
|
||||
"""Main class that performs system bootstrap."""
|
||||
@@ -66,23 +80,12 @@ class Bootstrapper(object):
|
||||
|
||||
if distro in ('CentOS', 'CentOS Linux'):
|
||||
cls = CentOSBootstrapper
|
||||
elif distro in ('Debian', 'debian'):
|
||||
elif distro in DEBIAN_DISTROS:
|
||||
cls = DebianBootstrapper
|
||||
elif distro == 'Fedora':
|
||||
cls = FedoraBootstrapper
|
||||
elif distro == 'Gentoo Base System':
|
||||
cls = GentooBootstrapper
|
||||
elif distro in ('Mint', 'LinuxMint'):
|
||||
# Most Linux Mint editions are based on Ubuntu; one is based on
|
||||
# Debian, and reports this in dist_id
|
||||
if dist_id == 'debian':
|
||||
cls = DebianBootstrapper
|
||||
else:
|
||||
cls = UbuntuBootstrapper
|
||||
elif distro == 'Ubuntu':
|
||||
cls = UbuntuBootstrapper
|
||||
elif distro in ('Elementary OS', 'Elementary', '"elementary OS"'):
|
||||
cls = UbuntuBootstrapper
|
||||
elif os.path.exists('/etc/arch-release'):
|
||||
# Even on archlinux, platform.linux_distribution() returns ['','','']
|
||||
cls = ArchlinuxBootstrapper
|
||||
|
||||
@@ -8,6 +8,26 @@ import sys
|
||||
from mozboot.base import BaseBootstrapper
|
||||
|
||||
|
||||
MERCURIAL_INSTALL_PROMPT = '''
|
||||
Mercurial releases a new version every 3 months and your distro's package
|
||||
may become out of date. This may cause incompatibility with some
|
||||
Mercurial extensions that rely on new Mercurial features. As a result,
|
||||
you may not have an optimal version control experience.
|
||||
|
||||
To have the best Mercurial experience possible, we recommend installing
|
||||
Mercurial via the "pip" Python packaging utility. This will likely result
|
||||
in files being placed in /usr/local/bin and /usr/local/lib.
|
||||
|
||||
How would you like to continue?
|
||||
|
||||
1) Install a modern Mercurial via pip (recommended)
|
||||
2) Install a legacy Mercurial via apt
|
||||
3) Do not install Mercurial
|
||||
|
||||
Choice:
|
||||
'''.strip()
|
||||
|
||||
|
||||
class DebianBootstrapper(BaseBootstrapper):
|
||||
# These are common packages for all Debian-derived distros (such as
|
||||
# Ubuntu).
|
||||
@@ -15,8 +35,8 @@ class DebianBootstrapper(BaseBootstrapper):
|
||||
'autoconf2.13',
|
||||
'build-essential',
|
||||
'ccache',
|
||||
'mercurial',
|
||||
'python-dev',
|
||||
'python-pip',
|
||||
'python-setuptools',
|
||||
'unzip',
|
||||
'uuid',
|
||||
@@ -132,3 +152,27 @@ class DebianBootstrapper(BaseBootstrapper):
|
||||
|
||||
def _update_package_manager(self):
|
||||
self.apt_update()
|
||||
|
||||
def upgrade_mercurial(self, current):
|
||||
"""Install Mercurial from pip because Debian packages typically lag."""
|
||||
if self.no_interactive:
|
||||
# Install via Apt in non-interactive mode because it is the more
|
||||
# conservative option and less likely to make people upset.
|
||||
self.apt_install('mercurial')
|
||||
return
|
||||
|
||||
res = self.prompt_int(MERCURIAL_INSTALL_PROMPT, 1, 3)
|
||||
|
||||
# Apt.
|
||||
if res == 2:
|
||||
self.apt_install('mercurial')
|
||||
return False
|
||||
|
||||
# No Mercurial.
|
||||
if res == 3:
|
||||
print('Not installing Mercurial.')
|
||||
return False
|
||||
|
||||
# pip.
|
||||
assert res == 1
|
||||
self.run_as_root(['pip', 'install', '--upgrade', 'Mercurial'])
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
import os
|
||||
|
||||
|
||||
from mozboot.debian import DebianBootstrapper
|
||||
|
||||
|
||||
MERCURIAL_PPA = '''
|
||||
Ubuntu does not provide a modern Mercurial in its package repository. So,
|
||||
we will install a PPA that does.
|
||||
'''.strip()
|
||||
|
||||
|
||||
# Ubuntu shares much logic with Debian, so it inherits from it.
|
||||
class UbuntuBootstrapper(DebianBootstrapper):
|
||||
DISTRO_PACKAGES = [
|
||||
# This contains add-apt-repository.
|
||||
'software-properties-common',
|
||||
]
|
||||
|
||||
def upgrade_mercurial(self, current):
|
||||
# Ubuntu releases up through at least 13.04 don't ship a modern
|
||||
# Mercurial. So we hook up a PPA that provides one.
|
||||
self._add_ppa('mercurial-ppa/releases')
|
||||
self._update_package_manager()
|
||||
self.apt_install('mercurial')
|
||||
|
||||
def _add_ppa(self, ppa):
|
||||
# Detect PPAs that have already been added. Sadly add-apt-repository
|
||||
# doesn't do this for us and will import keys, etc every time. This
|
||||
# incurs a user prompt and is annoying, so we try to prevent it.
|
||||
list_file = ppa.replace('/', '-')
|
||||
for source in os.listdir('/etc/apt/sources.list.d'):
|
||||
if source.startswith(list_file) and source.endswith('.list'):
|
||||
return
|
||||
|
||||
self.run_as_root(['add-apt-repository', 'ppa:%s' % ppa])
|
||||
Reference in New Issue
Block a user