import subprocessimport sysfrom pathlib import Pathfrom common import (check_in_project,get_git_access_token,get_git_api_url_org,request_get)from command_ls_p import get_and_print_remote_repo_treedef get_submodule_info(submodule_path):"""Get the commit-id (first 7 characters), current branch name, and current version (git tag) of the submodule."""info = {}submodule_abs_path = Path(submodule_path)# Get the commit-id (first 7 characters)git_rev_parse_command = ['git', 'rev-parse', '--verify', 'HEAD']full_commit_id = subprocess.check_output(git_rev_parse_command, cwd=submodule_abs_path, text=True).strip()info['commit_id'] = full_commit_id[:7]# Get the current branch namegit_branch_command = ['git', 'symbolic-ref', '--short', '-q', 'HEAD']info['current_branch'] = subprocess.check_output(git_branch_command, cwd=submodule_abs_path, text=True).strip()# Get the current version (latest git tag)try:git_describe_command = ['git', 'describe', '--tags', '--abbrev=0']info['current_version'] = subprocess.check_output(git_describe_command, cwd=submodule_abs_path, stderr=subprocess.DEVNULL, text=True).strip()except subprocess.CalledProcessError as e:if e.returncode != 0:info['current_version'] = ''return infodef get_git_repo_tree_recursively(base_path, repo_tree=None, processed_submodules=set(), root_path=None):if repo_tree is None:repo_tree = []current_path = Path(base_path)submodule_list_command = ['git', 'submodule', 'status']submodule_status_output = subprocess.check_output(submodule_list_command, cwd=current_path, text=True)submodule_lines = submodule_status_output.splitlines()for line in submodule_lines:# Parse the submodule status line to get the submodule path and SHAsubmodule_info = line.strip().split(' ')submodule_path = submodule_info[1]# Construct the absolute path of the submodulesubmodule_abs_path = current_path / submodule_path# Avoid processing already processed submodulesif submodule_abs_path in processed_submodules:continueprocessed_submodules.add(submodule_abs_path)# Get detailed information of the submodulesubmodule_info = get_submodule_info(submodule_abs_path)# Calculate the relative path of the submodule to the top-level repositoryrelative_submodule_path = submodule_abs_path.relative_to(root_path)# Create a dictionary for the submodule and add it to the current repository treesubmodule_repo_dict = {'repo_path': str(relative_submodule_path),'commit_id': submodule_info.get('commit_id'),'current_branch': submodule_info.get('current_branch'),'current_version': submodule_info.get('current_version') or '','submodules': []}repo_tree.append(submodule_repo_dict)# Recursively process nested submodulesget_git_repo_tree_recursively(submodule_abs_path, submodule_repo_dict['submodules'], processed_submodules, root_path=root_path)return repo_treedef highlight(text, color_code):return f'033円[{color_code}m{text}033円[0m'def print_git_repo_tree(repo_tree, indent=0, is_last=False):for i, repo in enumerate(repo_tree):branch_symbol = '├──' if i < len(repo_tree) - 1 else '└──'info_line = f' {indent * " "}{highlight(branch_symbol + " " + repo["repo_path"], 35)}'if any([repo['commit_id'], repo['current_branch'], repo['current_version']]):info_line += ' ('if repo['commit_id']:info_line += f'commit: {highlight(repo["commit_id"], 32)}, 'if repo['current_branch']:info_line += f'branch: {highlight(repo["current_branch"], 33)}, 'if repo['current_version']:info_line += f'version: {highlight(repo["current_version"], 36)}'info_line = info_line.rstrip(', ') + ')'print(info_line)if repo['submodules']:print_git_repo_tree(repo['submodules'], indent + 2, is_last=(i == len(repo_tree) - 1))def get_and_print_git_repo_tree():top_level_path = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], text=True).strip()# Get detailed information of the top-level repositorytop_repo_info = {'repo_path': '.','commit_id': subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'], cwd=top_level_path, text=True).strip()[:7],'current_branch': subprocess.check_output(['git', 'symbolic-ref', '--short', '-q', 'HEAD'], cwd=top_level_path, text=True).strip(),'current_version': ''}# Try to get the latest git tag of the top-level repositorytry:git_describe_command = ['git', 'describe', '--tags', '--abbrev=0']top_repo_info['current_version'] = subprocess.check_output(git_describe_command, cwd=top_level_path, stderr=subprocess.DEVNULL, text=True).strip()except subprocess.CalledProcessError as e:if e.returncode != 0:top_repo_info['current_version'] = ''# Print the information of the top-level repository ensuring that the information is highlightedprint_git_repo_tree_entry(top_repo_info['repo_path'], top_repo_info, highlight_top=True)repo_tree = get_git_repo_tree_recursively(top_level_path, root_path=top_level_path)print_git_repo_tree(repo_tree)def print_git_repo_tree_entry(path, info, highlight_top=False):commit_id = info.get('commit_id')current_branch = info.get('current_branch')current_version = info.get('current_version') or ''# If it's the top-level repository, use highlightingif highlight_top:commit_id = highlight(commit_id, 32)current_branch = highlight(current_branch, 33)current_version = highlight(current_version, 36)print(f"{' ' * 0}{highlight('├── ' + path, 35)} (commit: {commit_id}, branch: {current_branch}, version: {current_version})")def get_and_print_remote_git_repos():repos = []page = 1while True:api_url = get_git_api_url_org()response = request_get(api_url, params={'page': page, 'per_page': 100})response.raise_for_status()current_repos = response.json()repos.extend(repo['name'] for repo in current_repos)if len(current_repos) < 100:breakpage += 1for repo in repos:print(repo)# List package informationdef list_packages(local=True, remote=False, remote_pkg_name=None, version=None):try:if local:if version:print("Error: The -v option can only be used with the -p option, but is not required.")sys.exit(1)if remote or remote_pkg_name:print("Error: Cannot simultaneously use the options -l, -r and -p for `ls` command.")sys.exit(1)if not check_in_project():print("Error: Current directory is not in QuecPython project.")sys.exit(1)get_and_print_git_repo_tree() # ls -lelif remote:if version:print("Error: The -v option can only be used with the -p option, but is not required.")sys.exit(1)if remote_pkg_name:print("Error: Cannot simultaneously use the options -l, -r and -p for `ls` command.")sys.exit(1)get_and_print_remote_git_repos() # ls -relif remote_pkg_name:get_and_print_remote_repo_tree(remote_pkg_name, version) # ls -p <remote_pkg_name> [-v <version>]elif version:print("Error: The -v option can only be used with the -p option, but is not required.")sys.exit(1)else:if not check_in_project():print("Error: Current directory is not in QuecPython project.")sys.exit(1)get_and_print_git_repo_tree() # lsexcept Exception as e:print(f"Error: Failed to list packages: {e}")sys.exit(1)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。