63f834b630796e1e6c1420bc0dc0d94226297cb9
[dragonfly.git] / tools / tools / commitsdb / make_commit_db
1 #!/usr/bin/env perl -w
2
3 # $FreeBSD: src/tools/tools/commitsdb/make_commit_db,v 1.2 2002/10/17 16:29:26 joe Exp $
4
5 # This script walks the tree from the current directory
6 # and spits out a database generated by md5'ing the cvs log
7 # messages of each revision of every file in the tree.
8
9 use strict;
10 use Digest::MD5 qw(md5_hex);
11
12 my $dbname = "commitsdb";
13 open DB, "> $dbname" or die "$!\n";
14
15 # Extract all the logs for the current directory.
16 my @dirs = ".";
17 while (@dirs) {
18         my $dir = shift @dirs;
19         my %logs;
20
21         opendir DIR, $dir or die $!;
22         foreach my $f (grep { /[^\.]/ } readdir DIR) {
23                 my $filename = "$dir/$f";
24                 if (-f $filename) {
25                         my %loghash = parse_log_message($filename);
26                         next unless %loghash;
27
28                         $logs{$filename} = {%loghash};
29                 } elsif (-d $filename) {
30                         next if $filename =~ /\/CVS$/;
31                         push @dirs, $filename;
32                 }
33         }
34         close DIR;
35
36         # Produce a database of the commits
37         foreach my $f (keys %logs) {
38                 my $file = $logs{$f};
39                 foreach my $rev (keys %$file) {
40                         my $hash = $$file{$rev};
41
42                         print DB "$f $rev $hash\n";
43                 }
44         }
45
46         print "\r" . " " x 30 . "\r$dir";
47 }
48 print "\n";
49
50 close DB;
51
52
53
54 ##################################################
55 # Run a cvs log on a file and return a parse entry.
56 ##################################################
57 sub parse_log_message {
58         my $file = shift;
59
60         # Get a log of the file.
61         open LOG, "cvs -R log $file 2>/dev/null |" or die $!;
62         my @log = <LOG>;
63         my $log = join "", @log;
64         close LOG;
65
66         # Split the log into revisions.
67         my @entries = split /(?<=\n)-{28}\n(?=revision\s)/, $log;
68
69         # Throw away the first entry.
70         shift @entries;
71
72         # Record the hash of the message against the revision.
73         my %loghash = ();
74         foreach my $e (@entries) {
75                 # Get the revision number
76                 $e =~ s/^revision\s+(\S+)(\s+locked\s+by:\s+\w+;)?\n//s;
77                 my $rev = $1;
78
79                 # Strip off any other headers.
80                 my $user;
81                 while ($e =~ s/^(date|branches):([^\n]*)\n//sg) {
82                         my $sub = $2;
83                         $user = $1 if $sub =~ /author: (.*?);/;
84                 };
85
86                 my $hash = string_to_hash($e);
87                 $loghash{$rev} = "$user:$hash";
88         }
89
90         return %loghash;
91 }
92
93
94 ##################################################
95 # Convert a log message into an md5 checksum.
96 ##################################################
97 sub string_to_hash {
98         my $logmsg = shift;
99
100         return md5_hex($logmsg);
101 }
102
103
104
105 #end