Combine normal and okay statuses.

- Changed all normal results to ok.
- Normal results were intended for tools that produced info and
  weren't expected to have problem results.
  - Ultimately not worth distinguishing from tools that sometimes
    show problems.
- One less color status makes the summary table simpler.
- Also changed the not-applicable status color to the lighter grey
  that normal used to have.
- Made the success status non-configurable since ok status is the
  only sensible status at the moment.
This commit is contained in:
Andrew Hamilton 2021-07-20 00:48:18 +10:00
parent e6380bb1d7
commit 4197cebd1b
5 changed files with 53 additions and 85 deletions

View file

@ -47,26 +47,24 @@ class Status(enum.IntEnum):
ok = 1
problem = 2
normal = 3
error = 4
not_applicable = 5
running = 6
pending = 7
timed_out = 8
error = 3
not_applicable = 4
running = 5
pending = 6
timed_out = 7
_STATUS_COLORS = {Status.ok: termstr.Color.green,
Status.problem: termstr.Color.dark_green,
Status.normal: termstr.Color.grey_80,
Status.not_applicable: termstr.Color.grey_50,
Status.not_applicable: termstr.Color.grey_80,
Status.running: termstr.Color.blue,
Status.error: termstr.Color.red,
Status.timed_out: termstr.Color.purple}
STATUS_MEANINGS = [
(Status.normal, "Normal"), (Status.ok, "Ok"),
(Status.problem, "Problem"), (Status.not_applicable, "Not applicable"),
(Status.running, "Running"), (Status.timed_out, "Timed out"),
(Status.pending, "Pending"), (Status.error, "Error")
(Status.ok, "Ok"), (Status.problem, "Problem"),
(Status.not_applicable, "Not applicable"), (Status.running, "Running"),
(Status.timed_out, "Timed out"), (Status.pending, "Pending"),
(Status.error, "Error")
]
STATUS_TO_TERMSTR = {
status: termstr.TermStr(" ", termstr.CharStyle(bg_color=color))
@ -101,9 +99,8 @@ def _do_command(command, **kwargs):
_fix_input(completed_process.stderr), completed_process.returncode)
def _run_command(command, success_status=None, error_status=None,
has_color=False, timeout=None, **kwargs):
success_status = Status.ok if success_status is None else success_status
def _run_command(command, error_status=None, has_color=False, timeout=None,
**kwargs):
error_status = Status.problem if error_status is None else error_status
if has_color:
process = subprocess.run(command, stdout=subprocess.PIPE,
@ -114,7 +111,7 @@ def _run_command(command, success_status=None, error_status=None,
termstr.TermStr.from_term(process.stderr), process.returncode)
else:
stdout, stderr, returncode = _do_command(command, timeout=timeout)
result_status = success_status if returncode == 0 else error_status
result_status = Status.ok if returncode == 0 else error_status
return result_status, (stdout + stderr)
@ -164,7 +161,7 @@ def _syntax_highlight_using_path(text, path):
def linguist(path):
# Dep: ruby?, ruby-dev, libicu-dev, cmake, "gem install github-linguist"
return _run_command(["linguist", path], Status.normal)
return _run_command(["linguist", path], Status.ok)
def _permissions_in_octal(permissions):
@ -233,7 +230,7 @@ def metadata(path):
name = termstr.TermStr(name + ":").fg_color(
termstr.Color.blue).ljust(16)
text.append(name + fill3.join("", value) + "\n")
return (Status.normal, fill3.join("", text))
return (Status.ok, fill3.join("", text))
@deps(deps={"pip/pygments"}, url="http://pygments.org/")
@ -249,7 +246,7 @@ def contents(path):
text = _syntax_highlight_using_path(text, path)
except pygments.util.ClassNotFound:
pass
return Status.normal, text
return Status.ok, text
def _has_shebang_line(path):
@ -331,7 +328,7 @@ def python_coverage(path):
with open(os.path.join(temp_dir, cover_filename), "r") as f:
lines = f.read().splitlines(keepends=True)
failed_lines = [line for line in lines if line.startswith("! ")]
status = Status.ok if not failed_lines else Status.normal
status = Status.ok if not failed_lines else Status.problem
return status, _colorize_coverage_report(lines)
@ -362,7 +359,7 @@ def python_gut(path):
del lines[start_line-deleted:end_line-deleted]
deleted += (end_line - start_line)
gutted_source = "".join(lines)
return Status.normal, _syntax_highlight_using_path(gutted_source, path)
return Status.ok, _syntax_highlight_using_path(gutted_source, path)
def _get_mccabe_line_score(line):
@ -392,7 +389,7 @@ def python_mccabe(path):
# @deps(deps={"pip/xdis"}, executables={"pydisasm"},
# url="https://pypi.python.org/pypi/xdis")
# def pydisasm(path):
# return _run_command(["pydisasm", path], Status.normal,
# return _run_command(["pydisasm", path], Status.ok,
# Status.not_applicable)
@ -400,7 +397,7 @@ def python_mccabe(path):
executables={"perltidy"})
def perltidy(path):
stdout, *rest = _do_command(["perltidy", "-st", path])
return Status.normal, _syntax_highlight_using_path(stdout, path)
return Status.ok, _syntax_highlight_using_path(stdout, path)
@deps(deps={"tidy"}, url="https://www.html-tidy.org/", executables={"tidy"})
@ -454,7 +451,7 @@ def pil(path):
with PIL.Image.open(image_file).convert("RGB") as image:
if image.width > MAX_IMAGE_SIZE:
image = _resize_image(image, MAX_IMAGE_SIZE)
return Status.normal, _image_to_text(image)
return Status.ok, _image_to_text(image)
@deps(deps={"pip/svglib"}, url="https://github.com/deeplook/svglib")
@ -465,7 +462,7 @@ def svglib(path):
image = reportlab.graphics.renderPM.drawToPIL(drawing)
if image.width > MAX_IMAGE_SIZE:
image = _resize_image(image, MAX_IMAGE_SIZE)
return Status.normal, _image_to_text(image)
return Status.ok, _image_to_text(image)
@deps(deps={"golang-go"},
@ -477,7 +474,7 @@ def godoc(path):
stdout, stderr, returncode = _do_command(["go", "doc", "."], cwd=temp_dir)
os.remove(symlink_path)
status = (Status.not_applicable if stdout.strip() == "" or returncode != 0
else Status.normal)
else Status.ok)
return status, stdout + stderr
@ -486,26 +483,24 @@ def godoc(path):
def git_log(path):
status, output = _run_command(
["git", "log", "--find-renames", "--follow", "--stat", "--color",
path], success_status=Status.normal,
error_status=Status.not_applicable, has_color=True)
path], error_status=Status.not_applicable, has_color=True)
if output.data == "":
return Status.not_applicable, ""
else:
return status, output
def make_tool_function(dependencies, command, url=None, success_status=None,
error_status=None, has_color=False, timeout=None):
def make_tool_function(dependencies, command, url=None, error_status=None,
has_color=False, timeout=None):
if url is None:
url = dependencies[0]
command_parts = command.split()
executables = set([command_parts[0]])
success_status = None if success_status is None else Status[success_status]
error_status = None if error_status is None else Status[error_status]
@deps(deps=set(dependencies), url=url, executables=executables)
def func(path):
return _run_command(command_parts + [path], success_status,
error_status, has_color, timeout)
return _run_command(command_parts + [path], error_status, has_color,
timeout)
func.command = command
return func
@ -576,8 +571,8 @@ def compression_open_func(compression):
class Result:
COMPLETED_STATUSES = {
Status.ok, Status.problem, Status.normal, Status.error,
Status.not_applicable, Status.timed_out}
Status.ok, Status.problem, Status.error, Status.not_applicable,
Status.timed_out}
def __init__(self, path, tool):
self.path = path
@ -800,4 +795,4 @@ if __name__ == "__main__":
assert tool in valid_tools, valid_tools
status, text = run_tool_no_error(path, tool)
print(text)
sys.exit(0 if status in [Status.ok, Status.normal] else 1)
sys.exit(0 if status == Status.ok else 1)

