sub interactive_get_maintainers()

in scripts/get_maintainer.pl [1766:2044]


sub interactive_get_maintainers {
    my ($list_ref) = @_;
    my @list = @$list_ref;

    vcs_exists();

    my %selected;
    my %authored;
    my %signed;
    my $count = 0;
    my $maintained = 0;
    foreach my $entry (@list) {
	$maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i);
	$selected{$count} = 1;
	$authored{$count} = 0;
	$signed{$count} = 0;
	$count++;
    }

    #menu loop
    my $done = 0;
    my $print_options = 0;
    my $redraw = 1;
    while (!$done) {
	$count = 0;
	if ($redraw) {
	    printf STDERR "\n%1s %2s %-65s",
			  "*", "#", "email/list and role:stats";
	    if ($email_git ||
		($email_git_fallback && !$maintained) ||
		$email_git_blame) {
		print STDERR "auth sign";
	    }
	    print STDERR "\n";
	    foreach my $entry (@list) {
		my $email = $entry->[0];
		my $role = $entry->[1];
		my $sel = "";
		$sel = "*" if ($selected{$count});
		my $commit_author = $commit_author_hash{$email};
		my $commit_signer = $commit_signer_hash{$email};
		my $authored = 0;
		my $signed = 0;
		$authored++ for (@{$commit_author});
		$signed++ for (@{$commit_signer});
		printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email;
		printf STDERR "%4d %4d", $authored, $signed
		    if ($authored > 0 || $signed > 0);
		printf STDERR "\n     %s\n", $role;
		if ($authored{$count}) {
		    my $commit_author = $commit_author_hash{$email};
		    foreach my $ref (@{$commit_author}) {
			print STDERR "     Author: @{$ref}[1]\n";
		    }
		}
		if ($signed{$count}) {
		    my $commit_signer = $commit_signer_hash{$email};
		    foreach my $ref (@{$commit_signer}) {
			print STDERR "     @{$ref}[2]: @{$ref}[1]\n";
		    }
		}

		$count++;
	    }
	}
	my $date_ref = \$email_git_since;
	$date_ref = \$email_hg_since if (vcs_is_hg());
	if ($print_options) {
	    $print_options = 0;
	    if (vcs_exists()) {
		print STDERR <<EOT

Version Control options:
g  use git history      [$email_git]
gf use git-fallback     [$email_git_fallback]
b  use git blame        [$email_git_blame]
bs use blame signatures [$email_git_blame_signatures]
c# minimum commits      [$email_git_min_signatures]
%# min percent          [$email_git_min_percent]
d# history to use       [$$date_ref]
x# max maintainers      [$email_git_max_maintainers]
t  all signature types  [$email_git_all_signature_types]
m  use .mailmap         [$email_use_mailmap]
EOT
	    }
	    print STDERR <<EOT

Additional options:
0  toggle all
tm toggle maintainers
tg toggle git entries
tl toggle open list entries
ts toggle subscriber list entries
f  emails in file       [$email_file_emails]
k  keywords in file     [$keywords]
r  remove duplicates    [$email_remove_duplicates]
p# pattern match depth  [$pattern_depth]
EOT
	}
	print STDERR
"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): ";

	my $input = <STDIN>;
	chomp($input);

	$redraw = 1;
	my $rerun = 0;
	my @wish = split(/[, ]+/, $input);
	foreach my $nr (@wish) {
	    $nr = lc($nr);
	    my $sel = substr($nr, 0, 1);
	    my $str = substr($nr, 1);
	    my $val = 0;
	    $val = $1 if $str =~ /^(\d+)$/;

	    if ($sel eq "y") {
		$interactive = 0;
		$done = 1;
		$output_rolestats = 0;
		$output_roles = 0;
		last;
	    } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) {
		$selected{$nr - 1} = !$selected{$nr - 1};
	    } elsif ($sel eq "*" || $sel eq '^') {
		my $toggle = 0;
		$toggle = 1 if ($sel eq '*');
		for (my $i = 0; $i < $count; $i++) {
		    $selected{$i} = $toggle;
		}
	    } elsif ($sel eq "0") {
		for (my $i = 0; $i < $count; $i++) {
		    $selected{$i} = !$selected{$i};
		}
	    } elsif ($sel eq "t") {
		if (lc($str) eq "m") {
		    for (my $i = 0; $i < $count; $i++) {
			$selected{$i} = !$selected{$i}
			    if ($list[$i]->[1] =~ /^(maintainer|supporter)/i);
		    }
		} elsif (lc($str) eq "g") {
		    for (my $i = 0; $i < $count; $i++) {
			$selected{$i} = !$selected{$i}
			    if ($list[$i]->[1] =~ /^(author|commit|signer)/i);
		    }
		} elsif (lc($str) eq "l") {
		    for (my $i = 0; $i < $count; $i++) {
			$selected{$i} = !$selected{$i}
			    if ($list[$i]->[1] =~ /^(open list)/i);
		    }
		} elsif (lc($str) eq "s") {
		    for (my $i = 0; $i < $count; $i++) {
			$selected{$i} = !$selected{$i}
			    if ($list[$i]->[1] =~ /^(subscriber list)/i);
		    }
		}
	    } elsif ($sel eq "a") {
		if ($val > 0 && $val <= $count) {
		    $authored{$val - 1} = !$authored{$val - 1};
		} elsif ($str eq '*' || $str eq '^') {
		    my $toggle = 0;
		    $toggle = 1 if ($str eq '*');
		    for (my $i = 0; $i < $count; $i++) {
			$authored{$i} = $toggle;
		    }
		}
	    } elsif ($sel eq "s") {
		if ($val > 0 && $val <= $count) {
		    $signed{$val - 1} = !$signed{$val - 1};
		} elsif ($str eq '*' || $str eq '^') {
		    my $toggle = 0;
		    $toggle = 1 if ($str eq '*');
		    for (my $i = 0; $i < $count; $i++) {
			$signed{$i} = $toggle;
		    }
		}
	    } elsif ($sel eq "o") {
		$print_options = 1;
		$redraw = 1;
	    } elsif ($sel eq "g") {
		if ($str eq "f") {
		    bool_invert(\$email_git_fallback);
		} else {
		    bool_invert(\$email_git);
		}
		$rerun = 1;
	    } elsif ($sel eq "b") {
		if ($str eq "s") {
		    bool_invert(\$email_git_blame_signatures);
		} else {
		    bool_invert(\$email_git_blame);
		}
		$rerun = 1;
	    } elsif ($sel eq "c") {
		if ($val > 0) {
		    $email_git_min_signatures = $val;
		    $rerun = 1;
		}
	    } elsif ($sel eq "x") {
		if ($val > 0) {
		    $email_git_max_maintainers = $val;
		    $rerun = 1;
		}
	    } elsif ($sel eq "%") {
		if ($str ne "" && $val >= 0) {
		    $email_git_min_percent = $val;
		    $rerun = 1;
		}
	    } elsif ($sel eq "d") {
		if (vcs_is_git()) {
		    $email_git_since = $str;
		} elsif (vcs_is_hg()) {
		    $email_hg_since = $str;
		}
		$rerun = 1;
	    } elsif ($sel eq "t") {
		bool_invert(\$email_git_all_signature_types);
		$rerun = 1;
	    } elsif ($sel eq "f") {
		bool_invert(\$email_file_emails);
		$rerun = 1;
	    } elsif ($sel eq "r") {
		bool_invert(\$email_remove_duplicates);
		$rerun = 1;
	    } elsif ($sel eq "m") {
		bool_invert(\$email_use_mailmap);
		read_mailmap();
		$rerun = 1;
	    } elsif ($sel eq "k") {
		bool_invert(\$keywords);
		$rerun = 1;
	    } elsif ($sel eq "p") {
		if ($str ne "" && $val >= 0) {
		    $pattern_depth = $val;
		    $rerun = 1;
		}
	    } elsif ($sel eq "h" || $sel eq "?") {
		print STDERR <<EOT

Interactive mode allows you to select the various maintainers, submitters,
commit signers and mailing lists that could be CC'd on a patch.

Any *'d entry is selected.

If you have git or hg installed, you can choose to summarize the commit
history of files in the patch.  Also, each line of the current file can
be matched to its commit author and that commits signers with blame.

Various knobs exist to control the length of time for active commit
tracking, the maximum number of commit authors and signers to add,
and such.

Enter selections at the prompt until you are satisfied that the selected
maintainers are appropriate.  You may enter multiple selections separated
by either commas or spaces.

EOT
	    } else {
		print STDERR "invalid option: '$nr'\n";
		$redraw = 0;
	    }
	}
	if ($rerun) {
	    print STDERR "git-blame can be very slow, please have patience..."
		if ($email_git_blame);
	    goto &get_maintainers;
	}
    }

    #drop not selected entries
    $count = 0;
    my @new_emailto = ();
    foreach my $entry (@list) {
	if ($selected{$count}) {
	    push(@new_emailto, $list[$count]);
	}
	$count++;
    }
    return @new_emailto;
}