Merge "Allow configurable mappings to different LP projects"
diff --git a/jeepyb/cmd/create_cgitrepos.py b/jeepyb/cmd/create_cgitrepos.py
index 3fc4f19..bda452f 100644
--- a/jeepyb/cmd/create_cgitrepos.py
+++ b/jeepyb/cmd/create_cgitrepos.py
@@ -31,6 +31,9 @@
                             '/etc/cgitrepos')
 REPO_PATH = os.environ.get('REPO_PATH',
                            '/var/lib/git')
+SCRATCH_SUBPATH = os.environ.get('SCRATCH_SUBPATH')
+SCRATCH_OWNER = os.environ.get('SCRATCH_OWNER', 'scratch')
+SCRATCH_GROUP = os.environ.get('SCRATCH_GROUP', 'scratch')
 CGIT_USER = os.environ.get('CGIT_USER', 'cgit')
 CGIT_GROUP = os.environ.get('CGIT_GROUP', 'cgit')
 
@@ -45,6 +48,20 @@
         assert name not in names
         names.add(name)
         gitorgs.setdefault(org, []).append((name, description))
+    if SCRATCH_SUBPATH:
+        assert SCRATCH_SUBPATH not in gitorgs
+        scratch_path = os.path.join(REPO_PATH, SCRATCH_SUBPATH)
+        for org in gitorgs:
+            scratch_dir = os.path.join(scratch_path, org)
+            if not os.path.isdir(scratch_dir):
+                os.makedirs(scratch_dir)
+            projects = gitorgs[org]
+            for (name, description) in projects:
+                scratch_repo = "%s.git" % os.path.join(scratch_dir, name)
+                subprocess.call(['git', 'init', '--bare', scratch_repo])
+                subprocess.call(['chown', '-R', '%s:%s'
+                                 % (SCRATCH_OWNER, SCRATCH_GROUP),
+                                 scratch_repo])
     for org in gitorgs:
         if not os.path.isdir('%s/%s' % (REPO_PATH, org)):
             os.makedirs('%s/%s' % (REPO_PATH, org))
diff --git a/jeepyb/cmd/manage_projects.py b/jeepyb/cmd/manage_projects.py
index 634ce42..844eeb7 100644
--- a/jeepyb/cmd/manage_projects.py
+++ b/jeepyb/cmd/manage_projects.py
@@ -14,21 +14,24 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-# manage_projects.py reads a project config file called projects.yaml
+# manage_projects.py reads a config file called projects.ini
 # It should look like:
 
-# - homepage: http://openstack.org
-#   gerrit-host: review.openstack.org
-#   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>
-#   has-github: True
-#   has-wiki: False
-#   has-issues: False
-#   has-downloads: False
-#   acl-dir: /home/gerrit2/acls
-#   acl-base: /home/gerrit2/acls/project.config
-# ---
+# [projects]
+# homepage=http://openstack.org
+# gerrit-host=review.openstack.org
+# 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>
+# has-github=True
+# has-wiki=False
+# has-issues=False
+# has-downloads=False
+# acl-dir=/home/gerrit2/acls
+# acl-base=/home/gerrit2/acls/project.config
+#
+# manage_projects.py reads a project listing file called projects.yaml
+# It should look like:
 # - project: PROJECT_NAME
 #   options:
 #    - has-wiki
@@ -176,7 +179,7 @@
     con = jeepyb.gerritdb.connect()
     for x in range(10):
         cursor = con.cursor()
-        cursor.execute(query, group)
+        cursor.execute(query, (group,))
         data = cursor.fetchone()
         cursor.close()
         con.commit()
@@ -235,21 +238,16 @@
     return dict(GIT_SSH=name)
 
 
-def create_github_project(defaults, options, project, description, homepage):
+def create_github_project(
+        default_has_issues, default_has_downloads, default_has_wiki,
+        github_secure_config, options, project, description, homepage):
     created = False
-    default_has_issues = defaults.get('has-issues', False)
-    default_has_downloads = defaults.get('has-downloads', False)
-    default_has_wiki = defaults.get('has-wiki', False)
     has_issues = 'has-issues' in options or default_has_issues
     has_downloads = 'has-downloads' in options or default_has_downloads
     has_wiki = 'has-wiki' in options or default_has_wiki
 
-    GITHUB_SECURE_CONFIG = defaults.get(
-        'github-config',
-        '/etc/github/github-projects.secure.config')
-
     secure_config = ConfigParser.ConfigParser()
