python获取svn信息

主要根据svn log命令解析出需要的数据,为了做到通用,使用了传参的方式。

1、执行以下命令
python svn_info.py "代码仓" "写入日志的文件"
2、代码如下
# svn_info.py
import subprocess
import os
import sys
import xml.etree.ElementTree
from datetime import datetime, timedelta
from urllib.parse import unquote

changed = {
    "A": "Added",
    "D": "Deleted",
    "M": "Modified",
    "R": "Replacing"
}


class Client:
    def __init__(self, resp_url, stdout=subprocess.PIPE):
        self.cmd = ["svn"]
        self.resp_url = resp_url
        self.log_content = None
        self.stdout = stdout
        self.diff_cache = {}

    def all_log_info(self):
        log_cmd = self.cmd + ["log", "-v", self.resp_url, "--xml"]
        return self.formate_data(log_cmd)

    def log_info(self, start_version, end_version=None):
        if end_version:
            log_cmd = self.cmd + ["log", "-r", "{0}:{1}".format(start_version, end_version), "-v", self.resp_url,
                                  "--xml"]
        else:
            log_cmd = self.cmd + ["log", "-r", str(start_version), "-v", self.resp_url, "--xml"]

        return self.formate_data(log_cmd)

    def formate_data(self, log_cmd):
        if self.log_content is None:
            self.log_content = []
            data = subprocess.Popen(log_cmd, stdout=self.stdout).stdout.read()
            root = xml.etree.ElementTree.fromstring(data)

            for e in root.iter('logentry'):
                entry_info = {x.tag: x.text for x in list(e)}

                log_entry = {
                    'msg': entry_info.get('msg'),
                    'author': entry_info.get('author'),
                    'revision': int(e.get('revision')),
                    'date': entry_info.get('date')
                }
                cl = []
                try:
                    for ch in e.findall('paths/path'):
                        cl.append("%s: %s" % (changed[ch.attrib['action']], ch.text))
                except Exception:
                    pass

                log_entry['changelist'] = cl

                self.log_content.append(log_entry)

            return self.log_content

    def diff(self, start_version, end_version=None, decoding='utf8', cache=False):
        if end_version is None:
            end_version = start_version
            start_version = end_version - 1

        diff_cmd = self.cmd + ["diff", "-r", "{0}:{1}".format(start_version, end_version), "--summarize", self.resp_url]

        if cache and self.diff_cache.setdefault(start_version, {})[end_version]:
            diff_content = self.diff_cache[start_version][end_version]
        else:
            diff_content = []
            data = subprocess.Popen(diff_cmd, stdout=self.stdout).stdout.read()
            for b in data.split(b'\n'):
                try:
                    diff_content.append(bytes.decode(b, decoding))
                except:
                    diff_content.append(bytes.decode(b, "gbk"))
                else:
                    pass

        diff_content = "\n".join(diff_content)

        if cache and self.diff_cache[start_version][end_version] is None:
            self.diff_cache[start_version][end_version] = diff_content

        return diff_content

    def numstat(self, start_version, end_version=None, decoding='utf8', cache=False):
        diff_content = self.diff(start_version, end_version, decoding, cache)

        changed_file = []
        for s in diff_content.split('\n'):
            changed_file = self.parase_info(s)
        return changed_file

    def parase_info(self, s):
        changed_file = []
        if s and s.startswith(s[0]):
            s_split = s.split(" ")
            temp_split = list(filter(lambda x: x != "", s_split))
            if len(temp_split) > 0:
                remove_http = temp_split[1]
                changed_file.append("%s: %s" % (changed[temp_split[0]], unquote(remove_http)))
        return changed_file

    def write_info(self, file_path, entrys, mode="w"):
        """默认重写"""
        with open(file_path, mode=mode, encoding='utf8') as f:
            for entry in entrys[::-1]:
                version = entry['revision']
                author = entry['author']

                date = entry['date']  # 最新提交的时间
                try:
                    date_temp = datetime.strptime(date.replace("T", " ").replace("Z", ""), '%Y-%m-%d %H:%M:%S.%f')
                except AttributeError:
                    continue
                utc_8 = date_temp + timedelta(hours=8)
                msg = entry['msg']
                changelist = entry['changelist']

                f.write("Revision: %s\n" % version)
                f.write("Author: %s\n" % author)
                f.write("Date: %s\n" % utc_8)
                f.write("Message: %s\n" % msg)
                f.write("-" * 40 + "\n")
                f.write("\n".join(changelist) + "\n")
                f.write("-" * 40 + "\n")
                f.write("=" * 80 + "\n")

if __name__ == '__main__':
    """
    sys.argv[1]: resp_url
    sys.argv[2]: file
    """
    resp_url = sys.argv[1]
    file = sys.argv[2]
    
    client = Client(resp_url)

    all_log = client.all_log_info()
    client.write_info(file, all_log)



  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaron.Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值