Warning, /sdk/kde-dev-scripts/cvsblame is written in an unsupported language. File is not indexed.
0001 #! /usr/bin/env perl 0002 0003 # cvs blame inspired by Bonsai 0004 # Author: Bernd Gehrmann <bernd@physik.hu-berlin.de> 0005 0006 =head1 NAME 0007 0008 cvsblame - Shows a blame-annotated representation of a CVS controlled file in Konqueror. 0009 0010 =head1 SYNOPSIS 0011 0012 cvsblame <filename> 0013 0014 =head1 DESCRIPTION 0015 0016 cvsblame opens Konqueror to display the output of cvs annotate of 0017 a cvs controlled file. When the mouse is on a revision number shown 0018 in the second column, a popup with the respective log message 0019 appears. 0020 0021 In the popup, a proper mailto: link to the author of a revision 0022 can be created as follows: In your home directory, make a file 0023 .cvsblame. In that file, enter for each repository you are working 0024 with a line like 0025 0026 accounts :pserver:gehrmab@cvs.kde.org:/home/kde /home/bernd/.kdeaccounts 0027 0028 where the accounts file contains a simple list of cvs usernames in 0029 the first column and the respective mail address in the second. 0030 0031 =head1 BUGS 0032 0033 =over 4 0034 0035 =item Does not really work for filenames which are not in the current directory 0036 0037 =item Is a hack. Really. 0038 0039 =back 0040 0041 =head1 AUTHOR 0042 0043 Bernd Gehrmann <bernd@physik.hu-berlin.de> 0044 0045 =cut 0046 0047 $file = $ARGV[0]; 0048 $outputfile = `kde4-config --path tmp` || './#'; # if we put the file in the cwd, then we keep a '#' at the beggining to help CVS ignore it 0049 ($outputfile) = split(/:/,$outputfile); 0050 chomp $outputfile; 0051 $outputfile .= "cvsblame.$$.html"; 0052 $configfile = $ENV{HOME}. "/.cvsblame"; 0053 $rootfile = "`pwd`/CVS/Root"; 0054 $cvsroot = `cat "$rootfile"`; 0055 chop $cvsroot; 0056 0057 # 0058 # Look for a username -> mail address mapping 0059 # 0060 0061 if (open(CONFIG, $configfile)) { 0062 while (<CONFIG>) { 0063 if (/accounts\s*([^\s]*)\s+([^\s]*)/) { 0064 if ($1 eq $cvsroot) { 0065 $accountfile = $2; 0066 } 0067 } 0068 } 0069 close CONFIG; 0070 } 0071 if ($accountfile) { 0072 open(ACCOUNTS, $accountfile) || die "Account file not found: $accountfile"; 0073 while (<ACCOUNTS>) { 0074 if (/([^\s]*)\s+([^\s].*[^\s])\s+([^\s]+)/) { 0075 $mail{$1} = "$2 <$3>"; 0076 } 0077 elsif (/([^\s]*)\s+([^\s]*)/) { 0078 $mail{$1} = $2; 0079 } 0080 } 0081 } 0082 0083 0084 # 0085 # The real work, first the html header 0086 # 0087 0088 0089 open(OUTPUT, ">$outputfile"); 0090 print OUTPUT <<EOF; 0091 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 0092 <html> 0093 <head> 0094 <title>Blame annotation for $file</title> 0095 </head> 0096 <script type="text/javascript"> 0097 function hidelog(event) { 0098 var target = event.relatedTarget; 0099 while (target && target.id != "popup") 0100 target = target.offsetParent; 0101 if (target) 0102 return; 0103 target = event.target; 0104 while (target.id != "popup") 0105 target = target.offsetParent; 0106 target.style.visibility = "hidden"; 0107 } 0108 function init() { 0109 document.getElementById("popup").addEventListener("mouseout", hidelog, false); 0110 } 0111 function poplog(target, rev) { 0112 var popup = document.getElementById("popup"); 0113 var x = 120, y = 0; 0114 while (target && target != document) 0115 { 0116 x += target.offsetLeft; 0117 y += target.offsetTop; 0118 target = target.offsetParent; 0119 } 0120 popup.style.pixelLeft = x; 0121 popup.style.pixelTop = y; 0122 popup.innerHTML = rev; 0123 popup.style.visibility = "visible"; 0124 return true; 0125 } 0126 EOF 0127 0128 # 0129 # Translate information from cvs log in javascript stuff 0130 # 0131 0132 $revision = ""; 0133 open (LOG, "cvs log \"$file\"|"); 0134 while (<LOG>) { 0135 chop; 0136 $line = $_; 0137 if ($line =~ /^revision (.*)/) { 0138 $revision = $1; 0139 $revstr = "log$revision"; 0140 $revstr =~ s/\./_/g; 0141 } elsif ($line =~ /date: ([^;]*);\s*author: ([^;]*);.*/) { 0142 $date = $1; 0143 $author = $2; 0144 if ($mail{$author}) { 0145 $author = "<a href=\\\"mailto:$mail{$author}\\\">$author</a>"; 0146 } 0147 $content = "<b>$revision</b> $author <b>$date<b>"; 0148 } elsif ($line eq "----------------------------" && !($revision eq "")) { 0149 print OUTPUT "var $revstr = \"$content\";\n"; 0150 } elsif ($line eq "=============================================================================" && !($revision eq "")) { 0151 print OUTPUT "var $revstr = \"$content\";\n"; 0152 } else { 0153 $line =~ s/\"/\\\"/g; 0154 $line =~ s/&/&/g; 0155 $line =~ s/</</g; 0156 $line =~ s/>/>/g; 0157 $content = "$content<br>$line"; 0158 } 0159 } 0160 close LOG; 0161 0162 print OUTPUT <<EOF; 0163 </script> 0164 <style type="text/css"> 0165 body { 0166 background: #eeeee0; 0167 } 0168 #popup { 0169 position: absolute; 0170 background: #ffcc99; 0171 border: 1px solid #80664D; 0172 padding: 2px; 0173 } 0174 a:link { 0175 text-decoration: none; 0176 } 0177 a:hover { 0178 text-decoration: underline; 0179 } 0180 </style> 0181 <body text="#000000" onload="init()"> 0182 <h1>$file</h1> 0183 <table border=0 cellpadding=0 cellspacing=0 width="100%"> 0184 EOF 0185 0186 # 0187 # Information from cvs annotate 0188 # 0189 0190 $color = 1; 0191 $lineno = 1; 0192 $oldrevision = ""; 0193 $oldlineno = ""; 0194 $oldrevstr = ""; 0195 open (ANNOTATE, "cvs annotate \"$file\" 2>/dev/null|"); 0196 while (<ANNOTATE>) { 0197 chop; 0198 $line = $_; 0199 $revision = substr $line, 0, 13; 0200 $revision =~ s/\s//g; 0201 $author = substr $line, 14, 9; 0202 $author =~ s/\s//g; 0203 $date = substr $line, 23, 9; 0204 $content = substr $line, 35; 0205 $content =~ s/\&/&/g; 0206 $content =~ s/\</</g; 0207 $content =~ s/\>/>/g; 0208 $revstr = "log$revision"; 0209 $revstr =~ s/\./_/g; 0210 if ($revision eq $oldrevision) { 0211 if ($lineno == $oldlineno+20) { 0212 $linkstr = "<span onmouseover=\"return poplog(this, $revstr)\"'>"; 0213 $linkendstr = "</span>"; 0214 $revauthor = "$author $revision"; 0215 $oldlineno = $lineno; 0216 } else { 0217 $linkstr = ""; 0218 $linkendstr = ""; 0219 $revauthor = ""; 0220 } 0221 } else { 0222 $color = ($color == 0)? 1 : 0; 0223 $linkstr = "<span onmouseover=\"return poplog(this, $revstr)\"'>"; 0224 $linkendstr = "</span>"; 0225 $revauthor = "$author $revision"; 0226 $oldlineno = $lineno; 0227 $oldrevision = $revision; 0228 } 0229 print OUTPUT "<tr><td nowrap style=\"background: ", ($color==1)? "#EEEEE0" : "#FFFFCC", "\"><pre>"; 0230 0231 print OUTPUT sprintf '%-5i%s%-14s%s%s', $lineno, $linkstr, $revauthor,$linkendstr, $content; 0232 print OUTPUT "</pre></td></tr>\n"; 0233 $lineno++; 0234 } 0235 close ANNOTATE; 0236 0237 # 0238 # Finally, the html footer 0239 # 0240 0241 print OUTPUT <<EOF; 0242 </table> 0243 <div id="popup" style="visibility: hidden"></div> 0244 </body> 0245 </html> 0246 EOF 0247 0248 close OUTPUT; 0249 0250 system("kfmclient openProfile webbrowsing $outputfile"); 0251 0252 exit 0;