]>
Commit | Line | Data |
---|---|---|
84fb5b46 MKG |
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 be passing always | |
190 | be passing all tests. While it is acceptable to break tests in an | |
191 | intermediate commit, a branch which does not pass tests will not be | |
192 | merged. Ideally, commits which fix a bug should also include a testcase | |
193 | which fails 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 |