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