Index: third_party/upload.py |
diff --git a/third_party/upload.py b/third_party/upload.py |
index abd17c742f7bccf4bd7e7ab2cd1c8c2d84381459..3570b50e9888bbc1cc915c59c44031db9b647d40 100755 |
--- a/third_party/upload.py |
+++ b/third_party/upload.py |
@@ -170,6 +170,9 @@ class ClientLoginError(urllib2.HTTPError): |
@property |
def reason(self): |
+ # reason is a property on python 2.7 but a member variable on <=2.6. |
+ # self.args is modified so it cannot be used as-is so save the value in |
+ # self._reason. |
return self._reason |
@@ -178,7 +181,7 @@ class AbstractRpcServer(object): |
def __init__(self, host, auth_function, host_override=None, extra_headers={}, |
save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): |
- """Creates a new HttpRpcServer. |
+ """Creates a new AbstractRpcServer. |
Args: |
host: The host to send requests to. |
@@ -599,6 +602,48 @@ group.add_option("--p4_user", action="store", dest="p4_user", |
metavar="P4_USER", default=None, |
help=("Perforce user")) |
+ |
+class KeyringCreds(object): |
+ def __init__(self, server, host, email): |
+ self.server = server |
+ self.host = host |
+ self.email = email |
+ self.accounts_seen = set() |
+ |
+ def GetUserCredentials(self): |
+ """Prompts the user for a username and password. |
+ |
+ Only use keyring on the initial call. If the keyring contains the wrong |
+ password, we want to give the user a chance to enter another one. |
+ """ |
+ # Create a local alias to the email variable to avoid Python's crazy |
+ # scoping rules. |
+ global keyring |
+ email = self.email |
+ if email is None: |
+ email = GetEmail("Email (login for uploading to %s)" % self.server) |
+ password = None |
+ if keyring and not email in self.accounts_seen: |
+ try: |
+ password = keyring.get_password(self.host, email) |
+ except: |
+ # Sadly, we have to trap all errors here as |
+ # gnomekeyring.IOError inherits from object. :/ |
+ print "Failed to get password from keyring" |
+ keyring = None |
+ if password is not None: |
+ print "Using password from system keyring." |
+ self.accounts_seen.add(email) |
+ else: |
+ password = getpass.getpass("Password for %s: " % email) |
+ if keyring: |
+ answer = raw_input("Store password in system keyring?(y/N) ").strip() |
+ if answer == "y": |
+ keyring.set_password(host, email, password) |
+ self.accounts_seen.add(email) |
+ return (email, password) |
+ |
+ |
def GetRpcServer(server, email=None, host_override=None, save_cookies=True, |
account_type=AUTH_ACCOUNT_TYPE): |
"""Returns an instance of an AbstractRpcServer. |
@@ -613,18 +658,16 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True, |
or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. |
Returns: |
- A new AbstractRpcServer, on which RPC calls can be made. |
+ A new HttpRpcServer, on which RPC calls can be made. |
""" |
- rpc_server_class = HttpRpcServer |
- |
# If this is the dev_appserver, use fake authentication. |
host = (host_override or server).lower() |
if re.match(r'(http://)?localhost([:/]|$)', host): |
if email is None: |
email = "test@example.com" |
logging.info("Using debug user %s. Override with --email" % email) |
- server = rpc_server_class( |
+ server = HttpRpcServer( |
server, |
lambda: (email, "password"), |
host_override=host_override, |
@@ -636,37 +679,10 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True, |
server.authenticated = True |
return server |
- def GetUserCredentials(): |
- """Prompts the user for a username and password.""" |
- # Create a local alias to the email variable to avoid Python's crazy |
- # scoping rules. |
- global keyring |
- local_email = email |
- if local_email is None: |
- local_email = GetEmail("Email (login for uploading to %s)" % server) |
- password = None |
- if keyring: |
- try: |
- password = keyring.get_password(host, local_email) |
- except: |
- # Sadly, we have to trap all errors here as |
- # gnomekeyring.IOError inherits from object. :/ |
- print "Failed to get password from keyring" |
- keyring = None |
- if password is not None: |
- print "Using password from system keyring." |
- else: |
- password = getpass.getpass("Password for %s: " % local_email) |
- if keyring: |
- answer = raw_input("Store password in system keyring?(y/N) ").strip() |
- if answer == "y": |
- keyring.set_password(host, local_email, password) |
- return (local_email, password) |
- |
- return rpc_server_class(server, |
- GetUserCredentials, |
- host_override=host_override, |
- save_cookies=save_cookies) |
+ return HttpRpcServer(server, |
+ KeyringCreds(server, host, email).GetUserCredentials, |
+ host_override=host_override, |
+ save_cookies=save_cookies) |
def EncodeMultipartFormData(fields, files): |
@@ -1299,21 +1315,24 @@ class GitVCS(VersionControlSystem): |
# this by overriding the environment (but there is still a problem if the |
# git config key "diff.external" is used). |
env = os.environ.copy() |
- if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] |
+ if "GIT_EXTERNAL_DIFF" in env: |
+ del env["GIT_EXTERNAL_DIFF"] |
# -M/-C will not print the diff for the deleted file when a file is renamed. |
# This is confusing because the original file will not be shown on the |
- # review when a file is renamed. So first get the diff of all deleted files, |
- # then the diff of everything except deleted files with rename and copy |
- # support enabled. |
+ # review when a file is renamed. So, get a diff with ONLY deletes, then |
+ # append a diff (with rename detection), without deletes. |
cmd = [ |
"git", "diff", "--no-color", "--no-ext-diff", "--full-index", |
"--ignore-submodules", |
] |
diff = RunShell( |
- cmd + ["--diff-filter=D"] + extra_args, env=env, silent_ok=True) |
+ cmd + ["--no-renames", "--diff-filter=D"] + extra_args, |
+ env=env, silent_ok=True) |
diff += RunShell( |
- cmd + ["--find-copies-harder", "--diff-filter=ACMRT"] + extra_args, |
+ cmd + ["--find-copies-harder", "-l100000", "--diff-filter=AMCRT"] |
+ + extra_args, |
env=env, silent_ok=True) |
+ |
# The CL could be only file deletion or not. So accept silent diff for both |
# commands then check for an empty diff manually. |
if not diff: |