|
NameSVN::Notify::Filter - Create output filters for SVN::NotifySynopsispackage SVN::Notify::Filter::Textile; use Text::Textile (); sub log_message { my ($notifier, $lines) = @_; return $lines unless $notify->content_type eq 'text/html'; return [ Text::Textile->new->process( join $/, @$lines ) ]; } DescriptionThis document covers the output filtering capabilities of SVN::Notify. Output filters are simply subroutines that modify content before SVN::Notify outputs it. The idea is to provide a simple interface for anyone to use to change the format of the messages that SVN::Notify creates. Filters are loaded by the "filter" parameter to "new()" or by the "--filter" option to the "svnnotify" command-line program.A Quick ExampleThe most common use for an output filter is to modify the format of log commit messages. Say that your developers write their commit messages in Markdown format, and you'd like it to be reformatted as HTML in the messages sent by SVN::Notify::HTML. To do so, just create a Perl module and put it somewhere in the Perl path. Something like this:package SVN::Notify::Filter::Markdown; use strict; use Text::Markdown (); sub log_message { my ($notifier, $lines) = @_; return $lines unless $notify->content_type eq 'text/html'; return [ Text::Markdown->new->markdown( join $/, @$lines ) ]; } Put this code in a file named SVN/Notify/Filter/Markdown.pm somewhere in your Perl's path. The way that SVN::Notify filters work is that you simply define a subroutine named for what you want to filter. The subroutine's first argument will always be the SVN::Notify object that's generating the notification message, and the second argument will always be the content to be filtered. In this example, we wanted to filter the commit log message, so we just defined a subroutine named "log_message()" and, if the message will be HTML, passed the lines of the commit message to Text::Markdown to format, returning a new array reference. And that's all there is to writing SVN::Notify filters: Define a subroutine, process the second argument, and return a data structure in the same format as that argument (usually an array reference). Now, to use this filter, just use the "--filter" option: svnnotify -p "$1" -r "$2" --handler HTML --filter Markdown SVN::Notify will assume that a filter option without "::" is in the SVN::Notify::Filter name space, and will load it accordingly. If you instead created your filter in some other name space, say "My::Filter::Markdown", then you'd specify the full package name in the "--filter" option: svnnotify -p "$1" -r "$2" --handler HTML --filter My::Filter::Markdown And that's it! The filter modifies the contents of the log message before SVN::Notify::HTML spits it out. The DetailsWriting SVN::Notify filters is easy. The name of each subroutine in a filter module determines what content it filters. The filter subroutines take two arguments: the SVN::Notify object that's creating the notification message, and the content to be filtered. They should return the filtered content in the same data structure as that in which it was passed. This makes it easy to change the output of SVN::Notify without the hassle of subclassing or sending patches to the maintainer.The names of the filter subroutines and the types of their content arguments and return values are as follows, in the order in which they execute: Sub Name | Second Argument -------------+--------------------------------------------------------------- pre_prepare | undef recipients | Array reference of email addresses. from | String with sender address. subject | String with the subject line. post_prepare | undef pre_execute | undef headers | Array reference of individual email headers lines. start_html | An array of lines starting an SVN::Notify::HTML document. css | An array of lines of CSS. Used only by SVN::Notify::HTML. start_body | Array reference of lines at the start of the message body. metadata | Array reference of lines of the metadata part of the message. log_message | Array reference of lines of log message. file_lists | Array reference of lines of file names. The first line will | be the type of change for the list, the next a simple line of | dashes, and each of the rest of the lines a file name. diff | A file handle reference to the diff. end_body | Array reference of lines at the end of the message body. post_execute | undef Note that the data passed to the filters by SVN::Notify subclasses (SVN::Notify::HTML and SVN::Notify::HTML::ColorDiff) may be in a slightly different format than documented here. Consult the documentation for the relevant methods in those classes for details. There are four special filter subroutines that are called at the beginning and at the end of the execution of the "prepare()" and "execute()" methods, named "pre_prepare", "post_prepare", "pre_execute", and "post_execute". No data is passed to them and their return values are ignored, but they are included to enable callbacks at the points at which they execute. If, for example, you wanted to set the value of the "to" attribute before SVN::Notify checks to make sure that there are recipients to whom to send an email, you'd want to do so in a "pre_prepare" filter. The package name of the filter module can be anything you like; just pass it via the "filter" parameter, e.g., "filter => [ 'My::Filter' ]" (or "--filter My::Filter" on the command-line). If, however, it's in the "SVN::Notify::Filter" name space, you can just pass the last bit as the filter name, for example "filter => [ 'NoSpam' ]" (or "--filter NoSpam" on the command-line) for "SVN::Notify::Filter::NoSpam". The first argument to a filter subroutine is always the SVN::Notify object that's generating the message to be delivered. This is so that you can access its attributes for your own nefarious purposes in the filter, as in the first example below. But more importantly -- and more hackerously -- you can add attributes to the SVN::Notify class from your filters. Just call "SVN::Notify->register_attributes" to do so, as in the final example below. below. ExamplesFirst, see the "Synopsis" for an example that converts Textile-formatted log messages to HTML, and "A Quick Example" for a filter that converts a Markdown-formatted log message to HTML. If you format your log messages for Trac, just use the included SVN::Notify::Filter::Trac filter. There is also SVN::Notify::Filter::Markdown on CPAN, and maybe other filters as well.But if you can't find anything that does what you want, here are some examples to get you started writing your own filters:
Contributing FiltersI created the filtering feature of SVN::Notify in the hopes that all those folks who want new features for SVN::Notify will stop asking me for them and instead start writing them themselves. I should have thought to do it a long time ago, because, in truth, about half the features of SVN::Notify could have been implemented as filters (maybe more than half).So by all means write your filters for SVN::Notify. If you've think you've got a really good one, or a filter that others will find useful, please do not send it to me. A better option is to package it up and put it on the CPAN. Go ahead! Take an example from this document, if you want, put it in a module, write a few tests, and upload the distribution. Model your distribution on SVN::Notify::Filter::Markdown, which is already separately distributed on CPAN. Let's create a mini-ecosystem of SVN::Notify filters, all available via CPAN. That way, lots of people can take advantage of them, new "features" can be added on a regular basis, and I don't have to keep adding cruft to SVN::Notify itself! See Also
AuthorDavid E. Wheeler <david@justatheory.com>Copyright and LicenseCopyright (c) 2008-2016 David E. Wheeler. Some Rights Reserved.This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. |