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
5"""module for tooltool operations"""
6from __future__ import absolute_import
7import os
8import sys
9
10from mozharness.base.errors import PythonErrorList
11from mozharness.base.log import ERROR, FATAL
12
13TooltoolErrorList = PythonErrorList + [{"substr": "ERROR - ", "level": ERROR}]
14
15
16_here = os.path.abspath(os.path.dirname(__file__))
17_external_tools_path = os.path.normpath(
18    os.path.join(_here, "..", "..", "external_tools")
19)
20
21
22class TooltoolMixin(object):
23    """Mixin class for handling tooltool manifests.
24    To use a tooltool server other than the Mozilla server, set
25    TOOLTOOL_HOST in the environment.
26    """
27
28    def tooltool_fetch(self, manifest, output_dir=None, privileged=False, cache=None):
29        """docstring for tooltool_fetch"""
30        if cache is None:
31            cache = os.environ.get("TOOLTOOL_CACHE")
32
33        for d in (output_dir, cache):
34            if d is not None and not os.path.exists(d):
35                self.mkdir_p(d)
36        if self.topsrcdir:
37            cmd = [
38                sys.executable,
39                "-u",
40                os.path.join(self.topsrcdir, "mach"),
41                "artifact",
42                "toolchain",
43                "-v",
44            ]
45        else:
46            cmd = [
47                sys.executable,
48                "-u",
49                os.path.join(_external_tools_path, "tooltool.py"),
50            ]
51
52        if self.topsrcdir:
53            cmd.extend(["--tooltool-manifest", manifest])
54            cmd.extend(
55                ["--artifact-manifest", os.path.join(self.topsrcdir, "toolchains.json")]
56            )
57        else:
58            cmd.extend(["fetch", "-m", manifest, "-o"])
59
60        if cache:
61            cmd.extend(["--cache-dir" if self.topsrcdir else "-c", cache])
62
63        timeout = self.config.get("tooltool_timeout", 10 * 60)
64
65        self.retry(
66            self.run_command,
67            args=(cmd,),
68            kwargs={
69                "cwd": output_dir,
70                "error_list": TooltoolErrorList,
71                "privileged": privileged,
72                "output_timeout": timeout,
73            },
74            good_statuses=(0,),
75            error_message="Tooltool %s fetch failed!" % manifest,
76            error_level=FATAL,
77        )
78
79    def create_tooltool_manifest(self, contents, path=None):
80        """Currently just creates a manifest, given the contents.
81        We may want a template and individual values in the future?
82        """
83        if path is None:
84            dirs = self.query_abs_dirs()
85            path = os.path.join(dirs["abs_work_dir"], "tooltool.tt")
86        self.write_to_file(path, contents, error_level=FATAL)
87        return path
88