Search code examples
python-3.xmercurialtortoisehgmercurial-hook

precommit hook returns list of checked marked files in tortoiseHg


precommit hook returns list of checked marked files in tortoiseHg

So Basically i am writing a pre-commit hook which, will static analysis the code and give me HTML output of error report.

What I had done: I am done with
Get a list MODIFIED and ADDED files and run static code analyzer on it.

get Result in the form of HTML. Most of the work is done, But issue is, How to get list file which are marked check in TortoiseHg, Not all the list of ADDED and MODIFIED files enter image description here

So in list of files, only get 2 files in this example: 1. .classpath 2. servlet-api.jar

Basically I want to read tortoiseHg Ui in python script :) Thanks in advance


Solution

  • After years of years research and after reading Ayurvedic books

    Just kidding...............

    So finally I was able to write pre-commit hooks script, after few days after posting the question here!

    Pre-requisite:

    • Python above version 2 or any distribution of version 3
    • SonarQube running instance
    • a sonar-scanner.properties file

    So the pre-commit hook is

    import subprocess
    import re
    import os
    import json
    from tkinter import *
    
    print(os.getcwd())
    #get current working directory echo pwd 
    repoPath = os.getcwd() 
    
    #hg status -a -m gives the modified files and added files 
    #git status --porcelain
    cmd = "hg status -a -m"
    
    #this is the html file name to show report errors
    sonarScannedReport = 'SonarScannedReport.html'
    
    # returns output as byte string
    returned_output = subprocess.check_output(cmd)
    
    # List of Modified and Added files
    fileList = returned_output.splitlines()
    
    fileList = list(fileList)
    # iterate over list and find .java files
    # seperate list with "." seprator
    javaFilesAbsolutePaths = []
    for file in fileList:
        fileExtList = file.decode("utf-8").split(".")
        if fileExtList[1] == "java":
            fileRelativePath = re.split('A |M ', file.decode("utf-8"))
            javaFilesAbsolutePaths.append(os.path.abspath(fileRelativePath[1].replace('/', '\\')))
    
    
    # Working Directory to PMD working Directory
    
    def getOutputFileName(java_file):
        fileArr = java_file.split("\\")
        return fileArr[len(fileArr) - 1].split('.')[0]
    
    
    issue_found = False
    
    javaFiles = ""
    i = 0
    for javaFile in javaFilesAbsolutePaths:
        if i == 0:
            javaFiles = javaFile
        else:
            javaFiles = javaFiles + "," + javaFile
    # javaFiles comma separated string and now run sonar command on it.
    cmd1 = " -Dsonar.analysis.mode=preview -Dsonar.issuesReport.console.enable=true "
    cmd2 = "-Dsonar.java.binaries=" + repoPath.replace('\\',
                                                       '/') + "/CatalystOne/res/WEB-INF/classes -Dsonar.issuesReport.json.enable"
    cmd = "sonar-scanner -Dsonar.sources=" + javaFiles + cmd1 + cmd2
    
    outputJsonFile = ""
    AbsPath = ""
    try:
        p2 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (output2, err2) = p2.communicate()
        p2_status = p2.wait()
        output = output2.decode("utf-8").splitlines()
        for o in output:
            if "INFO: Export issues to" in o:
                AbsPath = os.getcwd() + "\\.scannerwork\\sonar-report.json"
                break
    
        if AbsPath == "":
            print("Problem with Sonar Scanner Connections")
            exit(1)
    
        with open(AbsPath, 'r') as f:
            array = json.load(f)
        issues = array['issues']
    
        f = open(sonarScannedReport, 'w')
    
        HTML_OPEN = "<html><head><title>Sonar scanner report </title></head><body align='center'>"
        TABLE_OPEN = "<table>"
        TR_OPEN = "<tr>"
        TR_CLOSE = "</tr>"
        TH_OPEN = "<th>"
        TH_CLOSE = "</th>"
        TD_OPEN = "<td>"
        TD_CLOSE = "</td>"
        TABLE_CLOSE = "</table>"
        HTML_CLOSE = "</body></html>"
    
        table_header = TR_OPEN + TH_OPEN + "FILE" + TH_CLOSE + TH_OPEN + "L. NO" + TH_CLOSE + TH_OPEN + "Message" + TH_CLOSE + TH_OPEN + "Severity" + TH_CLOSE + TH_OPEN + "Rule" + TH_CLOSE + TR_CLOSE
    
        f.write(HTML_OPEN)
        f.write(TABLE_OPEN)
        f.write(table_header)
        for issue in issues:
            fileName = issue['component'].split(':')[1]
            if 'line' in issue:
                lineNo = str(issue['line'])
            else:
                lineNo = ""
    
            if 'rule' in issue:
                rule = str(issue['rule'])
            else:
                rule = ""
            issue_found = True;
            tr = TR_OPEN + TD_OPEN + fileName + TD_CLOSE + \
                 TD_OPEN + lineNo + TD_CLOSE + \
                 TD_OPEN + issue['message'] + TD_CLOSE + \
                 TD_OPEN + issue['severity'] + TD_CLOSE + \
                 TD_OPEN + rule + TD_CLOSE + \
                 TR_CLOSE
            f.write(tr)
    
        f.write(TABLE_CLOSE)
        f.write(HTML_CLOSE)
        f.close()
    
    except ValueError:
        print(ValueError)
    
    if issue_found:
        errorMsg = "Please open following file to problems with your code :) "
        reportFilePath = os.getcwd() + "\\" + sonarScannedReport
        window = Tk()
        window.title("Error report")
        window.geometry('550x100')
        lbl = Label(window, text=errorMsg + " \n " + reportFilePath)
        lbl.grid(column=0, row=0)
        window.mainloop()
        exit(1)
    else:
        exit(0)
    

    Soon I will write Github readme or can make a tutorial