hgbook

view es/hook.tex @ 468:7df73b3bc2eb

translated more text.
author Javier Rojas <jerojasro@devnull.li>
date Sat Dec 27 18:55:03 2008 -0500 (2008-12-27)
parents 616656741ba7
children 9438521abfc4
line source
1 \chapter{Manejo de eventos en repositorios mediante ganchos}
2 \label{chap:hook}
4 Mercurial ofrece un poderoso mecanismo para permitirle a usted
5 automatizar la ejecución de acciones en respuesta a eventos que
6 ocurran en un repositorio. En algunos casos, usted puede controlar
7 incluso la respuesta de Mercurial a dichos eventos.
9 Mercurial usa el término \emph{gancho} para identificar estas
10 acciones. Los ganchos son conocidos como ``disparadores'' en algunos
11 sistemas de control de revisiones, pero los dos nombres se refieren al
12 mismo concepto.
14 \section{Vistazo general de ganchos en Mercurial}
16 A continuación se encuentra una breve lista de los ganchos que
17 Mercurial soporta. Volveremos a cada uno de estos ganchos con más
18 detalle después, en la sección~\ref{sec:hook:ref}.
20 \begin{itemize}
21 \item[\small\hook{changegroup}] Es ejecutado luego de que un grupo de
22 conjuntos de cambios ha sido traído al repositorio desde algún
23 otro sitio.
24 \item[\small\hook{commit}] Es ejecutado después de la creación de
25 un conjunto de cambios en el repositorio local.
26 \item[\small\hook{incoming}] Es ejecutado una vez por cada conjunto de
27 cambios traído al repositorio desde otra ubicación. Note la
28 diferencia respecto al gancho \hook{changegroup}, que es ejecutado
29 una vez por cada \emph{grupo} de conjuntos de cambios que se
30 traiga.
31 \item[\small\hook{outgoing}] Es ejecutado luego de que un grupo de
32 conjuntos de cambios ha sido transmitido desde el repositorio.
33 \item[\small\hook{prechangegroup}] Es ejecutado antes de iniciar la
34 recepción de un grupo de conjuntos de cambios en el repositorio.
35 \item[\small\hook{precommit}] De control. Es ejecutado antes de
36 iniciar una consignación.
37 \item[\small\hook{preoutgoing}] De control. Es ejecutado antes de
38 iniciar la transmisión de un grupo de conjuntos de cambios desde
39 el repositorio.
40 \item[\small\hook{pretag}] De control. Es ejecutado antes de crear una
41 etiqueta.
42 \item[\small\hook{pretxnchangegroup}] De control. Es ejecutado después
43 de haber recibido un grupo de conjuntos de cambios en el
44 repositorio local, pero antes de que la transacción se complete y
45 los cambios sean permanentes dentro del repositorio.
46 \item[\small\hook{pretxncommit}] De control. Es ejecutado luego de la
47 creación de un conjunto de cambios en el repositorio local, pero
48 antes de que la transacción que hace permanente el cambio sea
49 completada.
50 \item[\small\hook{preupdate}] De control. Es ejecutado antes de
51 iniciar una actualización o fusión en el directorio de trabajo.
52 \item[\small\hook{tag}] Es ejecutado después de la creación de una
53 etiqueta.
54 \item[\small\hook{update}] Es ejecutado después de que termina una
55 actualización o una fusión.
56 \end{itemize}
57 Cada uno de los ganchos cuya descripción empieza con la frase
58 ``de control'' tiene la facultad de determinar si una actividad puede
59 continuar. Si el gancho se ejecuta con éxito, la actividad puede
60 continuar; si falla, o bien la actividad no es permitida, o se
61 deshacen los cambios que se puedan haber llevado a cabo, dependiendo
62 del gancho involucrado.
64 \section{Ganchos y seguridad}
66 \subsection{Los ganchos se ejecutan con sus privilegios de usuario}
68 Cuando usted ejecuta un comando de Mercurial en un repositorio, y el
69 comando causa la ejecución de un gancho, dicho gancho se ejecuta en
70 \emph{su} sistema, en \emph{su} cuenta de usuario, con \emph{sus}
71 privilegios. Ya que los ganchos son elementos arbitrarios de código
72 ejecutable, usted debería tratarlos con un nivel adecuado de
73 desconfianza. No instale un gancho a menos en que confíe en quien lo
74 creó y en lo que el gancho hace.
76 En algunos casos, usted puede estar expuesto a ganchos que usted no
77 %TODO acá introduzco algo de texto por mi cuenta, por claridad
78 instaló. Si usted usa Mercurial en un sistema extraño, tenga en cuenta
79 que Mercurial ejecutará los ganchos definidos en el fichero \hgrc.
81 Si está trabajando con un repositorio propiedad de otro usuario,
82 Mercurial podrá ejecutar los ganchos definidos en el repositorio de
83 dicho usuario, pero los ejecutará como ``usted''. Por ejemplo, si
84 usted jala (\hgcmd{pull}) desde ese repositorio, y el
85 \sfilename{.hg/hgrc} define un gancho saliente (\hook{outgoing}),
86 dicho gancho se ejecuta bajo su cuenta de usuario, aun cuando usted no
87 es el propietario del repositorio.
89 \begin{note}
90 Esto sólo aplica si usted está jalando desde un repositorio en un
91 sistema de ficheros local o de red. Si está jalando a través de http
92 o ssh, cualquier gancho saliente (\hook{outgoing}) se ejecutará bajo
93 la cuenta que está ejecutando el proceso servidor, en el servidor.
94 \end{note}
96 XXX Para ver qué ganchos han sido definidos en un repositorio, use el
97 comando \hgcmdargs{config}{hooks}. Si usted está trabajando en un
98 repositorio, pero comunicándose con otro que no le pertenece
99 (por ejemplo, usando \hgcmd{pull} o \hgcmd{incoming}), recuerde que
100 los ganchos que debe considerar son los del otro repositorio, no los
101 del suyo.
103 \subsection{Los ganchos no se propagan}
105 En Mercurial, no se hace control de revisiones de los ganchos, y no se
106 propagan cuando usted clona, o jala de, un repositorio. El motivo para
107 esto es simple: un gancho es código ejecutable arbitrario. Se ejecuta
108 bajo su identidad, con su nivel de privilegios, en su máquina.
110 Sería extremadamente descuidado de parte de cualquier sistema
111 distribuido de control de revisiones el implementar control de
112 revisiones para ganchos, ya que esto ofrecería maneras fácilmente
113 %TODO subvertir
114 aprovechables de subvertir las cuentas de los usuarios del sistema de
115 control de revisiones.
117 Ya que Mercurial no propaga los ganchos, si usted está colaborando con
118 otras personas en un proyecto común, no debería asumir que ellos están
119 usando los mismos ganchos para Mercurial que usted usa, o que los de
120 ellos están configurado correctamente. Usted debería documentar los
121 ganchos que usted espera que la gente use.
123 En una intranet corporativa, esto es algo más fácil de manejar, ya que
124 usted puede, por ejemplo, proveer una instalación ``estándar'' de
125 Mercurial en un sistema de ficheros NFS, y usar un fichero \hgrc\
126 global para definir los ganchos que verán todos los usuarios. Sin
127 embargo, este enfoque tiene sus límites; vea más abajo.
129 \subsection{Es posible hacer caso omiso de los ganchos}
131 Mercurial le permite hacer caso omiso de la deficinión de un gancho,
132 a través de la redefinición del mismo. Usted puede deshabilitar el
133 gancho fijando su valor como una cadena vacía, o cambiar su
134 comportamiento como desee.
136 Si usted instala un fichero \hgrc\ a nivel de sistema o sitio completo
137 que define algunos ganchos, debe entender que sus usuarios pueden
138 deshabilitar o hacer caso omiso de los mismos.
140 \subsection{Asegurarse de que ganchos críticos sean ejecutados}
142 Algunas veces usted puede querer hacer respetar una política, y no
143 permitir que los demás sean capaces de evitarla. Por ejemplo, usted
144 puede tener como requerimiento que cada conjunto de cambios debe pasar
145 un riguroso conjunto de pruebas. Definir este requerimientos a través
146 de un gancho en un fichero \hgrc\ global no servirá con usuarios
147 remotos en computadoras portátiles, y por supuesto que los usuarios
148 locales pueden evitar esto a voluntad haciendo caso omiso del gancho.
150 En vez de eso, usted puede definir las políticas para usar Mercurial
151 de tal forma que se espere que los usuarios propaguen los cambios a
152 través de un servidor ``canónico'' bien conocido que usted ha
153 asegurado y configurado apropiadamente.
155 Una manera de hacer esto es a través de una combinación de ingeniería
156 socual y tecnología. Cree una cuenta de acceso restringido; los
157 usuarios pueden empujar cambios a través de la red a los repositorios
158 administrados por esta cuenta, pero no podrán ingresar a dicha cuenta
159 para ejecutar órdenes en el intérprete de comandos. En este escenario,
160 un usuario puede enviar un conjunto de cambios que contenga la
161 porquería que él desee.
163 Cuando alguien empuja un conjunto de cambios al servidor del que todos
164 jalan, el servidor probará el conjunto de cambios antes de aceptarlo
165 como permanente, y lo rechazará si no logra pasar el conjunto de
166 pruebas. Si la gente sólo jala cambios desde este servidor de filtro,
167 servirá para asegurarse de que todos los cambios que la gente jala han
168 sido examinados automáticamente
170 \section{Precauciones con ganchos \texttt{pretxn} en un repositorio de
171 acceso compartido}
173 Si usted desea usar ganchos para llevar a cabo automáticamente algún
174 trabajo en un repositorio al que varias personas tienen acceso
175 compartido, debe tener cuidado con la forma de hacerlo.
177 Mercurial sólo bloquea un repositorio cuando está escribiendo al
178 mismo, y sólo las partes de Mercurial que escriben al repositorio le
179 prestan atención a los bloqueos. Los bloqueos de escritura son
180 necesarios para evitar que múltiples escritores simultáneos
181 interfieran entre sí, corrompiendo el repositorio.
183 Ya que Mercurial tiene cuidado con el orden en que lee y escribe
184 datos, no necesita adquirir un bloqueo cuando desea leer datos del
185 repositorio. Las partes de Mercurial que leen del repositorio nunca le
186 prestan atención a los bloqueos. Este esquema de lectura libre de
187 bloqueos incremententa en gran medida el desempeño y la concurrencia.
189 Sin embargo, para tener un gran desempeño es necesario hacer
190 sacrificios, uno de los cuales tiene el potencial de causarle
191 problemas a menos de que usted esté consciente de él. Describirlo
192 requiere algo de detalle respecto a cómo Mercurial añade conjuntos de
193 cambios al repositorio y cómo lee esos cambios de vuelta.
195 Cuando Mercurial \emph{escribe} metadatos, los escribe directamente en
196 el fichero de destino. Primero escribe los datos del fichero, luego
197 los datos del manifiesto (que contienen punteros a los nuevos datos
198 del fichero), luego datos de la bitácora de cambios (que contienen
199 punteros a los nuevos datos del manifiesto). Antes de la primera
200 escritura a cada fichero, se guarda un registro de dónde estaba el
201 final de fichero en su registro de transacciones. Si la transacción
202 debe ser deshecha, Mercurial simplemente trunca cada fichero de vuelta
203 al tamaño que tenía antes de que empezara la transacción.
205 Cuando Mercurial \emph{lee} metadatos, lee la bitácora de cambios
206 primero, y luego todo lo demás. Como un lector sólo accederá a las
207 partes del manifiesto o de los metadatos de fichero que él puede ver
208 en la bitácora de cambios, nunca puede ver datos parcialmente
209 escritos.
211 Algunos ganchos de control (\hook{pretxncommit} y
212 \hook{pretxnchangegroup}) se ejecutan cuando una transacción está casi
213 completa. Todos los metadatos han sido escritos, pero Mercurial aún
214 puede deshacer la transacción y hacer que los datos recién escritos
215 desaparezcan.
217 Si alguno de estos ganchos permanece en ejecución por mucho tiempo,
218 abre una ventana de tiempo en la que un lector puede ver los metadatos
219 de conjuntos de cambios que aún no son permanentes y que no debería
220 considerarse que estén ``realmante ahí''. Entre más tiempo tome la
221 ejecución del gancho, más tiempo estará abierta esta ventana.
223 \subsection{Ilustración del problema}
225 En principio, un buen uso del gancho \hook{pretxnchangegroup} sería
226 ensamblar y probar automáticamente todos los cambios entrantes antes
227 de que sean aceptados en un repositorio central. Esto le permitiría a
228 usted garantizar que nadie pueda empujar cambios que ``rompan el
229 ensamblaje''. Pero si un cliente puede jalar cambios mientras están
230 siendo probados, la utilidad de esta prueba es nula; alguien confiado
231 puede jalar cambios sin probar, lo que potencialmente podría romper su
232 proceso de ensamblaje.
234 La respuesta técnica más segura frente a este retos es montar dicho
235 repositorio ``guardián'' como \emph{unidireccional}. Permita que
236 reciba cambios desde el exterior, pero no permita que nadie jale
237 cambios de él (use el gancho \hook{preoutgoing} para bloquear esto).
238 Configure un gancho \hook{changegroup} para que si el ensamblaje o
239 prueba tiene éxito, el gancho empuje los nuevos cambios a otro
240 repositorio del que la gente \emph{pueda} jalar.
242 En la práctica, montar un cuello de botella centralizado como éste a
243 menudo no es una buena idea, y la visibilidad de las transacciones no
244 tiene nada que ver con el problema. A medida que el tamaño de un
245 proyecto---y el tiempo que toma ensamblarlo y probarlo---crece, usted
246 se acerca rápidamente a un límite con este enfoque ``pruebe antes de
247 comprar'', en el que tiene más conjuntos de cambios a probar que
248 tiempo para ocuparse de ellos. El resultado inevitable es frustración
249 para todos los que estén involucrados.
251 Una aproximación que permite manejar mejor el crecimiento es hacer que
252 la gente ensamble y pruebe antes de empujar, y ejecutar el ensamble y
253 pruebas automáticas centralmente \emph{después} de empujar, para
254 asegurarse de que todo esté bien. La ventaja de este enfoque es que no
255 impone un límite a la rata en la que un repositorio puede aceptar
256 cambios.
258 \section{Tutorial corto de uso de ganchos}
259 \label{sec:hook:simple}
261 Escribir un gancho para Mercurial es fácil. Empecemos con un gancho
262 que se ejecute cuando usted termine un \hgcmd{commit}, y simplemente
263 muestre el hash del conjunto de cambios que usted acaba de crear. El
264 gancho se llamará \hook{commit}.
266 \begin{figure}[ht]
267 \interaction{hook.simple.init}
268 \caption{Un gancho simple que se ejecuta al hacer la consignación de
269 un conjunto de cambios}
270 \label{ex:hook:init}
271 \end{figure}
273 Todos los ganchos siguen el patrón del ejemplo~\ref{ex:hook:init}.
274 Usted puede añadir una entrada a la sección \rcsection{hooks} de su
275 fichero \hgrc. A la izquierda está el nombre del evento respecto al
276 cual dispararse; a la derecha está la acción a llevar a cabo. Como
277 puede ver, es posible ejecutar cualquier orden de la línea de comandos
278 en un gancho. Mercurial le pasa información extra al gancho usando
279 variables de entorno (busque \envar{HG\_NODE} en el ejemplo).
281 \subsection{Llevar a cabo varias acciones por evento}
283 A menudo, usted querrá definir más de un gancho para un tipo de evento
284 particular, como se muestra en el ejemplo~\ref{ex:hook:ext}.
285 Mercurial le permite hacer esto añadiendo una \emph{extensión} al
286 final del nombre de un gancho. Usted extiende el nombre del gancho
287 %TODO Yuk, no me gusta ese "parada completa"
288 poniendo el nombre del gancho, seguido por una parada completa (el
289 caracter ``\texttt{.}''), seguido de algo más de texto de su elección.
290 Por ejemplo, Mercurial ejecutará tanto \texttt{commit.foo} como
291 \texttt{commit.bar} cuando ocurra el evento \texttt{commit}.
293 \begin{figure}[ht]
294 \interaction{hook.simple.ext}
295 \caption{Definición de un segundo gancho \hook{commit}}
296 \label{ex:hook:ext}
297 \end{figure}
299 Para dar un orden bien definido de ejecución cuando hay múltiples
300 ganchos definidos para un evento, Mercurial ordena los ganchos de
301 acuerdo a su extensión, y los ejecuta en dicho orden. En el ejemplo de
302 arribam \texttt{commit.bar} se ejecutará antes que
303 \texttt{commit.foo}, y \texttt{commit} se ejecutará antes de ambos.
305 Es una buena idea usar una extensión descriptiva cuando usted define
306 un gancho. Esto le ayudará a recordar para qué se usa el gancho. Si el
307 gancho falla, usted recibirá un mensaje de error que contiene el
308 nombre y la extensión del gancho, así que usar una extensión
309 descriptiva le dará una pista inmediata de porqué el gancho falló (vea
310 un ejemplo en la sección~\ref{sec:hook:perm}).
312 \subsection{Controlar cuándo puede llevarse a cabo una actividad}
313 \label{sec:hook:perm}
315 En los ejemplos anteriores, usamos el gancho \hook{commit}, que es
316 ejecutado después de que se ha completado una consignación. Este es
317 uno de los varios ganchos que Mercurial ejecuta luego de que una
318 actividad termina. Tales ganchos no tienen forma de influenciar la
319 actividad como tal.
321 Mercurial define un número de eventos que ocurren antes de que una
322 actividad empiece; o luego de que empiece, pero antes de que termine.
323 Los ganchos que se disparan con estos eventos tienen la capacidad
324 adicional de elegir si la actividad puede continuar, o si su ejecución
325 es abortada.
327 El gancho \hook{pretxncommit} se ejecuta justo antes de que una
328 consignación se ejecute. En otras palabras, los metadatos que
329 representan el conjunto de cambios han sido escritos al disco, pero no
330 se ha terminado la transacción. El gancho \hook{pretxncommit} tiene la
331 capacidad de decidir si una transacción se completa, o debe
332 deshacerse.
334 Si el gancho \hook{pretxncommit} termina con un código de salida de
335 cero, se permite que la transacción se complete; la consignación
336 termina; y el gancho \hook{commit} es ejecutado. Si el gancho
337 \hook{pretxncommit} termina con un código de salida diferente de cero,
338 la transacción es revertida; los metadatos representando el conjunto
339 de cambios son borrados; y el gancho \hook{commit} no es ejecutado.
341 \begin{figure}[ht]
342 \interaction{hook.simple.pretxncommit}
343 \caption{Uso del gancho \hook{pretxncommit} hook to control commits}
344 \label{ex:hook:pretxncommit}
345 \end{figure}
347 El gancho en el ejemplo~\ref{ex:hook:pretxncommit} revisa si el
348 mensaje de consignación contiene el ID de algún fallo. Si lo contiene,
349 la consignación puede continuar. Si no, la consignación es cancelada.
351 \section{Escribir sus propios ganchos}
353 Cuando usted escriba un gancho, puede encontrar útil el ejecutar
354 Mercurial o bien pasándole la opción \hggopt{-v}, o con el valor de
355 configuración \rcitem{ui}{verbose} fijado en ``true'' (verdadero).
356 Cuando lo haga, Mercurial imprimirá un mensaje antes de llamar cada
357 gancho.
359 \subsection{Escoger cómo debe ejecutarse su gancho}
360 \label{sec:hook:lang}
362 Usted puede escribir un gancho que funcione como un programa normal
363 ---típicamente un guión de línea de comandos---o como una función de
364 Python que se ejecuta dentro del proceso Mercurial.
366 Escribir un gancho como un programa externo tiene la ventaja de que no
367 requiere ningún conocimiento del funcionamiento interno de Mercurial.
368 Usted puede ejecutar comandos Mercurial normales para obtener la
369 informción extra que pueda necesitar. La contraparte de esto es que
370 los ganchos externos son más lentos que los ganchos internos
371 ejecutados dentro del proceso.
373 Un gancho Python interno tiene acceso completo a la API de Mercurial,
374 y no se ``externaliza'' a otro proceso, así que es inherentemente más
375 rápido que un gancho externo. Adicionalmente es más fácil obtener la
376 mayoría de la información que un gancho requiere a través de llamadas
377 directas a la API de Mercurial que hacerlo ejecutando comandos
378 Mercurial.
380 Si se siente a gusto con Python, o requiere un alto desempeño,
381 escribir sus ganchos en Python puede ser una buena elección. Sin
382 embargo, cuando usted tiene un gancho bastante directo por escribir y
383 no le importa el desempeño (el caso de la mayoría de los ganchos), es
384 perfectamente admisible un guión de línea de comandos.
386 \subsection{Parámetros para ganchos}
387 \label{sec:hook:param}
389 Mercurial llama cada gancho con un conjunto de paŕametros bien
390 definidos. En Python, un parámetro se pasa como argumento de palabra
391 clave a su función de gancho. Para un programa externo, los parámetros
392 son pasados como variables de entornos.
394 Sin importar si su gancho está escrito en Python o como guión de línea
395 de comandos, los nombres y valores de los parámetros específicos de
396 los ganchos serán los mismos. Un parámetro booleano será representado
397 como un valor booleano en Python, pero como el número 1 (para
398 ``verdadero'') o 0 (para falso) en una variable de entorno para un
399 gancho externo. Si un parámetro se llama \texttt{foo}, el argumento de
400 palabra clave para un gancho en Python también se llamará
401 \texttt{foo}, mientras que la variable de entorno para un gancho
402 externo se llamará \texttt{HG\_FOO}.
404 \subsection{Valores de retorno de ganchos y control de actividades}
406 Un gancho que se ejecuta exitosamente debe terminar con un código de
407 salida de cero, si es externo, o retornar el valor booleano
408 ``falso'', si es interno. Un fallo se indica con un código de salida
409 diferente de cero desde un gancho externo, o un valor de retorno
410 booleano ``verdadero''. Si un gancho interno genera una excepción, se
411 considera que el gancho ha fallado.
413 Para los ganchos que controlan si una actividad puede continuar o no,
414 cero/falso quiere decir ``permitir'', mientras que
415 % TODO me suena mejor "no permitir" que "denegar"
416 no-cero/verdadero/excepción quiere decir ``no permitir''.
418 \subsection{Escribir un gancho externo}
420 Cuando usted define un gancho externo en su fichero \hgrc\ y el mismo
421 es ejecutado, dicha definición pasa a su intérprete de comandos, que
422 hace la interpretación correspondiente. Esto significa que usted puede
423 usar elementos normales del intérprete en el cuerpo del gancho.
425 Un gancho ejecutable siempre es ejecutado con su directorio actual
426 fijado al directorio raíz del repositorio.
428 Cada parámetro para el gancho es pasado como una variable de entorno;
429 el nombre está en mayúsculas, y tiene como prefijo la cadena
430 ``\texttt{HG\_}''.
432 Con la excepción de los parámetros para los ganchos, Mercurial no
433 define o modifica ninguna variable de entorno al ejecutar un gancho.
434 Es útil recordar esto al escribir un gancho global que podría ser
435 ejecutado por varios usuarios con distintas variables de entorno
436 fijadas. En situaciones con múltiples usuarios, usted no debería
437 asumir la existencia de ninguna variable de entorno, ni que sus
438 valores sean los mismos que tenían cuando usted probó el gancho en su
439 ambiente de trabajo.
441 \subsection{Indicar a Mercurial que use un gancho interno}
443 La sintaxis para definir un gancho interno en el fichero \hgrc\ es
444 ligeramente diferente de la usada para un gancho externo. El valor del
445 gancho debe comenzar con el texto ``\texttt{python:}'', y continuar
446 con el nombre completamente cualificado de un objeto invocable que se
447 usará como el valor del gancho.
449 El módulo en que vive un gancho es importado automáticamente cuando se
450 ejecuta un gancho. Siempre que usted tenga el nombre del módulo y la
451 variable de entorno \envar{PYTHONPATH} ajustada adecuadamente, todo
452 debería funcionar sin problemas.
454 El siguiente fragmento de ejemplo de un fichero \hgrc\ ilustra la
455 sintaxis y significado de los conceptos que acabamos de describir.
456 \begin{codesample2}
457 [hooks]
458 commit.example = python:mymodule.submodule.myhook
459 \end{codesample2}
460 Cuando Mercurial ejecuta el gancho \texttt{commit.example}, importa
461 \texttt{mymodule.submodule}, busca el objeto invocable llamado
462 \texttt{myhook}, y lo invoca (llama).
464 \subsection{Escribir un gancho interno}
466 El gancho interno más sencillo no hace nada, pero ilustra la
467 estructura básica de la API\footnote{\emph{Application Progamming
468 Interface}, Interfaz para Programación de Aplicaciones} para ganchos:
469 \begin{codesample2}
470 def myhook(ui, repo, **kwargs):
471 pass
472 \end{codesample2}
473 El primer argumento para un gancho Python siempre es un objeto
474 \pymodclass{mercurial.ui}{ui}. El segundo es un objeto repositorio;
475 de momento, siempre es una instancia de
476 \pymodclass{mercurial.localrepo}{localrepository}. Después de estos
477 dos argumentos están los argumentos de palabra clave. Los argumentos
478 que se pasen dependerán del tipo de gancho que se esté llamando, pero
479 un gancho siempre puede ignorar los argumentos que no le interesen,
480 relegándolos a un diccionario de argumentos por palabras clave, como se
481 hizo arriba con \texttt{**kwargs}.
483 \section{Ejemplos de ganchos}
485 \subsection{Escribir mensajes de consignación significativos}
487 Es difícil de imaginar un mensaje de consignación útil y al mismo
488 tiempo muy corto. El simple gancho \hook{pretxncommit} de la
489 figura~\ref{ex:hook:msglen.go} evitará que usted consigne un conjunto
490 de cambios con un mensaje de menos de 10 bytes de longitud.
492 \begin{figure}[ht]
493 \interaction{hook.msglen.go}
494 \caption{Un gancho que prohíbe mensajes de consignación demasiado
495 cortos}
496 \label{ex:hook:msglen.go}
497 \end{figure}
499 \subsection{Comprobar espacios en blanco finales}
501 Un uso interesante para ganchos relacionados con consignaciones es
502 ayudarle a escribir código más limpio. Un ejemplo simple de
503 %TODO dictum => regla
504 ``código más limpio'' es la regla de que un cambio no debe añadir
505 líneas de texto que contengan ``espacios en blanco finales''. El
506 espacio en blanco final es una serie de caracteres de espacio y
507 tabulación que se encuentran al final de una línea de texto. En la
508 mayoría de los casos, el espacio en blanco final es innecesario, ruido
509 invisible, pero ocasionalmente es problemático, y la gente en general
510 prefiere deshacerse de él.
512 Usted puede usar cualquiera de los ganchos \hook{precommit} o
513 \hook{pretxncommit} para revisar si tiene el problema de los espacios
514 en blanco finales. Si usa el gancho \hook{precommit}, el gancho no
515 sabrá qué ficheros se están consignando, por lo que se tendrá que
516 revisar cada fichero modificado en el repositorio para ver si tiene
517 espacios en blanco finales. Si usted sólo quiere consignar un cambio
518 al fichero \filename{foo}, y el fichero \filename{bar} contiene
519 espacios en blanco finales, hacer la revisión en el gancho
520 \hook{precommit} evitará que usted haga la consignación de
521 \filename{foo} debido al problem en \filename{bar}. Este no parece el
522 enfoque adeucado.
524 Si usted escogiera el gancho \hook{pretxncommit}, la revisión no
525 ocurriría sino hasta justo antes de que la transacción para la
526 consignación se complete. Esto le permitirá comprobar por posibles
527 problemas sólo en los ficheros que serán consignados. Sin embargo, si
528 usted ingresó el mensaje de consignación de manera interactiva y el
529 %TODO roll-back
530 gancho falla, la transacción será deshecha; usted tendrá que
531 reingresar el mensaje de consignación luego de que corrija el problema
532 con los espacios en blanco finales y ejecute \hgcmd{commit} de nuevo.
534 \begin{figure}[ht]
535 \interaction{hook.ws.simple}
536 \caption{Un gancho simple que revisa si hay espacios en blanco
537 finales}
538 \label{ex:hook:ws.simple}
539 \end{figure}
541 La figura~\ref{ex:hook:ws.simple} presenta un gancho
542 \hook{pretxncommit} simple que comprueba la existencia de espacios en
543 blanco finales. Este gancho es corto, pero no brinda mucha ayuda.
544 Termina con un código de salida de error si un cambio añade una línea
545 con espacio en blanco final a cualquier fichero, pero no muestra
546 ninguna información que pueda ser útil para identificar el fichero o
547 la línea de texto origen del problema. También tiene la agradable
548 propiedad de no prestar atención a las líneas que no sufrieron
549 modificaciones; sólo las líneas que introducen nuevos espacios en
550 blanco finales causan problemas.
552 \begin{figure}[ht]
553 \interaction{hook.ws.better}
554 \caption{A better trailing whitespace hook}
555 \label{ex:hook:ws.better}
556 \end{figure}
558 El ejemplo de la figura~\ref{ex:hook:ws.better} es mucho más complejo,
559 pero también más útil. El gancho procesa un diff unificado para
560 revisar si alguna línea añade espacios en blanco finales, e imprime el
561 nombre del fichero y el número de línea de cada ocurrencia. Aún mejor,
562 si el cambio añade espacios en blanco finales, este gancho guarda el
563 mensaje de consignación e imprime el nombre del fichero en el que el
564 mensaje fue guardado, antes de terminar e indicarle a Mercurial que
565 deshaga la transacción, para que uste pueda usar
566 \hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{nombre\_fichero}} para
567 reutilizar el mensaje de consignación guardado anteriormente, una vez
568 usted haya corregido el problema.
570 Como anotación final, note en la figura~\ref{ex:hook:ws.better} el
571 %TODO on-site => in-situ ?
572 uso de la característica de edición \emph{in-situ} de \command{perl}
573 para eliminar los espacios en blanco finales en un fichero. Esto es
574 lo suficientemente conciso y poderoso para que lo presente aquí.
575 % TODO corregí el backslash, y comprobé por mi cuenta un archivo
576 % aparte, y el comando hace lo que debe hacer. Favor copiar del pdf el
577 % comando perl y comprobar con un archivo con espacios en blanco
578 % finales, y si todo está bien (que debería), borrar esta nota
579 \begin{codesample2}
580 perl -pi -e 's,\textbackslash{}s+\$,,' nombre\_fichero
581 \end{codesample2}
583 %TODO bundled
584 \section{Ganchos bundled}
586 Mercurial se instala con varios ganchos bundled. Usted puede
587 encontrarlos en el directorio \dirname{hgext} del árbol de ficheros
588 fuente de Mercurial. Si usted está usando un paquete binario de
589 Mercurial, los ganchos estarán ubicados en el directorio
590 \dirname{hgext} en donde su instalador de paquetes haya puesto a
591 Mercurial.
593 \subsection{\hgext{acl}---control de acceso a partes de un repositorio}
595 La extensión \hgext{acl} le permite controlar a qué usuarios remotos
596 les está permitido empujar conjuntos de cambios a un servidor en red.
597 Usted puede proteger cualquier porción de un repositorio (incluyendo
598 el repositorio completo), de tal manera que un usuario remoto
599 específico pueda empujar cambios que no afecten la porción protegida.
601 Esta extensión implementa control de acceso basado en la identidad del
602 usuario que empuja los conjuntos de cambios, \emph{no} en la identidad
603 de quien hizo la consignación de los mismos. Usar este gancho tiene
604 sentido sólo si se tiene un servidor adecuadamente asegurado que
605 autentique a los usuarios remotos, y si usted desea segurarse de que
606 sólo se le permita a ciertos usuarios empujar cambios a dicho
607 servidor.
609 \subsubsection{Configurar el gancho \hook{acl}}
611 Para administrar los conjuntos de cambios entrantes, se debe usar el
612 gancho \hgext{acl} como un gancho de tipo \hook{pretxnchangegroup}.
613 Esto le permite ver qué ficheros son modificados por cada conjunto de
614 %TODO rollback => "deshacer el efecto"
615 cambios entrante, y deshacer el efecto de un grupo de conjuntos de
616 cambios si alguno de ellos modifica algún fichero ``prohibido''.
617 Ejemplo:
618 \begin{codesample2}
619 [hooks]
620 pretxnchangegroup.acl = python:hgext.acl.hook
621 \end{codesample2}
623 La extensión \hgext{acl} es configurada mediante tres secciones.
625 La sección \rcsection{acl} sólo tiene una entrada,
626 \rcitem{acl}{sources}\footnote{Fuentes.}, que lista las fuentes de los
627 conjuntos de cambios entrantes a las que el gancho debe prestar
628 atención. Usualmente usted no necesita configurar esta sección.
629 \begin{itemize}
630 \item[\rcitem{acl}{serve}] Controlar conjuntos de
631 cambios entrantes que están llegando desde un repositorio a
632 través de http o ssh. Este es el valor por defecto de
633 \rcitem{acl}{sources}, y usualmente es el único valor de
634 configuración que necesitará para este ítem.
635 \item[\rcitem{acl}{pull}] Controlar conjuntos de cambios entrantes que
636 lleguen vía un pull (jalado) desde un repositorio local.
637 \item[\rcitem{acl}{push}] Controlar conjuntos de cambios entrantes que
638 lleguen vía un push (empuje) desde un repositorio local.
639 \item[\rcitem{acl}{bundle}] Controlar conjuntos de cambios entrantes
640 %TODO bundle
641 que lleguen desde otro repositorio a través de un bundle.
642 \end{itemize}
644 La sección \rcsection{acl.allow} controla los usuarios a los que les
645 está permitido añadir conjuntos de cambios al repositorio. Si esta
646 sección no está presente, se le permite acceso a todos los usuarios
647 excepto a los que se les haya negado explícitamente el acceso. Si
648 esta sección no está presente, se niega el acceso a todos los usuarios
649 excepto a todos a los que se les haya permitido de manera explícita
650 (así que una sección vacía implica que se niega el acceso a todos los
651 usuarios).
653 La sección \rcsection{acl.deny} determina a qué usuarios no se les
654 permite añadir conjuntos de cambios al repositorio. Si esta sección no
655 está presente o está vacía, no se niega el acceso a ningún usuario.
657 La sintaxis para los ficheros \rcsection{acl.allow} y
658 \rcsection{acl.deny} es idéntica. A la izquierda de cada entrada se
659 encuentra un patrón glob que asocia ficheros o directorios, respecto a
660 la raíz del repositorio; a la derecha, un nombre usuario.
662 En el siguiente ejemplo, el usuario \texttt{escritordoc} sólo puede
663 empujar cambios al directorio \dirname{docs} del repositorio, mientras
664 que \texttt{practicante} puede enviar cambios a cualquier fichero o
665 directorio excepto \dirname{fuentes/sensitivo}.
666 \begin{codesample2}
667 [acl.allow]
668 docs/** = escritordoc
670 [acl.deny]
671 fuentes/sensitivo/** = practicante
672 \end{codesample2}
674 \subsubsection{Pruebas y resolución de problemas}
676 Si usted desea probar el gancho \hgext{acl}, ejecútelo habilitando la
677 opción de salida de depuración habilitada. Ya que usted probablemente
678 lo estará ejecutando en un servidor donde no es conveniente (o incluso
679 posible) pasar la opción \hggopt{--debug}, no olvide que usted puede
680 habilitar la salida de depuración en su \hgrc:
681 \begin{codesample2}
682 [ui]
683 debug = true
684 \end{codesample2}
685 Con esto habilitado, el gancho \hgext{acl} imprimirá suficiente
686 información para permitirle saber porqué está permitiendo o denegando
687 la operación de empujar a usuarios específicos.
689 \subsection{\hgext{bugzilla}---integración con Bugzilla}
691 La extensión \hgext{bugzilla} añade un comentario a un fallo Bugzilla
692 siempre que encuentre una referencia al ID de dicho fallo en un
693 mensaje de consignación. Usted puede instalar este gancho en un
694 servidor compartido, para que cada vez que un usuario remoto empuje
695 cambios al servidor, el gancho sea ejecutado.
697 Se añade un comentario al fallo que se ve así (usted puede configurar
698 los contenidos del comentario---vea más abajo):
699 %TODO traducir?
700 \begin{codesample2}
701 Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
702 the frobnitz repository, refers to this bug.
704 For complete details, see
705 http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
707 Changeset description:
708 Fix bug 10483 by guarding against some NULL pointers
709 \end{codesample2}
710 El valor de este gancho se encuentra en que automatiza el proceso de
711 actualizar un fallo cuando un conjunto de cambios se refiera a él. Si
712 usted configura este gancho adecuadamente, hará fácil para la gente
713 navegar directamente desde un fallo Bugzilla a un conjunto de cambios
714 que se refiere a ese fallo.
716 Usted puede usar el código de este gancho como un punto de partida
717 para otras recetas de integración con Bugzilla aún más exóticas. Acá
718 hay algunas posibilidades:
719 \begin{itemize}
720 \item Requerir que cada conjunto de cambios tenga un ID de fallo en su
721 mensaje de consignación. En este caso, usted querrá configurar el
722 gancho como uno de tipo \hook{pretxncommit}. Esto le permitirá al
723 gancho rechazar cambios que no contiene IDs de fallos.
724 \item Permitir a los conjuntos de cambios entrantes modificar
725 automáticamente el \emph{estado} de un fallo, así como simplemente
726 añadir un comentario. Por ejemplo, el gancho podría reconocer la
727 cadena ``corregido fallo 31337'' como la señal de que debería
728 actualizar el estado del fallo 31337 a ``requiere pruebas''.
729 \end{itemize}
731 \subsubsection{Configuración del gancho \hook{bugzilla}}
732 \label{sec:hook:bugzilla:config}
734 Usted debería configurar este gancho en el \hgrc\ de su servidor como
735 un gancho \hook{incoming}\footnote{Entrante.}, por ejemplo como sigue:
736 \begin{codesample2}
737 [hooks]
738 incoming.bugzilla = python:hgext.bugzilla.hook
739 \end{codesample2}
741 Debido a la naturaleza especializada de este gancho, y porque Bugzilla
742 no fue escrito con este tipo de integración en mente, configurar este
743 % TODO involved => complejo ? no intarwebs here :(
744 gancho es un proceso algo complejo.
746 Antes de empezar, usted debe instalar la interfaz de Python para MySQL
747 en los sistemas en los que se vaya a ejecutar el gancho. Si no está
748 disponible como paquete binario para su sistema, usted puede descargar
749 el paquete desde~\cite{web:mysql-python}.
751 La información para configurar este gancho se ubica en la sección
752 \rcsection{bugzilla} de su \hgrc.
753 \begin{itemize}
754 \item[\rcitem{bugzilla}{version}] La versión de Bugzilla instalada en
755 el servidor. El esquema de base de datos que Bugzilla usa cambia
756 ocasionalmente, así que este gancho debe saber exactamente qué
757 esquema usar. A la fecha, la única versión soportada es la
758 \texttt{2.16}.
759 \item[\rcitem{bugzilla}{host}] El nombre de máquina (\emph{hostname})
760 del servidor MySQL que almacena sus datos Bugzilla. La base de datos
761 debe ser configurada para permitir conexiones desde las máquinas en
762 las que usted ejecute el gancho \hook{bugzilla}.
763 \item[\rcitem{bugzilla}{user}] El nombre de usuario que se usará para
764 conectarse al servidor MySQL. La base de datos debe ser configurada
765 para permitir a dicho usuario conectarse desde cualquiera de las
766 máquinas en las que se ejecute el gancho \hook{bugzilla}. Este
767 usuario debe tener acceso y poder modificar las tablas de Bugzilla.
768 El valor por defecto para este ítem es \texttt{bugs}, que es el
769 nombre estándar del usuario para Bugzilla en una base de datos
770 MySQL.
771 \item[\rcitem{bugzilla}{password}] La contraseña MySQL para el usuario
772 configurado anteriormente. Ésta es almacenada como texto plano, así
773 que usted deberá asegurarse de que los usuarios no autorizados no
774 puedan leer el fichero \hgrc\ en donde usted guarda esta
775 información.
776 \item[\rcitem{bugzilla}{db}] El nombre de la base de datos Bugzilla en
777 el servidor MySQL. El nombre por defecto para este ítem es
778 \texttt{bugs}, que es el nombre estándar de la base de datos MySQL
779 en donde Bugzilla almacena sus datos.
780 \item[\rcitem{bugzilla}{notify}] Si usted desea que Bugzilla envíe un
781 %TODO suBscriptores?
782 correo de notificación a los suscriptores después de que el gancho
783 haya añadido un comentario a un fallo, necesitará que este gancho
784 ejecute un comando siempre que actualice la base de datos. El
785 comando que se ejecute depende de en dónde haya sido instalado
786 Bugzilla, pero típicamente se verá así, si usted ha instalado
787 Bugzilla en \dirname{/var/www/html/bugzilla}:
788 \begin{codesample4}
789 cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
790 \end{codesample4}
791 El programa \texttt{processmail} de Bugzilla espera recibir un ID de
792 fallo (el gancho reemplaza ``\texttt{\%s}'' por el ID del fallo) y
793 una dirección de correo. También espera poder escribir a ciertos
794 ficheros en el directorio en que se ejecuta. Si Bugzilla y éste
795 gancho no están instalados en la misma máquina, usted deberá
796 encontrar una manera de ejecutar \texttt{processmail} en el servidor
797 donde está instalado Bugzilla.
798 \end{itemize}
800 \subsubsection{Asociar nombres de consignadores a nombres de usuario
801 Bugzilla}
803 Por defecto, el gancho \hgext{bugzilla} trata de usar la dirección de
804 correo electrónico de la persona que hizo la consignación del conjunto
805 de cambios como el nombre de usuario Bugzilla con el cual debe
806 actualizar el fallo. Si esto no se ajusta a sus necesidades, es
807 posible asociar direcciones de correo a nombres de usuario Bugzilla
808 usando una sección \rcsection{usermap}.
810 Cada ítem en la sección \rcsection{usermap} contiene una dirección de
811 correo electrónico a la izquierda, y un nombre de usuario Bugzilla a
812 la derecha.
813 \begin{codesample2}
814 [usermap]
815 jane.user@example.com = jane
816 \end{codesample2}
817 Usted puede mantener los datos de \rcsection{usermap} en un fichero
818 \hgrc, o decirle al gancho \hgext{bugzilla} que lea la información
819 desde un fichero \filename{usermap} externo. En este caso, usted
820 puede almacenar los datos de \filename{usermap} en (por ejemplo) un
821 repositorio modificable por los usuarios. Esto hace posible para sus
822 usuarios mantener sus propias entradas \rcitem{bugzilla}{usermap}. El
823 fichero \hgrc\ principal se vería así:
824 \begin{codesample2}
825 # fichero hgrc normal se refiere a un fichero usermap externo
826 [bugzilla]
827 usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
828 \end{codesample2}
829 Mientras que el fichero \filename{usermap} al que se hace referencia
830 se vería así:
831 \begin{codesample2}
832 # bugzilla-usermap.conf - dentro de un repositorio hg
833 [usermap]
834 stephanie@example.com = steph
835 \end{codesample2}
837 \subsubsection{Configurar el texto que se añade a un fallo}
839 Usted puede configurar el texto que este gancho añade como comentario;
840 usted los especifica como una plantilla Mercurial. Varias entradas
841 \hgrc\ (aún en la sección \rcsection{bugzilla}) controlan este
842 comportamiento.
843 \begin{itemize}
844 \item[\texttt{strip}] La cantidad de elementos iniciales de ruta a
845 remover de un nombre de ruta del repositorio para construir una ruta
846 parcial para una URL. Por ejemplo, si los repositorios en su
847 servidor se ubican en \dirname{/home/hg/repos}, y usted tiene un
848 repositorio cuya ruta es \dirname{/home/hg/repos/app/tests},
849 entonces fijar \texttt{strip} a \texttt{4} resultará en una ruta
850 parcial de \dirname{app/tests}. El gancho hará disponible esta ruta
851 parcial cuando expanda una plantilla, como \texttt{webroot}.
852 \item[\texttt{template}] El texto de la plantilla a usar. En adición a
853 las variables usuales relacionadas con conjuntos de cambios, esta
854 plantilla puede usar \texttt{hgweb} (el valor del ítem de
855 configuración \texttt{hgweb} de arriba) y \texttt{webroot} (la ruta
856 construida usando \texttt{strip} arriba).
857 \end{itemize}
859 Adicionalmente, usted puede añadir un ítem \rcitem{web}{baseurl} a la
860 sección \rcsection{web} de su \hgrc. El gancho \hgext{bugzilla}
861 publicará esto cuando expanda una plantilla, como la cadena base a
862 usar cuando se construya una URL que le permita a los usuarios navegar
863 desde un comentario de Bugzilla a la vista de un conjunto de cambios.
864 Ejemplo:
865 \begin{codesample2}
866 [web]
867 baseurl = http://hg.domain.com/
868 \end{codesample2}
870 A continuación se presenta un ejemplo completo de configuración para
871 el gancho \hgext{bugzilla}.
872 %TODO traducir?
873 \begin{codesample2}
874 [bugzilla]
875 host = bugzilla.example.com
876 password = mypassword
877 version = 2.16
878 # server-side repos live in /home/hg/repos, so strip 4 leading
879 # separators
880 strip = 4
881 hgweb = http://hg.example.com/
882 usermap = /home/hg/repos/notify/bugzilla.conf
883 template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
884 repo, refers to this bug.\\nFor complete details, see
885 \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
886 description:\\n\\t\{desc|tabindent\}
887 \end{codesample2}
889 \subsubsection{Pruebas y resolución de problemas}
891 Los problemas más comunes que aparecen en la configuración del gancho
892 \hgext{bugzilla} suelen estar relacionados con la ejecución del guión
893 de Bugzilla \filename{processmail} y la asociación de nombres de
894 consignadores a nombres de usuario.
896 Recuerde que en la sección~\ref{sec:hook:bugzilla:config} arriba que
897 el usuario que ejecuta el proceso Mercurial en el servidor es también
898 that runs the Mercurial process on the server is also the one that
899 will run the \filename{processmail} script. The
900 \filename{processmail} script sometimes causes Bugzilla to write to
901 files in its configuration directory, and Bugzilla's configuration
902 files are usually owned by the user that your web server runs under.
904 You can cause \filename{processmail} to be run with the suitable
905 user's identity using the \command{sudo} command. Here is an example
906 entry for a \filename{sudoers} file.
907 \begin{codesample2}
908 hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
909 \end{codesample2}
910 This allows the \texttt{hg\_user} user to run a
911 \filename{processmail-wrapper} program under the identity of
912 \texttt{httpd\_user}.
914 This indirection through a wrapper script is necessary, because
915 \filename{processmail} expects to be run with its current directory
916 set to wherever you installed Bugzilla; you can't specify that kind of
917 constraint in a \filename{sudoers} file. The contents of the wrapper
918 script are simple:
919 \begin{codesample2}
920 #!/bin/sh
921 cd `dirname $0` && ./processmail "$1" nobody@example.com
922 \end{codesample2}
923 It doesn't seem to matter what email address you pass to
924 \filename{processmail}.
926 If your \rcsection{usermap} is not set up correctly, users will see an
927 error message from the \hgext{bugzilla} hook when they push changes
928 to the server. The error message will look like this:
929 \begin{codesample2}
930 cannot find bugzilla user id for john.q.public@example.com
931 \end{codesample2}
932 What this means is that the committer's address,
933 \texttt{john.q.public@example.com}, is not a valid Bugzilla user name,
934 nor does it have an entry in your \rcsection{usermap} that maps it to
935 a valid Bugzilla user name.
937 \subsection{\hgext{notify}---send email notifications}
939 Although Mercurial's built-in web server provides RSS feeds of changes
940 in every repository, many people prefer to receive change
941 notifications via email. The \hgext{notify} hook lets you send out
942 notifications to a set of email addresses whenever changesets arrive
943 that those subscribers are interested in.
945 As with the \hgext{bugzilla} hook, the \hgext{notify} hook is
946 template-driven, so you can customise the contents of the notification
947 messages that it sends.
949 By default, the \hgext{notify} hook includes a diff of every changeset
950 that it sends out; you can limit the size of the diff, or turn this
951 feature off entirely. It is useful for letting subscribers review
952 changes immediately, rather than clicking to follow a URL.
954 \subsubsection{Configuring the \hgext{notify} hook}
956 You can set up the \hgext{notify} hook to send one email message per
957 incoming changeset, or one per incoming group of changesets (all those
958 that arrived in a single pull or push).
959 \begin{codesample2}
960 [hooks]
961 # send one email per group of changes
962 changegroup.notify = python:hgext.notify.hook
963 # send one email per change
964 incoming.notify = python:hgext.notify.hook
965 \end{codesample2}
967 Configuration information for this hook lives in the
968 \rcsection{notify} section of a \hgrc\ file.
969 \begin{itemize}
970 \item[\rcitem{notify}{test}] By default, this hook does not send out
971 email at all; instead, it prints the message that it \emph{would}
972 send. Set this item to \texttt{false} to allow email to be sent.
973 The reason that sending of email is turned off by default is that it
974 takes several tries to configure this extension exactly as you would
975 like, and it would be bad form to spam subscribers with a number of
976 ``broken'' notifications while you debug your configuration.
977 \item[\rcitem{notify}{config}] The path to a configuration file that
978 contains subscription information. This is kept separate from the
979 main \hgrc\ so that you can maintain it in a repository of its own.
980 People can then clone that repository, update their subscriptions,
981 and push the changes back to your server.
982 \item[\rcitem{notify}{strip}] The number of leading path separator
983 characters to strip from a repository's path, when deciding whether
984 a repository has subscribers. For example, if the repositories on
985 your server live in \dirname{/home/hg/repos}, and \hgext{notify} is
986 considering a repository named \dirname{/home/hg/repos/shared/test},
987 setting \rcitem{notify}{strip} to \texttt{4} will cause
988 \hgext{notify} to trim the path it considers down to
989 \dirname{shared/test}, and it will match subscribers against that.
990 \item[\rcitem{notify}{template}] The template text to use when sending
991 messages. This specifies both the contents of the message header
992 and its body.
993 \item[\rcitem{notify}{maxdiff}] The maximum number of lines of diff
994 data to append to the end of a message. If a diff is longer than
995 this, it is truncated. By default, this is set to 300. Set this to
996 \texttt{0} to omit diffs from notification emails.
997 \item[\rcitem{notify}{sources}] A list of sources of changesets to
998 consider. This lets you limit \hgext{notify} to only sending out
999 email about changes that remote users pushed into this repository
1000 via a server, for example. See section~\ref{sec:hook:sources} for
1001 the sources you can specify here.
1002 \end{itemize}
1004 If you set the \rcitem{web}{baseurl} item in the \rcsection{web}
1005 section, you can use it in a template; it will be available as
1006 \texttt{webroot}.
1008 Here is an example set of \hgext{notify} configuration information.
1009 \begin{codesample2}
1010 [notify]
1011 # really send email
1012 test = false
1013 # subscriber data lives in the notify repo
1014 config = /home/hg/repos/notify/notify.conf
1015 # repos live in /home/hg/repos on server, so strip 4 "/" chars
1016 strip = 4
1017 template = X-Hg-Repo: \{webroot\}
1018 Subject: \{webroot\}: \{desc|firstline|strip\}
1019 From: \{author\}
1021 changeset \{node|short\} in \{root\}
1022 details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
1023 description:
1024 \{desc|tabindent|strip\}
1026 [web]
1027 baseurl = http://hg.example.com/
1028 \end{codesample2}
1030 This will produce a message that looks like the following:
1031 \begin{codesample2}
1032 X-Hg-Repo: tests/slave
1033 Subject: tests/slave: Handle error case when slave has no buffers
1034 Date: Wed, 2 Aug 2006 15:25:46 -0700 (PDT)
1036 changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
1037 details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
1038 description:
1039 Handle error case when slave has no buffers
1040 diffs (54 lines):
1042 diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
1043 --- a/include/tests.h Wed Aug 02 15:19:52 2006 -0700
1044 +++ b/include/tests.h Wed Aug 02 15:25:26 2006 -0700
1045 @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
1046 [...snip...]
1047 \end{codesample2}
1049 \subsubsection{Pruebas y resolución de problemas}
1051 No olvide que por defecto, la extensión \hgext{notify} \emph{no
1052 enviará ningún correo electrónico} hasta que usted la configure
1053 explícitamente para hacerlo, fijando el valor de \rcitem{notify}{test}
1054 a \texttt{false}. Hasta que usted haga eso, simplemente se imprimirá
1055 el mensaje que se \emph{enviaría}.
1057 \section{Information for writers of hooks}
1058 \label{sec:hook:ref}
1060 \subsection{In-process hook execution}
1062 An in-process hook is called with arguments of the following form:
1063 \begin{codesample2}
1064 def myhook(ui, repo, **kwargs):
1065 pass
1066 \end{codesample2}
1067 The \texttt{ui} parameter is a \pymodclass{mercurial.ui}{ui} object.
1068 The \texttt{repo} parameter is a
1069 \pymodclass{mercurial.localrepo}{localrepository} object. The
1070 names and values of the \texttt{**kwargs} parameters depend on the
1071 hook being invoked, with the following common features:
1072 \begin{itemize}
1073 \item If a parameter is named \texttt{node} or
1074 \texttt{parent\emph{N}}, it will contain a hexadecimal changeset ID.
1075 The empty string is used to represent ``null changeset ID'' instead
1076 of a string of zeroes.
1077 \item If a parameter is named \texttt{url}, it will contain the URL of
1078 a remote repository, if that can be determined.
1079 \item Boolean-valued parameters are represented as Python
1080 \texttt{bool} objects.
1081 \end{itemize}
1083 An in-process hook is called without a change to the process's working
1084 directory (unlike external hooks, which are run in the root of the
1085 repository). It must not change the process's working directory, or
1086 it will cause any calls it makes into the Mercurial API to fail.
1088 If a hook returns a boolean ``false'' value, it is considered to have
1089 succeeded. If it returns a boolean ``true'' value or raises an
1090 exception, it is considered to have failed. A useful way to think of
1091 the calling convention is ``tell me if you fail''.
1093 Note that changeset IDs are passed into Python hooks as hexadecimal
1094 strings, not the binary hashes that Mercurial's APIs normally use. To
1095 convert a hash from hex to binary, use the
1096 \pymodfunc{mercurial.node}{bin} function.
1098 \subsection{External hook execution}
1100 An external hook is passed to the shell of the user running Mercurial.
1101 Features of that shell, such as variable substitution and command
1102 redirection, are available. The hook is run in the root directory of
1103 the repository (unlike in-process hooks, which are run in the same
1104 directory that Mercurial was run in).
1106 Hook parameters are passed to the hook as environment variables. Each
1107 environment variable's name is converted in upper case and prefixed
1108 with the string ``\texttt{HG\_}''. For example, if the name of a
1109 parameter is ``\texttt{node}'', the name of the environment variable
1110 representing that parameter will be ``\texttt{HG\_NODE}''.
1112 A boolean parameter is represented as the string ``\texttt{1}'' for
1113 ``true'', ``\texttt{0}'' for ``false''. If an environment variable is
1114 named \envar{HG\_NODE}, \envar{HG\_PARENT1} or \envar{HG\_PARENT2}, it
1115 contains a changeset ID represented as a hexadecimal string. The
1116 empty string is used to represent ``null changeset ID'' instead of a
1117 string of zeroes. If an environment variable is named
1118 \envar{HG\_URL}, it will contain the URL of a remote repository, if
1119 that can be determined.
1121 If a hook exits with a status of zero, it is considered to have
1122 succeeded. If it exits with a non-zero status, it is considered to
1123 have failed.
1125 \subsection{Finding out where changesets come from}
1127 A hook that involves the transfer of changesets between a local
1128 repository and another may be able to find out information about the
1129 ``far side''. Mercurial knows \emph{how} changes are being
1130 transferred, and in many cases \emph{where} they are being transferred
1131 to or from.
1133 \subsubsection{Sources of changesets}
1134 \label{sec:hook:sources}
1136 Mercurial will tell a hook what means are, or were, used to transfer
1137 changesets between repositories. This is provided by Mercurial in a
1138 Python parameter named \texttt{source}, or an environment variable named
1139 \envar{HG\_SOURCE}.
1141 \begin{itemize}
1142 \item[\texttt{serve}] Changesets are transferred to or from a remote
1143 repository over http or ssh.
1144 \item[\texttt{pull}] Changesets are being transferred via a pull from
1145 one repository into another.
1146 \item[\texttt{push}] Changesets are being transferred via a push from
1147 one repository into another.
1148 \item[\texttt{bundle}] Changesets are being transferred to or from a
1149 bundle.
1150 \end{itemize}
1152 \subsubsection{Where changes are going---remote repository URLs}
1153 \label{sec:hook:url}
1155 When possible, Mercurial will tell a hook the location of the ``far
1156 side'' of an activity that transfers changeset data between
1157 repositories. This is provided by Mercurial in a Python parameter
1158 named \texttt{url}, or an environment variable named \envar{HG\_URL}.
1160 This information is not always known. If a hook is invoked in a
1161 repository that is being served via http or ssh, Mercurial cannot tell
1162 where the remote repository is, but it may know where the client is
1163 connecting from. In such cases, the URL will take one of the
1164 following forms:
1165 \begin{itemize}
1166 \item \texttt{remote:ssh:\emph{ip-address}}---remote ssh client, at
1167 the given IP address.
1168 \item \texttt{remote:http:\emph{ip-address}}---remote http client, at
1169 the given IP address. If the client is using SSL, this will be of
1170 the form \texttt{remote:https:\emph{ip-address}}.
1171 \item Empty---no information could be discovered about the remote
1172 client.
1173 \end{itemize}
1175 \section{Hook reference}
1177 \subsection{\hook{changegroup}---after remote changesets added}
1178 \label{sec:hook:changegroup}
1180 This hook is run after a group of pre-existing changesets has been
1181 added to the repository, for example via a \hgcmd{pull} or
1182 \hgcmd{unbundle}. This hook is run once per operation that added one
1183 or more changesets. This is in contrast to the \hook{incoming} hook,
1184 which is run once per changeset, regardless of whether the changesets
1185 arrive in a group.
1187 Some possible uses for this hook include kicking off an automated
1188 build or test of the added changesets, updating a bug database, or
1189 notifying subscribers that a repository contains new changes.
1191 Parameters to this hook:
1192 \begin{itemize}
1193 \item[\texttt{node}] A changeset ID. The changeset ID of the first
1194 changeset in the group that was added. All changesets between this
1195 and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
1196 a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
1197 \item[\texttt{source}] A string. The source of these changes. See
1198 section~\ref{sec:hook:sources} for details.
1199 \item[\texttt{url}] A URL. The location of the remote repository, if
1200 known. See section~\ref{sec:hook:url} for more information.
1201 \end{itemize}
1203 See also: \hook{incoming} (section~\ref{sec:hook:incoming}),
1204 \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}),
1205 \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
1207 \subsection{\hook{commit}---after a new changeset is created}
1208 \label{sec:hook:commit}
1210 This hook is run after a new changeset has been created.
1212 Parameters to this hook:
1213 \begin{itemize}
1214 \item[\texttt{node}] A changeset ID. The changeset ID of the newly
1215 committed changeset.
1216 \item[\texttt{parent1}] A changeset ID. The changeset ID of the first
1217 parent of the newly committed changeset.
1218 \item[\texttt{parent2}] A changeset ID. The changeset ID of the second
1219 parent of the newly committed changeset.
1220 \end{itemize}
1222 See also: \hook{precommit} (section~\ref{sec:hook:precommit}),
1223 \hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
1225 \subsection{\hook{incoming}---after one remote changeset is added}
1226 \label{sec:hook:incoming}
1228 This hook is run after a pre-existing changeset has been added to the
1229 repository, for example via a \hgcmd{push}. If a group of changesets
1230 was added in a single operation, this hook is called once for each
1231 added changeset.
1233 You can use this hook for the same purposes as the \hook{changegroup}
1234 hook (section~\ref{sec:hook:changegroup}); it's simply more convenient
1235 sometimes to run a hook once per group of changesets, while other
1236 times it's handier once per changeset.
1238 Parameters to this hook:
1239 \begin{itemize}
1240 \item[\texttt{node}] A changeset ID. The ID of the newly added
1241 changeset.
1242 \item[\texttt{source}] A string. The source of these changes. See
1243 section~\ref{sec:hook:sources} for details.
1244 \item[\texttt{url}] A URL. The location of the remote repository, if
1245 known. See section~\ref{sec:hook:url} for more information.
1246 \end{itemize}
1248 See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}) \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}), \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
1250 \subsection{\hook{outgoing}---after changesets are propagated}
1251 \label{sec:hook:outgoing}
1253 This hook is run after a group of changesets has been propagated out
1254 of this repository, for example by a \hgcmd{push} or \hgcmd{bundle}
1255 command.
1257 One possible use for this hook is to notify administrators that
1258 changes have been pulled.
1260 Parameters to this hook:
1261 \begin{itemize}
1262 \item[\texttt{node}] A changeset ID. The changeset ID of the first
1263 changeset of the group that was sent.
1264 \item[\texttt{source}] A string. The source of the of the operation
1265 (see section~\ref{sec:hook:sources}). If a remote client pulled
1266 changes from this repository, \texttt{source} will be
1267 \texttt{serve}. If the client that obtained changes from this
1268 repository was local, \texttt{source} will be \texttt{bundle},
1269 \texttt{pull}, or \texttt{push}, depending on the operation the
1270 client performed.
1271 \item[\texttt{url}] A URL. The location of the remote repository, if
1272 known. See section~\ref{sec:hook:url} for more information.
1273 \end{itemize}
1275 See also: \hook{preoutgoing} (section~\ref{sec:hook:preoutgoing})
1277 \subsection{\hook{prechangegroup}---before starting to add remote changesets}
1278 \label{sec:hook:prechangegroup}
1280 This controlling hook is run before Mercurial begins to add a group of
1281 changesets from another repository.
1283 This hook does not have any information about the changesets to be
1284 added, because it is run before transmission of those changesets is
1285 allowed to begin. If this hook fails, the changesets will not be
1286 transmitted.
1288 One use for this hook is to prevent external changes from being added
1289 to a repository. For example, you could use this to ``freeze'' a
1290 server-hosted branch temporarily or permanently so that users cannot
1291 push to it, while still allowing a local administrator to modify the
1292 repository.
1294 Parameters to this hook:
1295 \begin{itemize}
1296 \item[\texttt{source}] A string. The source of these changes. See
1297 section~\ref{sec:hook:sources} for details.
1298 \item[\texttt{url}] A URL. The location of the remote repository, if
1299 known. See section~\ref{sec:hook:url} for more information.
1300 \end{itemize}
1302 See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
1303 \hook{incoming} (section~\ref{sec:hook:incoming}), ,
1304 \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
1306 \subsection{\hook{precommit}---before starting to commit a changeset}
1307 \label{sec:hook:precommit}
1309 This hook is run before Mercurial begins to commit a new changeset.
1310 It is run before Mercurial has any of the metadata for the commit,
1311 such as the files to be committed, the commit message, or the commit
1312 date.
1314 One use for this hook is to disable the ability to commit new
1315 changesets, while still allowing incoming changesets. Another is to
1316 run a build or test, and only allow the commit to begin if the build
1317 or test succeeds.
1319 Parameters to this hook:
1320 \begin{itemize}
1321 \item[\texttt{parent1}] A changeset ID. The changeset ID of the first
1322 parent of the working directory.
1323 \item[\texttt{parent2}] A changeset ID. The changeset ID of the second
1324 parent of the working directory.
1325 \end{itemize}
1326 If the commit proceeds, the parents of the working directory will
1327 become the parents of the new changeset.
1329 See also: \hook{commit} (section~\ref{sec:hook:commit}),
1330 \hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
1332 \subsection{\hook{preoutgoing}---before starting to propagate changesets}
1333 \label{sec:hook:preoutgoing}
1335 This hook is invoked before Mercurial knows the identities of the
1336 changesets to be transmitted.
1338 One use for this hook is to prevent changes from being transmitted to
1339 another repository.
1341 Parameters to this hook:
1342 \begin{itemize}
1343 \item[\texttt{source}] A string. The source of the operation that is
1344 attempting to obtain changes from this repository (see
1345 section~\ref{sec:hook:sources}). See the documentation for the
1346 \texttt{source} parameter to the \hook{outgoing} hook, in
1347 section~\ref{sec:hook:outgoing}, for possible values of this
1348 parameter.
1349 \item[\texttt{url}] A URL. The location of the remote repository, if
1350 known. See section~\ref{sec:hook:url} for more information.
1351 \end{itemize}
1353 See also: \hook{outgoing} (section~\ref{sec:hook:outgoing})
1355 \subsection{\hook{pretag}---before tagging a changeset}
1356 \label{sec:hook:pretag}
1358 This controlling hook is run before a tag is created. If the hook
1359 succeeds, creation of the tag proceeds. If the hook fails, the tag is
1360 not created.
1362 Parameters to this hook:
1363 \begin{itemize}
1364 \item[\texttt{local}] A boolean. Whether the tag is local to this
1365 repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
1366 managed by Mercurial (stored in \sfilename{.hgtags}).
1367 \item[\texttt{node}] A changeset ID. The ID of the changeset to be tagged.
1368 \item[\texttt{tag}] A string. The name of the tag to be created.
1369 \end{itemize}
1371 If the tag to be created is revision-controlled, the \hook{precommit}
1372 and \hook{pretxncommit} hooks (sections~\ref{sec:hook:commit}
1373 and~\ref{sec:hook:pretxncommit}) will also be run.
1375 See also: \hook{tag} (section~\ref{sec:hook:tag})
1377 \subsection{\hook{pretxnchangegroup}---before completing addition of
1378 remote changesets}
1379 \label{sec:hook:pretxnchangegroup}
1381 This controlling hook is run before a transaction---that manages the
1382 addition of a group of new changesets from outside the
1383 repository---completes. If the hook succeeds, the transaction
1384 completes, and all of the changesets become permanent within this
1385 repository. If the hook fails, the transaction is rolled back, and
1386 the data for the changesets is erased.
1388 This hook can access the metadata associated with the almost-added
1389 changesets, but it should not do anything permanent with this data.
1390 It must also not modify the working directory.
1392 While this hook is running, if other Mercurial processes access this
1393 repository, they will be able to see the almost-added changesets as if
1394 they are permanent. This may lead to race conditions if you do not
1395 take steps to avoid them.
1397 This hook can be used to automatically vet a group of changesets. If
1398 the hook fails, all of the changesets are ``rejected'' when the
1399 transaction rolls back.
1401 Parameters to this hook:
1402 \begin{itemize}
1403 \item[\texttt{node}] A changeset ID. The changeset ID of the first
1404 changeset in the group that was added. All changesets between this
1405 and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
1406 a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
1407 \item[\texttt{source}] A string. The source of these changes. See
1408 section~\ref{sec:hook:sources} for details.
1409 \item[\texttt{url}] A URL. The location of the remote repository, if
1410 known. See section~\ref{sec:hook:url} for more information.
1411 \end{itemize}
1413 See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
1414 \hook{incoming} (section~\ref{sec:hook:incoming}),
1415 \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup})
1417 \subsection{\hook{pretxncommit}---before completing commit of new changeset}
1418 \label{sec:hook:pretxncommit}
1420 This controlling hook is run before a transaction---that manages a new
1421 commit---completes. If the hook succeeds, the transaction completes
1422 and the changeset becomes permanent within this repository. If the
1423 hook fails, the transaction is rolled back, and the commit data is
1424 erased.
1426 This hook can access the metadata associated with the almost-new
1427 changeset, but it should not do anything permanent with this data. It
1428 must also not modify the working directory.
1430 While this hook is running, if other Mercurial processes access this
1431 repository, they will be able to see the almost-new changeset as if it
1432 is permanent. This may lead to race conditions if you do not take
1433 steps to avoid them.
1435 Parameters to this hook:
1436 \begin{itemize}
1437 \item[\texttt{node}] A changeset ID. The changeset ID of the newly
1438 committed changeset.
1439 \item[\texttt{parent1}] A changeset ID. The changeset ID of the first
1440 parent of the newly committed changeset.
1441 \item[\texttt{parent2}] A changeset ID. The changeset ID of the second
1442 parent of the newly committed changeset.
1443 \end{itemize}
1445 See also: \hook{precommit} (section~\ref{sec:hook:precommit})
1447 \subsection{\hook{preupdate}---before updating or merging working directory}
1448 \label{sec:hook:preupdate}
1450 This controlling hook is run before an update or merge of the working
1451 directory begins. It is run only if Mercurial's normal pre-update
1452 checks determine that the update or merge can proceed. If the hook
1453 succeeds, the update or merge may proceed; if it fails, the update or
1454 merge does not start.
1456 Parameters to this hook:
1457 \begin{itemize}
1458 \item[\texttt{parent1}] A changeset ID. The ID of the parent that the
1459 working directory is to be updated to. If the working directory is
1460 being merged, it will not change this parent.
1461 \item[\texttt{parent2}] A changeset ID. Only set if the working
1462 directory is being merged. The ID of the revision that the working
1463 directory is being merged with.
1464 \end{itemize}
1466 See also: \hook{update} (section~\ref{sec:hook:update})
1468 \subsection{\hook{tag}---after tagging a changeset}
1469 \label{sec:hook:tag}
1471 This hook is run after a tag has been created.
1473 Parameters to this hook:
1474 \begin{itemize}
1475 \item[\texttt{local}] A boolean. Whether the new tag is local to this
1476 repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
1477 managed by Mercurial (stored in \sfilename{.hgtags}).
1478 \item[\texttt{node}] A changeset ID. The ID of the changeset that was
1479 tagged.
1480 \item[\texttt{tag}] A string. The name of the tag that was created.
1481 \end{itemize}
1483 If the created tag is revision-controlled, the \hook{commit} hook
1484 (section~\ref{sec:hook:commit}) is run before this hook.
1486 See also: \hook{pretag} (section~\ref{sec:hook:pretag})
1488 \subsection{\hook{update}---after updating or merging working directory}
1489 \label{sec:hook:update}
1491 This hook is run after an update or merge of the working directory
1492 completes. Since a merge can fail (if the external \command{hgmerge}
1493 command fails to resolve conflicts in a file), this hook communicates
1494 whether the update or merge completed cleanly.
1496 \begin{itemize}
1497 \item[\texttt{error}] A boolean. Indicates whether the update or
1498 merge completed successfully.
1499 \item[\texttt{parent1}] A changeset ID. The ID of the parent that the
1500 working directory was updated to. If the working directory was
1501 merged, it will not have changed this parent.
1502 \item[\texttt{parent2}] A changeset ID. Only set if the working
1503 directory was merged. The ID of the revision that the working
1504 directory was merged with.
1505 \end{itemize}
1507 See also: \hook{preupdate} (section~\ref{sec:hook:preupdate})
1509 %%% Local Variables:
1510 %%% mode: latex
1511 %%% TeX-master: "00book"
1512 %%% End: