Merge "Log project names as the projects are processed"
diff --git a/jeepyb/cmd/close_pull_requests.py b/jeepyb/cmd/close_pull_requests.py
index 70bc543..c1b6a1f 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!
@@ -54,6 +55,8 @@
 and follow the instructions there to upload your change to Gerrit.
 """
 
+log = logging.getLogger("close_pull_requests")
+
 
 def main():
 
@@ -79,6 +82,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
@@ -93,9 +100,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/cmd/manage_projects.py b/jeepyb/cmd/manage_projects.py
index 91178b1..0e73585 100644
--- a/jeepyb/cmd/manage_projects.py
+++ b/jeepyb/cmd/manage_projects.py
@@ -23,6 +23,7 @@
 # local-git-dir=/var/lib/git
 # gerrit-key=/home/gerrit2/review_site/etc/ssh_host_rsa_key
 # gerrit-committer=Project Creator <openstack-infra@lists.openstack.org>
+# gerrit-replicate=True
 # has-github=True
 # has-wiki=False
 # has-issues=False
@@ -561,6 +562,7 @@
     GERRIT_USER = registry.get_defaults('gerrit-user')
     GERRIT_KEY = registry.get_defaults('gerrit-key')
     GERRIT_GITID = registry.get_defaults('gerrit-committer')
+    GERRIT_REPLICATE = registry.get_defaults('gerrit-replicate', True)
     GERRIT_SYSTEM_USER = registry.get_defaults('gerrit-system-user', 'gerrit2')
     GERRIT_SYSTEM_GROUP = registry.get_defaults('gerrit-system-group',
                                                 'gerrit2')
@@ -644,7 +646,8 @@
                 if project_created:
                     push_to_gerrit(
                         repo_path, project, push_string, remote_url, ssh_env)
-                    gerrit.replicate(project)
+                    if GERRIT_REPLICATE:
+                        gerrit.replicate(project)
 
                 # If we're configured to track upstream, make sure we have
                 # upstream's refs, and then push them to the appropriate
@@ -662,7 +665,7 @@
                         DEFAULT_HAS_ISSUES, DEFAULT_HAS_DOWNLOADS,
                         DEFAULT_HAS_WIKI, GITHUB_SECURE_CONFIG,
                         options, project, description, homepage)
-                    if created:
+                    if created and GERRIT_REPLICATE:
                         gerrit.replicate(project)
 
             except Exception:
diff --git a/jeepyb/cmd/notify_impact.py b/jeepyb/cmd/notify_impact.py
index 09b92bb..029c5d2 100644
--- a/jeepyb/cmd/notify_impact.py
+++ b/jeepyb/cmd/notify_impact.py
@@ -211,6 +211,7 @@
     parser.add_argument('--branch', default=None)
     parser.add_argument('--commit', default=None)
     parser.add_argument('--topic', default=None)
+    parser.add_argument('--change-owner', default=None)
 
     # change-merged
     parser.add_argument('--submitter', default=None)
@@ -219,6 +220,7 @@
     parser.add_argument('--uploader', default=None)
     parser.add_argument('--patchset', default=None)
     parser.add_argument('--is-draft', default=None)
+    parser.add_argument('--kind', default=None)
 
     # Not passed by gerrit:
     parser.add_argument('--impact', default=None)
diff --git a/jeepyb/cmd/openstackwatch.py b/jeepyb/cmd/openstackwatch.py
index 726912a..945674d 100644
--- a/jeepyb/cmd/openstackwatch.py
+++ b/jeepyb/cmd/openstackwatch.py
@@ -90,7 +90,7 @@
         print(msg)
 
 
-def get_javascript(project=None):
+def get_json(project=None):
     url = CONFIG['json_url']
     if project:
         url += "+project:" + project
@@ -99,8 +99,8 @@
     return ret
 
 
-def parse_javascript(javascript):
-    for row in javascript.splitlines():
+def parse_json(content):
+    for row in content.splitlines():
         try:
             json_row = json.loads(row)
         except(ValueError):
@@ -111,11 +111,7 @@
         yield json_row
 
 
-def upload_rss(xml, output_object):
-    if 'swift' not in CONFIG:
-        print(xml)
-        return
-
+def upload_to_swift(content, objectname):
     import swiftclient
     cfg = CONFIG['swift']
     client = swiftclient.Connection(cfg['auth_url'],
@@ -130,11 +126,11 @@
         # eventual consistenties
         time.sleep(1)
 
-    client.put_object(cfg['container'], output_object,
-                      cStringIO.StringIO(xml))
+    client.put_object(cfg['container'], objectname,
+                      cStringIO.StringIO(content))
 
 
-def generate_rss(javascript, project=""):
+def generate_rss(content, project=""):
     title = "OpenStack %s watch RSS feed" % (project)
     rss = PyRSS2Gen.RSS2(
         title=title,
@@ -143,7 +139,7 @@
                     "from Gerrit.",
         lastBuildDate=datetime.datetime.now()
     )
-    for row in parse_javascript(javascript):
+    for row in parse_json(content):
         author = row['owner']['name']
         author += " <%s>" % ('email' in row['owner'] and
                              row['owner']['email']
@@ -164,13 +160,19 @@
 
 def main():
     if CONFIG['output_mode'] == "combined":
-        upload_rss(generate_rss(get_javascript()),
-                   CONFIG['swift']['combined_output_object'])
+        content = generate_rss(get_json())
+        if 'swift' in CONFIG:
+            upload_to_swift(content, CONFIG['swift']['combined_output_object'])
+        else:
+            print(content)
     elif CONFIG['output_mode'] == "multiple":
         for project in CONFIG['projects']:
-            upload_rss(
-                generate_rss(get_javascript(project), project=project),
-                "%s.xml" % (os.path.basename(project)))
+            content = generate_rss(get_json(project), project=project)
+            if 'swift' in CONFIG:
+                objectname = "%s.xml" % os.path.basename(project)
+                upload_to_swift(content, objectname)
+            else:
+                print(content)
 
 if __name__ == '__main__':
     main()
diff --git a/jeepyb/cmd/update_blueprint.py b/jeepyb/cmd/update_blueprint.py
index 0231375..1cff559 100644
--- a/jeepyb/cmd/update_blueprint.py
+++ b/jeepyb/cmd/update_blueprint.py
@@ -139,12 +139,14 @@
     parser.add_argument('--branch', default=None)
     parser.add_argument('--commit', default=None)
     parser.add_argument('--topic', default=None)
+    parser.add_argument('--change-owner', default=None)
     #change-merged
     parser.add_argument('--submitter', default=None)
     # patchset-created
     parser.add_argument('--uploader', default=None)
     parser.add_argument('--patchset', default=None)
     parser.add_argument('--is-draft', default=None)
+    parser.add_argument('--kind', default=None)
 
     args = parser.parse_args()
 
diff --git a/jeepyb/cmd/update_bug.py b/jeepyb/cmd/update_bug.py
index f886ac2..807aa46 100644
--- a/jeepyb/cmd/update_bug.py
+++ b/jeepyb/cmd/update_bug.py
@@ -335,6 +335,7 @@
     parser.add_argument('--branch', default=None)
     parser.add_argument('--commit', default=None)
     parser.add_argument('--topic', default=None)
+    parser.add_argument('--change-owner', default=None)
     # change-abandoned
     parser.add_argument('--abandoner', default=None)
     parser.add_argument('--reason', default=None)
@@ -344,6 +345,7 @@
     parser.add_argument('--uploader', default=None)
     parser.add_argument('--patchset', default=None)
     parser.add_argument('--is-draft', default=None)
+    parser.add_argument('--kind', default=None)
 
     args = parser.parse_args()
 
diff --git a/jeepyb/cmd/welcome_message.py b/jeepyb/cmd/welcome_message.py
index 305ac7c..f4dbdf6 100644
--- a/jeepyb/cmd/welcome_message.py
+++ b/jeepyb/cmd/welcome_message.py
@@ -133,12 +133,14 @@
     parser.add_argument('--branch', default=None)
     parser.add_argument('--commit', default=None)
     parser.add_argument('--topic', default=None)
+    parser.add_argument('--change-owner', default=None)
     # change-merged
     parser.add_argument('--submitter', default=None)
     # patchset-created
     parser.add_argument('--uploader', default=None)
     parser.add_argument('--patchset', default=None)
     parser.add_argument('--is-draft', default=None)
+    parser.add_argument('--kind', default=None)
     # for Welcome Message
     parser.add_argument('--ssh-user', dest='ssh_user',
                         help='The gerrit welcome message user')
diff --git a/jeepyb/projects.py b/jeepyb/projects.py
index 713072d..81db5ba 100644
--- a/jeepyb/projects.py
+++ b/jeepyb/projects.py
@@ -26,6 +26,8 @@
     - no-launchpad-blueprints
 """
 
+import ConfigParser
+
 import jeepyb.utils as u
 
 
@@ -56,6 +58,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']