diff --git a/fixit/cli.py b/fixit/cli.py index b5ecd6d..bcd7f07 100644 --- a/fixit/cli.py +++ b/fixit/cli.py @@ -2,6 +2,7 @@ import argparse import sys import uuid +from pathlib import Path from fixit import __version__, convert, jsonfmt, password, textutils, wordcount @@ -18,13 +19,16 @@ def build_parser() -> argparse.ArgumentParser: parser.add_argument("--version", action="version", version=f"fixit {__version__}") sub = parser.add_subparsers(dest="command", required=True) + wc = sub.add_parser("wc", help="count words, lines and characters") - wc.add_argument("text") + wc.add_argument("text", nargs="?") + wc.add_argument("--file", type=Path, help="read text from a file") cv = sub.add_parser("convert", help="convert units") cv.add_argument("value", type=float) cv.add_argument("kind", choices=sorted(CONVERSIONS)) + pw = sub.add_parser("password", help="generate a password") pw.add_argument("--length", type=int, default=12) pw.add_argument("--symbols", action="store_true") @@ -46,10 +50,26 @@ def build_parser() -> argparse.ArgumentParser: def main(argv=None) -> int: try: args = build_parser().parse_args(argv) + if args.command == "wc": - print(f"words={wordcount.count_words(args.text)} " - f"lines={wordcount.count_lines(args.text)} " - f"chars={wordcount.count_chars(args.text)}") + if args.file is not None: + try: + text = args.file.read_text(encoding="utf-8") + except OSError: + print(f"Error: cannot read file '{args.file}'", file=sys.stderr) + return 1 + elif args.text is not None: + text = args.text + else: + print("Error: provide text or use --file", file=sys.stderr) + return 1 + + print( + f"words={wordcount.count_words(text)} " + f"lines={wordcount.count_lines(text)} " + f"chars={wordcount.count_chars(text)}" + ) + elif args.command == "convert": print(CONVERSIONS[args.kind](args.value)) elif args.command == "password": diff --git a/tests/test_cli.py b/tests/test_cli.py index 62b729e..d60cd3e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -12,3 +12,20 @@ def test_version(capsys): def test_palindrome_command(capsys): main(["palindrome", "level"]) assert capsys.readouterr().out.strip() == "True" + + +def test_wc_file_option(tmp_path, capsys): + file_path = tmp_path / "sample.txt" + file_path.write_text("hello world\nhow are you", encoding="utf-8") + + result = main(["wc", "--file", str(file_path)]) + + assert result == 0 + assert capsys.readouterr().out.strip() == "words=5 lines=2 chars=23" + + +def test_wc_file_not_found(capsys): + result = main(["wc", "--file", "missing_file.txt"]) + + assert result == 1 + assert "missing_file.txt" in capsys.readouterr().err