Commit 7bf1b5dc authored by maruel@chromium.org's avatar maruel@chromium.org

Update upload.py from upstream at d5f7dffc2dbb.

Fix issue with invalid password in keyring and git renames.

R=petermayo@chromium.org
BUG=144408

Review URL: https://chromiumcodereview.appspot.com/10907089

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@155898 0039d316-1c4b-4281-b951-d872f2087c98
parent 9d72d2b9
...@@ -170,6 +170,9 @@ class ClientLoginError(urllib2.HTTPError): ...@@ -170,6 +170,9 @@ class ClientLoginError(urllib2.HTTPError):
@property @property
def reason(self): 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 return self._reason
...@@ -178,7 +181,7 @@ class AbstractRpcServer(object): ...@@ -178,7 +181,7 @@ class AbstractRpcServer(object):
def __init__(self, host, auth_function, host_override=None, extra_headers={}, def __init__(self, host, auth_function, host_override=None, extra_headers={},
save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): save_cookies=False, account_type=AUTH_ACCOUNT_TYPE):
"""Creates a new HttpRpcServer. """Creates a new AbstractRpcServer.
Args: Args:
host: The host to send requests to. host: The host to send requests to.
...@@ -599,6 +602,48 @@ group.add_option("--p4_user", action="store", dest="p4_user", ...@@ -599,6 +602,48 @@ group.add_option("--p4_user", action="store", dest="p4_user",
metavar="P4_USER", default=None, metavar="P4_USER", default=None,
help=("Perforce user")) 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, def GetRpcServer(server, email=None, host_override=None, save_cookies=True,
account_type=AUTH_ACCOUNT_TYPE): account_type=AUTH_ACCOUNT_TYPE):
"""Returns an instance of an AbstractRpcServer. """Returns an instance of an AbstractRpcServer.
...@@ -613,18 +658,16 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True, ...@@ -613,18 +658,16 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True,
or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE.
Returns: 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. # If this is the dev_appserver, use fake authentication.
host = (host_override or server).lower() host = (host_override or server).lower()
if re.match(r'(http://)?localhost([:/]|$)', host): if re.match(r'(http://)?localhost([:/]|$)', host):
if email is None: if email is None:
email = "test@example.com" email = "test@example.com"
logging.info("Using debug user %s. Override with --email" % email) logging.info("Using debug user %s. Override with --email" % email)
server = rpc_server_class( server = HttpRpcServer(
server, server,
lambda: (email, "password"), lambda: (email, "password"),
host_override=host_override, host_override=host_override,
...@@ -636,37 +679,10 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True, ...@@ -636,37 +679,10 @@ def GetRpcServer(server, email=None, host_override=None, save_cookies=True,
server.authenticated = True server.authenticated = True
return server return server
def GetUserCredentials(): return HttpRpcServer(server,
"""Prompts the user for a username and password.""" KeyringCreds(server, host, email).GetUserCredentials,
# Create a local alias to the email variable to avoid Python's crazy host_override=host_override,
# scoping rules. save_cookies=save_cookies)
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)
def EncodeMultipartFormData(fields, files): def EncodeMultipartFormData(fields, files):
...@@ -1299,21 +1315,24 @@ class GitVCS(VersionControlSystem): ...@@ -1299,21 +1315,24 @@ class GitVCS(VersionControlSystem):
# this by overriding the environment (but there is still a problem if the # this by overriding the environment (but there is still a problem if the
# git config key "diff.external" is used). # git config key "diff.external" is used).
env = os.environ.copy() 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. # -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 # 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, # review when a file is renamed. So, get a diff with ONLY deletes, then
# then the diff of everything except deleted files with rename and copy # append a diff (with rename detection), without deletes.
# support enabled.
cmd = [ cmd = [
"git", "diff", "--no-color", "--no-ext-diff", "--full-index", "git", "diff", "--no-color", "--no-ext-diff", "--full-index",
"--ignore-submodules", "--ignore-submodules",
] ]
diff = RunShell( 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( 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) env=env, silent_ok=True)
# The CL could be only file deletion or not. So accept silent diff for both # The CL could be only file deletion or not. So accept silent diff for both
# commands then check for an empty diff manually. # commands then check for an empty diff manually.
if not diff: if not diff:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment