Posted By

noah on 07/03/07


Tagged

regex email css script pattern code text filter utility report optimize jag review pitfalls deprecated


Versions (?)

Examine CSS selectors in JSP files and report on whether they match some patterns


 / Published in: Perl
 

Processe a directory of JSP source files, looks for regex matches, and reports on the number and location of matches. For detecting deprecated attributes in XHTML.

Uses Mail::Outlook to send an email. Requires you to click "ok" each time a notification is sent, but gets around firewalls.

  1. #! /usr/bin/perl -w
  2. use strict;
  3. use Mail::Outlook 'Attach'; #Use Outlook for notification, since port 25 is blocked.
  4.  
  5. =item usage
  6. for MyEcom Redesign:
  7. cd /d X:\storm\main\webapps\neb\src\webapp\WEB-INF\jsp
  8. find \( -name "*jsp" -o -name "*jspf" \) | xargs perl z:\noah\standards\cssSelector\csel.pl
  9.  
  10. for MyDev Redesign:
  11. cd /d X:\storm\nw2.0\webapps\neb\src\webapp\WEB-INF\jsp
  12. find \( -name "*jsp" -o -name "*jspf" \) | xargs perl z:\noah\standards\cssSelector\csel.pl
  13. =cut
  14.  
  15. =item toDo
  16. - do the whole find-pipe-xargs thing inside this script
  17. --- check that we are searching the right directory
  18. - exclude directories or files by regex
  19. - name the output file after today's date
  20. - if there is a previous output file, compare the failure counts in that file to the current failure count; and notify of the difference.
  21. - make verbose command line option
  22. - toggle "send email" from the command line
  23. --- print the email body to STDOUT if not sending email
  24. - with a command line switch, append to or replace the list of "send to" addresses
  25. - optionally generate only ONE list, of all files that failed ANY test
  26. - generate the report in a more readable format, like HTML
  27. =cut
  28.  
  29. #valid Outlook addresses:
  30. my $recipients = "MyDev Redesign Team;nsussman";
  31.  
  32.  
  33. my (%longClass, %digits, %cssPropName, %tooShort, %JSprotocol, %obtrusiveJS);
  34. my $failed = 0;
  35. my $warned = 0;
  36. my $failCount = 0;
  37. my $warnCount = 0;
  38. my $failedLines = 0;
  39. my $warnedLines = 0;
  40. my $fileHasFailed = 0;
  41. my $fileWasWarned = 0;
  42. my $verbose = 1;
  43. my $send_email = 1;
  44. my $outfile = "z:\\Noah\\esCssRefactor\\CSS_best_practices_autoEvaluation.txt";
  45. my $zipped_outfile = "z:\\Noah\\esCssRefactor\\CSS_best_practices_autoEvaluation.zip";
  46. #my appname = "MyEcom Redesign";
  47. my $appname = "MyDev Redesign";
  48.  
  49. checking_files:
  50. foreach my $input_file (@ARGV) {
  51.  
  52. open(FILE, $input_file) or next checking_files;
  53.  
  54. $. = 0;
  55. $fileHasFailed = 0;
  56. $fileWasWarned = 0;
  57.  
  58. while (<FILE>) {
  59. #FAILURE CHECKS
  60. if (m/class=("[^"<]*(fnt|pad|mar|txt|teal|aqua)[^"<]*")/) {
  61. $cssPropName{ $input_file } .= "ln:$.: $1\n ";
  62. $failedLines++ unless ($failed == 1);
  63. $failed = 1;
  64. }
  65. if (m/class=("[^"<]{1,2}(\s+[^"<]+)*")/) {
  66. $tooShort{ $input_file } .= "ln:$.: $1\n ";
  67. $failedLines++ unless ($failed == 1);
  68. $failed = 1;
  69. }
  70.  
  71. if (m/class=("[^"<]*\d\d[^"<]*")/) {
  72. $digits{ $input_file } .= "ln:$.: $1\n ";
  73. $failedLines++ unless ($failed == 1);
  74. $failed = 1;
  75. }
  76. if (m/class=("([^"<]+\s){2,}[^<"]+")/) {
  77. $longClass{ $input_file } .= "ln:$.: $1\n ";
  78. $failedLines++ unless ($failed == 1);
  79. $failed = 1;
  80. }
  81.  
  82. #WARNING CHECKS
  83. if ((m/^\s*(.*javascript:.*)\s*$/) && $warned !=1) {
  84. $JSprotocol{ $input_file } .= "ln:$.: $1\n "; #should trim whitespace when including entire line
  85. $warnedLines++;
  86. $warned = 1;
  87. }
  88.  
  89. if ((m/^\s*(.*\W(onabort|onblur|onchange|onclick|ondblclick|onerror|onfocus|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onresize|onselect|onsubmit|onunload).*)\s*$/i) && $warned !=1) {
  90. $obtrusiveJS{ $input_file } .= "ln:$.: $1\n ";
  91. $warnedLines++;
  92. $warned = 1;
  93. }
  94.  
  95.  
  96. #Keep track of failures
  97. if ($failed == 1) {
  98. if ($fileHasFailed == 0) {
  99. $failCount++;
  100. $fileHasFailed = 1;
  101. }
  102. $failedLines++;
  103. $failed = 0;
  104. }
  105.  
  106. #Keep track of warnings
  107. if ($warned == 1) {
  108. if ($fileWasWarned == 0) {
  109. $warnCount++;
  110. $fileWasWarned = 1;
  111. }
  112. $warnedLines++;
  113. $warned = 0;
  114. }
  115. }
  116. }
  117.  
  118.  
  119. open(OUTFILE, ">$outfile") or die("Couldn't open $outfile\n"); # > before $name opens $name for writing
  120.  
  121.  
  122. my $summary = <<"SUMMARY";
  123.  
  124. $appname automatic report:
  125.  
  126. Spaghetti Code alerts:
  127. Files flagged: $failCount
  128. Lines flagged: $failedLines
  129.  
  130. Deprecation warnings:
  131. Files warned: $warnCount
  132. Lines warned: $warnedLines
  133.  
  134. This validator enforces browser code best practices as developed by the JAG Web 2.0 team.
  135. Note that the validator checks every file in the source directory, so some of the files flagged here may not actually be part of the live app. If you notice superfluous files in the list, please let us know so we can correct the problem.
  136.  
  137. Spaghetti Code alerts (very bad):
  138.  - More than three selectors in one CLASS declaration.
  139.  - Selector names descriptive of CSS properties, for example: 'fnt, pad, teal'
  140.  - Digits (0-9) in a selector name. Currently we think _one_ digit is OK.
  141.  - selectors of less than 3 characters in length.
  142.  
  143. Deprecation warnings (arguably not so bad):
  144.  - "Obtrusive JavaScript". See http://jibbering.com/faq/#FAQ4_24 and http://www.kryogenix.org/code/browser/aqlists/
  145.  --- Use of the "javascript:" protocol.
  146.  --- Some, but not all, uses of inline event handlers (onclick, onload, onmouseover, etc.) instead of event listeners.
  147. SUMMARY
  148.  
  149. print OUTFILE $summary;
  150.  
  151. print OUTFILE "Files that failed to validate are listed below. ";
  152. print OUTFILE "Each file is followed by a list of the lines that were problematic." if ($verbose == 1);
  153. print OUTFILE "\n";
  154.  
  155. print OUTFILE "\n========================\ntoo many selectors in a CLASS declaration:\n";
  156.  
  157. foreach my $key ( keys(%longClass)){
  158. print OUTFILE " $key \n";
  159. if ($verbose == 1) {
  160. print OUTFILE " $longClass{$key}\n";
  161. }
  162. }
  163.  
  164. print OUTFILE "\n========================\nSelector is less than 3 characters long:\n";
  165. foreach my $key ( keys(%tooShort)){
  166. print OUTFILE " $key \n";
  167. if ($verbose == 1) {
  168. print OUTFILE " $tooShort{$key}\n";
  169. }
  170. }
  171.  
  172. print OUTFILE "\n========================\n'mar, pad, teal' or other string that describes a CSS property, in a selector:\n";
  173. foreach my $key ( keys(%cssPropName)){
  174. print OUTFILE " $key \n";
  175. if ($verbose == 1) {
  176. print OUTFILE " $cssPropName{$key}\n";
  177. }
  178. }
  179.  
  180. print OUTFILE "\n========================\ndigits (0-9) in a selector:\n";
  181. foreach my $key ( keys(%digits)){
  182. print OUTFILE " $key \n";
  183. if ($verbose == 1) {
  184. print OUTFILE " $digits{$key}\n";
  185. }
  186. }
  187.  
  188. print OUTFILE "\n|||||||||||||||||||| Only warnings below here |||||||||||||||||||||\n";
  189.  
  190. print OUTFILE "\n||||||||||||||||||||||||\nUses of the \"javascript:\" protocol:\n";
  191. foreach my $key ( keys(%JSprotocol)){
  192. print OUTFILE " $key \n";
  193. if ($verbose == 1) {
  194. print OUTFILE " $JSprotocol{$key}\n";
  195. }
  196. }
  197.  
  198. print OUTFILE "\n||||||||||||||||||||||||\nUses of inline event handlers:\n";
  199. foreach my $key ( keys(%obtrusiveJS)){
  200. print OUTFILE " $key \n";
  201. if ($verbose == 1) {
  202. print OUTFILE " $obtrusiveJS{$key}\n";
  203. }
  204. }
  205.  
  206.  
  207.  
  208.  
  209. #manage notification
  210.  
  211. if ($send_email) {
  212.  
  213. system("rm -r $zipped_outfile") if -e $zipped_outfile;
  214. system("zip -j $zipped_outfile $outfile");
  215.  
  216.  
  217. my $outlook = new Mail::Outlook();
  218. my @attachments;
  219. $attachments[0] = $zipped_outfile;
  220.  
  221. # create a message for sending
  222. my $message = $outlook->create();
  223. $message->To($recipients);
  224. $message->Cc('');
  225. $message->Bcc('');
  226. $message->Subject("$failCount files in $appname are becoming Spaghetti Code.");
  227. $message->Body("$summary\n\nA full report is attached.");
  228. $message->Attach(@attachments);
  229. $message->send;
  230.  
  231. }
  232.  
  233.  
  234. #here are useful greps
  235. #
  236. # CLASS declaration with 3 or more selectors
  237. # grep -niP 'class="([^("<)]+\s){2,}[^(<")]+"' advsearch.jsp
  238. #

Report this snippet  

You need to login to post a comment.