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:
parent
79a4232e02
commit
6cdc3ebb14
@ -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)
|
||||
|
||||
|
0
tests/resources/cli/config/custom
Normal file
0
tests/resources/cli/config/custom
Normal file
0
tests/resources/cli/config/primary
Normal file
0
tests/resources/cli/config/primary
Normal file
0
tests/resources/cli/config/primary.testplugin
Normal file
0
tests/resources/cli/config/primary.testplugin
Normal file
0
tests/resources/cli/config/secondary
Normal file
0
tests/resources/cli/config/secondary
Normal file
0
tests/resources/cli/config/secondary.testplugin
Normal file
0
tests/resources/cli/config/secondary.testplugin
Normal 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):
|
||||
|
Loading…
Reference in New Issue
Block a user