1
mirror of https://github.com/streamlink/streamlink synced 2024-11-14 01:04:54 +01:00

cli: fix order of config file deprecation log msgs

- Don't log when loading a config from a deprecated path when using the
  `--config` argument
- Only load the first existing plugin-specific config file
- Keep config file loading order
- Add tests for setup_config_args
This commit is contained in:
bastimeyer 2021-06-06 22:06:02 +02:00 committed by back-to
parent 79a4232e02
commit 6cdc3ebb14
7 changed files with 109 additions and 13 deletions

View File

@ -633,12 +633,9 @@ def setup_args(parser: argparse.ArgumentParser, config_files: List[Path] = None,
arglist = sys.argv[1:]
# Load arguments from config files
for config_file in filter(lambda path: path.is_file(), config_files or []):
if type(config_file) is DeprecatedPath:
log.info(f"Loaded config from deprecated path, see CLI docs for how to migrate: {config_file}")
arglist.insert(0, f"@{config_file}")
configs = [f"@{config_file}" for config_file in config_files or []]
args, unknown = parser.parse_known_args(arglist)
args, unknown = parser.parse_known_args(configs + arglist)
if unknown and not ignore_unknown:
msg = gettext('unrecognized arguments: %s')
parser.error(msg % ' '.join(unknown))
@ -654,20 +651,32 @@ def setup_args(parser: argparse.ArgumentParser, config_files: List[Path] = None,
def setup_config_args(parser, ignore_unknown=False):
config_files = []
if streamlink and args.url:
with ignored(NoPluginError):
plugin = streamlink.resolve_url(args.url)
config_files += [path.with_name(f"{path.name}.{plugin.module}") for path in CONFIG_FILES]
if args.config:
# We want the config specified last to get highest priority
config_files += map(lambda path: Path(path).expanduser(), reversed(args.config))
for config_file in map(lambda path: Path(path).expanduser(), reversed(args.config)):
if config_file.is_file():
config_files.append(config_file)
else:
# Only load first available default config
for config_file in filter(lambda path: path.is_file(), CONFIG_FILES):
if type(config_file) is DeprecatedPath:
log.info(f"Loaded config from deprecated path, see CLI docs for how to migrate: {config_file}")
config_files.append(config_file)
break
if streamlink and args.url:
# Only load first available plugin config
with ignored(NoPluginError):
plugin = streamlink.resolve_url(args.url)
for config_file in CONFIG_FILES:
config_file = config_file.with_name(f"{config_file.name}.{plugin.module}")
if not config_file.is_file():
continue
if type(config_file) is DeprecatedPath:
log.info(f"Loaded plugin config from deprecated path, see CLI docs for how to migrate: {config_file}")
config_files.append(config_file)
break
if config_files:
setup_args(parser, config_files, ignore_unknown=ignore_unknown)

View File

View File

View File

View File

@ -9,17 +9,20 @@ from unittest.mock import Mock, call, patch
import freezegun
import streamlink_cli.main
import tests.resources
from streamlink.plugin.plugin import Plugin
from streamlink.session import Streamlink
from streamlink_cli.compat import is_win32
from streamlink_cli.compat import DeprecatedPath, is_win32
from streamlink_cli.main import (
NoPluginError,
check_file_output,
create_output,
format_valid_streams,
handle_stream,
handle_url,
log_current_arguments,
resolve_stream_name
resolve_stream_name,
setup_config_args
)
from streamlink_cli.output import FileOutput, PlayerOutput
@ -269,6 +272,90 @@ class TestCLIMain(unittest.TestCase):
console.exit.assert_called_with("Cannot use record options with other file output options.")
@patch("streamlink_cli.main.log")
class TestCLIMainSetupConfigArgs(unittest.TestCase):
configdir = Path(tests.resources.__path__[0], "cli", "config")
parser = Mock()
@classmethod
def subject(cls, config_files, **args):
def resolve_url(name):
if name == "noplugin":
raise NoPluginError()
return Mock(module="testplugin")
session = Mock()
session.resolve_url.side_effect = resolve_url
args.setdefault("url", "testplugin")
with patch("streamlink_cli.main.setup_args") as mock_setup_args, \
patch("streamlink_cli.main.args", **args), \
patch("streamlink_cli.main.streamlink", session), \
patch("streamlink_cli.main.CONFIG_FILES", config_files):
setup_config_args(cls.parser)
return mock_setup_args
def test_no_plugin(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "primary", DeprecatedPath(self.configdir / "secondary")],
config=None,
url="noplugin"
)
expected = [self.configdir / "primary"]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [])
def test_default_primary(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "primary", DeprecatedPath(self.configdir / "secondary")],
config=None
)
expected = [self.configdir / "primary", self.configdir / "primary.testplugin"]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [])
def test_default_secondary_deprecated(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "non-existent", DeprecatedPath(self.configdir / "secondary")],
config=None
)
expected = [self.configdir / "secondary", self.configdir / "secondary.testplugin"]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [
call(f"Loaded config from deprecated path, see CLI docs for how to migrate: {expected[0]}"),
call(f"Loaded plugin config from deprecated path, see CLI docs for how to migrate: {expected[1]}")
])
def test_custom_with_primary_plugin(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "primary", DeprecatedPath(self.configdir / "secondary")],
config=[str(self.configdir / "custom")]
)
expected = [self.configdir / "custom", self.configdir / "primary.testplugin"]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [])
def test_custom_with_deprecated_plugin(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "non-existent", DeprecatedPath(self.configdir / "secondary")],
config=[str(self.configdir / "custom")]
)
expected = [self.configdir / "custom", DeprecatedPath(self.configdir / "secondary.testplugin")]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [
call(f"Loaded plugin config from deprecated path, see CLI docs for how to migrate: {expected[1]}")
])
def test_custom_multiple(self, mock_log):
mock_setup_args = self.subject(
[self.configdir / "primary", DeprecatedPath(self.configdir / "secondary")],
config=[str(self.configdir / "non-existent"), str(self.configdir / "primary"), str(self.configdir / "secondary")]
)
expected = [self.configdir / "secondary", self.configdir / "primary", self.configdir / "primary.testplugin"]
mock_setup_args.assert_called_once_with(self.parser, expected, ignore_unknown=False)
self.assertEqual(mock_log.info.mock_calls, [])
class _TestCLIMainLogging(unittest.TestCase):
@classmethod
def subject(cls, argv):