diff options
Diffstat (limited to 'rt/docs/hacking.pod')
-rw-r--r-- | rt/docs/hacking.pod | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/rt/docs/hacking.pod b/rt/docs/hacking.pod new file mode 100644 index 000000000..8aa84fd01 --- /dev/null +++ b/rt/docs/hacking.pod @@ -0,0 +1,301 @@ +=head1 Development of RT + +RT's source code is stored in a C<git> repository. If you are not +familiar with git, see L</git quickstart>, below, for a short tutorial +which will give you enough information to get started submitting patches +to RT. + +The rest of this document details conventions and tips surrounding the +organization of RT's version control, source code conventions, and how +to submit patches. + + + +=head1 Organization of rt.git + +The RT source repository is available via git from GitHub; you can +browse it at L<http://github.com/bestpractical/rt/> or obtain a local +copy via: + + git clone git://github.com/bestpractical/rt.git + +The bleeding-edge development happens in the C<master> branch. When a +major release is anticipated, a "trunk" branch will be branched from +this -- for example, C<4.0-trunk>. This will allow the trunk to +stabilize while feature development continues on C<master>. +Additionally, as a release is impending for a particular series, a +release engineering branch will be created, named, for example +C<4.0.0-releng>. + +New feature development should always be based off of the C<master> +branch. Branches to fix bugs should be based off of whichever trunk the +bug was first found in. If you found the bug in your RT 4.0.0 install, +you'd branch from 4.0-trunk. + +Branches should be named based on the trunk they are branched +from -- which is to say, the earliest branch they might be merged into. +For example, a bugfix branched from C<4.0-trunk> might be named +C<4.0/fail-taint-mode-early>. A feature branched from C<master> when +there exists a C<4.0-trunk> but no C<4.2-trunk> might be named +C<4.2/rename-LogToScreen>. For consistency, branches should use dashes, +not underscores, to separate words. + +Branches should be reviewed by another developer before being merged. +Reviewers should make sure that the branch accomplishes what it claims +to, and does not introduce any unwanted behavior in doing so. Commit +messages explain the B<why> as much as the B<what> of each commit, and +not include extranous changes. + + +=head1 Code conventions + +The RT codebase is more than ten years old; as such, there are sections +which do not (yet) conform to the guidelines below. Please attempt to +follow the guidelines, even if the code surrounding your changes does +not yet. + +RT also includes a F<.perltidyrc> in its top-level which encodes many of +the conventions. + +=over + +=item Indentation + +Each level of indentation should be four spaces; tabs should never be +used for indentation. + +=back + +=head1 Internationalization + +RT has been translated into several dozen languages. We use Launchpad +( https://translations.launchpad.net/rt ) to crowdsource our +translations into C<po> files. RT uses L<Locale::Maketext> to +localize its user interface. + +Your first stop on this magical journey of internationalization +is L<Locale::Maketext::TPJ13>, which explains the whys of +L<Locale::Maketext>. RT uses most of the features developed in that +article. + +Strings that are displayed to users should be passed through the +C<loc("...")> function or the C<< <&|/l&>...</&> >> Mason template. +C<loc> and C</l> both take parameters, which are used in place of +string interpolation (much like C<sprintf>). It's acceptable to use +HTML in C</l> calls, especially for bold and emphasis. However, you +should limit the amount of HTML that translators must keep exactly +correct, which means avoid including tags that wrap the entire +translatable string, especially C<< <p> >>. + + <p><&|/l, $button &>Do <em>not</em> click [_1]</&></p> # ok + + <&|/l, $button &><p>Do <em>not</em> click [_1]</p></&> # not ok + +In a few places in RT we also pass HTML as parameters to C<loc()> +so that translators do not have to reproduce it exactly, and we can +also change it more freely. For example: + + <&|/l, + '<a href="http://www.gnu.org/licenses/gpl-2.0.html">', + '</a>', + &>Distributed under [_1]version 2 of the GNU GPL[_2].</&> + +F<devel/tools/extract-message-catalog> looks for C<loc("...")> and +C<< <&|/l&>...</&> >> in our source code to pick out translatable +strings, clean them up, and put them into F<share/po> files. We use +our C<.po> files not only to populate L<Locale::Maketext>'s lexicons, +but also to sync new translatable strings and translations with +Launchpad. This Launchpad sync is typically done early during the +freeze of RC releases to give our volunteer translators time to +translate all the new strings which, because of the RC freeze, won't +continue changing. + +Because C<loc()> and C</l> are used to generate strings for human +eyes, they generally must be used "close to the browser". These are +directly in Mason templates, or in functions that return text that +will be passed through Mason. However, in many places in RT we have +hardcoded strings which need translations. For example, the C<$RIGHTS> +hash in F<lib/RT/Queue.pm> maps rights' names (which must be +translatable) to their descriptions (which also must be translatable). +However, when we're declaring such structures, we do not want to +translate them straight away. RT uses English internally, including +in its web forms, so we do not want to localize rights' names except +for display, otherwise things might break weirdly when you check +if a user has the "Superusuario" right. Furthermore, when we're +declaring such data structures at compile time, there is no current +user to select which language to use for localization. Thus, we +cannot call C<loc()> when declaring C<$RIGHTS> and other similar +places. + +For this reason, F<devel/tools/extract-message-catalog> lets you +denote translatable strings with comments. That's what the C<#loc_pair> +comments in the C<$RIGHTS> hash in F<lib/RT/Queue.pm> indicate. +Since we have those comments, our toolchain will put the rights' +names and descriptions into F<share/po> files, which enables +translation by our lovely volunteers. Later on, when RT displays +information about rights in the web UI, we'll pass the right's name +through C<loc>, and L<Locale::Maketext> will then be able to find +our "Superusuario". So although we never used a literal +C<loc("SuperUser")>, we still get its effects thanks to the +C<#loc_pair> comments and using C<loc($RightName)>. + +C<#loc_pair> is used for declaring that the both the key and value +of a particular C<< key => value >> pair are translatable. There +are other markers that you can use. + +C<#loc> is used for declaring that a particular string is translatable. +Its parsing is pretty strict so you can use it to declare that only +the value of a particular C<< key => value >> pair is translatable. + +C<#loc_left_pair> is used for declaring that the I<key> of a +particular C<< key => value >> pair is translatable. This is of +very limited usefulness. + +C<#loc_right_pair> does NOT exist. C<#loc> works in such cases since +its parser does not extend beyond the string at the end of a line. + +=head1 Development tips + +=head2 Setting up a development environment + +=head2 Test suite + +RT also comes with a fairly complete test suite. To run it, you will +need to set environment variables to a database user and password which +can create and drop databases: + + export RT_DBA_USER=root + export RT_DBA_PASSWORD= + +You'll need to configure RT and make sure you have all the dependencies +before running tests. To do this in place without installing: + + ./configure.ac --with-my-user-group --enable-layout=inplace --with-devel-mode + make testdeps + make fixdeps + +Adjust the relevant database options as necessary if you want to test on +Postgres, Oracle, or SQLite. The default is MySQL. + +To run the test suite: + + make test + +If you have multiple processors, you can run the test suite in parallel, +which will be significantly faster: + + make test-parallel + +The C<*-trunk> and C<master> branches are expected to be passing always +be passing all tests. While it is acceptable to break tests in an +intermediate commit, a branch which does not pass tests will not be +merged. Ideally, commits which fix a bug should also include a testcase +which fails before the fix and succeeds after. + + + +=head1 git quickstart + +=over + +=item 1. + +You will first need to obtain a copy of git; this is accomplished via +C<sudo yum install git> in RedHat and derivatives, or C<sudo apt-get +install git> for Debian or Ubuntu. + +=item 2. + +Next, obtain a copy of the RT source from git: + + git clone git://github.com/bestpractical/rt.git + cd rt + +=item 3. + +Configure git to know your name and email address; git uses these when +it makes commits. + + git config user.email your.email@example.com + git config user.name Examp L. Name + +=item 4. + +Switch to the appropriate point to base your work on; this is generally +C<origin/> followed by the major version, followed by C<-trunk>. For +example, if your bug was observed in version 3.8.9, you would choose +C<origin/3.8-trunk>; if it was in 4.0.0, you would choose +C<origin/4.0-trunk>. New features should be based on C<origin/master>. + + git checkout --track origin/4.0-trunk + +=item 5. + +Give your branch a name based on what you are attempting to accomplish. +We suggest that branch names be lower-case and separate words with +dashes, but this branch name is purely for your own reference. + + git branch -m gnupg-encryption + +=item 6. + +Edit the source tree to make your changes. A few commands you may find +useful in doing so are listed below. + +To see what files you have changed: + + git status + +To see a line-by-line list of changes: + + git diff + +To revert a file to the original version: + + git checkout path/to/file + +To revert only individual parts of a file: + + git checkout -p path/to/file + +See L</Development tips> for more tips for working with the RT codebase. + +=item 7. + +Check that you have no extraneous changes using C<git diff>, then commit +your changes: + + git commit -a + +You will be prompted to type your commit message. The first line should +be a short (E<lt> 80 character) summary of the changes, followed by a +blank line, followed by a longer description, if necessary. The commit +message should not simply restate the diff of which lines were added and +subtracted, but should rather explain B<what> those changes accomplish, +and B<why> they are desired. + +If your changes are easily split into multiple components, you may wish +to split your changes into more than one commit; simply return to step 6 +and repeat the with the next related change. If your changes are B<not> +related to each other, you should submit them separately; finish step 9, +then start over from step 4. + +=item 8. + +Save your commits to patch files: + + git format-patch @{u} + +This will print out the names of the files as it creates them. + +=item 9. + +Attach these files to an email using your standard email client, and +send it to C<rt-devel@bestpractical.com>. + +=back + +If you have another bug or feature to implement, simply restart the +process at step 4. + +=cut |