Skip to content

Commit

Permalink
Merge pull request #128 from willkg/71-color
Browse files Browse the repository at this point in the history
Redo tarrminal printin' and colorr (#71)
  • Loading branch information
willkg committed Jun 8, 2022
2 parents 5dcac03 + b6d34d7 commit 3d1f5de
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 167 deletions.
1 change: 0 additions & 1 deletion README.rst
Expand Up @@ -41,7 +41,6 @@ Quick start
Install::

$ pip install dennis
$ pip install blessings # Optional for prettier output

Lint a PO file for problems::

Expand Down
212 changes: 69 additions & 143 deletions dennis/cmdline.py
Expand Up @@ -12,8 +12,6 @@
from dennis.templatelinter import TemplateLinter
from dennis.templatelinter import get_lint_rules as get_template_linter_rules
from dennis.tools import (
FauxTerminal,
Terminal,
get_available_formats,
parse_pofile,
withlines,
Expand All @@ -24,13 +22,6 @@
USAGE = "%prog [options] [command] [command-options]"
VERSION = "dennis " + __version__

# blessings.Terminal and our FauxTerminal don't maintain any state so
# we can make it global
if sys.stdout.isatty():
TERM = Terminal()
else:
TERM = FauxTerminal()


def utf8_args(fun):
@wraps(fun)
Expand All @@ -41,20 +32,9 @@ def _utf8_args(*args):
return _utf8_args


def out(*s):
for part in s:
click.echo(part, nl=False)
click.echo("")


def err(*s):
def err(s):
"""Prints a single-line string to stderr."""
parts = [TERM.bold_red, "Error: "]
parts.extend(s)
parts.append(TERM.normal)
for part in parts:
click.echo(part, nl=False, err=True)
click.echo("")
click.secho(f"Error: {s}", fg="red", bold=True, err=True)


def format_formats():
Expand Down Expand Up @@ -136,7 +116,6 @@ def cli():

@cli.command()
@click.option("--quiet/--no-quiet", default=False)
@click.option("--color/--no-color", default=True)
@click.option(
"--varformat",
default="python-format,python-brace-format",
Expand Down Expand Up @@ -167,7 +146,7 @@ def cli():
@epilog(
format_formats() + "\n" + format_lint_rules() + "\n" + format_lint_template_rules()
)
def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly, path):
def lint(ctx, quiet, varformat, rules, excluderules, reporter, errorsonly, path):
"""
Lints .po/.pot files for issues
Expand All @@ -176,13 +155,8 @@ def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly
documentation for details.
"""
global TERM

if not quiet:
out("dennis version {version}".format(version=__version__))

if not color:
TERM = FauxTerminal()
click.echo(f"dennis version {__version__}")

# Make sure requested rules are valid
all_rules = get_linter_rules(with_names=True)
Expand Down Expand Up @@ -237,21 +211,20 @@ def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly
total_files_with_errors = 0

for fn in po_files:
formatted_fn = click.format_filename(fn)
try:
if not os.path.exists(fn):
raise click.UsageError(
'File "{fn}" does not exist.'.format(fn=click.format_filename(fn))
)
raise click.UsageError(f'File "{formatted_fn}" does not exist.')

if fn.endswith(".po"):
results = linter.verify_file(fn)
else:
results = templatelinter.verify_file(fn)
except IOError as ioe:
# This is not a valid .po file. So mark it as an error.
err(">>> Problem opening file: {fn}".format(fn=click.format_filename(fn)))
err(f">>> Problem opening file: {formatted_fn}")
err(repr(ioe))
out("")
click.echo("")

# FIXME - should we track this separately as an invalid
# file?
Expand All @@ -270,11 +243,7 @@ def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly
continue

if not quiet and not reporter:
out(
TERM.bold_green,
">>> Working on: {fn}".format(fn=click.format_filename(fn)),
TERM.normal,
)
click.secho(f">>> Working on: {formatted_fn}", fg="green", bold=True)

error_results = [res for res in results if res.kind == "err"]
warning_results = [res for res in results if res.kind == "warn"]
Expand All @@ -288,102 +257,64 @@ def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly
if not quiet:
for msg in error_results:
if reporter == "line":
out(
fn,
":",
str(msg.poentry.linenum),
":",
"0",
":",
msg.code,
":",
msg.msg,
)
click.echo(f"{fn}: {msg.poentry.linenum}: 0: {msg.code}: {msg.msg}")
else:
out(TERM.bold_red, msg.code, ": ", msg.msg, TERM.normal)
out(withlines(msg.poentry.linenum, msg.poentry.original))
out("")
err(f"{msg.code}: {msg.msg}")
click.echo(withlines(msg.poentry.linenum, msg.poentry.original))
click.echo("")

if not quiet and not errorsonly:
for msg in warning_results:
if reporter == "line":
out(
fn,
":",
str(msg.poentry.linenum),
":",
"0",
":",
msg.code,
":",
msg.msg,
)
click.echo(f"{fn}: {msg.poentry.linenum}: 0: {msg.code}: {msg.msg}")
else:
out(TERM.bold_yellow, msg.code, ": ", msg.msg, TERM.normal)
out(withlines(msg.poentry.linenum, msg.poentry.original))
out("")
click.secho(f"{msg.code}: {msg.msg}", fg="yellow", bold=True)
click.echo(withlines(msg.poentry.linenum, msg.poentry.original))
click.echo("")

files_to_errors[fn] = (error_count, warning_count)

if error_count > 0:
total_files_with_errors += 1

if not quiet and reporter != "line":
out("Totals")
click.echo("Totals")
if not errorsonly:
out(" Warnings: {warnings:5}".format(warnings=warning_count))
out(" Errors: {errors:5}\n".format(errors=error_count))
click.echo(f" Warnings: {warning_count:5}")
click.echo(f" Errors: {error_count:5}")
click.echo("")

if len(po_files) > 1 and not quiet and reporter != "line":
out("Final totals")
out(
" Number of files examined: {count:5}".format(count=len(po_files))
)
out(
" Total number of files with errors: {count:5}".format(
count=total_files_with_errors
)
)
click.echo("Final totals")
click.echo(f" Number of files examined: {len(po_files):5}")
click.echo(f" Total number of files with errors: {total_files_with_errors:5}")
if not errorsonly:
out(
" Total number of warnings: {count:5}".format(
count=total_warning_count
)
)
out(
" Total number of errors: {count:5}".format(
count=total_error_count
)
)
out("")
click.echo(f" Total number of warnings: {total_warning_count:5}")
click.echo(f" Total number of errors: {total_error_count:5}")
click.echo("")

file_counts = [
(counts[0], counts[1], fn.split(os.sep)[-3], fn.split(os.sep)[-1])
for (fn, counts) in files_to_errors.items()
]

# If we're showing errors only, then don't talk about warnings.
if errorsonly:
header = "Errors Filename"
line = " {errors:5} {locale} ({fn})"
else:
header = "Warnings Errors Filename"
line = " {warnings:5} {errors:5} {locale} ({fn})"

file_counts = list(reversed(sorted(file_counts)))
printed_header = False
for error_count, warning_count, locale, fn in file_counts:
if not error_count and not warning_count:
continue

if not printed_header:
out(header)
if errorsonly:
click.echo("Errors Filename")
else:
click.echo("Warnings Errors Filename")
printed_header = True

out(
line.format(
warnings=warning_count, errors=error_count, fn=fn, locale=locale
)
)
if errorsonly:
click.echo(f" {error_count:5} {locale} ({fn})")
else:
click.echo(f" {warning_count:5} {error_count:5} {locale} ({fn})")

# Return 0 if everything was fine or 1 if there were errors.
ctx.exit(code=1 if total_error_count else 0)
Expand All @@ -398,7 +329,7 @@ def lint(ctx, quiet, color, varformat, rules, excluderules, reporter, errorsonly
@click.pass_context
def status(ctx, showuntranslated, showfuzzy, path):
"""Show status of a .po file."""
out("dennis version {version}".format(version=__version__))
click.echo(f"dennis version {__version__}")

po_files = []
for item in path:
Expand All @@ -413,26 +344,21 @@ def status(ctx, showuntranslated, showfuzzy, path):
po_files = [os.path.abspath(fn) for fn in po_files if fn.endswith(".po")]

for fn in po_files:
formatted_fn = click.format_filename(fn)
try:
if not os.path.exists(fn):
raise IOError(
'File "{fn}" does not exist.'.format(fn=click.format_filename(fn))
)
raise IOError(f'File "{formatted_fn}" does not exist.')

pofile = parse_pofile(fn)
except IOError as ioe:
err(">>> Problem opening file: {fn}".format(fn=click.format_filename(fn)))
err(f">>> Problem opening file: {formatted_fn}")
err(repr(ioe))
continue

out("")
out(
TERM.bold_green,
">>> Working on: {fn}".format(fn=click.format_filename(fn)),
TERM.normal,
)
click.echo("")
click.secho(f">>> Working on: {formatted_fn}", fg="green", bold=True)

out("Metadata:")
click.echo("Metadata:")
for key in (
"Language",
"Report-Msgid-Bugs-To",
Expand All @@ -442,22 +368,22 @@ def status(ctx, showuntranslated, showfuzzy, path):
"Plural-Forms",
):
if key in pofile.metadata and pofile.metadata[key]:
out(" ", key, ": ", pofile.metadata[key])
out("")
click.echo(f" {key}: {pofile.metadata[key]}")
click.echo("")

if showuntranslated:
out("Untranslated strings:")
out("")
click.echo("Untranslated strings:")
click.echo("")
for poentry in pofile.untranslated_entries():
out(withlines(poentry.linenum, poentry.original))
out("")
click.echo(withlines(poentry.linenum, poentry.original))
click.echo("")

if showfuzzy:
out("Fuzzy strings:")
out("")
click.echo("Fuzzy strings:")
click.echo("")
for poentry in pofile.fuzzy_entries():
out(withlines(poentry.linenum, poentry.original))
out("")
click.echo(withlines(poentry.linenum, poentry.original))
click.echo("")

total_words = 0
translated_words = 0
Expand All @@ -474,18 +400,18 @@ def status(ctx, showuntranslated, showfuzzy, path):
fuzzy_total = len(pofile.fuzzy_entries())
untranslated_total = len(pofile.untranslated_entries())

out("Statistics:")
out(" Total strings: {}".format(total_strings))
out(" Translated: {}".format(translated_total))
out(" Untranslated: {}".format(untranslated_total))
out(" Fuzzy: {}".format(fuzzy_total))
out(" Total translateable words: {}".format(total_words))
out(" Translated: {}".format(translated_words))
out(" Untranslated: {}".format(untranslated_words))
click.echo("Statistics:")
click.echo(f" Total strings: {total_strings}")
click.echo(f" Translated: {translated_total}")
click.echo(f" Untranslated: {untranslated_total}")
click.echo(f" Fuzzy: {fuzzy_total}")
click.echo(f" Total translateable words: {total_words}")
click.echo(f" Translated: {translated_words}")
click.echo(f" Untranslated: {untranslated_words}")
if untranslated_words == 0:
out(" Percentage: 100% COMPLETE!")
click.echo(" Percentage: 100% COMPLETE!")
else:
out(" Percentage: {}%".format(pofile.percent_translated()))
click.echo(f" Percentage: {pofile.percent_translated()}%")

ctx.exit(0)

Expand Down Expand Up @@ -524,7 +450,7 @@ def translate(ctx, varformat, pipeline, strings, path):
"""
if not (path and path[0] == "-"):
# We don't want to print this if they're piping to stdin
out("dennis version {version}".format(version=__version__))
click.echo(f"dennis version {__version__}")

if not path:
raise click.UsageError("nothing to work on. Use --help for help.")
Expand All @@ -538,13 +464,13 @@ def translate(ctx, varformat, pipeline, strings, path):
# Args are strings to be translated
for arg in path:
data = translator.translate_string(arg)
out(data)
click.echo(data)

elif path[0] == "-":
# Read everything from stdin, then translate it
data = click.get_binary_stream("stdin").read()
data = translator.translate_string(data)
out(data)
click.echo(data)

else:
# Check all the paths first
Expand All @@ -571,8 +497,8 @@ def exception_handler(exc_type, exc_value, exc_tb):
click.echo("bug report:")
click.echo("")
click.echo("---")
out("Dennis: ", repr(__version__))
out("Python: ", repr(sys.version))
out("Command line: ", repr(sys.argv))
click.echo(f"Dennis: {__version__}")
click.echo(f"Python: {sys.version}")
click.echo(f"Command line: {sys.argv}")
click.echo("".join(traceback.format_exception(exc_type, exc_value, exc_tb)))
click.echo("---")

0 comments on commit 3d1f5de

Please sign in to comment.