2019-04-18 17:51:19 +00:00
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
2017-04-04 23:09:31 +00:00
|
|
|
"""
|
|
|
|
This module keeps commonly used components.
|
|
|
|
"""
|
2022-09-21 00:47:52 +00:00
|
|
|
|
2019-10-23 20:51:03 +00:00
|
|
|
try:
|
|
|
|
from builtins import object
|
|
|
|
except ImportError:
|
|
|
|
from __builtin__ import object
|
2022-09-21 00:47:52 +00:00
|
|
|
import os
|
2017-04-04 23:09:31 +00:00
|
|
|
import subprocess
|
2019-10-23 20:51:03 +00:00
|
|
|
import sys
|
2017-04-04 23:09:31 +00:00
|
|
|
import time
|
|
|
|
|
2022-09-21 00:47:52 +00:00
|
|
|
|
2023-08-25 23:22:09 +00:00
|
|
|
class ColorString:
|
2022-09-21 00:47:52 +00:00
|
|
|
"""Generate colorful strings on terminal"""
|
|
|
|
|
|
|
|
HEADER = "\033[95m"
|
|
|
|
BLUE = "\033[94m"
|
|
|
|
GREEN = "\033[92m"
|
|
|
|
WARNING = "\033[93m"
|
|
|
|
FAIL = "\033[91m"
|
|
|
|
ENDC = "\033[0m"
|
2017-04-04 23:09:31 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def _make_color_str(text, color):
|
2019-10-23 20:51:03 +00:00
|
|
|
# In Python2, default encoding for unicode string is ASCII
|
|
|
|
if sys.version_info.major <= 2:
|
2022-09-21 00:47:52 +00:00
|
|
|
return "".join([color, text.encode("utf-8"), ColorString.ENDC])
|
2019-10-23 20:51:03 +00:00
|
|
|
# From Python3, default encoding for unicode string is UTF-8
|
2022-09-21 00:47:52 +00:00
|
|
|
return "".join([color, text, ColorString.ENDC])
|
2017-04-04 23:09:31 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def ok(text):
|
|
|
|
if ColorString.is_disabled:
|
|
|
|
return text
|
|
|
|
return ColorString._make_color_str(text, ColorString.GREEN)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def info(text):
|
|
|
|
if ColorString.is_disabled:
|
|
|
|
return text
|
|
|
|
return ColorString._make_color_str(text, ColorString.BLUE)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def header(text):
|
|
|
|
if ColorString.is_disabled:
|
|
|
|
return text
|
|
|
|
return ColorString._make_color_str(text, ColorString.HEADER)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def error(text):
|
|
|
|
if ColorString.is_disabled:
|
|
|
|
return text
|
|
|
|
return ColorString._make_color_str(text, ColorString.FAIL)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def warning(text):
|
|
|
|
if ColorString.is_disabled:
|
|
|
|
return text
|
|
|
|
return ColorString._make_color_str(text, ColorString.WARNING)
|
|
|
|
|
|
|
|
is_disabled = False
|
|
|
|
|
|
|
|
|
|
|
|
def run_shell_command(shell_cmd, cmd_dir=None):
|
2022-09-21 00:47:52 +00:00
|
|
|
"""Run a single shell command.
|
|
|
|
@returns a tuple of shell command return code, stdout, stderr"""
|
2017-04-04 23:09:31 +00:00
|
|
|
|
|
|
|
if cmd_dir is not None and not os.path.exists(cmd_dir):
|
|
|
|
run_shell_command("mkdir -p %s" % cmd_dir)
|
|
|
|
|
|
|
|
start = time.time()
|
|
|
|
print("\t>>> Running: " + shell_cmd)
|
2022-09-21 00:47:52 +00:00
|
|
|
p = subprocess.Popen( # noqa
|
|
|
|
shell_cmd,
|
|
|
|
shell=True,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
cwd=cmd_dir,
|
|
|
|
)
|
2017-04-04 23:09:31 +00:00
|
|
|
stdout, stderr = p.communicate()
|
|
|
|
end = time.time()
|
|
|
|
|
|
|
|
# Report time if we spent more than 5 minutes executing a command
|
|
|
|
execution_time = end - start
|
|
|
|
if execution_time > (60 * 5):
|
2022-09-21 00:47:52 +00:00
|
|
|
mins = execution_time / 60
|
|
|
|
secs = execution_time % 60
|
2017-04-04 23:09:31 +00:00
|
|
|
print("\t>time spent: %d minutes %d seconds" % (mins, secs))
|
|
|
|
|
|
|
|
return p.returncode, stdout, stderr
|
|
|
|
|
|
|
|
|
|
|
|
def run_shell_commands(shell_cmds, cmd_dir=None, verbose=False):
|
2022-09-21 00:47:52 +00:00
|
|
|
"""Execute a sequence of shell commands, which is equivalent to
|
|
|
|
running `cmd1 && cmd2 && cmd3`
|
|
|
|
@returns boolean indication if all commands succeeds.
|
2017-04-04 23:09:31 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
if cmd_dir:
|
|
|
|
print("\t=== Set current working directory => %s" % cmd_dir)
|
|
|
|
|
|
|
|
for shell_cmd in shell_cmds:
|
|
|
|
ret_code, stdout, stderr = run_shell_command(shell_cmd, cmd_dir)
|
|
|
|
if stdout:
|
|
|
|
if verbose or ret_code != 0:
|
|
|
|
print(ColorString.info("stdout: \n"), stdout)
|
|
|
|
if stderr:
|
|
|
|
# contents in stderr is not necessarily to be error messages.
|
|
|
|
if verbose or ret_code != 0:
|
|
|
|
print(ColorString.error("stderr: \n"), stderr)
|
|
|
|
if ret_code != 0:
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|