Multiple project groups.

Jeepyb now pulls all project groups listed in review.projects.yaml
to check for bugs or blueprints. This is to support multiple
project group membership in storyboard. If 'groups' is not found,
it will fallback to the legacy 'group' or the short project name,
wrapped in an array.

Change-Id: I5f6d09fce609f387b089840f3903303869f33767
diff --git a/jeepyb/cmd/update_blueprint.py b/jeepyb/cmd/update_blueprint.py
index 2ce52f3..0231375 100644
--- a/jeepyb/cmd/update_blueprint.py
+++ b/jeepyb/cmd/update_blueprint.py
@@ -68,11 +68,18 @@
 
 
 def update_spec(launchpad, project, name, subject, link, topic=None):
+    spec = None
+
     if p.is_no_launchpad_blueprints(project):
         return
 
-    project = p.project_to_group(project)
-    spec = launchpad.projects[project].getSpecification(name=name)
+    projects = p.project_to_groups(project)
+
+    for project in projects:
+        spec = launchpad.projects[project].getSpecification(name=name)
+        if spec:
+            break
+
     if not spec:
         return
 
diff --git a/jeepyb/cmd/update_bug.py b/jeepyb/cmd/update_bug.py
index 8644106..d0c8cd0 100644
--- a/jeepyb/cmd/update_bug.py
+++ b/jeepyb/cmd/update_bug.py
@@ -290,7 +290,7 @@
     if p.is_no_launchpad_bugs(project):
         return []
 
-    project = p.project_to_group(project)
+    projects = p.project_to_groups(project)
 
     part1 = r'^[\t ]*(?P<prefix>[-\w]+)?[\s:]*'
     part2 = r'(?:\b(?:bug|lp)\b[\s#:]*)+'
@@ -307,7 +307,7 @@
             try:
                 lp_bug = launchpad.bugs[bug_num]
                 for lp_task in lp_bug.bug_tasks:
-                    if lp_task.bug_target_name == project:
+                    if lp_task.bug_target_name in projects:
                         bugtasks[bug_num] = Task(lp_task, prefix)
                         break
             except KeyError:
diff --git a/jeepyb/projects.py b/jeepyb/projects.py
index a801830..713072d 100644
--- a/jeepyb/projects.py
+++ b/jeepyb/projects.py
@@ -18,6 +18,8 @@
 - project: some/project
   launchpad: awesomeproject
   description: Best project ever.
+  groups:
+    - awesome-group
   options:
     - direct-release
     - no-launchpad-bugs
@@ -30,10 +32,12 @@
 registry = u.ProjectsRegistry()
 
 
-def project_to_group(project_full_name):
-    return registry[project_full_name].get(
-        'group', registry[project_full_name].get(
-            'launchpad', u.short_project_name(project_full_name)))
+def project_to_groups(project_full_name):
+    return registry[project_full_name] \
+        .get('groups',
+             [registry[project_full_name].get('group',
+                                              u.short_project_name(
+                                                  project_full_name))])
 
 
 def _is_no_launchpad(project_full_name, obj_type):