Git Pre Commit Hook for Phing PHP Build Select Files

时间:2013-09-01 20:48:55

标签: php git build phing pre-commit

我想在将它们提交给git之前使用预提交钩子来检查我的代码文件。为了检查,我将使用Phing(PHP构建工具)。

这是我的pre_commit_hook(MacOS):

#!/bin/sh
echo "Checking files before commit!"
phing -f pre_commit_build.xml || exit 1

这是构建文件:

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyApplication" default="main" basedir=".">

    <fileset id="php_project_files" dir="app">
        <include name="*.php" />
        <include name="**/*.php" />
    </fileset>

    <target name="main">

        <echo message="+------------------------------------------+"/>
        <echo message="|                                          |"/>
        <echo message="| Pre_Commit_Build                         |"/>
        <echo message="|                                          |"/>
        <echo message="+------------------------------------------+"/>

        <phingcall target="check_file_names" />
        <phingcall target="check_syntax" />
        <phingcall target="check_coding_guideline" />
        <phingcall target="unit_test" />

    </target>

    ...

    <target name="check_file_names">

        <property name="failure" value="0" />

        <adhoc-task name="check_filename"><![CDATA[
            class CheckFileName extends Task {

            /** Any filesets of files that should be appended. */
            private $filesets = array();

            /**
             * Nested creator, adds a set of files (nested <fileset> attribute).
             * This is for when you don't care what order files get appended.
             * @return FileSet
             */
             function createFileSet() {
                 $num = array_push($this->filesets, new FileSet());
                 return $this->filesets[$num-1];
             }

             function main() {

                 // append any files in filesets
                 foreach($this->filesets as $fs) {
                     try {
                         $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
                         foreach ($files as $file) {

                             if (preg_match('/^[a-z0-9-._]+$/', $file)) {
                                 $this->log("Checked: " . $file);
                             } else {
                                 $this->log("Error: " . $file . " : Allowed are only a-z 0-9 . - _", Project::MSG_ERR);
                                 $this->project->setProperty('failure', '1');
                             }
                          }
                      } catch (BuildException $be) {
                          $this->log($be->getMessage(), Project::MSG_WARN);
                      }
                  }    
              }
          }

      ]]></adhoc-task>

      <echo message="+------------------------------------------+"/>
      <echo message="|                                          |"/>
      <echo message="| Check PHP Filenames                      |"/>
      <echo message="|                                          |"/>
      <echo message="+------------------------------------------+"/>

          <check_filename>
              <fileset refid="php_project_files" />
          </check_filename>

          <echo message="Failure ${failure}" />

    ...

    <target name="check_syntax">

        <phplint level="verbose" haltonfailure="false">
            <fileset refid="php_project_files" />
        </phplint>

    </target>

    ...

</project>

目前git启动构建过程,将检查文件夹'app'的所有文件(不仅仅是我想要提交的文件)。在此过程之后,虽然会发现一些失败(即违反编码指南),但构建过程已完成并且文件将被提交(但在这种情况下他们不会)。

以下是我的问题:

  1. 我如何告诉Phing只使用我想要提交的文件。或者:如何将有关文件的信息从git传递到Phing?

  2. 如果构建过程必须失败,我如何“收集”构建过程目标中的失败(即错误的文件名或违反编码指南)和控制。

  3. 如果一个或多个目标失败,我如何向git发送返回值(1),以便git停止提交?

  4. 如何在adhoc-task中定义它失败(我已尝试使用属性$ {failure}?

  5. 非常感谢您的支持!

    的Stefan

2 个答案:

答案 0 :(得分:0)

关于“我想要提交的内容”:

our commit hook中,我们checkout the files到临时临时区域并检查这些区域。这是仅验证分阶段更改的唯一方法。 (还要想到git add -p)。

返回值:只是让你的构建失败。 phing存在非0状态代码。

答案 1 :(得分:0)

返回值:

如果我的任务失败,我会将其存储在$ {task_failed}属性中(失败= 1)。

比我让构建失败

<if>
    <equals arg1="${task_failed}" arg2="1" />
    <then> 
        <fail message="Task failed" />
    </then>
</if>

收集未提供的文件:

感谢@cweiske我创建了一个收集未提交文件的任务:

<target name="collect_uncommited_files">
    <exec command="git diff-index --name-only --cached --diff-filter=ACMR HEAD" output="uncommitted_files.txt" />
    <fileset id="uncommitted_files" dir="./" includesfiles="uncommited_files.txt">
    </fileset>
</target>

我使用git diff-index过滤未收集的文件,并将结果存储到外部文件uncommited_files.txt中。我将加载此文件以使用我未提交的文件创建文件集。 (当我将结果存储到属性并使用include构建我的文件集时,这也可以。)

在我的情况下,似乎是一种更好的方法,而不是将所有未提交的文件复制到像@cweiske:checkout the files中所做的单独目录中,因为我不想移动一些MB(我必须提交一些大文件)。