# 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/.
import os
import platform
import subprocess
import sys
from enum
import Enum, auto
# This is a collection of helper functions that use the subprocess.run
# command to execute commands. In the future, if we have cases where
# we find common python functionality in utilizing the data returned
# from these functions, that functionality can live here for easy reuse
# between other python scripts in dom/media/webrtc/third_party_build.
# must run 'hg' with HGPLAIN=1 to ensure aliases don't interfere with
# command output.
env = os.environ.copy()
env[
"HGPLAIN"] =
"1"
def run_hg(cmd):
cmd_list = cmd.split(
" ")
res = subprocess.run(
cmd_list,
capture_output=
True,
text=
True,
env=env,
check=
False,
)
if res.returncode !=
0:
print(
f
"Hit return code {res.returncode} running '{cmd}'. Aborting.",
file=sys.stderr,
)
print(res.stderr)
sys.exit(
1)
stdout = res.stdout.strip()
return []
if len(stdout) ==
0 else stdout.split(
"\n")
def run_git(cmd, working_dir):
cmd_list = cmd.split(
" ")
res = subprocess.run(
cmd_list,
capture_output=
True,
text=
True,
cwd=working_dir,
check=
False,
)
if res.returncode !=
0:
print(
f
"Hit return code {res.returncode} running '{cmd}'. Aborting.",
file=sys.stderr,
)
print(res.stderr)
sys.exit(
1)
stdout = res.stdout.strip()
return []
if len(stdout) ==
0 else stdout.split(
"\n")
def run_shell(cmd, capture_output=
True):
res = subprocess.run(
cmd,
shell=
True,
capture_output=capture_output,
text=
True,
check=
False,
)
if res.returncode !=
0:
print(
f
"Hit return code {res.returncode} running '{cmd}'. Aborting.",
file=sys.stderr,
)
if capture_output:
print(res.stderr)
sys.exit(
1)
output_lines = []
if capture_output:
stdout = res.stdout.strip()
output_lines = []
if len(stdout) ==
0 else stdout.split(
"\n")
return output_lines
def get_last_line(file_path):
# technique from https://stackoverflow.com/questions/46258499/how-to-read-the-last-line-of-a-file-in-python
with open(file_path,
"rb")
as f:
try:
# catch OSError in case of a one line file
f.seek(-
2, os.SEEK_END)
while f.read(
1) != b
"\n":
f.seek(-
2, os.SEEK_CUR)
except OSError:
f.seek(
0)
return f.readline().decode().strip()
def update_resume_state(state, resume_state_filename):
with open(resume_state_filename,
"w")
as ofile:
ofile.write(state)
ofile.write(
"\n")
class ErrorHelp:
def __init__(self):
self.prefix =
None
self.error_help =
None
self.postfix =
None
def set_prefix(self, prefix):
self.prefix = prefix
def set_postfix(self, postfix):
self.postfix = postfix
def set_help(self, error_help):
self.error_help = error_help
def print_help(self):
if self.prefix
is not None:
print(self.prefix)
if self.error_help
is not None:
print(self.error_help)
if self.postfix
is not None:
print(self.postfix)
class RepoType(Enum):
HG = auto()
GIT = auto()
def detect_repo_type():
if os.path.exists(
".git"):
return RepoType.GIT
elif os.path.exists(
".hg"):
return RepoType.HG
return None
def git_status(working_dir, search_path=
"."):
# We don't use run_git above because it strips all leading
# whitespace, which causes issues with the output of
# git status --porcelain since leading spaces matter in the output.
# For example, the following two lines mean different things:
# M file1.txt
# M file2.txt
# file2.txt is staged, while file1.txt is modified, but unstaged.
cmd = f
"git --no-optional-locks status --porcelain {search_path}"
cmd_list = cmd.split(
" ")
res = subprocess.run(
cmd_list,
capture_output=
True,
text=
True,
cwd=working_dir,
check=
False,
)
if res.returncode !=
0:
print(
f
"Hit return code {res.returncode} running '{cmd}'. Aborting.",
file=sys.stderr,
)
print(res.stderr)
sys.exit(
1)
stdout = res.stdout.strip(
"\n")
return []
if len(stdout) ==
0 else stdout.split(
"\n")
def check_repo_status(repo_type):
if not isinstance(repo_type, RepoType):
print(
"check_repo_status requires type RepoType")
raise TypeError
if repo_type == RepoType.GIT:
return git_status(
".",
"third_party/libwebrtc")
else:
return run_hg(
"hg status third_party/libwebrtc")
def is_mac_os():
return platform.system() ==
"Darwin"
def git_get_config(config_name, working_dir):
# using run_shell rather than run_git because a config name that is
# unset returns a non-zero error code.
stdout_lines = run_shell(f
"cd {working_dir} ; git config {config_name} || true")
line_cnt = len(stdout_lines)
if line_cnt >
1:
print(f
"Error: {config_name} returned multiple values ({line_cnt})")
sys.exit(
1)
elif line_cnt ==
1:
return stdout_lines[
0]
return None
def git_is_config_set(config_name, working_dir):
config_val = git_get_config(config_name, working_dir)
if config_val
is not None and config_val ==
"true":
return True
return False