Skip to content

Instantly share code, notes, and snippets.

@young40
Created May 9, 2019 05:02
Show Gist options
  • Save young40/2ea4732dca911d44b1caeb991deddcab to your computer and use it in GitHub Desktop.
Save young40/2ea4732dca911d44b1caeb991deddcab to your computer and use it in GitHub Desktop.
luacheck in git hooks
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import sys
import subprocess
def cmdGitDiffFiles():
fileList = []
gitDiff = ["/usr/bin/git", "diff", "--cached", "--name-only"]
rs = subprocess.Popen(gitDiff, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(gitDiffStr, error) = rs.communicate()
if rs.poll() == 0:
gitDiffStr = gitDiffStr.decode("utf-8")
fileList = gitDiffStr.split("\n")
return fileList
def cmdGitDiffStr(filePath):
diffStr = ""
gitDiff = ["/usr/bin/git", "diff", "--cached", "--no-ext-diff", "-U0", filePath]
rs = subprocess.Popen(gitDiff, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(gitDiffStr, error) = rs.communicate()
if rs.poll() == 0:
diffStr = gitDiffStr.decode("utf-8")
return diffStr
def cmdLuaCheckError(filePath):
output = ""
cmdLuaCheck = ["/usr/local/bin/luacheck", filePath]
rs = subprocess.Popen(cmdLuaCheck, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(rsStr, error) = rs.communicate()
if rs.poll() == 0:
pass
# print("luacheck OK: %s", filePath)
else:
output = rsStr.decode("utf-8")
return output
def getLuaList(fileList):
luaList = []
for filePath in fileList:
(_, fileExt) = os.path.splitext(filePath)
if os.path.exists(filePath) and (fileExt == ".lua"):
luaList.append(filePath)
return luaList
def luaChangeLines(diffStr):
lines = []
p = re.compile(r"@@.*@@", flags=re.M)
matchs = p.findall(diffStr)
for m in matchs:
p = re.compile(r"\+(\d.*,?\d*)\ ")
lineMatch = p.findall(m)
if lineMatch and lineMatch[0]:
if lineMatch[0].find(",") > 0:
(start, step) = lineMatch[0].split(",")
for line in range(int(start), int(start) + int(step)):
lines.append(line)
else:
lines.append(int(lineMatch[0]))
return lines
def luaErrorLines(checkStr):
lines = []
p = re.compile(r":(\d*):\d*:", flags=re.M)
matchs = p.findall(checkStr)
for line in matchs:
lines.append(int(line))
return lines
def getErrorLineStr(lineNumber, checkStr):
stringLines = []
checkStrLines = checkStr.split("\n")
for line in checkStrLines:
p = re.compile(r":%d:\d*:" % lineNumber)
matches = p.findall(line)
if len(matches) > 0:
stringLines.append(line)
return stringLines
def isItemInList(item, lists):
for i in lists:
if i == item:
return True
return False
def checkLuaError(luaFile):
hasError = False
diffStr = cmdGitDiffStr(luaFile)
changeLines = luaChangeLines(diffStr)
checkStr = cmdLuaCheckError(luaFile)
errorLines = luaErrorLines(checkStr)
errorStrLines = []
for cl in changeLines:
if isItemInList(cl, errorLines):
hasError = True
errlines = getErrorLineStr(cl, checkStr)
for line in errlines:
errorStrLines.append(line)
if hasError:
print("%s got %d failed." % (luaFile, len(errorStrLines)))
for line in errorStrLines:
print(line)
print("\n")
pass
return hasError
def main():
diffList = cmdGitDiffFiles()
luaList = getLuaList(diffList)
hasError = False
for luaFile in luaList:
if checkLuaError(luaFile):
hasError = True
if hasError:
print("luacheck got failed.")
sys.exit(1)
else:
print("OK.")
sys.exit(0)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment