gittool.py (3510B)
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 import os 6 import re 7 8 try: 9 import urlparse 10 except ImportError: 11 import urllib.parse as urlparse 12 13 from mozharness.base.errors import GitErrorList, VCSException 14 from mozharness.base.log import LogMixin, OutputParser 15 from mozharness.base.script import ScriptMixin 16 17 18 class GittoolParser(OutputParser): 19 """ 20 A class that extends OutputParser such that it can find the "Got revision" 21 string from gittool.py output 22 """ 23 24 got_revision_exp = re.compile(r"Got revision (\w+)") 25 got_revision = None 26 27 def parse_single_line(self, line): 28 m = self.got_revision_exp.match(line) 29 if m: 30 self.got_revision = m.group(1) 31 super().parse_single_line(line) 32 33 34 class GittoolVCS(ScriptMixin, LogMixin): 35 def __init__(self, log_obj=None, config=None, vcs_config=None, script_obj=None): 36 super().__init__() 37 38 self.log_obj = log_obj 39 self.script_obj = script_obj 40 if config: 41 self.config = config 42 else: 43 self.config = {} 44 # vcs_config = { 45 # repo: repository, 46 # branch: branch, 47 # revision: revision, 48 # ssh_username: ssh_username, 49 # ssh_key: ssh_key, 50 # } 51 self.vcs_config = vcs_config 52 self.gittool = self.query_exe("gittool.py", return_type="list") 53 54 def ensure_repo_and_revision(self): 55 """Makes sure that `dest` is has `revision` or `branch` checked out 56 from `repo`. 57 58 Do what it takes to make that happen, including possibly clobbering 59 dest. 60 """ 61 c = self.vcs_config 62 for conf_item in ("dest", "repo"): 63 assert self.vcs_config[conf_item] 64 dest = os.path.abspath(c["dest"]) 65 repo = c["repo"] 66 revision = c.get("revision") 67 branch = c.get("branch") 68 clean = c.get("clean") 69 share_base = c.get("vcs_share_base", os.environ.get("GIT_SHARE_BASE_DIR", None)) 70 env = {"PATH": os.environ.get("PATH")} 71 env.update(c.get("env", {})) 72 if self._is_windows(): 73 # git.exe is not in the PATH by default 74 env["PATH"] = "%s;C:/mozilla-build/Git/bin" % env["PATH"] 75 # SYSTEMROOT is needed for 'import random' 76 if "SYSTEMROOT" not in env: 77 env["SYSTEMROOT"] = os.environ.get("SYSTEMROOT") 78 if share_base is not None: 79 env["GIT_SHARE_BASE_DIR"] = share_base 80 81 cmd = self.gittool[:] 82 if branch: 83 cmd.extend(["-b", branch]) 84 if revision: 85 cmd.extend(["-r", revision]) 86 if clean: 87 cmd.append("--clean") 88 89 for base_mirror_url in self.config.get( 90 "gittool_base_mirror_urls", self.config.get("vcs_base_mirror_urls", []) 91 ): 92 bits = urlparse.urlparse(repo) 93 mirror_url = urlparse.urljoin(base_mirror_url, bits.path) 94 cmd.extend(["--mirror", mirror_url]) 95 96 cmd.extend([repo, dest]) 97 parser = GittoolParser( 98 config=self.config, log_obj=self.log_obj, error_list=GitErrorList 99 ) 100 retval = self.run_command( 101 cmd, error_list=GitErrorList, env=env, output_parser=parser 102 ) 103 104 if retval != 0: 105 raise VCSException("Unable to checkout") 106 107 return parser.got_revision