按时间统计GitLab所有用户代码提交量-《GO开发知识笔记》

admin 2025-11-04 01:08:31 编程 来源:ZONE.CI 全球网 0 阅读模式
  • 准备
  • 逻辑
  • 脚本
  • !/usr/bin/python3
  • coding=utf8
  • @Author: Mario
  • @Date : 2020/11/04
  • @Desc : GitLab 按时间查看各用户代码提交量官方API版
  • UTC时间转时间戳
  • 输出格式化
  • 获取 GitLab 上的所有项目
    • 结果

    今天接到主管命令,需要统计每个人每月的代码提交量,纳入每月的绩效考核(神奇的需求)。虽然可以通过查看 GitLab 上每个人的提交记录来统计,但是费时费力,所以这里通过脚本的方式来统计。注意:GitLab 的 API 请求得到的数据会自动分页,网上很多教程都没有说明,导致统计出来的数据有误

    准备

    1. GitLab 地址(内网外网都可以,内网需要在内网中执行脚本)
    2. 拥有 GitLab 管理权限的用户账号
    3. Python 3 环境

      逻辑

    4. 首先遍历所有项目

    5. 然后遍历所有项目下拥有的所有分支
    6. 遍历所有分支下每个用户提交的代码量
    7. 时间区间限制
    8. 数据去重相加,格式化输出

      脚本

    9. 登录 GitLab,选择 设置 - Access Tokens,创建个人访问令牌image.pngimage.png

    10. 复制生成的个人访问令牌到脚本的 private_token 中,再将 url 改为你的 GitLab 地址,最后修改 起-止时间 执行脚本即可
    11. 脚本,基于 GitLab 官方 API,注意 Git用户名 是提交工具上配置的名字,不是 GitLab 用户名 ```python

      !/usr/bin/python3

      coding=utf8

      @Author: Mario

      @Date : 2020/11/04

      @Desc : GitLab 按时间查看各用户代码提交量官方API版

    import json import requests from dateutil.parser import parse

    gitlab_url = “http://gitlab.xxxx“ # GitLab 地址 private_token = “token” # GitLab Access Tokens(管理员权限)

    info = []

    headers = { ‘Connection’: ‘close’, }

    UTC时间转时间戳

    def utc_time(time): dt = parse(time) return int(dt.timestamp())

    输出格式化

    def str_format(txt): lenTxt = len(txt) lenTxt_utf8 = len(txt.encode(‘utf-8’)) size = int((lenTxt_utf8 - lenTxt) / 2 + lenTxt) length = 20 - size return length

    获取 GitLab 上的所有项目

    def gitlab_projects(): project_ids = [] page = 1 while True: url = gitlab_url + “api/v4/projects/?private_token=” + private_token + “&page=” + str(page) + “&per_page=20” while True: try: res = requests.get(url, headers=headers, timeout=10) break except Exception as e: print(e) continue projects = json.loads(res.text) if len(projects) == 0: break else: for project in projects: project_ids.append(project[“id”]) page += 1 return project_ids

    1. # 获取 GitLab 上的项目 id 中的分支
    2. def project_branches(project_id):
    3. branch_names = []
    4. page = 1
    5. while True:
    6. url = gitlab_url + "api/v4/projects/" + str(
    7. project_id) + "/repository/branches?private_token=" + private_token + "&page=" + str(page) + "&per_page=20"
    8. while True:
    9. try:
    10. res = requests.get(url, headers=headers, timeout=10)
    11. break
    12. except Exception as e:
    13. print(e)
    14. continue
    15. branches = json.loads(res.text)
    16. '''Debug
    17. print(url)
    18. print('--' * 10)
    19. print(branches)
    20. print('*' * 10)
    21. '''
    22. if len(branches) == 0:
    23. break
    24. else:
    25. for branch in branches:
    26. branch_names.append(branch["name"])
    27. page += 1
    28. return branch_names
    29. # 获取 GitLab 上的项目分支中的 commits,当 title 或 message 首单词为 Merge 时,表示合并操作,剔除此代码量
    30. def project_commits(project_id, branch, start_time, end_time):
    31. commit_ids = []
    32. page = 1
    33. while True:
    34. url = gitlab_url + "api/v4/projects/" + str(
    35. project_id) + "/repository/commits?ref_name=" + branch + "&private_token=" + private_token + "&page=" + str(
    36. page) + "&per_page=20"
    37. while True:
    38. try:
    39. res = requests.get(url, headers=headers, timeout=10)
    40. break
    41. except Exception as e:
    42. print(e)
    43. continue
    44. commits = json.loads(res.text)
    45. if len(commits) == 0:
    46. break
    47. else:
    48. for commit in commits:
    49. if "Merge" in commit["title"] or "Merge" in commit["message"] or "合并" in commit["title"] or "合并" in \
    50. commit["message"]: # 不统计合并操作
    51. continue
    52. elif utc_time(commit["authored_date"]) < utc_time(start_time) or utc_time(
    53. commit["authored_date"]) > utc_time(end_time): # 不满足时间区间
    54. continue
    55. else:
    56. commit_ids.append(commit["id"])
    57. page += 1
    58. return commit_ids
    59. # 根据 commits 的 id 获取代码量
    60. def commit_code(project_id, commit_id):
    61. global info
    62. url = gitlab_url + "api/v4/projects/" + str(
    63. project_id) + "/repository/commits/" + commit_id + "?private_token=" + private_token
    64. while True:
    65. try:
    66. res = requests.get(url, headers=headers, timeout=10)
    67. break
    68. except Exception as e:
    69. print(e)
    70. continue
    71. data = json.loads(res.text)
    72. temp = {"name": data["author_name"], "additions": data["stats"]["additions"],
    73. "deletions": data["stats"]["deletions"], "total": data["stats"]["total"]} # Git工具用户名,新增代码数,删除代码数,总计代码数
    74. info.append(temp)
    75. # GitLab 数据查询
    76. def gitlab_info(start_time, end_time):
    77. for project_id in gitlab_projects(): # 遍历所有项目ID
    78. for branche_name in project_branches(project_id): # 遍历每个项目中的分支
    79. for commit_id in project_commits(project_id, branche_name, start_time, end_time): # 遍历每个分支中的 commit id
    80. commit_code(project_id, commit_id) # 获取代码提交量
    81. if __name__ == "__main__":
    82. print("正在统计数据,请耐心等待,这将花费不少时间~")
    83. gitlab_info('2020-12-01 00:00:00', '2020-12-01 23:59:59') # 起-止时间
    84. name = [] # Git工具用户名
    85. additions = [] # 新增代码数
    86. deletions = [] # 删除代码数
    87. total = [] # 总计代码数
    88. res = {}
    89. # 生成元组
    90. for i in info:
    91. for key, value in i.items():
    92. if key == "name":
    93. name.append(value)
    94. if key == "additions":
    95. additions.append(value)
    96. if key == "deletions":
    97. deletions.append(value)
    98. if key == "total":
    99. total.append(value)
    100. data = list(zip(name, additions, deletions, total))
    101. # print(data)
    102. # 去重累加
    103. for j in data:
    104. name = j[0]
    105. additions = j[1]
    106. deletions = j[2]
    107. total = j[3]
    108. if name in res.keys():
    109. res[name][0] += additions
    110. res[name][1] += deletions
    111. res[name][2] += total
    112. else:
    113. res.update({name: [additions, deletions, total]})
    114. # 打印结果
    115. print("Git用户名 新增代码数 删除代码数 总计代码数")
    116. for k in res.keys():
    117. print(k + " " * str_format(k) + str(res[k][0]) + " " * str_format(str(res[k][0])) + str(
    118. res[k][1]) + " " * str_format(str(res[k][1])) + str(res[k][2]))

    ```

    结果

    image.png参考:怎么统计公司Gitlab上每个人每天的提交量

    以太坊cppgolang区别 编程

    以太坊cppgolang区别

    以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
    progolang 编程

    progolang

    Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
    golangn个发送者 编程

    golangn个发送者

    Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
    golang技能图谱 编程

    golang技能图谱

    从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
    评论:0   参与:  17