aboutsummaryrefslogtreecommitdiffstats
path: root/python/servo/command_base.py
blob: dd02446eb63af473b766caf9b81964679017efd1 (plain) (blame)
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
import os
from os import path
import contextlib
import subprocess
import sys
import toml

from mach.registrar import Registrar


@contextlib.contextmanager
def cd(new_path):
    """Context manager for changing the current working directory"""
    previous_path = os.getcwd()
    try:
        os.chdir(new_path)
        yield
    finally:
        os.chdir(previous_path)


class CommandBase(object):
    """Base class for mach command providers.

    This mostly handles configuration management, such as .servobuild."""

    def __init__(self, context):
        self.context = context

        if not hasattr(self.context, "bootstrapped"):
            self.context.bootstrapped = False

        config_path = path.join(context.topdir, ".servobuild")
        if path.exists(config_path):
            self.config = toml.loads(open(config_path).read())
        else:
            self.config = {}

        # Handle missing/default items
        self.config.setdefault("tools", {})
        self.config["tools"].setdefault("system-rust", False)
        self.config["tools"].setdefault("system-cargo", False)
        self.config["tools"].setdefault("rust-root", "")
        self.config["tools"].setdefault("cargo-root", "")
        if not self.config["tools"]["system-rust"]:
            self.config["tools"]["rust-root"] = path.join(
                context.topdir, "rust")
        if not self.config["tools"]["system-cargo"]:
            self.config["tools"]["cargo-root"] = path.join(
                context.topdir, "cargo")

    def build_env(self):
        """Return an extended environment dictionary."""
        env = os.environ.copy()
        extra_path = []
        extra_lib = []
        if not self.config["tools"]["system-rust"] \
                or self.config["tools"]["rust-root"]:
            extra_path += [path.join(self.config["tools"]["rust-root"], "bin")]
            extra_lib += [path.join(self.config["tools"]["rust-root"], "lib")]
        if not self.config["tools"]["system-cargo"] \
                or self.config["tools"]["cargo-root"]:
            extra_path += [
                path.join(self.config["tools"]["cargo-root"], "bin")]

        if extra_path:
            env["PATH"] = "%s%s%s" % (
                os.pathsep.join(extra_path), os.pathsep, env["PATH"])
        if extra_lib:
            if sys.platform == "darwin":
                env["DYLD_LIBRARY_PATH"] = "%s%s%s" % \
                                           (os.pathsep.join(extra_lib),
                                            os.pathsep,
                                            env.get("DYLD_LIBRARY_PATH", ""))
            else:
                env["LD_LIBRARY_PATH"] = "%s%s%s" % \
                                         (os.pathsep.join(extra_lib),
                                          os.pathsep,
                                          env.get("LD_LIBRARY_PATH", ""))

        return env

    def ensure_bootstrapped(self):
        if self.context.bootstrapped:
            return

        submodules = subprocess.check_output(["git", "submodule", "status"])
        for line in submodules.split('\n'):
            components = line.strip().split(' ')
            if len(components) > 1 and components[0].startswith(('-', '+')):
                module_path = components[1]
                subprocess.check_call(["git", "submodule", "update",
                                       "--init", "--recursive",
                                       "--", module_path])

        if not self.config["tools"]["system-rust"] and \
           not path.exists(path.join(
                self.context.topdir, "rust", "bin", "rustc")):
            Registrar.dispatch("bootstrap-rust", context=self.context)
        if not self.config["tools"]["system-cargo"] and \
           not path.exists(path.join(
                self.context.topdir, "cargo", "bin", "cargo")):
            Registrar.dispatch("bootstrap-cargo", context=self.context)

        self.context.bootstrapped = True