Commit 8e2bb16a authored by maruel@chromium.org's avatar maruel@chromium.org

Update upload.py to ba420db469ba.

The main fix is 'Accept new empty files, like __init__.py'

TBR=dpranke@chromium.org
BUG=
TEST=


Review URL: http://codereview.chromium.org/8519005

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@109431 0039d316-1c4b-4281-b951-d872f2087c98
parent 7eda862b
...@@ -461,8 +461,39 @@ class HttpRpcServer(AbstractRpcServer): ...@@ -461,8 +461,39 @@ class HttpRpcServer(AbstractRpcServer):
return opener return opener
class CondensedHelpFormatter(optparse.IndentedHelpFormatter):
"""Frees more horizontal space by removing indentation from group
options and collapsing arguments between short and long, e.g.
'-o ARG, --opt=ARG' to -o --opt ARG"""
def format_heading(self, heading):
return "%s:\n" % heading
def format_option(self, option):
self.dedent()
res = optparse.HelpFormatter.format_option(self, option)
self.indent()
return res
def format_option_strings(self, option):
self.set_long_opt_delimiter(" ")
optstr = optparse.HelpFormatter.format_option_strings(self, option)
optlist = optstr.split(", ")
if len(optlist) > 1:
if option.takes_value():
# strip METAVAR from all but the last option
optlist = [x.split()[0] for x in optlist[:-1]] + optlist[-1:]
optstr = " ".join(optlist)
return optstr
parser = optparse.OptionParser( parser = optparse.OptionParser(
usage="%prog [options] [-- diff_options] [path...]") usage="%prog [options] [-- diff_options] [path...]",
add_help_option=False,
formatter=CondensedHelpFormatter()
)
parser.add_option("-h", "--help", action="store_true",
help="Show this help message and exit.")
parser.add_option("-y", "--assume_yes", action="store_true", parser.add_option("-y", "--assume_yes", action="store_true",
dest="assume_yes", default=False, dest="assume_yes", default=False,
help="Assume that the answer to yes/no questions is 'yes'.") help="Assume that the answer to yes/no questions is 'yes'.")
...@@ -528,7 +559,7 @@ group.add_option("-i", "--issue", type="int", action="store", ...@@ -528,7 +559,7 @@ group.add_option("-i", "--issue", type="int", action="store",
metavar="ISSUE", default=None, metavar="ISSUE", default=None,
help="Issue number to which to add. Defaults to new issue.") help="Issue number to which to add. Defaults to new issue.")
group.add_option("--base_url", action="store", dest="base_url", default=None, group.add_option("--base_url", action="store", dest="base_url", default=None,
help="Base repository URL (listed as \"Base URL\" when " help="Base URL path for files (listed as \"Base URL\" when "
"viewing issue). If omitted, will be guessed automatically " "viewing issue). If omitted, will be guessed automatically "
"for SVN repos and left blank for others.") "for SVN repos and left blank for others.")
group.add_option("--download_base", action="store_true", group.add_option("--download_base", action="store_true",
...@@ -544,10 +575,8 @@ group.add_option("--send_mail", action="store_true", ...@@ -544,10 +575,8 @@ group.add_option("--send_mail", action="store_true",
help="Send notification email to reviewers.") help="Send notification email to reviewers.")
group.add_option("-p", "--send_patch", action="store_true", group.add_option("-p", "--send_patch", action="store_true",
dest="send_patch", default=False, dest="send_patch", default=False,
help="Send notification email to reviewers, with a diff of " help="Same as --send_mail, but include diff as an "
"the changes included as an attachment instead of " "attachment, and prepend email subject with 'PATCH:'.")
"inline. Also prepends 'PATCH:' to the email subject. "
"(implies --send_mail)")
group.add_option("--vcs", action="store", dest="vcs", group.add_option("--vcs", action="store", dest="vcs",
metavar="VCS", default=None, metavar="VCS", default=None,
help=("Version control system (optional, usually upload.py " help=("Version control system (optional, usually upload.py "
...@@ -757,6 +786,12 @@ class VersionControlSystem(object): ...@@ -757,6 +786,12 @@ class VersionControlSystem(object):
""" """
self.options = options self.options = options
def GetGUID(self):
"""Return string to distinguish the repository from others, for example to
query all opened review issues for it"""
raise NotImplementedError(
"abstract method -- subclass %s must override" % self.__class__)
def PostProcessDiff(self, diff): def PostProcessDiff(self, diff):
"""Return the diff with any special post processing this VCS needs, e.g. """Return the diff with any special post processing this VCS needs, e.g.
to include an svn-style "Index:".""" to include an svn-style "Index:"."""
...@@ -911,6 +946,9 @@ class SubversionVCS(VersionControlSystem): ...@@ -911,6 +946,9 @@ class SubversionVCS(VersionControlSystem):
required = self.options.download_base or self.options.revision is not None required = self.options.download_base or self.options.revision is not None
self.svn_base = self._GuessBase(required) self.svn_base = self._GuessBase(required)
def GetGUID(self):
return self._GetInfo("Repository UUID")
def GuessBase(self, required): def GuessBase(self, required):
"""Wrapper for _GuessBase.""" """Wrapper for _GuessBase."""
return self.svn_base return self.svn_base
...@@ -922,12 +960,11 @@ class SubversionVCS(VersionControlSystem): ...@@ -922,12 +960,11 @@ class SubversionVCS(VersionControlSystem):
required: If true, exits if the url can't be guessed, otherwise None is required: If true, exits if the url can't be guessed, otherwise None is
returned. returned.
""" """
info = RunShell(["svn", "info"]) url = self._GetInfo("URL")
for line in info.splitlines(): if url:
if line.startswith("URL: "):
url = line.split()[1]
scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
guess = "" guess = ""
# TODO(anatoli) - repository specific hacks should be handled by server
if netloc == "svn.python.org" and scheme == "svn+ssh": if netloc == "svn.python.org" and scheme == "svn+ssh":
path = "projects" + path path = "projects" + path
scheme = "http" scheme = "http"
...@@ -944,6 +981,12 @@ class SubversionVCS(VersionControlSystem): ...@@ -944,6 +981,12 @@ class SubversionVCS(VersionControlSystem):
ErrorExit("Can't find URL in output from svn info") ErrorExit("Can't find URL in output from svn info")
return None return None
def _GetInfo(self, key):
"""Parses 'svn info' for current dir. Returns value for key or None"""
for line in RunShell(["svn", "info"]).splitlines():
if line.startswith(key + ": "):
return line.split(":", 1)[1].strip()
def _EscapeFilename(self, filename): def _EscapeFilename(self, filename):
"""Escapes filename for SVN commands.""" """Escapes filename for SVN commands."""
if "@" in filename and not filename.endswith("@"): if "@" in filename and not filename.endswith("@"):
...@@ -1181,6 +1224,15 @@ class GitVCS(VersionControlSystem): ...@@ -1181,6 +1224,15 @@ class GitVCS(VersionControlSystem):
# Map of new filename -> old filename for renames. # Map of new filename -> old filename for renames.
self.renames = {} self.renames = {}
def GetGUID(self):
revlist = RunShell("git rev-list --parents HEAD".split()).splitlines()
# M-A: Return the 1st root hash, there could be multiple when a
# subtree is merged. In that case, more analysis would need to
# be done to figure out which HEAD is the 'most representative'.
for r in revlist:
if ' ' not in r:
return r
def PostProcessDiff(self, gitdiff): def PostProcessDiff(self, gitdiff):
"""Converts the diff output to include an svn-style "Index:" line as well """Converts the diff output to include an svn-style "Index:" line as well
as record the hashes of the files, so we can upload them along with our as record the hashes of the files, so we can upload them along with our
...@@ -1291,7 +1343,8 @@ class GitVCS(VersionControlSystem): ...@@ -1291,7 +1343,8 @@ class GitVCS(VersionControlSystem):
status = "A +" # Match svn attribute name for renames. status = "A +" # Match svn attribute name for renames.
if filename not in self.hashes: if filename not in self.hashes:
# If a rename doesn't change the content, we never get a hash. # If a rename doesn't change the content, we never get a hash.
base_content = RunShell(["git", "show", "HEAD:" + filename]) base_content = RunShell(
["git", "show", "HEAD:" + filename], silent_ok=True)
elif not hash_before: elif not hash_before:
status = "A" status = "A"
base_content = "" base_content = ""
...@@ -1323,6 +1376,10 @@ class CVSVCS(VersionControlSystem): ...@@ -1323,6 +1376,10 @@ class CVSVCS(VersionControlSystem):
def __init__(self, options): def __init__(self, options):
super(CVSVCS, self).__init__(options) super(CVSVCS, self).__init__(options)
def GetGUID(self):
"""For now we don't know how to get repository ID for CVS"""
return
def GetOriginalContent_(self, filename): def GetOriginalContent_(self, filename):
RunShell(["cvs", "up", filename], silent_ok=True) RunShell(["cvs", "up", filename], silent_ok=True)
# TODO need detect file content encoding # TODO need detect file content encoding
...@@ -1398,6 +1455,12 @@ class MercurialVCS(VersionControlSystem): ...@@ -1398,6 +1455,12 @@ class MercurialVCS(VersionControlSystem):
else: else:
self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip()
def GetGUID(self):
# See chapter "Uniquely identifying a repository"
# http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html
info = RunShell("hg log -r0 --template {node}".split())
return info.strip()
def _GetRelPath(self, filename): def _GetRelPath(self, filename):
"""Get relative path of a file according to the current directory, """Get relative path of a file according to the current directory,
given its logical path in the repo.""" given its logical path in the repo."""
...@@ -1522,6 +1585,10 @@ class PerforceVCS(VersionControlSystem): ...@@ -1522,6 +1585,10 @@ class PerforceVCS(VersionControlSystem):
if len(lines): if len(lines):
options.message = lines[0] options.message = lines[0]
def GetGUID(self):
"""For now we don't know how to get repository ID for Perforce"""
return
def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False, def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False,
universal_newlines=True): universal_newlines=True):
args = ["p4"] args = ["p4"]
...@@ -2108,6 +2175,14 @@ def RealMain(argv, data=None): ...@@ -2108,6 +2175,14 @@ def RealMain(argv, data=None):
script (applies only to SVN checkouts). script (applies only to SVN checkouts).
""" """
options, args = parser.parse_args(argv[1:]) options, args = parser.parse_args(argv[1:])
if options.help:
if options.verbose < 2:
# hide Perforce options
parser.epilog = "Use '--help -v' to show additional Perforce options."
parser.option_groups.remove(parser.get_option_group('--p4_port'))
parser.print_help()
sys.exit(0)
global verbosity global verbosity
verbosity = options.verbose verbosity = options.verbose
if verbosity >= 3: if verbosity >= 3:
...@@ -2157,6 +2232,10 @@ def RealMain(argv, data=None): ...@@ -2157,6 +2232,10 @@ def RealMain(argv, data=None):
options.save_cookies, options.save_cookies,
options.account_type) options.account_type)
form_fields = [("subject", message)] form_fields = [("subject", message)]
repo_guid = vcs.GetGUID()
if repo_guid:
form_fields.append(("repo_guid", repo_guid))
if base: if base:
b = urlparse.urlparse(base) b = urlparse.urlparse(base)
username, netloc = urllib.splituser(b.netloc) username, netloc = urllib.splituser(b.netloc)
......
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