Categories
程式開發

基於Serverless架構的Git代碼統計


前言

自己畢業也有一年多了,很想統計一下過去一年自己貢獻了多少的代碼。想了一下,可能要用git log,簡單的做了一下,感覺不是很爽,正直自己想通過Serverless做一個工具合集,就想能不能通過Serverless做一個Git的代碼統計功能?

代碼實現

其實整個邏輯是比較簡單的,只需要將git整合到雲函數中,再加一個API網關作為觸發器,就可以輕鬆實現。整體代碼為:

import random
import subprocess
import os
import json
import uuid
import tarfile

randomStr = lambda num: "".join(random.sample('zyxwvutsrqponmlkjihgfedcba',num))

def return_msg(error, msg):
return_data = {
"uuid": str(uuid.uuid1()),
"error": error,
"message": msg
}
print(return_data)
return return_data

def installGit():
targetDir = "/tmp/git"
dir_path = os.path.dirname(os.path.realpath(__file__))
tar = tarfile.open(os.path.join(dir_path, 'git-2.14.0.tar'))
tar.extractall(targetDir)
git_path = os.path.join(targetDir, 'git')
bin_path = os.path.join(git_path, 'bin')

template_dir = os.path.join(
git_path,
'share',
'git-core',
'templates'
)

exec_path = os.path.join(
git_path,
'libexec',
'git-core'
)
os.environ['PATH'] = bin_path + ':' + os.environ['PATH']
os.environ['GIT_TEMPLATE_DIR'] = template_dir
os.environ['GIT_EXEC_PATH'] = exec_path

installGit()

def doPopen(gitStr, path):
child = subprocess.Popen("cd %s && %s" % (path, gitStr), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return child.stdout.read().decode("utf-8")

def main_handler(event, context):
try:
path = "/tmp/%s" % (randomStr(5))
print("git clone %s %s" % (json.loads(event["body"])["url"], path))
child = subprocess.Popen("git clone %s %s" % (json.loads(event["body"])["url"], path), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(child.stdout.read().decode("utf-8"))
users = {}
for eveCommit in doPopen("git log --format='%aN'", path).split("n"):
if eveCommit:
if eveCommit not in users:
users[eveCommit] = {"commits": 1,
"added_lines": 0,
"removed_lines": 0,
"total_lines": 0}
for eveItem in doPopen('git log --author="%s" --pretty=tformat: --numstat'%eveCommit, path).split("n"):
if eveItem:
eveItemList = eveItem.split("t")
users[eveCommit]["added_lines"] = users[eveCommit]["added_lines"] + int(eveItemList[0])
users[eveCommit]["removed_lines"] = users[eveCommit]["removed_lines"] + int(eveItemList[1])
users[eveCommit]["total_lines"] = users[eveCommit]["added_lines"] - users[eveCommit]["removed_lines"]

else:
users[eveCommit]['commits'] = users[eveCommit]['commits'] + 1
return return_msg(False, users)
except Exception as e:
return return_msg(True, e)

在這段代碼中,主要就是將Git的壓縮包,解壓到/tmp/目錄,然後將其裝載到環境變量中,確保git指令可用。

接下來通過git clone指令來進行用戶提供的倉庫的clone,將其同樣存放在/tmp/目錄下。

然後通過git log –format=’%aN’獲得該倉庫所有提交過過的人的列表,並且可以統計出每個人提交的次數。

最後通過git log –author=”user” –pretty=tformat: –numstat來統計user的代碼行數,最後進行組裝並且返回。

Serverless的Yaml文件為:

GitStatistics:
component: "@serverless/tencent-scf"
inputs:
name: GitStatistics
codeUri: ./
exclude:
- .gitignore
- .git/**
- .serverless
- .env
handler: index.main_handler
runtime: Python3.6
region: ap-beijing
description: git提交次数统计
namespace: serverless_tools
memorySize: 64
timeout: 1800
events:
- apigw:
name: serverless
parameters:
serviceId: service-8d3fi753
environment: release
endpoints:
- path: /git/statistics
serviceTimeout: 1800
description: git提交次数统计
method: POST
enableCORS: true

代碼的接口信息:

請求地址: http://service-8d3fi753-1256773370.bj.apigw.tencentcs.com/release/git/statistics

請求類型:POST

入參類型:JSON

入參參數:url: git地址,例如:{“url”: “https://github.com/serverless-components/tencent-scf.git”}

出參列表:

{
"uuid": "6ff62096-819d-11ea-a6a2-0242cb007105",
"error": false,
"message": {
"yugasun": {
"commits": 23,
"added_lines": 435,
"removed_lines": 137,
"total_lines": 298
}
}
}

完整之後,我們可以通過POSTMAN測試一下:

基於Serverless架構的Git代碼統計 1

總結

Serverless架構有很多有趣的應用,通過將Git集成到函數計算中,不僅僅可以更加簡單快速,方便的集成CICD流程,也可以額實現代碼行數統計,還可以做很多有趣的事情,希望通過我的拋磚引玉,可以讓大家有更多的想法,創新性的提出更多的應用。