View file

@ -53,7 +53,6 @@ tools_for_extensions = [
dependencies = []
url = "https://docs.python.org/3/library/pydoc.html"
command = "pydoc_color"
success_status = "normal"
error_status = "not_applicable"
has_color = true
timeout = 60
@ -83,7 +82,6 @@ tools_for_extensions = [
dependencies = []
url = "https://docs.python.org/3/library/modulefinder.html"
command = "python3.9 -m modulefinder"
success_status = "normal"
[bandit]
dependencies = ["pip/bandit"]
@ -107,7 +105,6 @@ tools_for_extensions = [
dependencies = ["perl-doc"]
url = "http://perldoc.perl.org/"
command = "perldoc -oterm"
success_status = "normal"
error_status = "not_applicable"
has_color = true
@ -115,15 +112,12 @@ tools_for_extensions = [
dependencies = ["git"]
url = "https://git-scm.com/docs/git-diff"
command = "git diff --word-diff=color --exit-code"
success_status = "normal"
error_status = "problem"
has_color = true
[git_blame]
dependencies = ["git"]
url = "https://git-scm.com/docs/git-blame"
command = "git blame --show-stats --date=short --color-lines --color-by-age"
success_status = "normal"
error_status = "not_applicable"
has_color = true
@ -131,109 +125,91 @@ tools_for_extensions = [
dependencies = []
url = "https://docs.python.org/3/library/dis.html"
command = "python3.9 -m dis"
success_status = "normal"
[objdump_headers]
dependencies = ["binutils"]
url = "https://en.wikipedia.org/wiki/Objdump"
command = "objdump --all-headers"
success_status = "normal"
[objdump_disassemble]
dependencies = ["binutils"]
url = "https://en.wikipedia.org/wiki/Objdump"
command = "objdump --disassemble --reloc --dynamic-reloc"
success_status = "normal"
[readelf]
dependencies = ["binutils"]
url = "https://en.wikipedia.org/wiki/Objdump"
command = "readelf --all"
success_status = "normal"
[zipinfo]
dependencies = ["unzip"]
url = "http://www.info-zip.org/UnZip.html"
command = "zipinfo"
success_status = "normal"
[tar_gz]
dependencies = ["tar"]
url = "http://www.gnu.org/software/tar/manual/tar.html"
command = "tar ztvf"
success_status = "normal"
[tar_bz2]
dependencies = ["tar"]
url = "http://www.gnu.org/software/tar/manual/tar.html"
command = "tar jtvf"
success_status = "normal"
[unrar]
dependencies = ["unrar"]
url = "http://www.rarlabs.com/"
command = "unrar l"
success_status = "normal"
[7z]
dependencies = ["p7zip"]
url = "http://p7zip.sourceforge.net/"
command = "7zr l"
success_status = "normal"
[unxz]
dependencies = ["xz-utils"]
url = "https://tukaani.org/xz/"
command = "unxz --list"
success_status = "normal"
[dpkg_contents]
dependencies = ["dpkg"]
url = "https://wiki.debian.org/Teams/Dpkg"
command = "dpkg --contents"
success_status = "normal"
[dpkg_info]
dependencies = ["dpkg"]
url = "https://wiki.debian.org/Teams/Dpkg"
command = "dpkg --info"
success_status = "normal"
[rpm]
dependencies = ["rpm"]
url = "http://rpm.org/"
command = "rpm --query --list"
success_status = "normal"
[ar]
dependencies = ["binutils"]
url = "https://en.wikipedia.org/wiki/Ar_(Unix)"
command = "ar t"
success_status = "normal"
[nm]
dependencies = ["binutils"]
url = "https://linux.die.net/man/1/nm"
command = "nm --demangle"
success_status = "normal"
[pdf2txt]
dependencies = ["pip/pdfminer.six"]
url = "https://github.com/pdfminer/pdfminer.six"
command = "pdf2txt.py"
success_status = "normal"
[html2text]
dependencies = ["html2text"]
url = "http://www.mbayer.de/html2text/"
command = "html2text"
success_status = "normal"
[elinks]
dependencies = ["elinks"]
url = "http://elinks.cz/"
command = "elinks -dump-color-mode 1 -dump -no-numbering -no-references"
success_status = "normal"
has_color = true
[c_syntax_gcc]
@ -299,7 +275,6 @@ tools_for_extensions = [
dependencies = ["wabt"]
url = "https://github.com/WebAssembly/wabt"
command = "wasm-objdump --disassemble"
success_status = "normal"
[yamllint]
dependencies = ["pip/yamllint"]
@ -311,10 +286,8 @@ tools_for_extensions = [
dependencies = ["mediainfo"]
url = "https://mediaarea.net/MediaInfo"
command = "mediainfo"
success_status = "normal"
[isoinfo]
dependencies = ["genisoimage"]
url = "https://manpages.debian.org/jessie/genisoimage/isoinfo.1.en.html"
command = "isoinfo -l -i"
success_status = "normal"

View file

@ -26,10 +26,9 @@
│ x - Open the current file with xdg-open. │
│ │
│Statuses: │
  Normal │
  Ok │
  Problem │
  Not applicable │
  Not applicable │
  Running │
  Timed out │
. Pending │
@ -56,5 +55,6 @@
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
 help quit tab:focus orient log edit next sort refresh fullscreen xdg-open 

View file

@ -76,10 +76,10 @@ class ToolsTestCase(unittest.TestCase):
with unittest.mock.patch.object(tools.pwd, "getpwuid",
return_value=mock_pw_entry):
self._test_tool(tools.metadata,
[("hi3.py", tools.Status.normal)])
[("hi3.py", tools.Status.ok)])
def test_contents(self):
self._test_tool(tools.contents, [("hi3.py", tools.Status.normal)])
self._test_tool(tools.contents, [("hi3.py", tools.Status.ok)])
HI_OK = [("hi3.py", tools.Status.ok)]
@ -94,12 +94,12 @@ class ToolsTestCase(unittest.TestCase):
# ("hi3_test.py", tools.Status.ok),
# ("test_foo.py", tools.Status.ok)])
HI_NORMAL = [("hi3.py", tools.Status.normal)]
HI_OK = [("hi3.py", tools.Status.ok)]
def test_pydoc(self):
# FIX: This is failing inside AppImages.
if "APPDIR" not in os.environ:
self._test_tool(tools.pydoc, self.HI_NORMAL)
self._test_tool(tools.pydoc, self.HI_OK)
def test_mypy(self):
self._test_tool(tools.mypy, self.HI_OK)
@ -114,10 +114,10 @@ class ToolsTestCase(unittest.TestCase):
self._test_tool(tools.pylint, self.HI_OK)
def test_python_gut(self):
self._test_tool(tools.python_gut, self.HI_NORMAL)
self._test_tool(tools.python_gut, self.HI_OK)
def test_python_modulefinder(self):
self._test_tool(tools.python_modulefinder, self.HI_NORMAL)
self._test_tool(tools.python_modulefinder, self.HI_OK)
def test_python_mccabe(self):
self._test_tool(tools.python_mccabe, self.HI_OK)
@ -125,7 +125,7 @@ class ToolsTestCase(unittest.TestCase):
# FIX: Make the golden-file deterministic
# def test_pydisasm(self):
# self._test_tool(tools.pydisasm,
# [("hi3.cpython-34.pyc", tools.Status.normal)])
# [("hi3.cpython-34.pyc", tools.Status.ok)])
def test_perl_syntax(self):
self._test_tool(tools.perl_syntax,
@ -134,7 +134,7 @@ class ToolsTestCase(unittest.TestCase):
])
# def test_perltidy(self):
# self._test_tool(tools.perltidy, [("perl.pl", tools.Status.normal)])
# self._test_tool(tools.perltidy, [("perl.pl", tools.Status.ok)])
# def test_perl6_syntax(self):
# self._test_tool(tools.perl6_syntax,
@ -145,37 +145,37 @@ class ToolsTestCase(unittest.TestCase):
def test_objdump_headers(self):
self._test_tool(tools.objdump_headers,
[("Mcrt1.o", tools.Status.normal)])
[("Mcrt1.o", tools.Status.ok)])
def test_objdump_disassemble(self):
self._test_tool(tools.objdump_disassemble,
[("Mcrt1.o", tools.Status.problem)])
def test_readelf(self):
self._test_tool(tools.readelf, [("Mcrt1.o", tools.Status.normal)])
self._test_tool(tools.readelf, [("Mcrt1.o", tools.Status.ok)])
def test_zipinfo(self):
self._test_tool(tools.zipinfo, [("hi.zip", tools.Status.normal)])
self._test_tool(tools.zipinfo, [("hi.zip", tools.Status.ok)])
def test_tar_gz(self):
self._test_tool(tools.tar_gz, [("hi.tar.gz", tools.Status.normal),
("hi.tgz", tools.Status.normal)])
self._test_tool(tools.tar_gz, [("hi.tar.gz", tools.Status.ok),
("hi.tgz", tools.Status.ok)])
def test_tar_bz2(self):
self._test_tool(tools.tar_bz2, [("hi.tar.bz2", tools.Status.normal)])
self._test_tool(tools.tar_bz2, [("hi.tar.bz2", tools.Status.ok)])
def test_nm(self):
self._test_tool(tools.nm, [("libieee.a", tools.Status.normal),
("libpcprofile.so", tools.Status.normal)])
self._test_tool(tools.nm, [("libieee.a", tools.Status.ok),
("libpcprofile.so", tools.Status.ok)])
def test_pdf2txt(self):
self._test_tool(tools.pdf2txt, [("standard.pdf", tools.Status.normal)])
self._test_tool(tools.pdf2txt, [("standard.pdf", tools.Status.ok)])
def test_html_syntax(self):
self._test_tool(tools.html_syntax, [("hi.html", tools.Status.problem)])
def test_html2text(self):
self._test_tool(tools.html2text, [("hi.html", tools.Status.normal)])
self._test_tool(tools.html2text, [("hi.html", tools.Status.ok)])
def test_cpp_syntax_gcc(self):
self._test_tool(tools.cpp_syntax_gcc, [("hello.cpp", tools.Status.ok)])
@ -186,7 +186,7 @@ class ToolsTestCase(unittest.TestCase):
def test_pil(self):
for extension in ["png", "jpg", "gif", "bmp", "ppm", "tiff", "tga"]:
self._test_tool(tools.pil, [("circle." + extension,
tools.Status.normal)])
tools.Status.ok)])
class LruCacheWithEvictionTestCase(unittest.TestCase):

View file

@ -32,7 +32,7 @@ class WorkerTestCase(unittest.TestCase):
worker_.process.stdin.write(f"{compression}\n".encode("utf-8"))
future = worker_.run_tool("foo", tools.metadata)
status = loop.run_until_complete(future)
self.assertEqual(status, tools.Status.normal)
self.assertEqual(status, tools.Status.ok)
result_path = os.path.join(tools.CACHE_PATH, "foo-metadata")
self.assertTrue(os.path.exists(result_path))