Merge branch 'ss/svn-prompt' into maint
authorJunio C Hamano <gitster@pobox.com>
Sat, 12 Jan 2013 00:45:06 +0000 (16:45 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 12 Jan 2013 00:45:06 +0000 (16:45 -0800)
The way "git svn" asked for password using SSH_ASKPASS and
GIT_ASKPASS was not in line with the rest of the system.

* ss/svn-prompt:
git-svn, perl/Git.pm: extend and use Git->prompt method for querying users
perl/Git.pm: Honor SSH_ASKPASS as fallback if GIT_ASKPASS is not set
git-svn, perl/Git.pm: add central method for prompting passwords

perl/Git.pm
perl/Git/SVN/Prompt.pm
index 497f420178a73061901393f8c21a9feb17054b6d..931047c51da22cddefe0eab08d0fdaa595daefef 100644 (file)
@@ -58,7 +58,7 @@ =head1 SYNOPSIS
                 command_output_pipe command_input_pipe command_close_pipe
                 command_bidi_pipe command_close_bidi_pipe
                 version exec_path html_path hash_object git_cmd_try
-                remote_refs
+                remote_refs prompt
                 temp_acquire temp_release temp_reset temp_path);
 
 
@@ -511,6 +511,58 @@ sub version {
 
 sub html_path { command_oneline('--html-path') }
 
+=item prompt ( PROMPT , ISPASSWORD  )
+
+Query user C<PROMPT> and return answer from user.
+
+Honours GIT_ASKPASS and SSH_ASKPASS environment variables for querying
+the user. If no *_ASKPASS variable is set or an error occoured,
+the terminal is tried as a fallback.
+If C<ISPASSWORD> is set and true, the terminal disables echo.
+
+=cut
+
+sub prompt {
+       my ($prompt, $isPassword) = @_;
+       my $ret;
+       if (exists $ENV{'GIT_ASKPASS'}) {
+               $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
+       }
+       if (!defined $ret && exists $ENV{'SSH_ASKPASS'}) {
+               $ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
+       }
+       if (!defined $ret) {
+               print STDERR $prompt;
+               STDERR->flush;
+               if (defined $isPassword && $isPassword) {
+                       require Term::ReadKey;
+                       Term::ReadKey::ReadMode('noecho');
+                       $ret = '';
+                       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>);
+               }
+       }
+       return $ret;
+}
+
+sub _prompt {
+       my ($askpass, $prompt) = @_;
+       return unless length $askpass;
+       $prompt =~ s/\n/ /g;
+       my $ret;
+       open my $fh, "-|", $askpass, $prompt or return;
+       $ret = <$fh>;
+       $ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
+       close ($fh);
+       return $ret;
+}
 
 =item repo_path ()
 
index 3a6f8af0d9849c5f2fc886f8fc3ac9a8575e271e..74daa7a597fcf55a649a4e90367b1e783a74fcd5 100644 (file)
@@ -62,16 +62,16 @@ sub ssl_server_trust {
                                       issuer_dname fingerprint);
        my $choice;
 prompt:
-       print STDERR $may_save ?
+       my $options = $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) {
+       $choice = lc(substr(Git::prompt("Certificate problem.\n" . $options) || '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;
@@ -109,9 +109,7 @@ sub username {
        if (defined $_username) {
                $username = $_username;
        } else {
-               print STDERR "Username: ";
-               STDERR->flush;
-               chomp($username = <STDIN>);
+               $username = Git::prompt("Username: ");
        }
        $cred->username($username);
        $cred->may_save($may_save);
@@ -120,25 +118,7 @@ sub username {
 
 sub _read_password {
        my ($prompt, $realm) = @_;
-       my $password = '';
-       if (exists $ENV{GIT_ASKPASS}) {
-               open(PH, "-|", $ENV{GIT_ASKPASS}, $prompt);
-               $password = <PH>;
-               $password =~ s/[\012\015]//; # \n\r
-               close(PH);
-       } else {
-               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
-                       $password .= $key;
-               }
-               Term::ReadKey::ReadMode('restore');
-               print STDERR "\n";
-               STDERR->flush;
-       }
+       my $password = Git::prompt($prompt, 1);
        $password;
 }