Merge branch 'patch-8' of https://github.com/gjones2/Freeside (#13854 as this bug...
[freeside.git] / rt / docs / hacking.pod
1 =head1 Development of RT
2
3 RT's source code is stored in a C<git> repository.  If you are not
4 familiar with git, see L</git quickstart>, below, for a short tutorial
5 which will give you enough information to get started submitting patches
6 to RT.
7
8 The rest of this document details conventions and tips surrounding the
9 organization of RT's version control, source code conventions, and how
10 to submit patches.
11
12
13
14 =head1 Organization of rt.git
15
16 The RT source repository is available via git from GitHub; you can
17 browse it at L<http://github.com/bestpractical/rt/> or obtain a local
18 copy via:
19
20     git clone git://github.com/bestpractical/rt.git
21
22 The bleeding-edge development happens in the C<master> branch.  When a
23 major release is anticipated, a "trunk" branch will be branched from
24 this -- for example, C<4.0-trunk>.  This will allow the trunk to
25 stabilize while feature development continues on C<master>.
26 Additionally, as a release is impending for a particular series, a
27 release engineering branch will be created, named, for example
28 C<4.0.0-releng>.
29
30 New feature development should always be based off of the C<master>
31 branch.  Branches to fix bugs should be based off of whichever trunk the
32 bug was first found in.  If you found the bug in your RT 4.0.0 install,
33 you'd branch from 4.0-trunk.
34
35 Branches should be named based on the trunk they are branched
36 from -- which is to say, the earliest branch they might be merged into.
37 For example, a bugfix branched from C<4.0-trunk> might be named
38 C<4.0/fail-taint-mode-early>.  A feature branched from C<master> when
39 there exists a C<4.0-trunk> but no C<4.2-trunk> might be named
40 C<4.2/rename-LogToScreen>.  For consistency, branches should use dashes,
41 not underscores, to separate words.
42
43 Branches should be reviewed by another developer before being merged.
44 Reviewers should make sure that the branch accomplishes what it claims
45 to, and does not introduce any unwanted behavior in doing so.  Commit
46 messages explain the B<why> as much as the B<what> of each commit, and
47 not include extranous changes.
48
49
50 =head1 Code conventions
51
52 The RT codebase is more than ten years old; as such, there are sections
53 which do not (yet) conform to the guidelines below.  Please attempt to
54 follow the guidelines, even if the code surrounding your changes does
55 not yet.
56
57 RT also includes a F<.perltidyrc> in its top-level which encodes many of
58 the conventions.
59
60 =over
61
62 =item Indentation
63
64 Each level of indentation should be four spaces; tabs should never be
65 used for indentation.
66
67 =back
68
69 =head1 Internationalization
70
71 RT has been translated into several dozen languages. We use Launchpad
72 ( https://translations.launchpad.net/rt ) to crowdsource our
73 translations into C<po> files. RT uses L<Locale::Maketext> to
74 localize its user interface.
75
76 Your first stop on this magical journey of internationalization
77 is L<Locale::Maketext::TPJ13>, which explains the whys of
78 L<Locale::Maketext>. RT uses most of the features developed in that
79 article.
80
81 Strings that are displayed to users should be passed through the
82 C<loc("...")> function or the C<< <&|/l&>...</&> >> Mason template.
83 C<loc> and C</l> both take parameters, which are used in place of
84 string interpolation (much like C<sprintf>). It's acceptable to use
85 HTML in C</l> calls, especially for bold and emphasis. However, you
86 should limit the amount of HTML that translators must keep exactly
87 correct, which means avoid including tags that wrap the entire
88 translatable string, especially C<< <p> >>.
89
90     <p><&|/l, $button &>Do <em>not</em> click [_1]</&></p> # ok
91
92     <&|/l, $button &><p>Do <em>not</em> click [_1]</p></&> # not ok
93
94 In a few places in RT we also pass HTML as parameters to C<loc()>
95 so that translators do not have to reproduce it exactly, and we can
96 also change it more freely. For example:
97
98     <&|/l,
99         '<a href="http://www.gnu.org/licenses/gpl-2.0.html">',
100         '</a>',
101     &>Distributed under [_1]version 2 of the GNU GPL[_2].</&>
102
103 F<devel/tools/extract-message-catalog> looks for C<loc("...")> and
104 C<< <&|/l&>...</&> >> in our source code to pick out translatable
105 strings, clean them up, and put them into F<share/po> files. We use
106 our C<.po> files not only to populate L<Locale::Maketext>'s lexicons,
107 but also to sync new translatable strings and translations with
108 Launchpad. This Launchpad sync is typically done early during the
109 freeze of RC releases to give our volunteer translators time to
110 translate all the new strings which, because of the RC freeze, won't
111 continue changing.
112
113 Because C<loc()> and C</l> are used to generate strings for human
114 eyes, they generally must be used "close to the browser". These are
115 directly in Mason templates, or in functions that return text that
116 will be passed through Mason. However, in many places in RT we have
117 hardcoded strings which need translations. For example, the C<$RIGHTS>
118 hash in F<lib/RT/Queue.pm> maps rights' names (which must be
119 translatable) to their descriptions (which also must be translatable).
120 However, when we're declaring such structures, we do not want to
121 translate them straight away. RT uses English internally, including
122 in its web forms, so we do not want to localize rights' names except
123 for display, otherwise things might break weirdly when you check
124 if a user has the "Superusuario" right. Furthermore, when we're
125 declaring such data structures at compile time, there is no current
126 user to select which language to use for localization. Thus, we
127 cannot call C<loc()> when declaring C<$RIGHTS> and other similar
128 places.
129
130 For this reason, F<devel/tools/extract-message-catalog> lets you
131 denote translatable strings with comments. That's what the C<#loc_pair>
132 comments in the C<$RIGHTS> hash in F<lib/RT/Queue.pm> indicate.
133 Since we have those comments, our toolchain will put the rights'
134 names and descriptions into F<share/po> files, which enables
135 translation by our lovely volunteers. Later on, when RT displays
136 information about rights in the web UI, we'll pass the right's name
137 through C<loc>, and L<Locale::Maketext> will then be able to find
138 our "Superusuario". So although we never used a literal
139 C<loc("SuperUser")>, we still get its effects thanks to the
140 C<#loc_pair> comments and using C<loc($RightName)>.
141
142 C<#loc_pair> is used for declaring that the both the key and value
143 of a particular C<< key => value >> pair are translatable. There
144 are other markers that you can use.
145
146 C<#loc> is used for declaring that a particular string is translatable.
147 Its parsing is pretty strict so you can use it to declare that only
148 the value of a particular C<< key => value >> pair is translatable.
149
150 C<#loc_left_pair> is used for declaring that the I<key> of a
151 particular C<< key => value >> pair is translatable. This is of
152 very limited usefulness.
153
154 C<#loc_right_pair> does NOT exist. C<#loc> works in such cases since
155 its parser does not extend beyond the string at the end of a line.
156
157 =head1 Development tips
158
159 =head2 Setting up a development environment
160
161 =head2 Test suite
162
163 RT also comes with a fairly complete test suite.  To run it, you will
164 need to set environment variables to a database user and password which
165 can create and drop databases:
166
167     export RT_DBA_USER=root
168     export RT_DBA_PASSWORD=
169
170 You'll need to configure RT and make sure you have all the dependencies
171 before running tests.  To do this in place without installing:
172
173     ./configure.ac --with-my-user-group --enable-layout=inplace --with-devel-mode
174     make testdeps
175     make fixdeps
176
177 Adjust the relevant database options as necessary if you want to test on
178 Postgres, Oracle, or SQLite.  The default is MySQL.
179
180 To run the test suite:
181
182     make test
183
184 If you have multiple processors, you can run the test suite in parallel,
185 which will be significantly faster:
186
187     make test-parallel
188
189 The C<*-trunk> and C<master> branches are expected to always be passing
190 all tests.  While it is acceptable to break tests in an intermediate
191 commit, a branch which does not pass tests will not be merged.  Ideally,
192 commits which fix a bug should also include a testcase which fails
193 before the fix and succeeds after.
194
195
196
197 =head1 git quickstart
198
199 =over
200
201 =item 1.
202
203 You will first need to obtain a copy of git; this is accomplished via
204 C<sudo yum install git> in RedHat and derivatives, or C<sudo apt-get
205 install git> for Debian or Ubuntu.
206
207 =item 2.
208
209 Next, obtain a copy of the RT source from git:
210
211     git clone git://github.com/bestpractical/rt.git
212     cd rt
213
214 =item 3.
215
216 Configure git to know your name and email address; git uses these when
217 it makes commits.
218
219     git config user.email your.email@example.com
220     git config user.name Examp L. Name
221
222 =item 4.
223
224 Switch to the appropriate point to base your work on; this is generally
225 C<origin/> followed by the major version, followed by C<-trunk>.  For
226 example, if your bug was observed in version 3.8.9, you would choose
227 C<origin/3.8-trunk>; if it was in 4.0.0, you would choose
228 C<origin/4.0-trunk>.  New features should be based on C<origin/master>.
229
230     git checkout --track origin/4.0-trunk
231
232 =item 5.
233
234 Give your branch a name based on what you are attempting to accomplish.
235 We suggest that branch names be lower-case and separate words with
236 dashes, but this branch name is purely for your own reference.
237
238     git branch -m gnupg-encryption
239
240 =item 6.
241
242 Edit the source tree to make your changes.  A few commands you may find
243 useful in doing so are listed below.
244
245 To see what files you have changed:
246
247     git status
248
249 To see a line-by-line list of changes:
250
251     git diff
252
253 To revert a file to the original version:
254
255     git checkout path/to/file
256
257 To revert only individual parts of a file:
258
259     git checkout -p path/to/file
260
261 See L</Development tips> for more tips for working with the RT codebase.
262
263 =item 7.
264
265 Check that you have no extraneous changes using C<git diff>, then commit
266 your changes:
267
268     git commit -a
269
270 You will be prompted to type your commit message.  The first line should
271 be a short (E<lt> 80 character) summary of the changes, followed by a
272 blank line, followed by a longer description, if necessary.  The commit
273 message should not simply restate the diff of which lines were added and
274 subtracted, but should rather explain B<what> those changes accomplish,
275 and B<why> they are desired.
276
277 If your changes are easily split into multiple components, you may wish
278 to split your changes into more than one commit; simply return to step 6
279 and repeat the with the next related change.  If your changes are B<not>
280 related to each other, you should submit them separately; finish step 9,
281 then start over from step 4.
282
283 =item 8.
284
285 Save your commits to patch files:
286
287     git format-patch @{u}
288
289 This will print out the names of the files as it creates them.
290
291 =item 9.
292
293 Attach these files to an email using your standard email client, and
294 send it to C<rt-devel@bestpractical.com>.
295
296 =back
297
298 If you have another bug or feature to implement, simply restart the
299 process at step 4.
300
301 =cut