Be more careful about when to close pull requests

* jeepyb/cmd/close_pull_requests.py: Only try to close pull requests
if actually configured to use GitHub. Also log verbose errors when
it fails to find the project there.

* jeepyb/projects.py: Add a convenience has_github function to
encode the somewhat twisty per-project override/default fallback
determination for the has-github global bool and local flag.

Change-Id: I0bbfabd2f110269cb8331383173f0dd588500778
diff --git a/jeepyb/cmd/close_pull_requests.py b/jeepyb/cmd/close_pull_requests.py
index ce07501..086d761 100644
--- a/jeepyb/cmd/close_pull_requests.py
+++ b/jeepyb/cmd/close_pull_requests.py
@@ -43,6 +43,7 @@
 import logging
 import os
 
+import jeepyb.projects as p
 import jeepyb.utils as u
 
 MESSAGE = """Thank you for contributing to %(project)s!
@@ -53,6 +54,8 @@
 instructions there to upload your change to Gerrit.
 """
 
+log = logging.getLogger("close_pull_requests")
+
 
 def main():
 
@@ -78,6 +81,10 @@
     for section in registry.configs_list:
         project = section['project']
 
+        # Make sure we're using GitHub for this project:
+        if not p.has_github(project):
+            continue
+
         # Make sure we're supposed to close pull requests for this project:
         if 'options' in section and 'has-pull-requests' in section['options']:
             continue
@@ -92,9 +99,8 @@
                 repo = org.get_repo(project_split[1])
             else:
                 repo = ghub.get_user().get_repo(project)
-        except KeyError:
-            continue
-        except github.GithubException:
+        except (KeyError, github.GithubException):
+            log.exception("Could not find project %s on GitHub." % project)
             continue
 
         # Close each pull request
diff --git a/jeepyb/projects.py b/jeepyb/projects.py
index a801830..e2015c1 100644
--- a/jeepyb/projects.py
+++ b/jeepyb/projects.py
@@ -24,6 +24,8 @@
     - no-launchpad-blueprints
 """
 
+import ConfigParser
+
 import jeepyb.utils as u
 
 
@@ -52,6 +54,23 @@
     return _is_no_launchpad(project_full_name, 'blueprints')
 
 
+def has_github(project_full_name):
+    try:
+        if not registry.defaults.get('projects', 'has-github'):
+            # If the default is not to use GitHub...
+            try:
+                # ...then rely on the existence of a per-project option...
+                return 'has-github' in registry[project_full_name]['options']
+            except KeyError:
+                # ...and if it's not set, then still don't use it.
+                return False
+    # It's okay if the global option or even the section for this don't exist.
+    except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
+        pass
+    # If we got this far, we either explicitly or implicitly default to use it.
+    return True
+
+
 def is_direct_release(project_full_name):
     try:
         return 'direct-release' in registry[project_full_name]['options']