summaryrefslogtreecommitdiffstats
path: root/tools/phabricator/mach_commands.py
blob: 6de99d9292d4018fae3ac5468ca2ba79b072c361 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 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/.

from __future__ import absolute_import, unicode_literals

import mozfile
from mach.decorators import CommandProvider, Command, CommandArgument
from mozbuild.base import MachCommandBase


@CommandProvider
class PhabricatorCommandProvider(MachCommandBase):
    @Command(
        "install-moz-phab",
        category="misc",
        description="Install patch submission tool.",
    )
    @CommandArgument(
        "--force",
        "-f",
        action="store_true",
        help="Force installation even if already installed.",
    )
    def install_moz_phab(self, force=False):
        import logging
        import os
        import re
        import subprocess
        import sys

        existing = mozfile.which("moz-phab")
        if existing and not force:
            self.log(
                logging.ERROR,
                "already_installed",
                {},
                "moz-phab is already installed in %s." % existing,
            )
            sys.exit(1)

        # pip3 is part of Python since 3.4, however some distros choose to
        # remove core components from languages, so show a useful error message
        # if pip3 is missing.
        pip3 = mozfile.which("pip3")
        if not pip3:
            self.log(
                logging.ERROR,
                "pip3_not_installed",
                {},
                "`pip3` is not installed. Try installing it with your system "
                "package manager.",
            )
            sys.exit(1)

        command = [pip3, "install", "--upgrade", "MozPhab"]

        if (
            sys.platform.startswith("linux")
            or sys.platform.startswith("openbsd")
            or sys.platform.startswith("dragonfly")
            or sys.platform.startswith("freebsd")
        ):
            # On all Linux and BSD distros we consider doing a user installation.
            platform_prefers_user_install = True

        elif sys.platform.startswith("darwin"):
            # On MacOS we require brew or ports, which work better without --user.
            platform_prefers_user_install = False

        elif sys.platform.startswith("win32") or sys.platform.startswith("msys"):
            # Likewise for Windows we assume a system level install is preferred.
            platform_prefers_user_install = False

        else:
            # Unsupported, default to --user.
            self.log(
                logging.WARNING,
                "unsupported_platform",
                {},
                "Unsupported platform (%s), assuming per-user installation is "
                "preferred." % sys.platform,
            )
            platform_prefers_user_install = True

        if platform_prefers_user_install and not os.environ.get("VIRTUAL_ENV"):
            # Virtual environments don't see user packages, so only perform a user
            # installation if we're not within one.
            command.append("--user")

        self.log(logging.INFO, "run", {}, "Installing moz-phab")
        subprocess.run(command)

        # There isn't an elegant way of determining the CLI location of a pip-installed package.
        # The viable mechanism used here is to:
        # 1. Get the list of info about the installed package via pip
        # 2. Parse out the install location. This gives us the python environment in which the
        #    package is installed
        # 3. Parse out the relative location of the cli script
        # 4. Join the two paths, and execute the script at that location

        info = subprocess.check_output(
            [pip3, "show", "-f", "MozPhab"], universal_newlines=True
        )
        mozphab_package_location = re.compile(r"Location: (.*)").search(info).group(1)
        potential_cli_paths = re.compile(r"([^\s]*moz-phab(?:\.exe)?)").findall(info)

        if len(potential_cli_paths) != 1:
            self.log(
                logging.WARNING,
                "no_mozphab_console_script",
                {},
                "Could not find the CLI script for moz-phab. Skipping install-certificate step.",
            )
            sys.exit(1)

        console_script = os.path.realpath(
            os.path.join(mozphab_package_location, potential_cli_paths[0])
        )
        subprocess.run([console_script, "install-certificate"])