Skip to content

Commit

Permalink
Use red text when printing errors on command line (#649)
Browse files Browse the repository at this point in the history
* colorama shorthand ANSI sequence for red error text

* ignore colorama imports in mypy config file

* update tests and authors list

* style

* gracefully handle colorama not being available

* remove colorama import exception handling

* moving colorama.init() & remove local colorama bindings

* add no-color flag

* add no-color test

* f-string colorama formatting in helper method

* no-color option working for twine check with updated tests

* Move --no-color to base command

Co-authored-by: Brian Rutledge <brian@bhrutledge.com>
  • Loading branch information
callmecampos and bhrutledge committed Jun 18, 2020
1 parent b1c2191 commit cb7e116
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 8 deletions.
4 changes: 4 additions & 0 deletions mypy.ini
Expand Up @@ -18,6 +18,10 @@ warn_return_any = True
no_implicit_reexport = True
strict_equality = True

[mypy-colorama]
; https://github.com/tartley/colorama/issues/206
ignore_missing_imports = True

[mypy-importlib_metadata]
; https://gitlab.com/python-devs/importlib_metadata/-/issues/10
ignore_missing_imports = True
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Expand Up @@ -43,6 +43,7 @@ install_requires=
importlib_metadata; python_version < "3.8"
keyring >= 15.1
rfc3986 >= 1.4.0
colorama >= 0.4.3
setup_requires =
setuptools_scm >= 1.15
include_package_data = True
Expand Down
18 changes: 12 additions & 6 deletions tests/test_main.py
Expand Up @@ -10,14 +10,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import pretend
import sys

import colorama

from twine import __main__ as dunder_main
from twine import cli
from twine import exceptions


def test_exception_handling(monkeypatch):
replaced_dispatch = pretend.raiser(exceptions.InvalidConfiguration("foo"))
monkeypatch.setattr(cli, "dispatch", replaced_dispatch)
assert dunder_main.main() == "InvalidConfiguration: foo"
monkeypatch.setattr(sys, "argv", ["twine", "upload", "missing.whl"])
message = "InvalidDistribution: Cannot find file (or expand pattern): 'missing.whl'"
assert dunder_main.main() == colorama.Fore.RED + message + colorama.Style.RESET_ALL


def test_no_color_exception(monkeypatch):
monkeypatch.setattr(sys, "argv", ["twine", "--no-color", "upload", "missing.whl"])
message = "InvalidDistribution: Cannot find file (or expand pattern): 'missing.whl'"
assert dunder_main.main() == message
1 change: 1 addition & 0 deletions tox.ini
Expand Up @@ -11,6 +11,7 @@ deps =
portend
pytest-services
munch
colorama
passenv =
PYTEST_ADDOPTS
commands =
Expand Down
12 changes: 11 additions & 1 deletion twine/__main__.py
Expand Up @@ -15,6 +15,7 @@
import sys
from typing import Any

import colorama
import requests

from twine import cli
Expand All @@ -25,7 +26,16 @@ def main() -> Any:
try:
return cli.dispatch(sys.argv[1:])
except (exceptions.TwineException, requests.HTTPError) as exc:
return "{}: {}".format(exc.__class__.__name__, exc.args[0])
return _format_error(f"{exc.__class__.__name__}: {exc.args[0]}")


def _format_error(message: str) -> str:
pre_style, post_style = "", ""
if not cli.args.no_color:
colorama.init()
pre_style, post_style = colorama.Fore.RED, colorama.Style.RESET_ALL

return f"{pre_style}{message}{post_style}"


if __name__ == "__main__":
Expand Down
11 changes: 10 additions & 1 deletion twine/cli.py
Expand Up @@ -27,6 +27,8 @@
import twine
from twine import _installed

args = argparse.Namespace()


def _registered_commands(
group: str = "twine.registered_commands",
Expand Down Expand Up @@ -59,14 +61,21 @@ def dispatch(argv: List[str]) -> Any:
action="version",
version="%(prog)s version {} ({})".format(twine.__version__, dep_versions()),
)
parser.add_argument(
"--no-color",
default=False,
required=False,
action="store_true",
help="disable colored output",
)
parser.add_argument(
"command", choices=registered_commands.keys(),
)
parser.add_argument(
"args", help=argparse.SUPPRESS, nargs=argparse.REMAINDER,
)

args = parser.parse_args(argv)
parser.parse_args(argv, namespace=args)

main = registered_commands[args.command].load()

Expand Down

0 comments on commit cb7e116

Please sign in to comment.