#!/usr/bin/env python

"""
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import os
import re
import subprocess

from lib.core.common import openFile
from lib.core.convert import getText

def getRevisionNumber():
    """
    获取Git仓库的简短提交哈希值(通过"git rev-parse --short HEAD"命令)
    
    返回值是7位长的哈希字符串或None
    >>> len(getRevisionNumber() or (' ' * 7)) == 7
    True
    """

    # 初始化返回值和文件路径
    retVal = None  # 最终返回的哈希值
    filePath = None  # Git HEAD文件的路径
    _ = os.path.dirname(__file__)  # 获取当前文件所在目录

    # 向上遍历目录树,寻找.git目录
    while True:
        filePath = os.path.join(_, ".git", "HEAD")  # 拼接.git/HEAD的完整路径
        if os.path.exists(filePath):  # 如果找到了.git目录就退出循环
            break
        else:
            filePath = None
            if _ == os.path.dirname(_):  # 已经到达根目录,退出循环
                break
            else:
                _ = os.path.dirname(_)  # 继续向上一级目录查找

    # 读取并解析HEAD文件内容
    while True:
        if filePath and os.path.isfile(filePath):  # 确认HEAD文件存在且是文件
            with openFile(filePath, "r") as f:
                content = getText(f.read())  # 读取HEAD文件内容
                filePath = None

                # HEAD文件可能包含引用(ref)或直接的哈希值
                if content.startswith("ref: "):  # 如果是引用格式
                    try:
                        # 获取引用指向的实际文件路径
                        filePath = os.path.join(_, ".git", content.replace("ref: ", "")).strip()
                    except UnicodeError:
                        pass

                if filePath is None:  # 如果是直接的哈希值格式
                    # 使用正则表达式匹配32位的十六进制哈希值
                    match = re.match(r"(?i)[0-9a-f]{32}", content)
                    retVal = match.group(0) if match else None
                    break
        else:
            break

    # 如果通过读取文件方式未获取到哈希值,尝试使用git命令获取
    if not retVal:
        try:
            # 执行git命令获取当前HEAD的完整哈希值
            process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, _ = process.communicate()
            # 从命令输出中提取哈希值
            match = re.search(r"(?i)[0-9a-f]{32}", getText(stdout or ""))
            retVal = match.group(0) if match else None
        except:
            pass

    # 返回前7位的简短哈希值,如果没有获取到则返回None
    return retVal[:7] if retVal else None
