From 83fd1f4c1a94cf4d9f760153620f97e4b28dc55c Mon Sep 17 00:00:00 2001 From: "yuanzhu.zhan" Date: Fri, 13 Aug 2021 15:20:00 +0800 Subject: [PATCH] feat(cli): catch the known custom exception and print error message --- tensorbay/cli/auth.py | 61 +++++++++++++++++++++-------------------- tensorbay/cli/commit.py | 44 +++++++++++++++-------------- tensorbay/cli/config.py | 54 +++++++++++++++++++----------------- tensorbay/cli/cp.py | 52 ++++++++++++++++++++--------------- tensorbay/cli/draft.py | 48 +++++++++++++++----------------- tensorbay/cli/log.py | 60 ++++++++++++++++++++++------------------ tensorbay/cli/ls.py | 26 ++++++++++-------- tensorbay/cli/rm.py | 34 +++++++++++++---------- tensorbay/cli/tag.py | 37 +++++++++++++------------ 9 files changed, 223 insertions(+), 193 deletions(-) diff --git a/tensorbay/cli/auth.py b/tensorbay/cli/auth.py index 5db7abbbc..99098732a 100644 --- a/tensorbay/cli/auth.py +++ b/tensorbay/cli/auth.py @@ -12,7 +12,7 @@ import click -from ..exception import UnauthorizedError +from ..exception import TensorBayException, UnauthorizedError from .utility import ( ContextInfo, error, @@ -35,38 +35,41 @@ def _implement_auth( # pylint: disable=too-many-arguments unset: bool, is_all: bool, ) -> None: - _check_args_and_options(arg1, arg2, get, status, unset, is_all) - - if get: - _get_auth(obj, is_all) - return - - if status: - _status_auth(obj, is_all) - return - - if unset: - _unset_auth(obj, is_all) - return + try: + _check_args_and_options(arg1, arg2, get, status, unset, is_all) - if not arg1 and not arg2: - arg1 = _interactive_auth() + if get: + _get_auth(obj, is_all) + return - elif is_accesskey(arg1): - if _is_gas_url(arg2): - error('Please use "gas auth [url] [accessKey]" to specify the url and accessKey') - if arg2: - error(f'Redundant argument "{arg2}"') + if status: + _status_auth(obj, is_all) + return - elif _is_gas_url(arg1): - if not arg2: - arg2 = _interactive_auth(arg1) - elif not is_accesskey(arg2): - error("Wrong accesskey format") - else: - error(f'Invalid argument "{arg1}"') + if unset: + _unset_auth(obj, is_all) + return - _update_profile(obj, arg1, arg2) + if not arg1 and not arg2: + arg1 = _interactive_auth() + + elif is_accesskey(arg1): + if _is_gas_url(arg2): + error('Please use "gas auth [url] [accessKey]" to specify the url and accessKey') + if arg2: + error(f'Redundant argument "{arg2}"') + + elif _is_gas_url(arg1): + if not arg2: + arg2 = _interactive_auth(arg1) + elif not is_accesskey(arg2): + error("Wrong accesskey format") + else: + error(f'Invalid argument "{arg1}"') + + _update_profile(obj, arg1, arg2) + except TensorBayException as err: + error(str(err)) def _get_auth(obj: ContextInfo, is_all: bool) -> None: diff --git a/tensorbay/cli/commit.py b/tensorbay/cli/commit.py index 332a5d855..c687d8055 100644 --- a/tensorbay/cli/commit.py +++ b/tensorbay/cli/commit.py @@ -9,6 +9,7 @@ import click +from ..exception import TensorBayException from .tbrn import TBRN, TBRNType from .utility import ContextInfo, edit_message, error, format_hint, get_dataset_client, get_gas @@ -21,24 +22,25 @@ def _implement_commit(obj: ContextInfo, tbrn: str, message: Tuple[str, ...]) -> None: - gas = get_gas(*obj) - info = TBRN(tbrn=tbrn) - dataset_client = get_dataset_client(gas, info) - - if info.type != TBRNType.DATASET: - error(f'To operate a commit, "{info}" must be a dataset') - - if not info.is_draft: - error(f'To commit, "{info}" must be in draft status, like "{info}#1"') - - dataset_client.checkout(draft_number=info.draft_number) - - draft = dataset_client.get_draft() - hint_message = format_hint(draft.title, draft.description, _COMMIT_HINT) - title, description = edit_message(message, hint_message, obj.config_parser) - if not title: - error("Aborting commit due to empty commit message") - - dataset_client.commit(title, description) - commit_tbrn = TBRN(info.dataset_name, revision=dataset_client.status.commit_id).get_tbrn() - click.echo(f"Committed successfully: {tbrn} -> {commit_tbrn}") + try: + gas = get_gas(*obj) + info = TBRN(tbrn=tbrn) + dataset_client = get_dataset_client(gas, info) + + if info.type != TBRNType.DATASET: + error(f'To operate a commit, "{info}" must be a dataset') + if not info.is_draft: + error(f'To commit, "{info}" must be in draft status, like "{info}#1"') + + dataset_client.checkout(draft_number=info.draft_number) + draft = dataset_client.get_draft() + hint_message = format_hint(draft.title, draft.description, _COMMIT_HINT) + title, description = edit_message(message, hint_message, obj.config_parser) + if not title: + error("Aborting commit due to empty commit message") + + dataset_client.commit(title, description) + commit_tbrn = TBRN(info.dataset_name, revision=dataset_client.status.commit_id).get_tbrn() + click.echo(f"Committed successfully: {tbrn} -> {commit_tbrn}") + except TensorBayException as err: + error(str(err)) diff --git a/tensorbay/cli/config.py b/tensorbay/cli/config.py index 62c496a85..4b3ce5846 100644 --- a/tensorbay/cli/config.py +++ b/tensorbay/cli/config.py @@ -7,37 +7,41 @@ import click +from ..exception import TensorBayException from .utility import ContextInfo, error, write_config def _implement_config(obj: ContextInfo, key: str, value: str, unset: bool) -> None: - _check_args_and_options(key, value, unset) - - config_parser = obj.config_parser - - if not config_parser.has_section("config"): - config_parser.add_section("config") - config_section = config_parser["config"] - - if not key: - for config_key, config_value in config_section.items(): - click.echo(f"{config_key} = {config_value}\n") - return - - if not value: - if key not in config_section: - error(f"{key} has not been configured yet") - if unset: - del config_section[key] - write_config(config_parser, show_message=False) - click.echo(f'Unset "{key}" successfully') + try: + _check_args_and_options(key, value, unset) + + config_parser = obj.config_parser + + if not config_parser.has_section("config"): + config_parser.add_section("config") + config_section = config_parser["config"] + + if not key: + for config_key, config_value in config_section.items(): + click.echo(f"{config_key} = {config_value}\n") return - click.echo(f"{key} = {config_section[key]}\n") - else: - _check_key_and_value(key, value) - config_section[key] = value - write_config(config_parser) + if not value: + if key not in config_section: + error(f"{key} has not been configured yet") + if unset: + del config_section[key] + write_config(config_parser, show_message=False) + click.echo(f'Unset "{key}" successfully') + return + + click.echo(f"{key} = {config_section[key]}\n") + else: + _check_key_and_value(key, value) + config_section[key] = value + write_config(config_parser) + except TensorBayException as err: + error(str(err)) def _check_args_and_options(key: str, value: str, unset: bool) -> None: diff --git a/tensorbay/cli/cp.py b/tensorbay/cli/cp.py index 40d913bd7..35e73061a 100644 --- a/tensorbay/cli/cp.py +++ b/tensorbay/cli/cp.py @@ -10,6 +10,7 @@ from typing import Iterable from ..dataset import Data, Segment +from ..exception import TensorBayException from .tbrn import TBRN, TBRNType from .utility import ContextInfo, error, get_dataset_client, get_gas @@ -22,28 +23,35 @@ def _implement_cp( # pylint: disable=too-many-arguments jobs: int, skip_uploaded_files: bool, ) -> None: - gas = get_gas(*obj) - info = TBRN(tbrn=tbrn) - - dataset_client = get_dataset_client(gas, info, is_fusion=False) - - if info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE): - error(f'"{tbrn}" is not a segment or file type') - - target_remote_path = info.remote_path if info.type == TBRNType.NORMAL_FILE else "" - - local_abspaths = [os.path.abspath(local_path) for local_path in local_paths] - if ( - len(local_abspaths) == 1 - and not os.path.isdir(local_abspaths[0]) - and target_remote_path - and not target_remote_path.endswith("/") - ): - segment_client = dataset_client.get_or_create_segment(info.segment_name) - segment_client.upload_file(local_abspaths[0], target_remote_path) - else: - segment = _get_segment(info.segment_name, local_abspaths, target_remote_path, is_recursive) - dataset_client.upload_segment(segment, jobs=jobs, skip_uploaded_files=skip_uploaded_files) + try: + gas = get_gas(*obj) + info = TBRN(tbrn=tbrn) + + dataset_client = get_dataset_client(gas, info, is_fusion=False) + + if info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE): + error(f'"{tbrn}" is not a segment or file type') + + target_remote_path = info.remote_path if info.type == TBRNType.NORMAL_FILE else "" + + local_abspaths = [os.path.abspath(local_path) for local_path in local_paths] + if ( + len(local_abspaths) == 1 + and not os.path.isdir(local_abspaths[0]) + and target_remote_path + and not target_remote_path.endswith("/") + ): + segment_client = dataset_client.get_or_create_segment(info.segment_name) + segment_client.upload_file(local_abspaths[0], target_remote_path) + else: + segment = _get_segment( + info.segment_name, local_abspaths, target_remote_path, is_recursive + ) + dataset_client.upload_segment( + segment, jobs=jobs, skip_uploaded_files=skip_uploaded_files + ) + except TensorBayException as err: + error(str(err)) def _get_segment( diff --git a/tensorbay/cli/draft.py b/tensorbay/cli/draft.py index 2266711d4..f2f2e767c 100644 --- a/tensorbay/cli/draft.py +++ b/tensorbay/cli/draft.py @@ -13,7 +13,7 @@ from ..client.gas import DatasetClientType from ..client.struct import ROOT_COMMIT_ID -from ..exception import ResourceNotExistError +from ..exception import StatusError, TensorBayException from .auth import INDENT from .tbrn import TBRN, TBRNType from .utility import ContextInfo, edit_message, error, format_hint, get_dataset_client, get_gas @@ -38,21 +38,26 @@ def _implement_draft( # pylint: disable=too-many-arguments close: bool, message: Tuple[str, ...], ) -> None: - gas = get_gas(*obj) - info = TBRN(tbrn=tbrn) - dataset_client = get_dataset_client(gas, info) - - if info.type != TBRNType.DATASET: - error(f'To operate a draft, "{info}" must be a dataset') - - if is_list: - _list_drafts(dataset_client, info) - elif edit: - _edit_draft(dataset_client, info, message, obj.config_parser) - elif close: - _close_draft(dataset_client, info) - else: - _create_draft(dataset_client, info, message, obj.config_parser) + try: + gas = get_gas(*obj) + info = TBRN(tbrn=tbrn) + dataset_client = get_dataset_client(gas, info) + + if info.type != TBRNType.DATASET: + error(f'To operate a draft, "{info}" must be a dataset') + + if is_list: + _list_drafts(dataset_client, info) + elif edit: + _edit_draft(dataset_client, info, message, obj.config_parser) + elif close: + _close_draft(dataset_client, info) + else: + _create_draft(dataset_client, info, message, obj.config_parser) + except StatusError: + error("Draft number is required when editing draft") + except TensorBayException as err: + error(str(err)) def _create_draft( @@ -98,10 +103,7 @@ def _echo_draft( if not branch_name: error("Draft should be created based on a branch.") - try: - branch = dataset_client.get_branch(branch_name) - except ResourceNotExistError: - error(f'The branch "{branch_name}" does not exist') + branch = dataset_client.get_branch(branch_name) if branch.commit_id != ROOT_COMMIT_ID: commit_id = f"({branch.commit_id})" @@ -128,9 +130,6 @@ def _edit_draft( message: Tuple[str, ...], config_parser: ConfigParser, ) -> None: - if not info.is_draft: - error("Draft number is required when editing draft") - draft = dataset_client.get_draft() hint_message = format_hint(draft.title, draft.description, _DRAFT_HINT) title, description = edit_message(message, hint_message, config_parser) @@ -143,8 +142,5 @@ def _edit_draft( def _close_draft(dataset_client: DatasetClientType, info: TBRN) -> None: - if not info.is_draft: - error("Draft number is required when editing draft") - dataset_client.close_draft() click.echo(f"{info.get_tbrn()} is closed.") diff --git a/tensorbay/cli/log.py b/tensorbay/cli/log.py index f4ec35965..700747f00 100644 --- a/tensorbay/cli/log.py +++ b/tensorbay/cli/log.py @@ -15,6 +15,7 @@ from ..client.gas import DatasetClientType from ..client.struct import Commit +from ..exception import ResourceNotExistError from .auth import INDENT from .tbrn import TBRN, TBRNType from .utility import ContextInfo, error, get_gas, is_win, shorten @@ -56,34 +57,39 @@ def _implement_log( # pylint: disable=too-many-arguments is_all: bool, graph: bool, ) -> None: - gas = get_gas(*obj) - info = TBRN(tbrn=tbrn) - if info.type != TBRNType.DATASET: - error(f'To log commits, "{info}" must be a dataset') + try: + gas = get_gas(*obj) + info = TBRN(tbrn=tbrn) + if info.type != TBRNType.DATASET: + error(f'To log commits, "{info}" must be a dataset') + + dataset_client = gas._get_dataset_with_any_type( # pylint: disable=protected-access + info.dataset_name + ) + commit_id_to_branches: DefaultDict[str, List[str]] = defaultdict(list) + for branch in dataset_client.list_branches(): + commit_id_to_branches[branch.commit_id].append(branch.name) + if is_all: + revisions: List[Optional[str]] = [ + branch.name for branch in dataset_client.list_branches() + ] + else: + revisions = [info.revision] if info.revision else [dataset_client.status.branch_name] - dataset_client = gas._get_dataset_with_any_type( # pylint: disable=protected-access - info.dataset_name - ) - commit_id_to_branches: DefaultDict[str, List[str]] = defaultdict(list) - for branch in dataset_client.list_branches(): - commit_id_to_branches[branch.commit_id].append(branch.name) - if is_all: - revisions: List[Optional[str]] = [branch.name for branch in dataset_client.list_branches()] - else: - revisions = [info.revision] if info.revision else [dataset_client.status.branch_name] - - Printer: Union[Type[_GraphPrinter], Type[_CommitPrinter]] = ( - _GraphPrinter if graph else _CommitPrinter - ) - commit_generator = islice( - Printer(dataset_client, revisions, commit_id_to_branches, oneline).generate_commits(), - max_count, - ) - if is_win(): - for item in commit_generator: - click.echo(item) - else: - click.echo_via_pager(commit_generator) + Printer: Union[Type[_GraphPrinter], Type[_CommitPrinter]] = ( + _GraphPrinter if graph else _CommitPrinter + ) + commit_generator = islice( + Printer(dataset_client, revisions, commit_id_to_branches, oneline).generate_commits(), + max_count, + ) + if is_win(): + for item in commit_generator: + click.echo(item) + else: + click.echo_via_pager(commit_generator) + except ResourceNotExistError: + error(f"The dataset: {info.dataset_name} does not exist.") def _join_branch_names(commit_id: str, branch_names: List[str]) -> str: diff --git a/tensorbay/cli/ls.py b/tensorbay/cli/ls.py index 7a7fcd540..29e981bac 100644 --- a/tensorbay/cli/ls.py +++ b/tensorbay/cli/ls.py @@ -12,6 +12,7 @@ from ..client import GAS from ..client.dataset import FusionDatasetClient from ..client.gas import DatasetClientType +from ..exception import TensorBayException from .tbrn import TBRN, TBRNType from .utility import ContextInfo, error, get_dataset_client, get_gas @@ -122,14 +123,17 @@ def _ls_normal_file( def _implement_ls(obj: ContextInfo, tbrn: str, list_all_files: bool, show_total_num: bool) -> None: - gas = get_gas(*obj) - if not tbrn: - dataset_names = gas.list_dataset_names() - if show_total_num: - click.echo(f"total {len(dataset_names)}") - for dataset_name in dataset_names: - click.echo(TBRN(dataset_name).get_tbrn()) - return - - info = TBRN(tbrn=tbrn) - _LS_FUNCS[info.type](gas, info, list_all_files, show_total_num) + try: + gas = get_gas(*obj) + if not tbrn: + dataset_names = gas.list_dataset_names() + if show_total_num: + click.echo(f"total {len(dataset_names)}") + for dataset_name in dataset_names: + click.echo(TBRN(dataset_name).get_tbrn()) + return + + info = TBRN(tbrn=tbrn) + _LS_FUNCS[info.type](gas, info, list_all_files, show_total_num) + except TensorBayException as err: + error(str(err)) diff --git a/tensorbay/cli/rm.py b/tensorbay/cli/rm.py index ba2143684..a0acaea61 100644 --- a/tensorbay/cli/rm.py +++ b/tensorbay/cli/rm.py @@ -7,28 +7,32 @@ import click +from ..exception import TensorBayException from .tbrn import TBRN, TBRNType from .utility import ContextInfo, error, get_dataset_client, get_gas def _implement_rm(obj: ContextInfo, tbrn: str, is_recursive: bool) -> None: - gas = get_gas(*obj) - info = TBRN(tbrn=tbrn) - dataset_client = get_dataset_client(gas, info, is_fusion=False) + try: + gas = get_gas(*obj) + info = TBRN(tbrn=tbrn) + dataset_client = get_dataset_client(gas, info, is_fusion=False) - if info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE): - error(f'"{tbrn}" is an invalid path to remove') + if info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE): + error(f'"{tbrn}" is an invalid path to remove') - if not info.is_draft: - error(f'To remove the data, "{info}" must be in draft status, like "{info}#1"') + if not info.is_draft: + error(f'To remove the data, "{info}" must be in draft status, like "{info}#1"') - if info.type == TBRNType.SEGMENT: - if not is_recursive: - error("Please use -r option to remove the whole segment") + if info.type == TBRNType.SEGMENT: + if not is_recursive: + error("Please use -r option to remove the whole segment") - dataset_client.delete_segment(info.segment_name) - else: - segment = dataset_client.get_segment(info.segment_name) - segment.delete_data(info.remote_path) + dataset_client.delete_segment(info.segment_name) + else: + segment = dataset_client.get_segment(info.segment_name) + segment.delete_data(info.remote_path) - click.echo(f"{tbrn} is deleted successfully") + click.echo(f"{tbrn} is deleted successfully") + except TensorBayException as err: + error(str(err)) diff --git a/tensorbay/cli/tag.py b/tensorbay/cli/tag.py index a71fa33e7..22c4e92d4 100644 --- a/tensorbay/cli/tag.py +++ b/tensorbay/cli/tag.py @@ -8,25 +8,31 @@ import click from ..client.gas import DatasetClientType +from ..exception import InvalidParamsError, ResourceNotExistError, StatusError from .tbrn import TBRN, TBRNType from .utility import ContextInfo, error, get_dataset_client, get_gas def _implement_tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool) -> None: - info = TBRN(tbrn=tbrn) - - if info.type != TBRNType.DATASET: - error(f'To operate a tag, "{info}" must be a dataset') - - gas = get_gas(*obj) - dataset_client = get_dataset_client(gas, info) - - if is_delete: - _delete_tag(dataset_client, info) - elif name: - _create_tag(dataset_client, name) - else: - _list_tags(dataset_client) + try: + info = TBRN(tbrn=tbrn) + + if info.type != TBRNType.DATASET: + error(f'To operate a tag, "{info}" must be a dataset') + + gas = get_gas(*obj) + dataset_client = get_dataset_client(gas, info) + + if is_delete: + _delete_tag(dataset_client, info) + elif name: + _create_tag(dataset_client, name) + else: + _list_tags(dataset_client) + except StatusError: + error(f'To create a tag, "{dataset_client.name}" cannot be in draft status') + except (ResourceNotExistError, InvalidParamsError) as err: + error(str(err)) def _delete_tag(dataset_client: DatasetClientType, info: TBRN) -> None: @@ -39,9 +45,6 @@ def _delete_tag(dataset_client: DatasetClientType, info: TBRN) -> None: def _create_tag(dataset_client: DatasetClientType, name: str) -> None: - if dataset_client.status.is_draft: - error(f'To create a tag, "{dataset_client.name}" cannot be in draft status') - if not dataset_client.status.commit_id: error(f'To create a tag, "{dataset_client.name}" should have commit history')