blob: 133e4ea6c8d655d7d16bf99de260b925fe4ebd28 [file] [log] [blame]
""" Contains the global configuration object.
"""
import os
from . import shell
from . import packages
class RoboConfiguration:
__slots__ = ('_sushi_branch_prefix', '_gn_commit_title',
'_patches_commit_title', '_readme_chromium_commit_title',
'_origin_merge_base', '_llvm_path', '_autorename_git_file',
'_chrome_src', '_host_operating_system', '_host_architecture',
'_ffmpeg_home', '_relative_asan_directory', '_branch_name',
'_sushi_branch_name', '_readme_chromium_commit_title', '_nasm_path',
'_prompt_on_call', '_os_flavor')
def __init__(self):
"""Ensure that our config has basic fields fill in, and passes some sanity
checks too.
Important: We might be doing --setup, so these sanity checks should only be
for things that we don't plan for fix as part of that.
"""
self.set_prompt_on_call(False)
# This is the prefix that our branches start with.
self._sushi_branch_prefix = "sushi-"
# This is the title that we use for the commit with GN configs.
self._gn_commit_title = "GN Configuration"
# Title of the commit with chromium/patches/README.
self._patches_commit_title = "Chromium patches file"
# Title of the commit with README.chromium
self._readme_chromium_commit_title = "README.chromium file"
self.EnsureHostInfo()
self.EnsureChromeSrc()
# Origin side of the merge. Only needs to change if you're trying to
# modify and test robosushi itself. See robosushi.py for details.
self._origin_merge_base = "origin/master"
# Directory where llvm lives.
self._llvm_path = os.path.join(self.chrome_src(), "third_party",
"llvm-build", "Release+Asserts", "bin")
self.EnsurePathContainsLLVM()
shell.log("Using chrome src: %s" % self.chrome_src())
self.EnsureFFmpegHome()
shell.log("Using ffmpeg home: %s" % self.ffmpeg_home())
self.EnsureASANConfig()
self.ComputeBranchName()
shell.log("On branch: %s" % self.branch_name())
if self.sushi_branch_name():
shell.log("On sushi branch: %s" % self.sushi_branch_name())
# Filename that we'll ask generate_gn.py to write git commands to.
self._autorename_git_file = os.path.join(
self.ffmpeg_home(), "chromium", "scripts", ".git_commands.sh")
def chrome_src(self):
"""Return /path/to/chromium/src"""
return self._chrome_src
def host_operating_system(self):
"""Return host type, e.g. "linux" """
return self._host_operating_system
def host_architecture(self):
"""Return host architecture, e.g. "x64" """
return self._host_architecture
def ffmpeg_home(self):
"""Return /path/to/third_party/ffmpeg"""
return self._ffmpeg_home
def relative_asan_directory(self):
return self._relative_asan_directory
def absolute_asan_directory(self):
return os.path.join(self.chrome_src(), self.relative_asan_directory())
def chdir_to_chrome_src(self):
os.chdir(self.chrome_src())
def chdir_to_ffmpeg_home(self):
os.chdir(self.ffmpeg_home())
def branch_name(self):
"""Return the current workspace's branch name, or None. This might be any
branch (e.g., "master"), not just one that we've created."""
return self._branch_name
def sushi_branch_name(self):
"""If the workspace is currently on a branch that we created (a "sushi
branch"), return it. Else return None."""
return self._sushi_branch_name
def sushi_branch_prefix(self):
"""Return the branch name that indicates that this is a "sushi branch"."""
return self._sushi_branch_prefix
def gn_commit_title(self):
return self._gn_commit_title
def patches_commit_title(self):
return self._patches_commit_title
def readme_chromium_commit_title(self):
return self._readme_chromium_commit_title
def nasm_path(self):
return self._nasm_path
def origin_merge_base(self):
return self._origin_merge_base
def override_origin_merge_base(self, new_base):
self._origin_merge_base = new_base
def os_flavor(self):
return self._os_flavor
def EnsureHostInfo(self):
"""Ensure that the host architecture and platform are set."""
kernel, host, os, *rest = shell.output_or_error(["uname", "-a"]).split()
assert kernel in ("Linux", "linux")
assert "x86_64" in rest
self._host_operating_system = "linux"
self._host_architecture = "x64"
if "rodete" in os:
self._os_flavor = packages.OsFlavor.Debian
elif "arch" in os:
self._os_flavor = packages.OsFlavor.Arch
else:
raise Exception("Couldn't determine OS flavor (needed to install packages)")
def EnsureChromeSrc(self):
"""Find the /absolute/path/to/my_chrome_dir/src"""
wd = os.getcwd()
# Walk up the tree until we find src/AUTHORS
while wd != "/":
if os.path.isfile(os.path.join(wd, "src", "AUTHORS")):
self._chrome_src = os.path.join(wd, "src")
return
wd = os.path.dirname(wd)
raise Exception("could not find src/AUTHORS in any parent of the wd")
def EnsureFFmpegHome(self):
"""Ensure that |self| has "ffmpeg_home" set."""
self._ffmpeg_home = os.path.join(self.chrome_src(), "third_party", "ffmpeg")
def EnsureASANConfig(self):
"""Find the asan directories. Note that we don't create them."""
# Compute gn ASAN out dirnames.
self.chdir_to_chrome_src();
local_directory = os.path.join("out", "sushi_asan")
# ASAN dir, suitable for 'ninja -C'
self._relative_asan_directory = local_directory
def EnsurePathContainsLLVM(self):
"""Make sure that we have chromium's LLVM in $PATH.
We don't want folks to accidentally use the wrong clang.
"""
llvm_path = os.path.join(self.chrome_src(), "third_party",
"llvm-build", "Release+Asserts", "bin")
if self.llvm_path() not in os.environ["PATH"]:
raise UserInstructions(
"Please add:\n%s\nto the beginning of $PATH" %
self.llvm_path())
def llvm_path(self):
return self._llvm_path
def ComputeBranchName(self):
"""Get the current branch name and set it."""
self.chdir_to_ffmpeg_home()
branch_name = shell.output_or_error(
["git", "rev-parse", "--abbrev-ref", "HEAD"])
self.SetBranchName(str(branch_name))
def SetBranchName(self, name):
"""Set our branch name, which may be a sushi branch or not."""
self._branch_name = name
# If this is one of our branches, then record that too.
if name and not name.startswith(self.sushi_branch_prefix()):
name = None
self._sushi_branch_name = name
def autorename_git_file(self):
return self._autorename_git_file
def prompt_on_call(self):
""" Return True if and only if we're supposed to ask the user before running
any command that might have a side-effect."""
return self._prompt_on_call
def set_prompt_on_call(self, value):
self._prompt_on_call = value
def Call(self, args, **kwargs):
"""Run the command specified by |args| (see subprocess.call), optionally
prompting the user."""
if self.prompt_on_call():
print(f"[{os.getcwd()}] About to run: `{' '.join(args)}` ")
input("Press ENTER to continue, or interrupt the script: ")
return shell.check_run(args, **kwargs)