2010-09-15 23 views
7

Intentando hacer una sintaxis de php check hook para un repositorio de git. Me alegré cuando encontré un fragmento de código que hace exactamente esto.git hook sintaxis check

Pero parece que el script de fragmento tiene un defecto. Ejecuta

git diff-index --cached --name-only HEAD 

para obtener una lista de archivos en el índice. Ahora ejecuta php -l para cada archivo en esa lista. La falla es que un archivo puede diferir entre la copia de trabajo y el área de ensayo. Si el área de ensayo php tiene un error de sintaxis, pero la versión de copia de trabajo no lo hace, no se encuentra ningún error de sintaxis y la confirmación tiene éxito, que era lo que había que evitar.

¿Es este un problema no trivial para resolver, o hay alguna forma de ejecutar php -l en la versión provisional de cada archivo?

Respuesta

7

Estoy muy feliz de usar este php syntax validation hook. Espero que se ajuste a tus necesidades también.

Utiliza git diff-index --cached --full-index.

+0

+1 para un gancho de trabajo. – VonC

+0

Sí, esto lo hace mucho mejor que el gancho del artículo. – zedoo

+0

el gancho es bastante bueno, sin embargo requiere modificaciones pequeñas para que yo pueda usarlo. No puedo obtener el nombre de archivo correcto y la extensión debido al comando 'cortar' – cwhsu

2

No estoy seguro si hay un problema aquí.

El fragmento que menciona probablemente proviene de la entrada del blog Don’t Commit That Error.
E incluye:

A continuación, se llaman git diff-index con unos pocos parámetros.
Primero, agregamos --cached para decirle a Git que solo queremos archivos que vayan a cometerse.
Luego, agregamos --name-only para decirle a Git que solo muestre el nombre de los archivos que se están confirmando.

Parece que los archivos que se van a comprometer son precisamente los que un anzuelo de precompromiso desearía inspeccionar.
Incluso si difieren de los archivos en el directorio de trabajo, es su versión (en el índice) la que se va a confirmar. Y es la misma versión que se enviará al proceso php -l.


En realidad, el problema no está en la git diff-index sí mismo (con o sin --full-index) está en la forma en que va a leer el contenido del archivo en el índice

  • El "PHP Advent 2008" hook simplemente se trate de acceder al archivo desde su nombre (con el riesgo de acceder a la copia de trabajo)
 
exec("php -l " . escapeshellarg($file), $lint_output, $return); 
 
result=$(git cat-file -p $sha | /usr/bin/env $PHP_BIN -l 2>/dev/null) 

Usando git cat-file es la clave aquí, para acceder a un objeto en el repositorio Git (es decir, no en el "directorio de trabajo")

+0

Sí, ese es el código que estoy hablando. En $ salida obtienes la lista de archivos que se deben comprometer, corregir. Pero creo que estás equivocado con tu última oración. Es la versión de copia de trabajo que se envía a php -l, no a la versión del área de ensayo. Y eso es un error El gancho vinculado por Takehin parece funcionar mejor. – zedoo

+0

@zedoo: Tengo la actualización de mi respuesta para reflexionar sobre el problema real aquí (que no es 'git diff-index') – VonC

+0

Sí, exactamente. +1;) – zedoo

0

Causa pre-commit gancho no es bueno para trabajar en un equipo que debe utilizar pre-recepción instalado en el lado del servidor de rechazar todas las confirmaciones con la sintaxis de PHP no válida y el estándar de codificación incorrecta gancho.

He creado pre-reciben script en Python para que pupose:

# A server-side git hook script for checking PHP syntax and validating coding standard 
# Depends on: PHP_CodeSniffer (http://pear.php.net/package/PHP_CodeSniffer/) 
# Install: copy this script to <server side repo location>/hooks/pre-receive 
#!/usr/bin/python 

import os 
import sys 
oldrev, newrev, ref = sys.stdin.read().strip().split(' ') 
test_file = os.popen('mktemp').read().strip() 
coding_standards = 'PSR2' 
for line in os.popen('git diff --name-only %s %s' % (oldrev, newrev)).readlines(): 
    extension = line.split('.')[-1].strip() 
    file_name = line.strip() 

    if(extension == 'php'): 
     os.system("git cat-file -p %s:%s > %s" % (newrev, file_name, test_file)) 
     if 0 != os.system('php -l ' + test_file + ' > /dev/null'): 
      print "PHP Syntax error in file %s" % (file_name) 
      sys.exit(1) 

     if 0 != os.system("phpcs -n --standard=%s %s" % (coding_standards, test_file)): 
      print "Coding standards fail in file %s" % (file_name) 
      sys.exit(2) 
+2

El enlace está roto :-( –