Rev 4249: (vila) Stop requiring a controlling terminal to query for passwords in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Apr 3 17:45:57 BST 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4249
revision-id: pqm at pqm.ubuntu.com-20090403164553-wo2n7k4nvd1xcyw3
parent: pqm at pqm.ubuntu.com-20090403151446-o35ylr3cst5ioejg
parent: v.ladeuil+lp at free.fr-20090403153256-c7muvpegzm7lp2ht
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2009-04-03 17:45:53 +0100
message:
  (vila) Stop requiring a controlling terminal to query for passwords
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
  bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
    ------------------------------------------------------------
    revno: 4248.1.1
    revision-id: v.ladeuil+lp at free.fr-20090403153256-c7muvpegzm7lp2ht
    parent: pqm at pqm.ubuntu.com-20090403151446-o35ylr3cst5ioejg
    parent: v.ladeuil+lp at free.fr-20090402174141-e1liex2l44pv03v1
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: trunk
    timestamp: Fri 2009-04-03 17:32:56 +0200
    message:
      Stop requiring a controlling terminal to query for passwords
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
      bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
    ------------------------------------------------------------
    revno: 4237.2.2
    revision-id: v.ladeuil+lp at free.fr-20090402174141-e1liex2l44pv03v1
    parent: v.ladeuil+lp at free.fr-20090402104301-esvcd0lcqru9g4lb
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: not-a-terminal
    timestamp: Thu 2009-04-02 19:41:41 +0200
    message:
      Don't presume we have a tty.
      
      * bzrlib/ui/__init__.py:
      (CLIUIFactory.get_non_echoed_password): We care only about non
      echoing which matters only with a tty. Don't call getpass if we
      aren't connected with one.
    modified:
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
    ------------------------------------------------------------
    revno: 4237.2.1
    revision-id: v.ladeuil+lp at free.fr-20090402104301-esvcd0lcqru9g4lb
    parent: pqm at pqm.ubuntu.com-20090402093220-mqwls6dsncdfegbq
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: not-a-terminal
    timestamp: Thu 2009-04-02 12:43:01 +0200
    message:
      Stop requiring a tty for CLIUIFactory and derivatives.
      
      * bzrlib/ui/text.py:
      (TextUIFactory.prompt):  Deleted, not needed anymore.
      
      * bzrlib/ui/__init__.py:
      (CLIUIFactory.get_boolean): Delegate terminal handling to
      prompt().
      (CLIUIFactory.get_non_echoed_password): Simplified.
      (CLIUIFactory.get_password): Delegate terminal handling to
      prompt().
      (CLIUIFactory.prompt): Clear the terminal, builb, encode and
      displays the prompt.
      (SilentUIFactory.prompt): Update signature.
      
      * bzrlib/tests/__init__.py:
      (TestUIFactory.__init__): Simplified.
      (TestUIFactory.get_non_echoed_password): No need for prompt here.
      
      * errors.py:
      (NotATerminal): Deleted.
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
      bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
=== modified file 'NEWS'
--- a/NEWS	2009-04-03 01:11:32 +0000
+++ b/NEWS	2009-04-03 15:32:56 +0000
@@ -41,6 +41,9 @@
 * New ``mv --auto`` option recognizes renames after they occur.
   (Aaron Bentley)
 
+* ``bzr`` can now get passwords from stdin without requiring a controlling
+  terminal (i.e. by redirecting stdin). (Vincent Ladeuil)
+
 * ``bzr log`` now supports filtering of multiple files and directories
   and will show changes that touch any of them. Furthermore,
   directory filtering now shows the changes to any children of that

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2009-03-24 01:53:42 +0000
+++ b/bzrlib/errors.py	2009-04-02 10:43:01 +0000
@@ -2850,11 +2850,6 @@
     pass
 
 
