GitHub for Windows Pre-Commit Hook

前端 未结 4 982
你的背包
你的背包 2021-01-05 01:38

We have a development team that is using a 50/50 split of GitHub for windows and Bash shell for their Git management.

We have implemented a pre-commit hook (designed

4条回答
  •  轮回少年
    2021-01-05 02:21

    Using Git shell you can have commit hooks. I got some commit hooks working with PowerShell. I found a powerShell script that did lint that I expanded to run phpunit and phpcs (paths are hard coded so you will need to adjust):

    pre Commit File:

    #!/bin/sh
    echo 
    exec powershell.exe -ExecutionPolicy RemoteSigned -File '.\.git\hooks\pre-commit-hook.ps1'
    exit
    

    pre-commit.ps1 file:

    ###############################################################################
    #
    # PHP Syntax Check for Git pre-commit hook for Windows PowerShell
    #
    # Author: Vojtech Kusy 
    # Author: Chuck "MANCHUCK" Reeves 
    #
    ###############################################################################
    
    ### INSTRUCTIONS ###
    
    # Place the code to file "pre-commit" (no extension) and add it to the one of 
    # the following locations:
    # 1) Repository hooks folder - C:\Path\To\Repository\.git\hooks
    # 2) User profile template   - C:\Users\\.git\templates\hooks 
    # 3) Global shared templates - C:\Program Files (x86)\Git\share\git-core\templates\hooks
    # 
    # The hooks from user profile or from shared templates are copied from there
    # each time you create or clone new repository.
    
    ### SETTINGS ###
    
    # Path to the php.exe
    $php_exe = "C:\php\php.exe";
    
    # Path to the phpcs
    $php_cs = "C:\Includes\PEAR\phpcs.bat";
    
    # Path to the phpunit
    $php_unit = "C:\Includes\PEAR\phpunit.bat";
    
    # Path to the phpunit bootstrap file
    $bootstrap = "tests\bootstrap.php";
    
    # Flag, if set to 1 require test file to exist, set to 0 to disable
    $requireTest = 1;
    
    # Extensions of the PHP files 
    $php_ext = "php|phtml"
    
    # Flag, if set to 1 git will unstage all files with errors, set to 0 to disable
    $unstage_on_error = 0;
    
    ### FUNCTIONS ###
    
    function php_syntax_check {
        param([string]$php_bin, [string]$extensions, [int]$reset) 
    
        $err_counter = 0;
    
        write-host "Pre-commit PHP syntax check:" -foregroundcolor "white" -backgroundcolor "black"
    
        git diff-index --name-only --cached HEAD -- | foreach {             
            if ($_ -match ".*\.($extensions)$") {
                $file = $matches[0];
                $errors = & $php_bin -l $file   
                $testFileExists = (Test-Path $file -PathType Leaf)
                write-host $file ": "  -foregroundcolor "gray"  -backgroundcolor "black" -NoNewline
                if ($testFileExists) {
                    if ($errors -match "No syntax errors detected in $file") {
                        write-host "OK!" -foregroundcolor "green" -backgroundcolor "black"
                    }
                    else {              
                        write-host "ERROR! " $errors -foregroundcolor "red" -backgroundcolor "black"
                        if ($reset) {
                            git reset -q HEAD $file
                            write-host "Unstaging ..." -foregroundcolor "magenta" -backgroundcolor "black"
                        }
                        $err_counter++
                    }
                } else {
                    write-host "OK! (file deleted)" -foregroundcolor "green" -backgroundcolor "black"
                }
            }
        }
    
        if ($err_counter -gt 0) {
            write-host "Some File(s) have syntax errors. Please fix then commit" -foregroundcolor "red" -backgroundcolor "black"
            exit 1
        }    
    }
    
    function php_cs_check {
        param([string]$php_cs, [string]$extensions, [int]$reset) 
    
        $err_counter = 0;
    
        write-host "Pre-commit PHP codesniffer check:" -foregroundcolor "white" -backgroundcolor "black"
    
        git diff-index --name-only --cached HEAD -- | foreach {     
            if ($_ -match ".*\.($extensions)$") {
                $file = $matches[0];
    
                write-host $file ": "  -foregroundcolor "gray"  -backgroundcolor "black" -NoNewline
                if ($file -match "tests\/") {
                    write-host "PASSED! (test file)" -foregroundcolor "green" -backgroundcolor "black"
                } else {
                    $errors = & $php_cs --standard=Zend $file           
    
                    if ($LastExitCode) {
                        write-host "FAILED! (contains errors)"  -foregroundcolor "red" -backgroundcolor "black"
                        if ($reset) {
                            git reset -q HEAD $file
                            write-host "Unstaging ..." -foregroundcolor "magenta" -backgroundcolor "black"
                        }
                        $err_counter++
                    } else {                
                        write-host "PASSED!" -foregroundcolor "green" -backgroundcolor "black"
                    }
                }
            }
        }
    
        if ($err_counter -gt 0) {
            write-host "Some File(s) are not following proper codeing standards. Please fix then commit" -foregroundcolor "red" -backgroundcolor "black"
            exit 1
        }    
    }
    
    function php_unit_check {
        param([string]$php_unit, [string]$bootstrap, [string]$extensions, [int]$reset, [int]$requireTest) 
    
        $err_counter = 0;
    
        write-host "Pre-commit PHP unit check:" -foregroundcolor "white" -backgroundcolor "black"
    
        git diff-index --name-only --cached HEAD -- | foreach {     
            if ($_ -match ".*\.($extensions)$") {
                $file = $matches[0];
    
                write-host $file ": "  -foregroundcolor "gray"  -backgroundcolor "black" -NoNewline
                if ($file -match "tests\/") {
                    write-host "SKIPPED! (test file)" -foregroundcolor "green" -backgroundcolor "black"
                } elseif ($file -match ".*Bootstrap.php") {
                    write-host "SKIPPED! (bootstrap file)" -foregroundcolor "green" -backgroundcolor "black"
                } elseif ($file -match "([application|library\\NDX].*)(.($extensions))$") {
    
                    $testFile = 'tests/' + $matches[1] + "Test.php";
                    $testFileExists = (Test-Path $testFile -PathType Leaf)
    
                    if ($testFileExists) {
                        $errors = & $php_unit --bootstrap $bootstrap $testFile
                        if ($LastExitCode) {
                            write-host "FAILED! (" $testFile ")"  -foregroundcolor "red" -backgroundcolor "black"
                            if ($reset) {
                                git reset -q HEAD $file
                                write-host "Unstaging ..." -foregroundcolor "magenta" -backgroundcolor "black"
                            }
                            $err_counter++
                        } else {
                            write-host "PASSED!" -foregroundcolor "green" -backgroundcolor "black"
    
                        }
                    } elseif($requireTest) {
                        write-host "FAILED! Test file Not found: (" $testFile ")"  -foregroundcolor "red" -backgroundcolor "black"
                        if ($reset) {
                            git reset -q HEAD $file
                            write-host "Unstaging ..." -foregroundcolor "magenta" -backgroundcolor "black"
                        }
                        $err_counter++
                    } else {
                        write-host "PASSED! (Test file not found and not required)" -foregroundcolor "darkGreen" -backgroundcolor "black"
                    }
                } else {
                    write-host "IGNORED!" -foregroundcolor "darkGreen" -backgroundcolor "black"
                }
            }
        }
    
        if ($err_counter -gt 0) {
            write-host "Some File(s) failed unit testing. Please fix then commit" -foregroundcolor "red" -backgroundcolor "black"
            exit 1
        }    
    }
    ### MAIN ###
    
    php_syntax_check $php_exe "php|phtml" $unstage_on_error
    write-host
    php_cs_check $php_cs "php" $unstage_on_error
    write-host
    php_unit_check $php_unit $bootstrap "php" $unstage_on_error $requireTest
    

提交回复
热议问题