diff en/hook.tex @ 37:9fd0c59b009a

Add to hook chapter. Document each macro in 99defs.tex.
author Bryan O'Sullivan <bos@serpentine.com>
date Mon, 17 Jul 2006 00:01:01 -0700
parents c0979ed1eabd
children b49a7dd4e564
line wrap: on
line diff
--- a/en/hook.tex	Mon Jul 17 00:00:12 2006 -0700
+++ b/en/hook.tex	Mon Jul 17 00:01:01 2006 -0700
@@ -95,11 +95,18 @@
 comment contains a bug ID.  If it does, the commit can complete.  If
 not, the commit is rolled back.
 
-\section{Choosing how to write a hook}
-\label{sec:hook:impl}
+\section{Writing your own hooks}
+
+When you are writing a hook, you might find it useful to run Mercurial
+either with the \hggopt{-v} option, or the \rcitem{ui}{verbose} config
+item set to ``true''.  When you do so, Mercurial will print a message
+before it calls each hook.
+
+\subsection{Choosing how your hook should run}
+\label{sec:hook:lang}
 
 You can write a hook either as a normal program---typically a shell
-script---or as a Python function that is called within the Mercurial
+script---or as a Python function that is executed within the Mercurial
 process.
 
 Writing a hook as an external program has the advantage that it
@@ -119,7 +126,7 @@
 performance (probably the majority of hooks), a shell script is
 perfectly fine.
 
-\section{Hook parameters}
+\subsection{Hook parameters}
 \label{sec:hook:param}
 
 Mercurial calls each hook with a set of well-defined parameters.  In
@@ -128,9 +135,82 @@
 environment variable.
 
 Whether your hook is written in Python or as a shell script, the
-parameter names and values will be the same.  A boolean parameter will
-be represented as a boolean value in Python, but as the number 1 (for
-``true'') or 0 (for ``false'')
+hook-specific parameter names and values will be the same.  A boolean
+parameter will be represented as a boolean value in Python, but as the
+number 1 (for ``true'') or 0 (for ``false'') as an environment
+variable for an external hook.  If a hook parameter is named
+\texttt{foo}, the keyword argument for a Python hook will also be
+named \texttt{foo} Python, while the environment variable for an
+external hook will be named \texttt{HG\_FOO}.
+
+\subsection{Hook return values and activity control}
+
+A hook that executes successfully must exit with a status of zero if
+external, or return boolean ``false'' if in-process.  Failure is
+indicated with a non-zero exit status from an external hook, or an
+in-process hook returning boolean ``true''.  If an in-process hook
+raises an exception, the hook is considered to have failed.
+
+For a hook that controls whether an activity can proceed, zero/false
+means ``allow'', while non-zero/true/exception means ``deny''.
+
+\subsection{Writing an external hook}
+
+When you define an external hook in your \hgrc\ and the hook is run,
+its value is passed to your shell, which interprets it.  This means
+that you can use normal shell constructs in the body of the hook.
+
+An executable hook is always run with its current directory set to a
+repository's root directory.
+
+Each hook parameter is passed in as an environment variable; the name
+is upper-cased, and prefixed with the string ``\texttt{HG\_}''.
+
+With the exception of hook parameters, Mercurial does not set or
+modify any environment variables when running a hook.  This is useful
+to remember if you are writing a site-wide hook that may be run by a
+number of different users with differing environment variables set.
+In multi-user situations, you should not rely on environment variables
+being set to the values you have in your environment when testing the
+hook.
+
+\subsection{Telling Mercurial to use an in-process hook}
+
+The \hgrc\ syntax for defining an in-process hook is slightly
+different than for an executable hook.  The value of the hook must
+start with the text ``\texttt{python:}'', and continue with the
+fully-qualified name of a callable object to use as the hook's value.
+
+The module in which a hook lives is automatically imported when a hook
+is run.  So long as you have the module name and \envar{PYTHONPATH}
+right, it should ``just work''.
+
+The following \hgrc\ example snippet illustrates the syntax and
+meaning of the notions we just described.
+\begin{codesample2}
+  [hooks]
+  commit.example = python:mymodule.submodule.myhook
+\end{codesample2}
+When Mercurial runs the \texttt{commit.example} hook, it imports
+\texttt{mymodule.submodule}, looks for the callable object named
+\texttt{myhook}, and calls it.
+
+\subsection{Writing an in-process hook}
+
+The simplest in-process hook does nothing, but illustrates the basic
+shape of the hook API:
+\begin{codesample2}
+  def myhook(ui, repo, **kwargs):
+      pass
+\end{codesample2}
+The first argument to a Python hook is always a
+\pymodclass{mercurial.ui}{ui} object.  The second is a repository object;
+at the moment, it is always an instance of
+\pymodclass{mercurial.localrepo}{localrepository}.  Following these two
+arguments are other keyword arguments.  Which ones are passed in
+depends on the hook being called, but a hook can ignore arguments it
+doesn't care about by dropping them into a keyword argument dict, as
+with \texttt{**kwargs} above.
 
 
 %%% Local Variables: