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:
Gregory Szorc
2015-09-04 10:37:29 -07:00
parent 9d995bd34f
commit fef6091d15
5 changed files with 74 additions and 57 deletions

View File

@@ -44,7 +44,6 @@ REPOSITORY_PATHS = [
'mozboot/gentoo.py',
'mozboot/openbsd.py',
'mozboot/osx.py',
'mozboot/ubuntu.py',
]
TEMPDIR = None

View File

@@ -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))

View File

@@ -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

View File

@@ -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'])

View File

@@ -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])