#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Function Description: Set Git credentials for authentication
功能描述: 设置Git认证凭据
"""
from typing import Dict, Any
import os
import subprocess
from src.utils.common_tools import check_tools
def set_git_credentials(username: str, password: str, project_dir: str = None) -> Dict[str, Any]:
"""
Function Description: Set Git credentials for authentication
功能描述: 设置Git认证凭据
Parameters:
参数说明:
- username (str): Required. Git username or access token
- username (str): 必须。Git用户名或访问令牌
- password (str): Required. Git password or personal access token
- password (str): 必须。Git密码或个人访问令牌
- project_dir (Optional[str]): Optional. Project directory for local configuration
- project_dir (Optional[str]): 可选。项目目录,用于本地配置
Returns:
返回值:
- Dict[str, Any]: Contains status, log and error information
- Dict[str, Any]: 包含状态、日志和错误信息
Exception Handling:
异常处理:
- Tool detection failure or command execution exception will be reflected in the returned error information
- 工具检测失败或命令执行异常会体现在返回的错误信息中
"""
# Check if git tool is installed
# 检查git工具是否安装
tools_status = check_tools(["git"])
if not tools_status.get("git", False):
return {"status": "error", "log": "", "error": "git工具未安装"}
# Check project directory (if specified)
# 检查项目目录(如果指定了)
if project_dir is not None and not os.path.exists(project_dir):
return {"status": "error", "log": "", "error": f"项目目录不存在: {project_dir}"}
try:
# Determine if it's global or local configuration
# 确定是全局配置还是本地配置
config_scope = "--local" if project_dir is not None else "--global"
cwd = project_dir if project_dir is not None else None
# Check credential helper
# 检查凭据助手
cmd = ["git", "config", config_scope, "credential.helper"]
process = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
# If no credential helper is set, try to set a default one
# 如果没有设置凭据助手,尝试设置一个默认的
if process.returncode != 0 or not process.stdout.strip():
# Use wincred on Windows, try cache or store on other systems
# 在Windows上使用wincred,在其他系统上尝试使用cache或store
if os.name == "nt":
helper = "wincred"
else:
# Try to use cache, if it fails use store
# 尝试使用cache,如果失败则使用store
helper = "cache"
# Set credential helper
# 设置凭据助手
cmd = ["git", "config", config_scope, "credential.helper", helper]
process = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
if process.returncode != 0:
# If cache fails, try store
# 如果cache失败,尝试store
helper = "store"
cmd = ["git", "config", config_scope, "credential.helper", helper]
process = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
if process.returncode != 0:
return {
"status": "warning",
"log": "凭据设置成功,但无法配置凭据助手",
"error": f"配置凭据助手失败: {process.stderr}"
}
# Try to store credentials by simulating git operation
# 尝试通过模拟git操作来存储凭据
# Here we use a simple git ls-remote command to trigger credential storage
# 这里使用一个简单的git ls-remote命令来触发凭据存储
# Note: This method may not work on some systems, depending on the credential helper configuration
# 注意:这种方法可能在某些系统上不生效,取决于凭据助手的配置
cmd = ["git", "ls-remote", "https://github.com/", "HEAD"]
# Set environment variables to provide credentials
# 设置环境变量来提供凭据
env = os.environ.copy()
# Note: This method may not be secure enough for production use, it's just an example here
# 注意:在实际使用中,这种方式可能不够安全,这里仅作为示例
# Execute the command (don't care about the result, mainly to trigger credential storage)
# 执行命令(不关心结果,主要是为了触发凭据存储)
process = subprocess.run(cmd, cwd=cwd, env=env, capture_output=True, text=True)
# Regardless of whether the command succeeds or not, we consider the credentials to be set
# 无论命令是否成功,我们都认为凭据设置完成
# Because git ls-remote may fail due to network issues or permission issues
# 因为git ls-remote可能会因为网络问题或权限问题而失败
scope_text = "项目本地" if project_dir is not None else "全局"
return {
"status": "success",
"log": f"已成功设置{scope_text}Git凭据",
"error": ""
}
except Exception as e:
return {
"status": "error",
"log": "",
"error": f"设置Git凭据时发生错误: {str(e)}"
}