Skip to content

Commit

Permalink
[PATCH] cli: prioritize --help and fix its output (streamlink#4213)
Browse files Browse the repository at this point in the history
  • Loading branch information
Billy2011 committed Nov 27, 2021
1 parent a2406c5 commit ae20df2
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/streamlink_cli/argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ def build_parser():
Example:
%(prog)s --output "~/recordings/{author}/{category}/{id}-{time:%Y%m%d%H%M%S}.ts" <URL> [STREAM]
%(prog)s --output "~/recordings/{author}/{category}/{id}-{time:%%Y%%m%%d%%H%%M%%S}.ts" <URL> [STREAM]
"""
)
output.add_argument(
Expand Down Expand Up @@ -587,7 +587,7 @@ def build_parser():
Example:
%(prog)s --record "~/recordings/{author}/{category}/{id}-{time:%Y%m%d%H%M%S}.ts" <URL> [STREAM]
%(prog)s --record "~/recordings/{author}/{category}/{id}-{time:%%Y%%m%%d%%H%%M%%S}.ts" <URL> [STREAM]
"""
)
output.add_argument(
Expand All @@ -604,7 +604,7 @@ def build_parser():
Example:
%(prog)s --record-and-pipe "~/recordings/{author}/{category}/{id}-{time:%Y%m%d%H%M%S}.ts" <URL> [STREAM]
%(prog)s --record-and-pipe "~/recordings/{author}/{category}/{id}-{time:%%Y%%m%%d%%H%%M%%S}.ts" <URL> [STREAM]
"""
)
output.add_argument(
Expand Down
14 changes: 10 additions & 4 deletions src/streamlink_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ def setup_logger_and_console(stream=sys.stdout, filename=None, level="info", jso
datefmt="%H:%M:%S"
)

console = ConsoleOutput(streamhandler.stream, json)
console = ConsoleOutput(streamhandler.stream, streamlink, json)


def main():
Expand Down Expand Up @@ -1064,7 +1064,9 @@ def main():
with ignored(Exception):
check_version(force=args.version_check)

if args.plugins:
if args.help:
parser.print_help()
elif args.plugins:
print_plugins()
elif args.can_handle_url:
try:
Expand Down Expand Up @@ -1097,15 +1099,19 @@ def main():
stream_fd.close()
except KeyboardInterrupt:
error_code = 130
elif args.help:
parser.print_help()
else:
usage = parser.format_usage()
"""
msg = (
"{usage}\nUse -h/--help to see the available options or "
"read the manual at https://Billy2011.github.io/streamlink-27"
).format(usage=usage)
console.msg(msg)
"""
console.msg(
"{usage}\n"
"Use -h/--help to see the available options or read the manual at https://streamlink.github.io".format(usage=usage)
)

sys.exit(error_code)

Expand Down
76 changes: 76 additions & 0 deletions tests/test_cli_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import tempfile
import unittest
from textwrap import dedent

import streamlink_cli.main
from streamlink.session import Streamlink
Expand Down Expand Up @@ -470,3 +471,78 @@ def test_logfile_loglevel_none(self, mock_open, mock_stdout):
self.assertEqual(streamlink_cli.main.console.output, sys.stdout)
self.assertFalse(mock_open.called)
self.assertEqual(mock_stdout.write.mock_calls, [call("bar\n")])


class TestCLIMainPrint(unittest.TestCase):
def subject(self):
with patch.object(Streamlink, "load_builtin_plugins"), \
patch.object(Streamlink, "resolve_url") as mock_resolve_url, \
patch.object(Streamlink, "resolve_url_no_redirect") as mock_resolve_url_no_redirect:
session = Streamlink()
session.load_plugins(os.path.join(os.path.dirname(__file__), "plugin"))
with patch("streamlink_cli.main.streamlink", session), \
patch("streamlink_cli.main.CONFIG_FILES", []), \
patch("streamlink_cli.main.setup_streamlink"), \
patch("streamlink_cli.main.setup_plugins"), \
patch("streamlink_cli.main.setup_http_session"), \
patch("streamlink_cli.main.setup_signals"), \
patch("streamlink_cli.main.setup_options") as mock_setup_options:
with self.assertRaises(SystemExit) as cm:
streamlink_cli.main.main()
self.assertEqual(cm.exception.code, 0)
mock_resolve_url.assert_not_called()
mock_resolve_url_no_redirect.assert_not_called()
mock_setup_options.assert_not_called()

@staticmethod
def get_stdout(mock_stdout):
return "".join([call_arg[0][0] for call_arg in mock_stdout.write.call_args_list])

@patch("sys.stdout")
@patch("sys.argv", ["streamlink"])
def test_print_usage(self, mock_stdout):
self.subject()
self.assertEqual(
self.get_stdout(mock_stdout),
"usage: streamlink [OPTIONS] <URL> [STREAM]\n\n"
+ "Use -h/--help to see the available options or read the manual at https://streamlink.github.io\n"
)

@patch("sys.stdout")
@patch("sys.argv", ["streamlink", "--help"])
def test_print_help(self, mock_stdout):
self.subject()
output = self.get_stdout(mock_stdout)
self.assertIn(
"usage: streamlink [OPTIONS] <URL> [STREAM]",
output
)
self.assertIn(
dedent("""
Streamlink is a command-line utility that extracts streams from various
services and pipes them into a video player of choice.
"""),
output
)
self.assertIn(
dedent("""
For more in-depth documentation see:
https://Billy2011.github.io/streamlink-27
Please report broken plugins or bugs to the issue tracker on Github:
https://github.com/streamlink/streamlink/issues
"""),
output
)

@patch("sys.stdout")
@patch("sys.argv", ["streamlink", "--plugins"])
def test_print_plugins(self, mock_stdout):
self.subject()
self.assertEqual(self.get_stdout(mock_stdout), "Loaded plugins: testplugin\n")

@patch("sys.stdout")
@patch("sys.argv", ["streamlink", "--plugins", "--json"])
def test_print_plugins_json(self, mock_stdout):
self.subject()
self.assertEqual(self.get_stdout(mock_stdout), """[\n "testplugin"\n]\n""")

0 comments on commit ae20df2

Please sign in to comment.