pre-upload: allow repos to pass in custom options to hooks

Currently you can enable hooks in PRESUBMIT.cfg, but not tweak their
behavior.  A dedicated hook name would have to be created.  Instead,
let people pass in an open ended set of options that'll get passed to
the hook and it can do what it wants.

For example, you can enable checkpatch in a repo:
[Hook Overrides]
checkpatch_check: true

And you can pass in specific checkpatch options:
[Hook Overrides Options]
checkpatch_check: --no-tree --ignore=MSLEEP,VOLATILE

BUG=chromium:466264
TEST=`./pre-upload_unittest.py` passes

Change-Id: Ia9f09ecabb6f44785fcf8b78c2d0f8f1d003cea0
Reviewed-on: https://chromium-review.googlesource.com/262396
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-by: Steve Fung <stevefung@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/pre-upload.py b/pre-upload.py
index 383f33e..41f8f30 100755
--- a/pre-upload.py
+++ b/pre-upload.py
@@ -1170,10 +1170,12 @@
     config: A ConfigParser for the project's config file.
   """
   SECTION = 'Hook Overrides'
+  SECTION_OPTIONS = 'Hook Overrides Options'
   if not config.has_section(SECTION):
     return set(), set()
 
   valid_keys = set(_HOOK_FLAGS.iterkeys())
+  hooks = _HOOK_FLAGS.copy()
 
   enable_flags = []
   disable_flags = []
@@ -1183,16 +1185,25 @@
                        (flag, _CONFIG_FILE))
 
     try:
-      if not config.getboolean(SECTION, flag):
-        disable_flags.append(flag)
-      else:
-        enable_flags.append(flag)
+      enabled = config.getboolean(SECTION, flag)
     except ValueError as e:
       raise ValueError('Error: parsing flag "%s" in "%s" failed: %s' %
                        (flag, _CONFIG_FILE, e))
+    if enabled:
+      enable_flags.append(flag)
+    else:
+      disable_flags.append(flag)
 
-  enabled_hooks = set(_HOOK_FLAGS[key] for key in enable_flags)
-  disabled_hooks = set(_HOOK_FLAGS[key] for key in disable_flags)
+    # See if this hook has custom options.
+    if enabled:
+      try:
+        options = config.get(SECTION_OPTIONS, flag)
+        hooks[flag] = functools.partial(hooks[flag], options=options.split())
+      except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
+        pass
+
+  enabled_hooks = set(hooks[x] for x in enable_flags)
+  disabled_hooks = set(hooks[x] for x in disable_flags)
   return enabled_hooks, disabled_hooks