diff mbox series

[4/5] patchwork-bot: Handle repo being a worktree

Message ID 20211201001126.4106635-5-keescook@chromium.org (mailing list archive)
State New, archived
Headers show
Series patchwork-bot: Use worktrees for repos | expand

Commit Message

Kees Cook Dec. 1, 2021, 12:11 a.m. UTC
Locate the real git location when operating on a worktree, allowing
multiple pw.db files to be stored in a single top-level git repo.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 git-patchwork-bot.example.yaml |  1 +
 git-patchwork-bot.py           | 27 +++++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/git-patchwork-bot.example.yaml b/git-patchwork-bot.example.yaml
index c3f6c1ea3133..94ab334f5043 100644
--- a/git-patchwork-bot.example.yaml
+++ b/git-patchwork-bot.example.yaml
@@ -53,6 +53,7 @@  repos:
     # For the notification emails
     treename: 'khilman/linux-amlogic.git'
     # Optional: limit checking to a single branch (instead of --heads)
+    # This becomes a required setting if the repo path is a worktree.
     #branch: 'origin/master'
     # For the notification emails, must include %s
     commitlink: 'https://git.kernel.org/khilman/linux-amlogic/c/%.12s'
diff --git a/git-patchwork-bot.py b/git-patchwork-bot.py
index fc4d9e384122..9be945d92a8a 100755
--- a/git-patchwork-bot.py
+++ b/git-patchwork-bot.py
@@ -1054,8 +1054,28 @@  def pwrun(repo, rsettings):
         logger.info('Could not get the latest ref in %s', repo)
         sys.exit(1)
 
+    dbpath = repo
+    # If we're aimed at a worktree, move up from the ".git" file to
+    # the worktree directory.
+    if not os.path.isdir(dbpath):
+        gitdir = open(dbpath).readline().strip()
+        if not gitdir.startswith('gitdir: '):
+            logger.info('Could not find git tree in %s', dbpath)
+            sys.exit(1)
+        gitdir = gitdir.split(' ', 1)[1]
+        gitdir, worktree = os.path.split(gitdir)
+        gitdir, category = os.path.split(gitdir)
+        if category != "worktrees":
+            logger.info('Could not find git worktree in %s', dbpath)
+            sys.exit(1)
+        # To store multiple pw.db files in a single .git directory,
+        # add a suffix based on the repo treename.
+        treename = rsettings.get('treename').replace('/', '_')
+        dbpath = os.path.join(gitdir, f'pw-{treename}.db')
+    else:
+        dbpath = os.path.join(dbpath, 'pw.db')
+
     # Do we have a pw.db there yet?
-    dbpath = os.path.join(repo, 'pw.db')
     db_exists = os.path.isfile(dbpath)
     dbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
     c = dbconn.cursor()
@@ -1295,10 +1315,13 @@  def check_repos():
 
     for repo in CONFIG['repos']:
         fullpath = os.path.join(cmdargs.reposdir.rstrip('/'), repo.lstrip('/'))
-        if not os.path.isdir(fullpath):
+        if not os.path.exists(fullpath):
             logger.info('Repository not found: %s', repo)
             continue
         settings = CONFIG['repos'][repo]
+        if not os.path.isdir(fullpath) and settings.get('branch', None) == None:
+            logger.info('Worktree must specify "branch" setting: %s', repo)
+            continue
         logger.info('Processing: %s', repo)
         pwrun(fullpath, settings)