-    secure_config.read(GITHUB_SECURE_CONFIG)
+    secure_config.read(github_secure_config)
 
     # Project creation doesn't work via oauth
     ghub = github.Github(secure_config.get("github", "username"),
@@ -501,6 +499,15 @@
                        git_mirror_path))
 
 
+def get_option(options, section, key, default):
+    if options.has_option(section, key):
+        if type(default) is bool:
+            return options.getboolean(section, key)
+        else:
+            return options.get(section, key)
+    return default
+
+
 def main():
     parser = argparse.ArgumentParser(description='Manage projects')
     parser.add_argument('-v', dest='verbose', action='store_true',
@@ -519,19 +526,65 @@
     PROJECTS_YAML = os.environ.get('PROJECTS_YAML',
                                    '/home/gerrit2/projects.yaml')
     configs = [config for config in yaml.load_all(open(PROJECTS_YAML))]
-    defaults = configs[0][0]
-    default_has_github = defaults.get('has-github', True)
 
-    LOCAL_GIT_DIR = defaults.get('local-git-dir', '/var/lib/git')
-    JEEPYB_CACHE_DIR = defaults.get('jeepyb-cache-dir', '/var/lib/jeepyb')
-    ACL_DIR = defaults.get('acl-dir')
-    GERRIT_HOST = defaults.get('gerrit-host')
-    GERRIT_PORT = int(defaults.get('gerrit-port', '29418'))
-    GERRIT_USER = defaults.get('gerrit-user')
-    GERRIT_KEY = defaults.get('gerrit-key')
-    GERRIT_GITID = defaults.get('gerrit-committer')
-    GERRIT_SYSTEM_USER = defaults.get('gerrit-system-user', 'gerrit2')
-    GERRIT_SYSTEM_GROUP = defaults.get('gerrit-system-group', 'gerrit2')
+    PROJECTS_INI = os.environ.get('PROJECTS_INI',
+                                  '/home/gerrit2/projects.ini')
+    if os.path.exists(PROJECTS_INI):
+        # New-style - supports projects.ini
+        projects_yaml_list = configs[0]
+        defaults = ConfigParser.ConfigParser()
+        defaults.read(PROJECTS_INI)
+
+        default_has_github = get_option(
+            defaults, 'projects', 'has-github', True)
+
+        LOCAL_GIT_DIR = get_option(
+            defaults, 'projects', 'local-git-dir', '/var/lib/git')
+        JEEPYB_CACHE_DIR = get_option(
+            defaults, 'projects', 'jeepyb-cache-dir', '/var/lib/jeepyb')
+        ACL_DIR = defaults.get('projects', 'acl-dir')
+        GERRIT_HOST = defaults.get('projects', 'gerrit-host')
+        GERRIT_PORT = int(get_option(
+            defaults, 'projects', 'gerrit-port', '29418'))
+        GERRIT_USER = defaults.get('projects', 'gerrit-user')
+        GERRIT_KEY = defaults.get('projects', 'gerrit-key')
+        GERRIT_GITID = defaults.get('projects', 'gerrit-committer')
+        GERRIT_SYSTEM_USER = get_option(
+            defaults, 'projects', 'gerrit-system-user', 'gerrit2')
+        GERRIT_SYSTEM_GROUP = get_option(
+            defaults, 'projects', 'gerrit-system-group', 'gerrit2')
+        DEFAULT_HOMEPAGE = get_option(defaults, 'projects', 'homepage', None)
+        DEFAULT_HAS_ISSUES = get_option(
+            defaults, 'projects', 'has-issues', False)
+        DEFAULT_HAS_DOWNLOADS = get_option(
+            defaults, 'projects', 'has-downloads', False)
+        DEFAULT_HAS_WIKI = get_option(defaults, 'projects', 'has-wiki', False)
+        GITHUB_SECURE_CONFIG = get_option(
+            defaults, 'projects', 'github-config',
+            '/etc/github/github-projects.secure.config')
+    else:
+        # Old-style - embedded
+        projects_yaml_list = configs[1]
+        defaults = configs[0][0]
+        default_has_github = defaults.get('has-github', True)
+
+        LOCAL_GIT_DIR = defaults.get('local-git-dir', '/var/lib/git')
+        JEEPYB_CACHE_DIR = defaults.get('jeepyb-cache-dir', '/var/lib/jeepyb')
+        ACL_DIR = defaults.get('acl-dir')
+        GERRIT_HOST = defaults.get('gerrit-host')
+        GERRIT_PORT = int(defaults.get('gerrit-port', '29418'))
+        GERRIT_USER = defaults.get('gerrit-user')
+        GERRIT_KEY = defaults.get('gerrit-key')
+        GERRIT_GITID = defaults.get('gerrit-committer')
+        GERRIT_SYSTEM_USER = defaults.get('gerrit-system-user', 'gerrit2')
+        GERRIT_SYSTEM_GROUP = defaults.get('gerrit-system-group', 'gerrit2')
+        DEFAULT_HOMEPAGE = defaults.get('homepage', None)
+        DEFAULT_HAS_ISSUES = defaults.get('has-issues', False)
+        DEFAULT_HAS_DOWNLOADS = defaults.get('has-downloads', False)
+        DEFAULT_HAS_WIKI = defaults.get('has-wiki', False)
+        GITHUB_SECURE_CONFIG = defaults.get(
+            'github-config',
+            '/etc/github/github-projects.secure.config')
 
     gerrit = gerritlib.gerrit.Gerrit('localhost',
                                      GERRIT_USER,
@@ -541,7 +594,7 @@
     ssh_env = make_ssh_wrapper(GERRIT_USER, GERRIT_KEY)
     try:
 
-        for section in configs[1]:
+        for section in projects_yaml_list:
             project = section['project']
             if args.projects and project not in args.projects:
                 continue
@@ -550,8 +603,7 @@
                 # Figure out all of the options
                 options = section.get('options', dict())
                 description = section.get('description', None)
-                homepage = section.get(
-                    'homepage', defaults.get('homepage', None))
+                homepage = section.get('homepage', DEFAULT_HOMEPAGE)
                 upstream = section.get('upstream', None)
                 upstream_prefix = section.get('upstream-prefix', None)
                 track_upstream = 'track-upstream' in options
@@ -612,7 +664,9 @@
 
                 if 'has-github' in options or default_has_github:
                     created = create_github_project(
-                        defaults, options, project, description, homepage)
+                        DEFAULT_HAS_ISSUES, DEFAULT_HAS_DOWNLOADS,
+                        DEFAULT_HAS_WIKI, GITHUB_SECURE_CONFIG,
+                        options, project, description, homepage)
                     if created:
                         gerrit.replicate(project)
 
diff --git a/jeepyb/cmd/update_blueprint.py b/jeepyb/cmd/update_blueprint.py
index b0865aa..3e3604b 100644
--- a/jeepyb/cmd/update_blueprint.py
+++ b/jeepyb/cmd/update_blueprint.py
@@ -70,7 +70,7 @@
     if p.is_no_launchpad_blueprints(project):
         return
 
-    project = p.git2lp(project)
+    project = p.project_to_group(project)
     spec = launchpad.projects[project].getSpecification(name=name)
     if not spec:
         return
diff --git a/jeepyb/cmd/update_bug.py b/jeepyb/cmd/update_bug.py
index be24c46..3868651 100644
--- a/jeepyb/cmd/update_bug.py
+++ b/jeepyb/cmd/update_bug.py
@@ -272,7 +272,7 @@
     if p.is_no_launchpad_bugs(project):
         return []
 
-    project = p.git2lp(project)
+    project = p.project_to_group(project)
 
     part1 = r'^[\t ]*(?P<prefix>[-\w]+)?[\s:]*'
     part2 = r'(?:\b(?:bug|lp)\b[\s#:]*)+'
diff --git a/jeepyb/projects.py b/jeepyb/projects.py
index 13fca6d..da898b9 100644
--- a/jeepyb/projects.py
+++ b/jeepyb/projects.py
@@ -31,11 +31,10 @@
                                   'PROJECTS_YAML')
 
 
-def git2lp(project_full_name):
-    try:
-        return registry[project_full_name]['launchpad']
-    except KeyError:
-        return u.short_project_name(project_full_name)
+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 _is_no_launchpad(project_full_name, obj_type):
diff --git a/setup.cfg b/setup.cfg
index d71104c..a2a775d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -28,3 +28,4 @@
     trivial-rebase = jeepyb.cmd.trivial_rebase:main
     update-blueprint = jeepyb.cmd.update_blueprint:main
     update-bug = jeepyb.cmd.update_bug:main
+    welcome-message = jeepyb.cmd.welcome_message:main