1Perl::Critic::CORE_DEVEULsOePrERC(o3n)tributed Perl DocuPmeernlt:a:tCirointic::CORE_DEVELOPER(3)
2
3
4
6 Perl::Critic::CORE_DEVELOPER - Hints for working on the Perl::Critic
7 core.
8
10 This document is a grab-bag of notes for those who are working on the
11 underpinnings of Perl::Critic. They are intended to be informative, but
12 unfortunately can not really be considered authoritative. It is in the
13 nature of the task being described that the user of this document will
14 end up working out the details for him- or herself based on the actual
15 work being performed. Caveat lector.
16
18 Here are my thoughts on how to get started. Note that the steps are not
19 numbered because I'm not sure there is a clear order to them. The items
20 with two stars in front of them are from the mailing list; the ones
21 with one star are my opinion. Although sometimes I have felt it helpful
22 to comment on the two-star items, just to make things thoroughly
23 unclear.
24
25 * If you're unsure of yourself, install Perl::Critic, then download the
26 source and rummage around in it.
27
28 ** Subscribe to the developers' mailing list. There are instructions in
29 "EXTENDING THE CRITIC" in Perl::Critic. The commits mailing list is
30 another good one.
31
32 ** You will need to be registered as a developer before you can
33 actually change code. <http://perlcritic.tigris.org/> only lets you
34 register as an observer. I got promoted on registration, but if that
35 doesn't happen, a note to the developers' mailing list might help.
36
37 ** If you are working on an RT ticket, you should update the ticket to
38 say that you are, to keep other people from duplicating your effort.
39
40 * I personally would update RT at the point I was reasonably confident
41 I could hack it, just to prevent myself from having to update RT again
42 in a week or so saying "oops, bit off more than I could chew." But
43 that's me talking.
44
45 * Subversion (also known as svn, which is the command name) is a
46 version control system. It provides a repository for the code being
47 worked on. Developers check out the code into a local directory, work
48 on that, and and then commit changes back to the repository. Any
49 previous version of the code is available from the repository - a bad
50 change can be backed out, though the longer the bad change hangs around
51 the harder it may be to deal with.
52
53 * Install Subversion if you don't already have it. You can get it from
54 <http://subversion.tigris.org/>. The current version is Subversion 1.6,
55 but as of mid-2009, the 1.4.4 client seems to be adequate. The O'Reilly
56 book, "Version Control with Subversion", is available online at
57 <http://svnbook.red-bean.com/>. The English version of the 1.4
58 documentation may be still available at
59 <http://svnbook.red-bean.com/en/1.4/index.html>.
60
61 * Branching is essentially pulling off your own managed copy of the
62 code to develop on. It is creating a "sandbox", if you will. You can
63 commit changes back to the repository without affecting the main line
64 of development (the "trunk"). The entire branch can be abandoned
65 without affecting the trunk. The down side of branches is that it is a
66 bit of a pain to merge them back into the trunk.
67
68 Consult the developers' mailing list on whether you should branch or
69 work directly against the trunk.
70
71 ** The Perl Critic subversion repository on Tigris contains a bunch of
72 stuff other than Perl::Critic. You probably do not need it all. But if
73 you execute the 'svn checkout' command given on Tigris you get it all.
74 This is not recommended.
75
76 * Here is my "branch and checkout" cookbook:
77
78 Name the branch after the ticket you are working on (e.g. rt25046).
79 Issue the following commands (we assume '$ ' is your system prompt):
80
81 $ svn copy
82 http://perlcritic.tigris.org/svn/perlcritic/trunk/distributions/Perl-Critic
83 http://perlcritic.tigris.org/svn/perlcritic/branches/rt25046
84 -m "Put your comment here" --username your_username
85
86 $ svn checkout http://perlcritic.tigris.org/svn/perlcritic/branches/rt25046
87 --username your_username
88
89 The 'svn copy' command is the one that does the branch. Each 'svn'
90 command is one line, though sometimes (e.g. the 'branch') it's a huge
91 one. The "svn" commands above have been wrapped. A checkout from the
92 trunk is also done with the "svn checkout" command, but specifying the
93 trunk's URL. You can also specify, as a second argument to "svn
94 checkout", the directory you want the code to go into.
95
96 ** Development requires using Module::Build rather than
97 ExtUtils::MakeMaker. In other words,
98
99 $ perl Build.PL
100 $ ./Build
101 $ ./Build test
102
103 ** You need to run the suite of author tests by running
104
105 $ ./Build authortest
106
107 (but not 'make authortest', which is one of the reasons you should
108 start with Build.PL rather than Makefile.PL) These should run cleanly
109 before you declare your work done. My advice, though, is not to worry
110 about them until your code is functionally correct.
111
112 Modules required for authortest
113 The authortest requires a bunch of modules above and beyond those
114 required to run "Perl::Critic". The list probably depends on which
115 "Perl::Critic" you are testing, so the following should not be
116 considered definitive. You need the following in addition to all
117 optional modules for Perl::Critic itself.
118
119 Devel::EnforceEncapsulation
120 Perl::Critic::More
121 Test::Kwalitee
122 Test::Memory::Cycle
123 Test::Perl::Critic
124 Test::Pod
125 Test::Pod::Coverage
126 Test::Without::Module
127
128 You can find out what the optional modules are by looking at
129 "recommended_module_versions()" in inc/Perl/Critic/BuildUtilities.pm.
130
131 In the absence of "Test::Memory::Cycle", the relevant tests are simply
132 skipped. In the absence of the other modules, the tests die horribly.
133 Of course, either way they do not get run, so the difference is mainly
134 one of aesthetics.
135
136 Under Perl 5.12 and above, Devel::Cycle 1.11 needs to be patched to
137 handle a "Regexp" as a first-class Perl object. See
138 <https://rt.cpan.org/Public/Bug/Display.html?id=56681> for the details.
139
141 Perlcritic handles global configuration items and command line options
142 in very similar ways. These notes will cover adding both a global
143 configuration item and a corresponding, same-named command option.
144 These notes can not, of course, cover implementing the functionality of
145 the new item, just the mechanics of getting the item into Perl::Critic.
146
147 Naming Conventions
148 All names are lower-case, except for the names of constants (if any),
149 which are upper-case. When a name contains multiple words, dashes will
150 be used to separate the words in the configuration item name and the
151 command line option, and underscores will be used in the accessor and
152 attribute value names, and constant names if any.
153
154 For example, if "new item" is being added, the configuration item is
155 "new-item", the command option is "--new-item", the accessors are
156 "new_item()", and the value of the attribute will be stored in
157 "$self->{_new_item}". If there are constants involved, their names will
158 start with "NEW_ITEM_". These names will be used in the following
159 discussion.
160
161 Implementation
162 There are several files that must be modified to get your new
163 configuation item and/or command line option.
164
165 lib/Perl/Critic/Utils/Constants.pm
166
167 If there are manifest constants connected with your implementation they
168 go here. You may well at least have a
169
170 $NEW_ITEM_DEFAULT
171
172 to define. All the constants for your new item must be exported, and
173 should be exported not only individually but all together with export
174 tag
175
176 new_item
177
178 lib/Perl/Critic/Command.pm
179
180 If your new item is a command option, its Getopt::Long specification
181 must be defined in "_get_option_specification()". If your new
182 configuration item does not have a corresponding command option, you do
183 not need to make any changes to this file.
184
185 lib/Perl/Critic/OptionsProcessor.pm
186
187 If your new item is a global configuration item, you need to add the
188 code to handle it here. Specifically:
189
190 You must add code to the "_init()" method to store the value of your
191 item as an attribute value, defaulting it if necessary. Using our
192 naming convention, a single-valued item would be stored like this:
193
194 $self->{_new_item} = dor(delete $args{'new-item'},
195 $NEW_ITEM_DEFAULT);
196
197 If the item has synonyms (e.g. both 'color' and 'colour' meaning the
198 same thing), the "dor()" call must check for all of them. If the item
199 took a list of values, they would be parsed apart and stored as an
200 array reference.
201
202 You must also add and document an accessor for your new item. This
203 would look something like this:
204
205 sub new_item {
206 my ($self) = @_;
207 return $self->{_new_item};
208 }
209
210 In the case of multi-valued items, the accessor must return the array
211 reference, so the above specimen code works in that case also.
212
213 Note that no validation is done here -- this class is simply a bridge
214 between the physical .perlcriticrc file and Perl::Critic::Config, which
215 is where the action is.
216
217 If your new item is a command option without a corresponding global
218 configuration item, you do not need to modify this file.
219
220 lib/Perl/Critic/Config.pm
221
222 You must write a "_validate_and_store_new_item()" method to validate
223 and store the value of the new item. The signature of this method
224 depends on the details of your new item, but it must include at least
225 the value of the item, even if there is no corresponding global
226 configuration item. If it is possible to get validation failures, it
227 will also need an errors object to add the validation exception to.
228 Because the details vary, the best way to proceed is probably to find a
229 method similar to the one you want to write, and implement from there.
230 The "_validate_and_store_top()" method is a reasonable starting point
231 for an item having a single value. The validated value needs to be
232 stored in "$self->{_new_item}".
233
234 You must call "_validate_and_store_new_item()" in the "_init()" method.
235
236 You must write and document an accessor method for the value of the new
237 item. The typical accessor method for a single-valued item is
238
239 sub new_item {
240 my ($self) = @_;
241 return $self->{_new_item};
242 }
243
244 but the accessor for a multi-valued item must return a list:
245
246 sub new_item {
247 my ($self) = @_;
248 return @{ $self->{_new_item} };
249 }
250
251 Last, you must document the item iteself.
252
253 lib/Perl/Critic/ProfilePrototype.pm
254
255 If your new item has a corresponding global configuration item, you
256 must update the "to_string()" method to include the item in the string.
257 Your implementation of the item must be such that the generated string
258 is the same as the input string for the item, except for whitespace.
259
260 If your new item has no corresponding global configuration item, you do
261 not need to change this file.
262
263 bin/perlcriticrc
264
265 If your new item has a corresponding command option, you must document
266 it here. If it does not, you do not need to change this file.
267
268 examples/perlcriticrc
269
270 If your new item has a corresponding global configuration item, you
271 must add it here. If it does not, you do not need to change this file.
272
273 Testing
274 The following test files must be considered for modification:
275
276 t/00_modules.t
277 t/01_config.t
278 t/01_config_bad_perlcritic.t
279 t/04_options_processor.t
280 t/07_command.t
281 t/10_user_profile.t
282 t/16_roundtrip_defaults.t
283
284 Depending on your new item, you may not need to change all of these,
285 but you should at least review them. Depending on what your new item
286 actually does, other test files may need to be modified as well.
287
289 This is something to be done cautiously. The code in question may only
290 exist to serve Perl::Critic, but if it is documented as public it may
291 well be in use "in the wild", either in add-ons to Perl::Critic or by
292 users of Perl::Critic.
293
294 Before deprecating public code, the potential deprecator must discuss
295 the issues on the Perl::Critic developers' mailing list. There are
296 instructions on how to subscribe to this list in "EXTENDING THE CRITIC"
297 in Perl::Critic.
298
299 Once agreement is reached, the technical details of the deprecation are
300 fairly simple.
301
302 You must insert something like the following in the code to be
303 deprecated:
304
305 warnings::warnif(
306 'deprecated',
307 'Perl::Critic::Utils::foo() deprecated, use blah::foo() instead.',
308 );
309
310 You should have the deprecated subroutine delegate its functionality to
311 the new subroutine, if that is practical (it may not be).
312
313 You must update the documentation to say that the old code is
314 deprecated, and what the replacement is.
315
316 After the old code has been deprecated for a couple production
317 releases, it can be removed.
318
320 Thomas R. Wyant, III wyant at cpan dot org
321
323 Copyright (c) 2009-2011 Thomas R. Wyant, III
324
325 This program is free software; you can redistribute it and/or modify it
326 under the same terms as Perl itself. The full text of this license can
327 be found in the LICENSE file included with this module.
328
329
330
331perl v5.16.3 2014-06-09 Perl::Critic::CORE_DEVELOPER(3)