#! /usr/bin/env perl # cvs blame inspired by Bonsai # Author: Bernd Gehrmann =head1 NAME cvsblame - Shows a blame-annotated representation of a CVS controlled file in Konqueror. =head1 SYNOPSIS cvsblame =head1 DESCRIPTION cvsblame opens Konqueror to display the output of cvs annotate of a cvs controlled file. When the mouse is on a revision number shown in the second column, a popup with the respective log message appears. In the popup, a proper mailto: link to the author of a revision can be created as follows: In your home directory, make a file .cvsblame. In that file, enter for each repository you are working with a line like accounts :pserver:gehrmab@cvs.kde.org:/home/kde /home/bernd/.kdeaccounts where the accounts file contains a simple list of cvs usernames in the first column and the respective mail address in the second. =head1 BUGS =over 4 =item Does not really work for filenames which are not in the current directory =item Is a hack. Really. =back =head1 AUTHOR Bernd Gehrmann =cut $file = $ARGV[0]; $outputfile = `kde-config --path tmp` || './#'; # if we put the file in the cwd, then we keep a '#' at the beggining to help CVS ignore it ($outputfile) = split(/:/,$outputfile); chomp $outputfile; $outputfile .= "cvsblame.$$.html"; $configfile = $ENV{HOME}. "/.cvsblame"; $rootfile = "`pwd`/CVS/Root"; $cvsroot = `cat "$rootfile"`; chop $cvsroot; # # Look for a username -> mail address mapping # if (open(CONFIG, $configfile)) { while () { if (/accounts\s*([^\s]*)\s+([^\s]*)/) { if ($1 eq $cvsroot) { $accountfile = $2; } } } close CONFIG; } if ($accountfile) { open(ACCOUNTS, $accountfile) || die "Account file not found: $accountfile"; while () { if (/([^\s]*)\s+([^\s].*[^\s])\s+([^\s]+)/) { $mail{$1} = "$2 <$3>"; } elsif (/([^\s]*)\s+([^\s]*)/) { $mail{$1} = $2; } } } # # The real work, first the html header # open(OUTPUT, ">$outputfile"); print OUTPUT < Blame annotation for $file

$file

EOF # # Information from cvs annotate # $color = 1; $lineno = 1; $oldrevision = ""; $oldlineno = ""; $oldrevstr = ""; open (ANNOTATE, "cvs annotate \"$file\" 2>/dev/null|"); while () { chop; $line = $_; $revision = substr $line, 0, 13; $revision =~ s/\s//g; $author = substr $line, 14, 9; $author =~ s/\s//g; $date = substr $line, 23, 9; $content = substr $line, 35; $content =~ s/\&/&/g; $content =~ s/\/>/g; $revstr = "log$revision"; $revstr =~ s/\./_/g; if ($revision eq $oldrevision) { if ($lineno == $oldlineno+20) { $linkstr = ""; $linkendstr = ""; $revauthor = "$author $revision"; $oldlineno = $lineno; } else { $linkstr = ""; $linkendstr = ""; $revauthor = ""; } } else { $color = ($color == 0)? 1 : 0; $linkstr = ""; $linkendstr = ""; $revauthor = "$author $revision"; $oldlineno = $lineno; $oldrevision = $revision; } print OUTPUT "\n"; $lineno++; } close ANNOTATE; # # Finally, the html footer # print OUTPUT < EOF close OUTPUT; system("kfmclient openProfile webbrowsing $outputfile"); exit 0;
";

      print OUTPUT sprintf '%-5i%s%-14s%s%s', $lineno, $linkstr, $revauthor,$linkendstr, $content;
      print OUTPUT "