[BACKEND] Error if arg after positional arg
This commit is contained in:
parent
896a9e2073
commit
6eabd55043
4 changed files with 77 additions and 15 deletions
|
|
@ -7,7 +7,7 @@ from typing import Tuple
|
|||
|
||||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.cli.main_args_parser import MainArgs
|
||||
from ytdl_sub.cli.main_args_parser import MainArguments
|
||||
from ytdl_sub.config.config_validator import ConfigOptions
|
||||
from ytdl_sub.utils.exceptions import InvalidDlArguments
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ class DownloadArgsParser:
|
|||
self._config_options = config_options
|
||||
|
||||
for arg in extra_arguments:
|
||||
if arg in MainArgs.all():
|
||||
if arg in MainArguments.all():
|
||||
raise InvalidDlArguments(
|
||||
f"'{arg}' is a ytdl-sub argument and must placed behind 'dl'"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ from typing import List
|
|||
from typing import Tuple
|
||||
|
||||
from ytdl_sub.cli.download_args_parser import DownloadArgsParser
|
||||
from ytdl_sub.cli.main_args_parser import MainArguments
|
||||
from ytdl_sub.cli.main_args_parser import parser
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.exceptions import ValidationException
|
||||
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
|
||||
from ytdl_sub.utils.file_lock import working_directory_lock
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
|
|
@ -35,11 +37,19 @@ def _download_subscriptions_from_yaml_files(
|
|||
Returns
|
||||
-------
|
||||
List of (subscription, transaction_log)
|
||||
|
||||
Raises
|
||||
------
|
||||
Validation exception if main arg is specified as a subscription path
|
||||
"""
|
||||
subscription_paths: List[str] = args.subscription_paths
|
||||
subscriptions: List[Subscription] = []
|
||||
output: List[Tuple[Subscription, FileHandlerTransactionLog]] = []
|
||||
|
||||
# Make sure no main args are passed as a subscription path
|
||||
if main_argument := MainArguments.get_argument_if_exists(subscription_paths) is not None:
|
||||
raise ValidationException(f"The argument '{main_argument}' must be passed before 'sub'")
|
||||
|
||||
# Load all the subscriptions first to perform all validation before downloading
|
||||
for path in subscription_paths:
|
||||
subscriptions += Subscription.from_file_path(config=config, subscription_path=path)
|
||||
|
|
|
|||
|
|
@ -1,23 +1,73 @@
|
|||
import argparse
|
||||
import dataclasses
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from ytdl_sub.utils.logger import LoggerLevels
|
||||
|
||||
|
||||
class MainArgs(Enum):
|
||||
CONFIG = "--config"
|
||||
DRY_RUN = "--dry-run"
|
||||
LOG_LEVEL = "--log-level"
|
||||
@dataclasses.dataclass
|
||||
class MainArgument:
|
||||
short: str
|
||||
long: str
|
||||
is_positional: bool = False
|
||||
|
||||
|
||||
class MainArguments:
|
||||
CONFIG = MainArgument(
|
||||
short="-c",
|
||||
long="--config",
|
||||
)
|
||||
DRY_RUN = MainArgument(
|
||||
short="-d",
|
||||
long="--dry-run",
|
||||
is_positional=True,
|
||||
)
|
||||
LOG_LEVEL = MainArgument(
|
||||
short="-l",
|
||||
long="--log-level",
|
||||
is_positional=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def all(cls) -> List[str]:
|
||||
def all(cls) -> List[MainArgument]:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
List of all args used in main CLI
|
||||
List of MainArgument classes
|
||||
"""
|
||||
return list(map(lambda arg: arg.value, cls))
|
||||
return [cls.CONFIG, cls.DRY_RUN, cls.LOG_LEVEL]
|
||||
|
||||
@classmethod
|
||||
def all_arguments(cls) -> List[str]:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
List of all string args that can be used in the CLI
|
||||
"""
|
||||
all_args = []
|
||||
for arg in cls.all():
|
||||
all_args.extend([arg.short, arg.long])
|
||||
return all_args
|
||||
|
||||
@classmethod
|
||||
def get_argument_if_exists(cls, input_args: List[str]) -> Optional[str]:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
input_args
|
||||
List of arguments
|
||||
|
||||
Returns
|
||||
-------
|
||||
True if a Main argument is in the input arguments. False otherwise.
|
||||
"""
|
||||
for input_arg in input_args:
|
||||
for main_arg in cls.all_arguments():
|
||||
if input_arg == main_arg:
|
||||
return input_arg
|
||||
return None
|
||||
|
||||
|
||||
###################################################################################################
|
||||
|
|
@ -26,21 +76,23 @@ parser = argparse.ArgumentParser(
|
|||
description="ytdl-sub: Automate download and adding metadata with YoutubeDL"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
MainArgs.CONFIG.value,
|
||||
MainArguments.CONFIG.short,
|
||||
MainArguments.CONFIG.long,
|
||||
metavar="CONFIGPATH",
|
||||
type=str,
|
||||
help="path to the config yaml, uses config.yaml if not provided",
|
||||
default="config.yaml",
|
||||
)
|
||||
parser.add_argument(
|
||||
MainArgs.DRY_RUN.value,
|
||||
MainArguments.DRY_RUN.short,
|
||||
MainArguments.DRY_RUN.long,
|
||||
action="store_true",
|
||||
help="preview what a download would output, "
|
||||
"does not perform any video downloads or writes to output directories",
|
||||
)
|
||||
parser.add_argument(
|
||||
MainArgs.LOG_LEVEL.value,
|
||||
MainArguments.LOG_LEVEL.short,
|
||||
MainArguments.LOG_LEVEL.long,
|
||||
metavar="|".join(LoggerLevels.names()),
|
||||
type=str,
|
||||
help="level of logs to print to console, defaults to info",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from typing import Optional
|
|||
import pytest
|
||||
|
||||
from ytdl_sub.cli.download_args_parser import DownloadArgsParser
|
||||
from ytdl_sub.cli.main_args_parser import MainArgs
|
||||
from ytdl_sub.cli.main_args_parser import MainArguments
|
||||
from ytdl_sub.cli.main_args_parser import parser
|
||||
from ytdl_sub.config.config_validator import ConfigOptions
|
||||
from ytdl_sub.utils.exceptions import InvalidDlArguments
|
||||
|
|
@ -151,7 +151,7 @@ class TestDownloadArgsParser:
|
|||
extra_arguments=extra_args, config_options=config_options
|
||||
).to_subscription_dict()
|
||||
|
||||
@pytest.mark.parametrize("main_argument", MainArgs.all())
|
||||
@pytest.mark.parametrize("main_argument", MainArguments.all())
|
||||
def test_error_uses_main_args(self, main_argument, config_options_generator):
|
||||
config_options = config_options_generator()
|
||||
extra_args = _get_extra_arguments(cmd_string=f"dl {main_argument}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue