Following you can find my first proposal, based upon patch 1. It's only the perl part, because I haven't checked out Peffs git_prompt patch(es) and to avoid double work. ATM I'm unsure about the 'username' type, but I think it's quite necessary to make git-svn behave like git-core in case of asking for a username. A type 'userpass' (username and password in one dialog) isn't mentioned here, because it's not necessary for the git-svn part, but we should also specify/document it if we want to use it in the future. Btw. happy new year! ;) --- git-svn.perl | 24 +++++++------------ perl/Git.pm | 70 ++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 36 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 26d3559..54cf77f 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -4356,17 +4356,16 @@ sub ssl_server_trust { map $cert_info->$_, qw(hostname valid_from valid_until issuer_dname fingerprint); my $choice; -prompt: - print STDERR $may_save ? + my $prompt = $may_save ? "(R)eject, accept (t)emporarily or accept (p)ermanently? " : "(R)eject or accept (t)emporarily? "; - STDERR->flush; - $choice = lc(substr(<STDIN> || 'R', 0, 1)); - if ($choice =~ /^t$/i) { +prompt: + $choice = lc(substr(Git->prompt($prompt) || 'R', 0, 1)); + if ($choice eq "t") { $cred->may_save(undef); - } elsif ($choice =~ /^r$/i) { + } elsif ($choice eq "r") { return -1; - } elsif ($may_save && $choice =~ /^p$/i) { + } elsif ($may_save && $choice eq "p") { $cred->may_save($may_save); } else { goto prompt; @@ -4378,10 +4377,7 @@ prompt: sub ssl_client_cert { my ($cred, $realm, $may_save, $pool) = @_; $may_save = undef if $_no_auth_cache; - print STDERR "Client certificate filename: "; - STDERR->flush; - chomp(my $filename = <STDIN>); - $cred->cert_file($filename); + $cred->cert_file(Git->prompt("Client certificate filename: ", 'filename')); $cred->may_save($may_save); $SVN::_Core::SVN_NO_ERROR; } @@ -4404,9 +4400,7 @@ sub username { if (defined $_username) { $username = $_username; } else { - print STDERR "Username: "; - STDERR->flush; - chomp($username = <STDIN>); + $username = Git->prompt("Username: ", 'username'); } $cred->username($username); $cred->may_save($may_save); @@ -4415,7 +4409,7 @@ sub username { sub _read_password { my ($prompt, $realm) = @_; - my $password = Git->prompt($prompt); + my $password = Git->prompt($prompt, 'pass'); $password; } diff --git a/perl/Git.pm b/perl/Git.pm index ba9a5f2..17ddf40 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -512,52 +512,80 @@ C<git --html-path>). Useful mostly only internally. sub html_path { command_oneline('--html-path') } -=item prompt ( PROMPT ) +=item prompt ( PROMPT , TYPE ) Query user C<PROMPT> and return answer from user. -If an external helper is specified via GIT_ASKPASS or SSH_ASKPASS, it -is used to interact with the user; otherwise the prompt is given to -and the answer is read from the terminal. +If an external helper is specified via GIT_DIALOG, GIT_ASKPASS or +SSH_ASKPASS, it is used to interact with the user; otherwise the +prompt is given to and the answer is read from the terminal. + +Possible values for C<TYPE>: +- '' or 'text': prompt for normal text (only GIT_DIALOG) +- 'username': prompt for username (behaves exactly as 'text', but also + uses *_ASKPASS) +- 'pass': prompt for password, echoing of what is typed is disabled on + the terminal, GUI tool shows asterisks. +- 'filename': prompt for a filename, GUI tool migh provide file chooser + (only GIT_DIALOG) =cut sub prompt { - my ($self, $prompt) = _maybe_self(@_); + my ($self, $prompt, $type) = _maybe_self(@_); + $type = 'text' unless ($type); + my $useAskPass = ($type eq 'pass' || $type eq 'username'); my $ret; if (!defined $ret) { - $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt); + $ret = _promptgitdialog($ENV{'GIT_DIALOG'}, $prompt, $type); } - if (!defined $ret) { - $ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt); + if ($useAskPass && !defined $ret) { + $ret = _promptaskpass($ENV{'GIT_ASKPASS'}, $prompt); + } + if ($useAskPass && !defined $ret) { + $ret = _promptaskpass($ENV{'SSH_ASKPASS'}, $prompt); } if (!defined $ret) { $ret = ''; print STDERR $prompt; STDERR->flush; - require Term::ReadKey; - Term::ReadKey::ReadMode('noecho'); - while (defined(my $key = Term::ReadKey::ReadKey(0))) { - last if $key =~ /[\012\015]/; # \n\r - $ret .= $key; + if ($type eq 'pass') { + require Term::ReadKey; + Term::ReadKey::ReadMode('noecho'); + while (defined(my $key = Term::ReadKey::ReadKey(0))) { + last if $key =~ /[\012\015]/; # \n\r + $ret .= $key; + } + Term::ReadKey::ReadMode('restore'); + print STDERR "\n"; + STDERR->flush; + } else { + chomp($ret = <STDIN>); } - Term::ReadKey::ReadMode('restore'); - print STDERR "\n"; - STDERR->flush; } return $ret; } -sub _prompt { +sub _promptgitdialog { + my ($gitdialog, $prompt, $type) = @_; + return undef unless ($askpass); + my $ret; + open my $fh, "-|", $gitdialog, $type, $prompt + or return undef; + $ret = <$fh>; + $ret =~ s/\r?\n$//; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected + close ($fh); + return $ret; +} + +sub _promptaskpass { my ($askpass, $prompt) = @_; - unless ($askpass) { - return undef; - } + return undef unless ($askpass); my $ret; open my $fh, "-|", $askpass, $prompt or return undef; $ret = <$fh>; - $ret =~ s/[\012\015]//g; # \n\r + $ret =~ s/\r?\n$//; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected close ($fh); return $ret; } -- -- Best regards, Sven Strickroth ClamAV, a GPL anti-virus toolkit http://www.clamav.net PGP key id F5A9D4C4 @ any key-server -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html