Skip to content

Commit

Permalink
feat(cli): add "--sort" option for branch and tag to support sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
marshallmallows committed Nov 8, 2021
1 parent a4e5a68 commit acc1887
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 18 deletions.
19 changes: 13 additions & 6 deletions tensorbay/cli/branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@
import click

from tensorbay.cli.tbrn import TBRN, TBRNType
from tensorbay.cli.utility import ContextInfo, error, exception_handler, get_dataset_client, shorten
from tensorbay.cli.utility import (
ContextInfo,
error,
exception_handler,
get_dataset_client,
shorten,
sort_branches_or_tags,
)
from tensorbay.client.gas import DatasetClientType


@exception_handler
def _implement_branch(
obj: ContextInfo, tbrn: str, name: str, verbose: bool, is_delete: bool
def _implement_branch( # pylint: disable=too-many-arguments
obj: ContextInfo, tbrn: str, name: str, verbose: bool, is_delete: bool, sort_key: str
) -> None:
tbrn_info = TBRN(tbrn=tbrn)
if tbrn_info.type != TBRNType.DATASET:
Expand All @@ -30,7 +37,7 @@ def _implement_branch(
if name:
_create_branch(dataset_client, name)
else:
_list_branches(dataset_client, verbose)
_list_branches(dataset_client, verbose, sort_key)


def _create_branch(dataset_client: DatasetClientType, name: str) -> None:
Expand All @@ -42,8 +49,8 @@ def _create_branch(dataset_client: DatasetClientType, name: str) -> None:
click.echo(f'Successfully created branch "{branch_tbrn}"')


def _list_branches(dataset_client: DatasetClientType, verbose: bool) -> None:
branches = dataset_client.list_branches()
def _list_branches(dataset_client: DatasetClientType, verbose: bool, sort_key: str) -> None:
branches = sort_branches_or_tags(sort_key, dataset_client.list_branches())
if not verbose:
for branch in branches:
click.echo(branch.name)
Expand Down
18 changes: 12 additions & 6 deletions tensorbay/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def rm(obj: ContextInfo, tbrn: str, is_recursive: bool) -> None:

@command(
synopsis=(
"$ gas branch tb:<dataset_name> [--verbose] # List branches.",
"$ gas branch tb:<dataset_name> [--verbose] [--sort=[-]<key>] # List branches.",
"$ gas branch tb:<dataset_name>[@<revision>] <branch_name> # Create a branch.",
"$ gas branch -d tb:<dataset_name>@<branch_name> # Delete a branch.",
)
Expand All @@ -323,8 +323,11 @@ def rm(obj: ContextInfo, tbrn: str, is_recursive: bool) -> None:
@click.argument("name", type=str, default="")
@click.option("-v", "--verbose", is_flag=True, help="Show short commit id and commit message.")
@click.option("-d", "--delete", "is_delete", is_flag=True, help="Delete the branch")
@click.option("--sort", default="name", help="Sort based on the key given")
@click.pass_obj
def branch(obj: ContextInfo, tbrn: str, name: str, verbose: bool, is_delete: bool) -> None:
def branch( # pylint: disable=too-many-arguments
obj: ContextInfo, tbrn: str, name: str, verbose: bool, is_delete: bool, sort: str
) -> None:
"""List, create or delete branches.\f
Arguments:
Expand All @@ -333,37 +336,40 @@ def branch(obj: ContextInfo, tbrn: str, name: str, verbose: bool, is_delete: boo
name: The name of the branch to be created.
verbose: Whether to show the short commit id and commit message.
is_delete: Whether to delete the branch.
sort: The key based for sorting.
""" # noqa: D301,D415
from tensorbay.cli.branch import _implement_branch

_implement_branch(obj, tbrn, name, verbose, is_delete)
_implement_branch(obj, tbrn, name, verbose, is_delete, sort)


@command(
synopsis=(
"$ gas tag tb:<dataset_name> # List tags.",
"$ gas tag tb:<dataset_name> [--sort=<key>] # List tags.",
"$ gas tag tb:<dataset_name>[@<revision>] <tag_name> # Create a tag.",
"$ gas tag -d tb:<dataset_name>@<tag_name> # Delete a tag.",
)
)
@click.argument("tbrn", type=str)
@click.argument("name", type=str, default="")
@click.option("-d", "--delete", "is_delete", is_flag=True, help="Delete the tag.")
@click.option("--sort", default="name", help="Sort based on the key given")
@click.pass_obj
def tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool) -> None:
def tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool, sort: str) -> None:
"""List, create or delete tags.\f
Arguments:
obj: A :class:`.utility.ContextInfo` instance containing the command context.
tbrn: The tbrn of the dataset.
name: The name of the tag.
is_delete: Whether to delete the tag.
sort: The key based for sorting.
""" # noqa: D301,D415
from tensorbay.cli.tag import _implement_tag

_implement_tag(obj, tbrn, name, is_delete)
_implement_tag(obj, tbrn, name, is_delete, sort)


@command(
Expand Down
16 changes: 11 additions & 5 deletions tensorbay/cli/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
import click

from tensorbay.cli.tbrn import TBRN, TBRNType
from tensorbay.cli.utility import ContextInfo, error, exception_handler, get_dataset_client
from tensorbay.cli.utility import (
ContextInfo,
error,
exception_handler,
get_dataset_client,
sort_branches_or_tags,
)
from tensorbay.client.gas import DatasetClientType


@exception_handler
def _implement_tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool) -> None:
def _implement_tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool, sort_key: str) -> None:
tbrn_info = TBRN(tbrn=tbrn)

