pre-commit 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #!/usr/bin/perl
  2. # $Id: commandref_join.pl 5361 2014-03-29 06:24:20Z rudolfkoenig $
  3. use strict;
  4. use warnings;
  5. sub err($$);
  6. my $svnlook='/usr/bin/svnlook';
  7. my $repos=$ARGV[0];
  8. my $txn=$ARGV[1];
  9. my $arg="-t $txn";
  10. #my $arg="-r $txn"; # local testing
  11. my @lang = ("EN", "DE");
  12. my $exitCode = 0;
  13. use constant TAGS => qw{ul li code b i u td tr table div};
  14. my $log = `$svnlook log $arg $repos`;
  15. if($log !~ m/^.*:.*$/s) {
  16. print STDERR << 'EOF';
  17. A FHEM SVN comment must have the following format
  18. module: text-describing-the-change
  19. or
  20. module: text-describing-the-change (Forum #<forum.fhem.de threadnumber>)
  21. EOF
  22. exit(1);
  23. }
  24. my $fList = `$svnlook changed $arg $repos`;
  25. foreach my $row (split("\n", $fList)) {
  26. chomp($row);
  27. my ($type, $fName) = split(" ", $row);
  28. next if($type eq "D");
  29. next if(!$fName);
  30. # check for 80 chars per line conformity
  31. if($fName =~ m/CHANGED/) {
  32. my ($cCount, $cLineNo, $tLineNo, $lineNo) = (0,0,0,0,0);
  33. open(FILE, "$svnlook $arg cat $repos $fName|") ||
  34. die("Cant svnlook cat $fName:$!\n");
  35. while(my $l = <FILE>) {
  36. chomp $l;
  37. $lineNo++;
  38. $tLineNo = $lineNo if(!$tLineNo && $l =~ /\t/) ;
  39. if(length($l) > 80 && !$cLineNo) {
  40. $cCount = length($l);
  41. $cLineNo = $lineNo;
  42. }
  43. last if($cLineNo && $tLineNo);
  44. }
  45. close(FILE);
  46. err $fName, "file contains tabulators in line $tLineNo" if($tLineNo);
  47. err $fName, "file has over 80 chars/line in line $cLineNo" if($cLineNo);
  48. next;
  49. }
  50. next unless($fName =~ /\.pm$/);
  51. # check for SVN Id
  52. if($fName =~ m,trunk/fhem/FHEM/[^/]+\.pm$,) {
  53. my $hasId = 0;
  54. open(FILE, "$svnlook $arg cat $repos $fName|") ||
  55. die("Cant svnlook cat $fName:$!\n");
  56. while(my $l = <FILE>) {
  57. $hasId = ($l =~ /#.*?\$Id(?:\:.+)?\$/);
  58. last if($hasId);
  59. }
  60. close(FILE);
  61. err $fName, "file has no SVN Id as comment" unless($hasId);
  62. # check for activated Id property in svn:keywords
  63. my $props = `$svnlook $arg propget $repos svn:keywords $fName`;
  64. err $fName, "Id property not set in svn:keywords"
  65. unless($props =~ /Id/);
  66. }
  67. next if($fName !~ m+FHEM/(\d\d)_(.*).pm$+);
  68. my ($modNum, $modName) = ($1, $2);
  69. my %ninetyniners = ("SUNRISE_EL"=>1, "Utils"=>1);
  70. err $fName, "99 is a reserved prefix, not allowed for $modName"
  71. if($modNum eq "99" && !$ninetyniners{$modName});
  72. foreach my $lang (@lang) {
  73. my $suffix = ($lang eq "EN" ? "" : "_$lang");
  74. my $tag;
  75. my %tagcount= ();
  76. my %llwct = (); # Last line with closed tag
  77. open(MOD, "$svnlook $arg cat $repos $fName|") ||
  78. die("Cant svnlook cat $fName:$!\n");
  79. my $skip = 1;
  80. my $line = 0;
  81. my $docCount = 0;
  82. my $hasLink = 0;
  83. my $hasSummary = 0;
  84. while(my $l = <MOD>) {
  85. $line++;
  86. err $fName, "DOS line encoding is not supported."
  87. if($l =~ m/^=begin html$suffix.*\r/);
  88. if($l =~ m/^=item summary$suffix\s+(.+?)\s*$/) {
  89. err $fName, "$lang: summary is longer than 80 chars on line $line"
  90. if(length($1) > 80);
  91. $hasSummary = 1;
  92. }
  93. if($l =~ m/^=begin html$suffix$/) {
  94. $l = <MOD>; # skip one line, to be able to repeat join+split
  95. err($fName, "$lang: nonempty line after =begin html.")
  96. if($l =~ m/^...*$/);
  97. $skip = 0; $line++;
  98. } elsif($l =~ m/^=end html$suffix$/) {
  99. $skip = 1;
  100. } elsif(!$skip) {
  101. $docCount++;
  102. $hasLink = ($l =~ m/<a name="$modName"/) if(!$hasLink);
  103. foreach $tag (TAGS) {
  104. my $ot = ($tagcount{$tag} ? $tagcount{$tag} : 0);
  105. $tagcount{$tag} +=()= ($l =~ /<$tag>/gi);
  106. $tagcount{$tag} -=()= ($l =~ /<\/$tag>/gi);
  107. $llwct{$tag} = $line if(!$llwct{$tag} || ($ot && !$tagcount{$tag}));
  108. }
  109. }
  110. }
  111. close(MOD);
  112. err $fName, "$lang: No document text found"
  113. if(!$suffix && !$docCount);
  114. err $fName, "$lang: No <a name=\"$modName\"> link"
  115. if(!$suffix && $docCount && !$hasLink);
  116. err $fName, "$lang: No summary description found"
  117. if(!$suffix && $docCount && !$hasSummary);
  118. foreach $tag (TAGS) {
  119. err $fName, "$lang: Unbalanced $tag ($tagcount{$tag}, last line ok: $llwct{$tag})"
  120. if($tagcount{$tag});
  121. }
  122. }
  123. }
  124. exit($exitCode);
  125. sub
  126. err($$)
  127. {
  128. my ($fName, $txt) = @_;
  129. print STDERR "*** $fName: $txt\n";
  130. $exitCode = 1;
  131. }