=head1 NAME
Bric::Hacker - A guide for Bricolage hackers.
=head1 VERSION
$LastChangedRevision$
=head1 DATE
$LastChangedDate: 2007-08-09 11:16:38 +0200 (Thu, 09 Aug 2007) $
=head1 DESCRIPTION
This document is designed to provide information useful to Bricolage
developers. If you've got questions about hacking Bricolage that aren't
answered here please post to the Bricolage developer's mailing-list (see
below) and tell us about it.
=head1 MAILING LISTS
Bricolage has a number of mailing-lists that are relevant to developers:
=over 4
=item users@lists.bricolage.cc
Questions, installation problems, bug reports, job and site announcements,
other general discussion. Posts to this list are subscriber-only, because
otherwise we would be inundated with spam. Please subscribe before posting.
Subscribe: L
Archives: L
=item announce@lists.bricolage.cc
Official announcements from the Bricolage team. These are always Cc'd to the
users list, so you need not subscribe to both. Very low traffic. (read-only
except for core developers)
Subscribe: L
Archives: L
=item devel@lists.bricolage.cc
In-depth discussions about new development directions, proposed features,
implementation details. Posts to this list are subscriber-only, because
otherwise we would be inundated with spam. Please subscribe before posting.
Subscribe: L
Archives: L
=item commits@lists.bricolage.cc
Subversion context diffs for all checkins to the Bricolage repository. (read-only).
Subscribe: L
Archives: L
=item bugs@lists.bricolage.cc
Bricolage Bugzilla activity. This list is read-only. To report a bug in
Bricolage, please use our Bugzilla server.
Bugzilla: L
Subscribe: L
Archives: L
=back
=head1 IRC
You can often find folks hanging out and occasionally discussing development
issues on the #bricolage channel on the MagNet IRC network.
=head1 SUBVERSION
If you're developing Bricolage then you should be working with the latest code
from the Bricolage Subversion repository. You can browse the Subversion
repository at L.
Information on connecting to the repository to checkout a working copy is at
L.
=head1 BUG TRACKING
Bricolage has a Bugzilla server dedicated to it:
http://bugs.bricolage.cc/
You should use this system to report bugs in Bricolage. If you're looking for
something to do you can also use the system to find open bugs and fix them. For
more things to do see L.
=begin comment
To generate documentation that features private method documentation, use
Pod::Perldoc from CPAN to generate HTML files:
perldoc -MPod::Simple::HTML -w accept_targets:private lib/Bric.pm
=end comment
=head1 SUBMITTING PATCHES
Patches should be generated using the C command on each of the
files modified, from the root directory. For example, if you made changes to
F and F, you would generate a diff by
running this command from the root of your Subversion checkout:
svn diff lib/Bric/Changes.pod comp/foo.mc > patch.txt
If you created one or more new files in your changes then you'll have to add
them to the patch separately using normal C against C. For
example, if you created the file C then
you would add this to patch.txt with:
diff -u /dev/null inst/upgrade/1.9.1/solve_fermat.pl >> patch.txt
Always create patches using an up-to-date Subversion checkout if possible.
Send your patches to the devel list mentioned above.
=head1 APPLYING PATCHES
Patches created using the method above can be applied using C with the
C<-p0> option from the root of your Subversion checkout:
patch -p0 < patch.txt
Make sure you check the results with C before committing.
=head1 CODING STANDARDS
=head2 Perl
Try to follow the style of the existing Bricolage code. Except where it is
bad, of course. Basically, write in the style you see in most Perl books and
documentation, particularly L.
Although historically the Bricolage code has not enforced whitespace rules,
we now request that you use 4-space indents (2 spaces for continued lines)
and discourage the use of tabs. The following settings for some of the more
popular editors are thus recommended while editing Bricolage source code.
=head3 Emacs
We strongly recommend that you use C while editing Bricolage
sources in Emacs. Grab the latest version from the CPAN, install it, and then
place the following in your C<~/.emacs> file:
(setq-default indent-tabs-mode nil)
(custom-set-variables
'(case-fold-search t)
'(cperl-close-paren-offset -4)
'(cperl-continued-statement-offset 2)
'(cperl-indent-level 4)
'(cperl-indent-parens-as-block t)
'(cperl-tab-always-indent t)
'(indent-tabs-mode nil))
;; let hashes indent normally; I think this requires
;; at least version 4.32 of cperl-mode.el
'(cperl-indent-parens-as-block t)
'(cperl-close-paren-offset -4)
Also, if you'd like to take advantage of the full functionality of
C and have it automatically parse all Perl source files, add these
settings, as well:
(defalias 'perl-mode 'cperl-mode)
(setq auto-mode-alist
(append
'(("\\.\\([pP]\\([Llm]\\|erl\\)\\|al\\|pod\\)\\'" . cperl-mode))
auto-mode-alist))
(setq cperl-hairy t)
(setq interpreter-mode-alist (append interpreter-mode-alist
'(("miniperl" . cperl-mode))))
When editing Bricolage Mason components, C can help. It's Mason mode
will parse Mason component files and use C in HTML spaces and
C in Mason blocks. Grab it from
L, install it, and then add the following to
your C<~/.emacs> file to have it automatically parse your Bricolage Mason
component files:
(add-to-list 'load-path "/usr/local/share/emacs/site-lisp")
(require 'mmm-mode)
(require 'mmm-mason)
(setq mmm-global-mode 'maybe)
(add-to-list 'auto-mode-alist '("/usr/local/bricolage/comp" . sgml-mode))
(mmm-add-mode-ext-class 'sgml-mode "/usr/local/bricolage/comp" 'mason)
And if you need to examine the Mason object files created by Bricolage in
order to chase down bugs and such, you can use the C in those
files by adding this to your C<~/.emacs> file:
(add-to-list 'auto-mode-alist '("/usr/local/bricolage/data/obj" . cperl-mode))
=head3 Vim
Rafael Garcia-Suarez has written a Vim indent macro which (for the most
part) duplicates the behavior of Emacs C. It is now, as of Vim
6.0, included in the Vim distribution and should be found in
C<$VIMRUNTIME/indent/perl>. The easiest way to use it though is to place the
following line in your F<.vimrc> file:
source $VIMRUNTIME/indent.vim
You'll also need to add these lines.
set tabstop=8
set softtabstop=4
set shiftwidth=4
set expandtab
The first three lines make Vim duplicate the behavior of Emacs in creating
the appearance of 4 space tabs with a mix of tabs and spaces. This is
necessary for reading older Bricolage files which were written this way,
and haven't yet been re-tabbed.
The expandtab setting does the Right Thing under the new rules, in that it
doesn't use tabs at all, only spaces.
=head3 SQL
The standard for writing SQL in Bricolage is pretty straight-forward: format
the SQL in 80 columns or less, and use heredocs where possible. For example:
my $sql = "<< END_SQL";
SELECT id, name, description, publish_date, cover_date, current_version,
publish_status, active
FROM story
WHERE id = ?
END_SQL
Also, when writing your queries, please follow the following rules with regard
to table aliases:
=over 4
=item *
Do not alias any table names in queries, unless those table names are longer
than 8 characters, or are referred to in the FROM clause more than once. Under
this rule, for example, "story" and "member" would never be aliased unless
referenced twice.
=item *
For table names over 8 characters, abbreviated aliases are acceptable provided
that they are still long enough to be informative. i.e. "st_cat" instead of
"sc" for "story_category".
=item *
For multiple links to the same table, use an alias which is long enough to be
informative, such as "story2" or "inst_2" for the second reference to "story"
or "story_instance".
=back
The reason for these rules is that single-letter aliases for queries are as
unreadable and unmaintainable as single-letter variables names. You get
halfway down the page, and you can no longer remember to what tables they
refer.
The rules above are actually taken from O'Reilly's "Introduction to PL/SQL
Programming," which has an I chapter on code cleanliness in SQL and
SQL-extension languages.
=head2 OTHER GOOD PRACTICES
Keep subroutines short. Each subroutine should handle one task. For example,
if you have a subroutine C, and getting "foo" requires getting "bar"
and "qux", then make two more subroutines C and C and put
them in the "private functions" section. Also if you duplicate some code in
several subroutines, factor it out into another subroutine. It's easier to
maintain one subroutine than to maintain three.
Limit the width of your code to 80 characters if possible. This makes them
easier to read. Keeping subroutines short helps to meet this goal, as well.
Make enough comments so that someone maintaining your code can understand what
is going on. Comments shouldn't be redundant with the code. They should
explain non-obvious code. Comments can be bad in some cases if code changes
and the corresponding comment is not kept in sync. So keep the comments in
sync!
Use Perl idioms if it is clear and concise, but use them with care.
Implicit variables can be slick, but hard to understand; add a comment
if you use uncommon ones.
Use Mason components only for display, and put business logic into library
modules and callback components. But only for as long as callbacks are in
components! We hope to move them into libraries soon, at which time this rule
will become even more rigid.
For POD, generally you copy/paste it from another module. Recently
we are trying to cut out some of useless things like
C<< BESide Effects:E NONE >>. For a canonical example, see
C.
Avoid magic values, i.e. don't hard-code numbers into code. It tends to become
a maintenance problem if you put the number 1023 throughout a module and then
somewhere else you have 1021; is 1021 related to 1023 (1023 - 2), or is it
just another random number? And what does 1023 mean? Put a constant at the top
of the module and use that, instead.
In the end, just try to follow the existing code style, and take into
consideration any feedback you get from the mailing list when patches are
submitted.
=head1 TESTING
All Bricolage patches should be accompanied by the necessary tests. You are
strongly encouraged to write comprehensive tests that thoroughly test whatever
changes or additions you make to the Bricolage API. You are also strongly
encouraged to write tests for the current API, if you find that adequate tests
have not yet been written (and this is true in a great many places,
unfortunately). Although Bricolage does not yet support UI tests, we take our
API testing seriously, and so should you. Here's what you need to know to
write tests for Bricolage.
Bricolage contains a test suite based on L. The test
classes live in the F directory, and all subclass Bric::Test::Base. If
you're familiar with L, then the syntax for how the
Test::Class-based classes work should be pretty readily apparent. See the
L documentation for details. It's definitely worth a
read. If you haven't used Test::More, its documentation is also a must-read.
Bricolage has two different sets of tests, those run by C and those
run by C. The former are stand-alone tests that don't rely on the
presence of a Bricolage database to be run. They can thus be run before
C. The idea here is that we offer a basic set of tests that can
be run via the standard Perl installation pattern of
perl Makefile.PL
make
make test
make install
The tests run by are intended to be run during development.
They require that a Bricolage database be installed and running. They will
C