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;