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()
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)
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")
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}"')
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 )
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)
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))
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)
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)
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()}" )
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()}"')
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)