@matheusbsbs / matheus-bagliano / commits / 36db1eddf9
Fork 0

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>

Mark Lodato committed May 14, 2009 at 21:27 UTC 36db1eddf972c88edf402b99e2366ad533635ab8
3 files changed +106 -3
Documentation/git-svn.txt
+8
@@ -398,6 +398,14 @@ after the authors-file is modified should continue operation.
398
399 config key: svn.authorsfile
400
401 +--authors-prog=<filename>::
402 +
403 +If this option is specified, for each SVN committer name that does not
404 +exist in the authors file, the given file is executed with the committer
405 +name as the first argument. The program is expected to return a single
406 +line of the form "Name <email>", which will be treated as if included in
407 +the authors file.
408 +
409 -q::
410 --quiet::
411 Make 'git-svn' less verbose. Specify a second time to make it
git-svn.perl
+29 -3
@@ -5,7 +5,7 @@ use warnings;
5 use strict;
6 use vars qw/ $AUTHOR $VERSION
7 $sha1 $sha1_short $_revision $_repository
8 - $_q $_authors %users/;
8 + $_q $_authors $_authors_prog %users/;
9 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
10 $VERSION = '@@GIT_VERSION@@';
11
@@ -39,6 +39,7 @@ use Digest::MD5;
39 use IO::File qw//;
40 use File::Basename qw/dirname basename/;
41 use File::Path qw/mkpath/;
42 +use File::Spec;
43 use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
44 use IPC::Open3;
45 use Git;
@@ -76,6 +77,7 @@ my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
77 'ignore-paths=s' => \$SVN::Git::Fetcher::_ignore_regex );
78 my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
79 'authors-file|A=s' => \$_authors,
80 + 'authors-prog=s' => \$_authors_prog,
81 'repack:i' => \$Git::SVN::_repack,
82 'noMetadata' => \$Git::SVN::_no_metadata,
83 'useSvmProps' => \$Git::SVN::_use_svm_props,
@@ -263,6 +265,9 @@ usage(0) if $_help;
265 version() if $_version;
266 usage(1) unless defined $cmd;
267 load_authors() if $_authors;
268 +if (defined $_authors_prog) {
269 + $_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'";
270 +}
271
272 unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
273 Git::SVN::Migration::migration_check();
@@ -2664,12 +2669,33 @@ sub other_gs {
2669 $gs
2670 }
2671
2672 +sub call_authors_prog {
2673 + my ($orig_author) = @_;
2674 + my $author = `$::_authors_prog $orig_author`;
2675 + if ($? != 0) {
2676 + die "$::_authors_prog failed with exit code $?\n"
2677 + }
2678 + if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
2679 + my ($name, $email) = ($1, $2);
2680 + $email = undef if length $2 == 0;
2681 + return [$name, $email];
2682 + } else {
2683 + die "Author: $orig_author: $::_authors_prog returned "
2684 + . "invalid author format: $author\n";
2685 + }
2686 +}
2687 +
2688 sub check_author {
2689 my ($author) = @_;
2690 if (!defined $author || length $author == 0) {
2691 $author = '(no author)';
2671 - } elsif (defined $::_authors && ! defined $::users{$author}) {
2672 - die "Author: $author not defined in $::_authors file\n";
2692 + }
2693 + if (!defined $::users{$author}) {
2694 + if (defined $::_authors_prog) {
2695 + $::users{$author} = call_authors_prog($author);
2696 + } elsif (defined $::_authors) {
2697 + die "Author: $author not defined in $::_authors file\n";
2698 + }
2699 }
2700 $author;
2701 }
t/t9138-git-svn-authors-prog.sh new
+69
@@ -0,0 +1,69 @@
1 +#!/bin/sh
2 +#
3 +# Copyright (c) 2009 Eric Wong, Mark Lodato
4 +#
5 +
6 +test_description='git svn authors prog tests'
7 +
8 +. ./lib-git-svn.sh
9 +
10 +cat > svn-authors-prog <<'EOF'
11 +#!/usr/bin/perl
12 +$_ = shift;
13 +if (s/-sub$//) {
14 + print "$_ <$_\@sub.example.com>\n";
15 +}
16 +else {
17 + print "$_ <$_\@example.com>\n";
18 +}
19 +EOF
20 +chmod +x svn-authors-prog
21 +
22 +cat > svn-authors <<'EOF'
23 +ff = FFFFFFF FFFFFFF <fFf@other.example.com>
24 +EOF
25 +
26 +test_expect_success 'setup svnrepo' '
27 + for i in aa bb cc-sub dd-sub ee-foo ff
28 + do
29 + svn mkdir -m $i --username $i "$svnrepo"/$i
30 + done
31 + '
32 +
33 +test_expect_success 'import authors with prog and file' '
34 + git svn clone --authors-prog=./svn-authors-prog \
35 + --authors-file=svn-authors "$svnrepo" x
36 + '
37 +
38 +test_expect_success 'imported 6 revisions successfully' '
39 + (
40 + cd x
41 + test "`git rev-list refs/remotes/git-svn | wc -l`" -eq 6
42 + )
43 + '
44 +
45 +test_expect_success 'authors-prog ran correctly' '
46 + (
47 + cd x
48 + git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
49 + grep "^author ee-foo <ee-foo@example\.com> " &&
50 + git rev-list -1 --pretty=raw refs/remotes/git-svn~2 | \
51 + grep "^author dd <dd@sub\.example\.com> " &&
52 + git rev-list -1 --pretty=raw refs/remotes/git-svn~3 | \
53 + grep "^author cc <cc@sub\.example\.com> " &&
54 + git rev-list -1 --pretty=raw refs/remotes/git-svn~4 | \
55 + grep "^author bb <bb@example\.com> " &&
56 + git rev-list -1 --pretty=raw refs/remotes/git-svn~5 | \
57 + grep "^author aa <aa@example\.com> "
58 + )
59 + '
60 +
61 +test_expect_success 'authors-file overrode authors-prog' '
62 + (
63 + cd x
64 + git rev-list -1 --pretty=raw refs/remotes/git-svn | \
65 + grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> "
66 + )
67 + '
68 +
69 +test_done