def context_object(mocker: MockerFixture, tmp_path: Path) -> ContextInfo:
    """Get a ContextInfo instance containing the command context.

    Arguments:
        mocker: The mocker fixture.
        tmp_path: An instance of TempPathFactory.

    Returns:
        The ContextInfo instance.

    """
    path = tmp_path / "test_home"
    path.mkdir()
    mocker.patch(f"{os.__name__}.path.expanduser", return_value=path)

    access_key = "Accesskey-********************************"
    url = "https://gas.graviti.cn/"
    context = ContextInfo(access_key, url, "test")

    config_parser = context.config_parser
    config_parser.add_section("profiles")
    profiles = config_parser["profiles"]
    profiles["test"] = form_profile_value(access_key, "")
    profiles["test_01"] = form_profile_value(access_key, "")
    profiles["test_02"] = form_profile_value(access_key, url)
    context.write_config(False)

    return context
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]
            obj.write_config(show_message=False)
            click.echo(f'Successfully unset "{key}"')
            return

        click.echo(f"{key} = {config_section[key]}\n")
    else:
        _check_key_and_value(key, value)
        config_section[key] = value
        obj.write_config()
Beispiel #3
0
def _status_auth(obj: ContextInfo, is_all: bool) -> None:
    if is_all:
        for profile_name, access_key, url in obj.generate_profiles():
            _echo_user_info(access_key, url, obj, profile_name)
        return

    access_key, url = obj.read_profile()
    _echo_user_info(access_key, url, obj)
Beispiel #4
0
def _unset_auth(obj: ContextInfo, is_all: bool) -> None:
    config_parser = obj.config_parser
    if is_all:
        config_parser.remove_section("profiles")
    else:
        try:
            removed = config_parser.remove_option("profiles", obj.profile_name)
        except NoSectionError:
            removed = False
        if not removed:
            error(f'Profile "{obj.profile_name}" does not exist.')
    obj.write_config(show_message=False)
    hint = "all" if is_all else f'"{obj.profile_name}"'
    click.echo(f"Successfully unset {hint} auth info")
Beispiel #5
0
def _implement_log(  # pylint: disable=too-many-arguments
    obj: ContextInfo,
    tbrn: str,
    max_count: Optional[int],
    oneline: bool,
    is_all: bool,
    graph: bool,
    show_drafts: bool,
) -> None:
    gas = obj.get_gas()
    tbrn_info = TBRN(tbrn=tbrn)
    if tbrn_info.type != TBRNType.DATASET:
        error(f'To log commits, "{tbrn}" must be a dataset')

    dataset_client = gas._get_dataset_with_any_type(  # pylint: disable=protected-access
        tbrn_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 = (
            [tbrn_info.revision] if tbrn_info.revision else [dataset_client.status.branch_name]
        )
    Printer: Union[Type[_GraphPrinter], Type[_Printer]] = _GraphPrinter if graph else _Printer
    message_generator = islice(
        Printer(
            dataset_client, revisions, commit_id_to_branches, oneline, show_drafts=show_drafts
        ).generate_commits_and_drafts_messages(),
        max_count,
    )
    _echo_messages(message_generator)
def _implement_dataset(obj: ContextInfo, tbrn: str, is_delete: bool, yes: bool) -> None:
    gas = obj.get_gas()
    if not tbrn:
        if is_delete:
            error("Missing argument TBRN")
        for dataset_name in gas.list_dataset_names():
            click.echo(TBRN(dataset_name).get_tbrn())
        return

    tbrn_info = TBRN(tbrn=tbrn)
    if tbrn_info.type != TBRNType.DATASET:
        error(f'"{tbrn}" is not a dataset')
    colored_tbrn = tbrn_info.get_colored_tbrn()

    if is_delete:
        if not yes:
            click.confirm(
                f'Dataset "{colored_tbrn}" will be completely deleted.\nDo you want to continue?',
                abort=True,
            )

        gas.delete_dataset(tbrn_info.dataset_name)
        click.echo(f'Successfully deleted dataset "{colored_tbrn}"')
        return

    gas.create_dataset(tbrn_info.dataset_name)
    click.echo(f'Successfully created dataset "{colored_tbrn}"')
Beispiel #7
0
def _implement_cp(  # pylint: disable=too-many-arguments
    obj: ContextInfo,
    local_paths: Iterable[str],
    tbrn: str,
    is_recursive: bool,
    jobs: int,
    skip_uploaded_files: bool,
) -> None:
    gas = obj.get_gas()
    tbrn_info = TBRN(tbrn=tbrn)

    dataset_client = get_dataset_client(gas, tbrn_info, is_fusion=False)

    if tbrn_info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE):
        error(f'"{tbrn}" is not a segment or file type')

    target_remote_path = tbrn_info.remote_path if tbrn_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(tbrn_info.segment_name)
        segment_client.upload_file(local_abspaths[0], target_remote_path)
    else:
        segment = _get_segment(
            tbrn_info.segment_name, local_abspaths, target_remote_path, is_recursive
        )
        dataset_client.upload_segment(
            segment, jobs=jobs, skip_uploaded_files=skip_uploaded_files, _is_cli=True
        )
Beispiel #8
0
def _implement_ls(obj: ContextInfo, tbrn: str, list_all_files: bool,
                  show_total_num: bool) -> None:
    gas = obj.get_gas()
    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

    tbrn_info = TBRN(tbrn=tbrn)
    _LS_FUNCS[tbrn_info.type](gas, tbrn_info, list_all_files, show_total_num)