if tbrn_info.type != TBRNType.DATASET:
Expand All @@ -27,7 +33,7 @@ def _implement_tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool) -> N
elif name:
_create_tag(dataset_client, name)
else:
_list_tags(dataset_client)
_list_tags(dataset_client, sort_key)


def _delete_tag(dataset_client: DatasetClientType, tbrn_info: TBRN) -> None:
Expand All @@ -51,6 +57,6 @@ def _create_tag(dataset_client: DatasetClientType, name: str) -> None:
click.echo(f'Successfully created tag "{tag_tbrn}"')


def _list_tags(dataset_client: DatasetClientType) -> None:
for tag in dataset_client.list_tags():
def _list_tags(dataset_client: DatasetClientType, sort_key: str) -> None:
for tag in sort_branches_or_tags(sort_key, dataset_client.list_tags()):
click.echo(tag.name)
36 changes: 35 additions & 1 deletion tensorbay/cli/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from collections import OrderedDict
from configparser import ConfigParser, SectionProxy
from functools import wraps
from typing import Any, Callable, Iterable, Optional, Tuple, TypeVar, overload
from typing import Any, Callable, Iterable, List, Optional, Tuple, TypeVar, Union, overload

import click
from typing_extensions import Literal, NoReturn
Expand All @@ -21,13 +21,22 @@
from tensorbay.client import config as client_config
from tensorbay.client.dataset import DatasetClient, FusionDatasetClient
from tensorbay.client.gas import DatasetClientType
from tensorbay.client.lazy import PagingList
from tensorbay.client.log import dump_request_and_response
from tensorbay.client.requests import logger
from tensorbay.client.struct import Branch, Tag, _NamedCommit
from tensorbay.exception import InternalServerError, TensorBayException

_Callable = TypeVar("_Callable", bound=Callable[..., None])
INDENT = " " * 4

_KEY_FUNC_GETTER = {
"name": lambda x: x.name,
"commit_id": lambda x: (x.commit_id, x.name),
"parent_commit_id": lambda x: (x.parent_commit_id, x.name),
"commit_date": lambda x: (x.committer.date, x.name),
}


class ContextInfo:
"""This class contains command context."""
Expand Down Expand Up @@ -430,3 +439,28 @@ def wrapper(*args: Any, **kwargs: Any) -> None:
error(str(err))

return wrapper # type: ignore[return-value]


def sort_branches_or_tags(
sort_key: str, target: Union[PagingList[Branch], PagingList[Tag]]
) -> Union[PagingList[Branch], PagingList[Tag], List[_NamedCommit]]:
"""Check whether the sort_key is valid and sort the target.
Arguments:
sort_key: The key based for sorting.
target: The target to be sorted.
Returns:
The sorted target.
"""
key, reverse = (sort_key, False) if sort_key[0] != "-" else (sort_key[1:], True)
if key not in _KEY_FUNC_GETTER:
error(
'The "--sort" option must be one of "name", "commit_id", "parent_commit_id" '
'and "commit_date" with an optional "-" before them'
)
return (
target
if not reverse and sort_key == "name"
else sorted(target, key=_KEY_FUNC_GETTER[key], reverse=reverse)
)

0 comments on commit acc1887

Please sign in to comment.