-class NotATerminal(BzrError):
-
-    _fmt = 'Unable to ask for a password without real terminal.'
-
-
 class UnableEncodePath(BzrError):
 
     _fmt = ('Unable to encode %(kind)s path %(path)r in '

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-04-03 01:11:32 +0000
+++ b/bzrlib/tests/__init__.py	2009-04-03 15:32:56 +0000
@@ -675,25 +675,14 @@
     Allows get_password to be tested without real tty attached.
     """
 
-    def __init__(self,
-                 stdout=None,
-                 stderr=None,
-                 stdin=None):
-        super(TestUIFactory, self).__init__()
+    def __init__(self, stdout=None, stderr=None, stdin=None):
         if stdin is not None:
             # We use a StringIOWrapper to be able to test various
             # encodings, but the user is still responsible to
             # encode the string and to set the encoding attribute
             # of StringIOWrapper.
-            self.stdin = StringIOWrapper(stdin)
-        if stdout is None:
-            self.stdout = sys.stdout
-        else:
-            self.stdout = stdout
-        if stderr is None:
-            self.stderr = sys.stderr
-        else:
-            self.stderr = stderr
+            stdin = StringIOWrapper(stdin)
+        super(TestUIFactory, self).__init__(stdin, stdout, stderr)
 
     def clear(self):
         """See progress.ProgressBar.clear()."""
@@ -701,9 +690,6 @@
     def clear_term(self):
         """See progress.ProgressBar.clear_term()."""
 
-    def clear_term(self):
-        """See progress.ProgressBar.clear_term()."""
-
     def finished(self):
         """See progress.ProgressBar.finished()."""
 
@@ -720,10 +706,8 @@
     def update(self, message, count=None, total=None):
         """See progress.ProgressBar.update()."""
 
-    def get_non_echoed_password(self, prompt):
+    def get_non_echoed_password(self):
         """Get password from stdin without trying to handle the echo mode"""
-        if prompt:
-            self.stdout.write(prompt.encode(self.stdout.encoding, 'replace'))
         password = self.stdin.readline()
         if not password:
             raise EOFError

=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/ui/__init__.py	2009-04-02 17:41:41 +0000
@@ -157,7 +157,6 @@
         self.stderr = stderr or sys.stderr
 
     def get_boolean(self, prompt):
-        self.clear_term()
         # FIXME: make a regexp and handle case variations as well.
         while True:
             self.prompt(prompt + "? [y/n]: ")
@@ -167,11 +166,20 @@
             if line in ('n\n', 'no\n'):
                 return False
 
-    def get_non_echoed_password(self, prompt):
-        if not sys.stdin.isatty():
-            raise errors.NotATerminal()
-        encoding = osutils.get_terminal_encoding()
-        return getpass.getpass(prompt.encode(encoding, 'replace'))
+    def get_non_echoed_password(self):
+        isatty = getattr(self.stdin, 'isatty', None)
+        if isatty is not None and isatty():
+            # getpass() ensure the password is not echoed and other
+            # cross-platform niceties
+            password = getpass.getpass('')
+        else:
+            # echo doesn't make sense without a terminal
+            password = self.stdin.readline()
+            if not password:
+                password = None
+            elif password[-1] == '\n':
+                password = password[:-1]
+        return password
 
     def get_password(self, prompt='', **kwargs):
         """Prompt the user for a password.
@@ -184,13 +192,16 @@
                  canceled the request.
         """
         prompt += ': '
-        prompt = (prompt % kwargs)
+        self.prompt(prompt, **kwargs)
         # There's currently no way to say 'i decline to enter a password'
         # as opposed to 'my password is empty' -- does it matter?
-        return self.get_non_echoed_password(prompt)
+        return self.get_non_echoed_password()
 
-    def prompt(self, prompt):
+    def prompt(self, prompt, **kwargs):
         """Emit prompt on the CLI."""
+        prompt = prompt % kwargs
+        prompt = prompt.encode(osutils.get_terminal_encoding(), 'replace')
+        self.clear_term()
         self.stdout.write(prompt)
 
     def note(self, msg):
@@ -210,7 +221,7 @@
     def get_password(self, prompt='', **kwargs):
         return None
 
-    def prompt(self, prompt):
+    def prompt(self, prompt, **kwargs):
         pass
 
     def note(self, msg):

=== modified file 'bzrlib/ui/text.py'
--- a/bzrlib/ui/text.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/ui/text.py	2009-04-02 10:43:01 +0000
@@ -60,10 +60,6 @@
         # paints progress, network activity, etc
         self._progress_view = TextProgressView(self.stderr)
 
-    def prompt(self, prompt):
-        """Emit prompt on the CLI."""
-        self.stdout.write(prompt)
-
     def clear_term(self):
         """Prepare the terminal for output.
 




More information about the bazaar-commits mailing list