Beispiel #9
0
def _update_profile(obj: ContextInfo, arg1: str, arg2: str) -> None:
    access_key, url = (arg2, arg1) if arg2 else (arg1, arg2)
    profile_name, config_parser = obj.profile_name, obj.config_parser
    gas_client = obj.get_gas(access_key, url)
    try:
        user_info = gas_client.get_user()
    except UnauthorizedError:
        error(f"{access_key} is not a valid AccessKey")

    if not config_parser.has_section("profiles"):
        config_parser.add_section("profiles")
    config_parser["profiles"][profile_name] = form_profile_value(access_key, url)
    obj.write_config(show_message=False)

    messages = [
        f'Successfully set authentication info of "{click.style(user_info.name, bold=True)}"'
    ]
    if user_info.team:
        messages.append(f' in "{click.style(user_info.team.name, bold=True)}" team')
    if profile_name != "default":
        messages.append(f' into profile "{click.style(profile_name, bold=True)}"')
    click.echo("".join(messages))
Beispiel #10
0
def _implement_tag(obj: ContextInfo, tbrn: str, name: str, is_delete: bool) -> None:
    tbrn_info = TBRN(tbrn=tbrn)

    if tbrn_info.type != TBRNType.DATASET:
        error(f'To operate a tag, "{tbrn}" must be a dataset')

    gas = obj.get_gas()
    dataset_client = get_dataset_client(gas, tbrn_info)

    if is_delete:
        _delete_tag(dataset_client, tbrn_info)
    elif name:
        _create_tag(dataset_client, name)
    else:
        _list_tags(dataset_client)
Beispiel #11
0
def _implement_branch(obj: ContextInfo, tbrn: str, name: str, verbose: bool,
                      is_delete: bool) -> None:
    tbrn_info = TBRN(tbrn=tbrn)
    if tbrn_info.type != TBRNType.DATASET:
        error(f'To operate a branch, "{tbrn_info}" must be a dataset')

    gas = obj.get_gas()
    dataset_client = get_dataset_client(gas, tbrn_info)

    if is_delete:
        _delete_branch(dataset_client, tbrn_info)
        return

    if name:
        _create_branch(dataset_client, name)
    else:
        _list_branches(dataset_client, verbose)
Beispiel #12
0
def _echo_user_info(
    access_key: str, url: str, obj: ContextInfo, profile_name: Optional[str] = None
) -> None:
    gas_client = obj.get_gas(access_key, url)
    if not profile_name:
        profile_name = obj.profile_name
    try:
        user_info = gas_client.get_user()
    except UnauthorizedError:
        error(f"{access_key} is not a valid AccessKey")

    click.echo(f"{profile_name}\n{INDENT}USER: {user_info.name}")
    team = user_info.team
    if team:
        click.echo(f"{INDENT}TEAM: {team.name}")
    click.echo(f"{INDENT}{access_key}")
    if url:
        click.echo(f"{INDENT}{url}\n")
def _implement_commit(obj: ContextInfo, tbrn: str, message: Tuple[str, ...]) -> None:
    gas = obj.get_gas()
    tbrn_info = TBRN(tbrn=tbrn)
    dataset_client = get_dataset_client(gas, tbrn_info)

    if tbrn_info.type != TBRNType.DATASET:
        error(f'To operate a commit, "{tbrn}" must be a dataset')
    if not tbrn_info.is_draft:
        error(f'To commit, "{tbrn}" must be in draft status, like "{tbrn}#1"')

    dataset_client.checkout(draft_number=tbrn_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(tbrn_info.dataset_name, revision=dataset_client.status.commit_id)
    click.echo(
        "Committed successfully: "
        f"{tbrn_info.get_colored_tbrn()} -> {commit_tbrn.get_colored_tbrn()}"
    )
Beispiel #14
0
def _implement_rm(obj: ContextInfo, tbrn: str, is_recursive: bool) -> None:
    gas = obj.get_gas()
    tbrn_info = TBRN(tbrn=tbrn)
    dataset_client = get_dataset_client(gas, tbrn_info, is_fusion=False)

    if tbrn_info.type not in (TBRNType.SEGMENT, TBRNType.NORMAL_FILE):
        error(f'"{tbrn}" is an invalid path to remove')

    if not tbrn_info.is_draft:
        error(
            f'To remove the data, "{tbrn}" must be in draft status, like "{tbrn}#1"'
        )

    if tbrn_info.type == TBRNType.SEGMENT:
        if not is_recursive:
            error("Please use -r option to remove the whole segment")

        dataset_client.delete_segment(tbrn_info.segment_name)
    else:
        segment = dataset_client.get_segment(tbrn_info.segment_name)
        segment.delete_data(tbrn_info.remote_path)

    click.echo(f'Successfully deleted "{tbrn_info.get_colored_tbrn()}"')
Beispiel #15
0
def _implement_draft(  # pylint: disable=too-many-arguments
    obj: ContextInfo,
    tbrn: str,
    is_list: bool,
    edit: bool,
    close: bool,
    message: Tuple[str, ...],
) -> None:
    gas = obj.get_gas()
    tbrn_info = TBRN(tbrn=tbrn)
    dataset_client = get_dataset_client(gas, tbrn_info)

    if tbrn_info.type != TBRNType.DATASET:
        error(f'To operate a draft, "{tbrn}" must be a dataset')

    if is_list:
        _list_drafts(dataset_client, tbrn_info)
    elif edit:
        _edit_draft(dataset_client, tbrn_info, message, obj.config_parser)
    elif close:
        _close_draft(dataset_client, tbrn_info)
    else:
        _create_draft(dataset_client, tbrn_info, message, obj.config_parser)