git-svn: add --authors-prog option

Add a new option, --authors-prog, to git-svn that allows a more flexible
alternative (or supplement) to --authors-file.  This allows more
advanced username operations than the authors file will allow.  For
example, one may look up Subversion users via LDAP, or may generate the
name and email address from the Subversion username.

Notes:

* If both --authors-name and --authors-prog are given, the former is
  tried first, falling back to the later.

* The program is called once per unique SVN username, and the result is
  cached.

* The command-line argument must be the path to a program, not a generic
  shell command line.  The absolute path to this program is taken at
  startup since the git-svn script changes directory during operation.

* The option is not enabled for `git svn log'.

[ew: fixed case where neither --authors-(name|prog) were defined]
Signed-off-by: Mark Lodato <lodatom@gmail.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
Mark Lodato
2009-05-14 21:27:15 -04:00
committed by Eric Wong
parent 42a5da1806
commit 36db1eddf9
3 changed files with 106 additions and 3 deletions

View File

@ -5,7 +5,7 @@ use warnings;
use strict;
use vars qw/ $AUTHOR $VERSION
$sha1 $sha1_short $_revision $_repository
$_q $_authors %users/;
$_q $_authors $_authors_prog %users/;
$AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
$VERSION = '@@GIT_VERSION@@';
@ -39,6 +39,7 @@ use Digest::MD5;
use IO::File qw//;
use File::Basename qw/dirname basename/;
use File::Path qw/mkpath/;
use File::Spec;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use IPC::Open3;
use Git;
@ -76,6 +77,7 @@ my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
'authors-file|A=s' => \$_authors,
'authors-prog=s' => \$_authors_prog,
'repack:i' => \$Git::SVN::_repack,
'noMetadata' => \$Git::SVN::_no_metadata,
'useSvmProps' => \$Git::SVN::_use_svm_props,
@ -263,6 +265,9 @@ usage(0) if $_help;
version() if $_version;
usage(1) unless defined $cmd;
load_authors() if $_authors;
if (defined $_authors_prog) {
$_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'";
}
unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
Git::SVN::Migration::migration_check();
@ -2664,12 +2669,33 @@ sub other_gs {
$gs
}
sub call_authors_prog {
my ($orig_author) = @_;
my $author = `$::_authors_prog $orig_author`;
if ($? != 0) {
die "$::_authors_prog failed with exit code $?\n"
}
if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
my ($name, $email) = ($1, $2);
$email = undef if length $2 == 0;
return [$name, $email];
} else {
die "Author: $orig_author: $::_authors_prog returned "
. "invalid author format: $author\n";
}
}
sub check_author {
my ($author) = @_;
if (!defined $author || length $author == 0) {
$author = '(no author)';
} elsif (defined $::_authors && ! defined $::users{$author}) {
die "Author: $author not defined in $::_authors file\n";
}
if (!defined $::users{$author}) {
if (defined $::_authors_prog) {
$::users{$author} = call_authors_prog($author);
} elsif (defined $::_authors) {
die "Author: $author not defined in $::_authors file\n";
}
}
$author;
}