@ -33,6 +33,7 @@ my $email_git_max_maintainers = 5;
my $ email_git_min_percent = 5 ;
my $ email_git_since = "1-year-ago" ;
my $ email_hg_since = "-365" ;
my $ interactive = 0 ;
my $ email_remove_duplicates = 1 ;
my $ output_multiline = 1 ;
my $ output_separator = ", " ;
@ -52,6 +53,8 @@ my $help = 0;
my $ exit = 0 ;
my % shortlog_buffer ;
my @ penguin_chief = ( ) ;
push ( @ penguin_chief , "Linus Torvalds:torvalds\@linux-foundation.org" ) ;
#Andrew wants in on most everything - 2009/01/14
@ -93,7 +96,8 @@ my %VCS_cmds_git = (
"blame_range_cmd" = > "git blame -l -L \$diff_start,+\$diff_length \$file" ,
"blame_file_cmd" = > "git blame -l \$file" ,
"commit_pattern" = > "^commit [0-9a-f]{40,40}" ,
"blame_commit_pattern" = > "^([0-9a-f]+) "
"blame_commit_pattern" = > "^([0-9a-f]+) " ,
"shortlog_cmd" = > "git log --no-color --oneline --since=\$email_git_since --author=\"\$email\" -- \$file"
) ;
my % VCS_cmds_hg = (
@ -107,7 +111,8 @@ my %VCS_cmds_hg = (
"blame_range_cmd" = > "" , # not supported
"blame_file_cmd" = > "hg blame -c \$file" ,
"commit_pattern" = > "^commit [0-9a-f]{40,40}" ,
"blame_commit_pattern" = > "^([0-9a-f]+):"
"blame_commit_pattern" = > "^([0-9a-f]+):" ,
"shortlog_cmd" = > "ht log --date=\$email_hg_since"
) ;
my $ conf = which_conf ( ".get_maintainer.conf" ) ;
@ -148,6 +153,7 @@ if (!GetOptions(
'git-min-percent=i' = > \ $ email_git_min_percent ,
'git-since=s' = > \ $ email_git_since ,
'hg-since=s' = > \ $ email_hg_since ,
'i|interactive!' = > \ $ interactive ,
'remove-duplicates!' = > \ $ email_remove_duplicates ,
'm!' = > \ $ email_maintainer ,
'n!' = > \ $ email_usename ,
@ -225,6 +231,8 @@ if ($email_git_all_signature_types) {
$ signaturePattern = "(.+?)[Bb][Yy]:" ;
}
## Read MAINTAINERS for type/value pairs
my @ typevalue = ( ) ;
@ -450,10 +458,13 @@ foreach my $file (@files) {
( $ email_git || ( $ email_git_fallback && ! $ exact_pattern_match ) ) ) {
vcs_file_signoffs ( $ file ) ;
}
if ( $ email && $ email_git_blame ) {
vcs_file_blame ( $ file ) ;
}
if ( $ email && $ interactive ) {
vcs_file_shortlogs ( $ file ) ;
}
}
if ( $ keywords ) {
@ -486,9 +497,13 @@ if ($email) {
}
}
if ( $ email || $ email_list ) {
my @ to = ( ) ;
if ( $ email ) {
if ( $ interactive ) {
@ email_to = @ { vcs_interactive_menu ( \ @ email_to ) } ;
}
@ to = ( @ to , @ email_to ) ;
}
if ( $ email_list ) {
@ -501,7 +516,6 @@ if ($scm) {
@ scm = uniq ( @ scm ) ;
output ( @ scm ) ;
}
if ( $ status ) {
@ status = uniq ( @ status ) ;
output ( @ status ) ;
@ -556,6 +570,7 @@ MAINTAINER field selection options:
- - git - blame = > use git blame to find modified commits for patch or file
- - git - since = > git history to use ( default: $ email_git_since )
- - hg - since = > hg history to use ( default: $ email_hg_since )
- - interactive = > display a menu ( mostly useful if used with the - - git option )
- - m = > include maintainer ( s ) if any
- - n = > include name 'Full Name <addr\@domain.tld>'
- - l = > include list ( s ) if any
@ -1156,6 +1171,127 @@ sub vcs_exists {
return 0 ;
}
sub vcs_interactive_menu {
my $ list_ref = shift ;
my @ list = @$ list_ref ;
return if ( ! vcs_exists ( ) ) ;
my % selected ;
my % shortlog ;
my $ input ;
my $ count = 0 ;
#select maintainers by default
foreach my $ entry ( @ list ) {
my $ role = $ entry - > [ 1 ] ;
$ selected { $ count } = ( $ role =~ /maintainer:|supporter:/ ) ;
$ count + + ;
}
#menu loop
do {
my $ count = 0 ;
foreach my $ entry ( @ list ) {
my $ email = $ entry - > [ 0 ] ;
my $ role = $ entry - > [ 1 ] ;
if ( $ selected { $ count } ) {
print STDERR "* " ;
} else {
print STDERR " " ;
}
print STDERR "$count: $email,\t\t $role" ;
print STDERR "\n" ;
if ( $ shortlog { $ count } ) {
my $ entries_ref = vcs_get_shortlog ( $ email ) ;
foreach my $ entry_ref ( @ { $ entries_ref } ) {
my $ filename = @ { $ entry_ref } [ 0 ] ;
my @ shortlog = @ { @ { $ entry_ref } [ 1 ] } ;
print STDERR "\tshortlog for $filename (authored commits: " . @ shortlog . ").\n" ;
foreach my $ commit ( @ shortlog ) {
print STDERR "\t $commit\n" ;
}
print STDERR "\n" ;
}
}
$ count + + ;
}
print STDERR "\n" ;
print STDERR "Choose whom to cc by entering a commaseperated list of numbers and hitting enter.\n" ;
print STDERR "To show a short list of commits, precede the number by a '?',\n" ;
print STDERR "A blank line indicates that you are satisfied with your choice.\n" ;
$ input = <STDIN> ;
chomp ( $ input ) ;
my @ wish = split ( /[, ]+/ , $ input ) ;
foreach my $ nr ( @ wish ) {
my $ logtoggle = 0 ;
if ( $ nr =~ /\?/ ) {
$ nr =~ s/\?// ;
$ logtoggle = 1 ;
}
#skip out of bounds numbers
next unless ( $ nr <= $ count && $ nr >= 0 ) ;
if ( $ logtoggle ) {
$ shortlog { $ nr } = ! $ shortlog { $ nr } ;
} else {
$ selected { $ nr } = ! $ selected { $ nr } ;
#switch shortlog on if an entry get's selected
if ( $ selected { $ nr } ) {
$ shortlog { $ nr } = 1 ;
}
}
} ;
} while ( length ( $ input ) > 0 ) ;
#drop not selected entries
$ count = 0 ;
my @ new_emailto ;
foreach my $ entry ( @ list ) {
if ( $ selected { $ count } ) {
push ( @ new_emailto , $ list [ $ count ] ) ;
print STDERR "$count: " ;
print STDERR $ email_to [ $ count ] - > [ 0 ] ;
print STDERR ",\t\t " ;
print STDERR $ email_to [ $ count ] - > [ 1 ] ;
print STDERR "\n" ;
}
$ count + + ;
}
return \ @ new_emailto ;
}
sub vcs_get_shortlog {
my $ arg = shift ;
my ( $ name , $ address ) = parse_email ( $ arg ) ;
return $ shortlog_buffer { $ address } ;
}
sub vcs_file_shortlogs {
my ( $ file ) = @ _ ;
print STDERR "shortlog processing $file:" ;
foreach my $ entry ( @ email_to ) {
my ( $ name , $ address ) = parse_email ( $ entry - > [ 0 ] ) ;
print STDERR "." ;
my $ commits_ref = vcs_email_shortlog ( $ address , $ file ) ;
push ( @ { $ shortlog_buffer { $ address } } , [ $ file , $ commits_ref ] ) ;
}
print STDERR "\n" ;
}
sub vcs_email_shortlog {
my $ email = shift ;
my ( $ file ) = @ _ ;
my $ cmd = $ VCS_cmds { "shortlog_cmd" } ;
$ cmd =~ s/(\$\w+)/$1/eeg ; #substitute variables
my @ lines = & { $ VCS_cmds { "execute_cmd" } } ( $ cmd ) ;
return \ @ lines ;
}
sub vcs_assign {
my ( $ role , $ divisor , @ lines ) = @ _ ;
@ -1236,7 +1372,7 @@ sub vcs_file_blame {
my @ commit_signers = ( ) ;
my $ cmd = $ VCS_cmds { "find_commit_signers_cmd" } ;
$ cmd =~ s/(\$\w+)/$1/eeg ; #interpolate $cmd
$ cmd =~ s/(\$\w+)/$1/eeg ; #substitute variables in $cmd
( $ commit_count , @ commit_signers ) = vcs_find_signers ( $ cmd ) ;