summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2022-06-07 10:22:34 -0700
committerFranck Cuny <franck@fcuny.net>2022-06-07 14:54:40 -0700
commit03d903cdb1d6d26bda0860a94018f378e26d28f4 (patch)
treeb127eac4706e5c2345ff4cb33c08d019b1429055
parentfeat(tramp): add function to quickly ssh to a machine (diff)
downloademacs.d-03d903cdb1d6d26bda0860a94018f378e26d28f4.tar.gz
feat(gerrit): add transient options for git-push to work with Gerrit
It's possible to configure the status of a change by adding options to a
ref when creating the review.

To mark a change as `work in progress', appending `%wip' to the ref does
the trick. It's then possible to mark the change as ready for review by
adding `%ready' to the ref.

We add helpers to make this work from Emacs and a few transient
functions to push changes to Gerrit:
- a change without options (which will be open by default)
- a change for WIP
- a change for 'ready' (which is needed when the change is currently
  marked as WIP and we want others to see it)

In addition there's transient options to submit the change and to review
the change, using labels.

Change-Id: I164c6641a10517204e6867852a6363053ead6318
Reviewed-on: https://cl.fcuny.net/c/emacs.d/+/285
Reviewed-by: Franck Cuny <franck@fcuny.net>
-rw-r--r--emacs/elisp/my-gerrit.el76
1 files changed, 76 insertions, 0 deletions
diff --git a/emacs/elisp/my-gerrit.el b/emacs/elisp/my-gerrit.el
new file mode 100644
index 0000000..856d01f
--- /dev/null
+++ b/emacs/elisp/my-gerrit.el
@@ -0,0 +1,76 @@
+;;; my-gerrit.el --- magit integration for Gerrit -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; interact with Gerrit from magit
+
+;;; Code:
+
+(require 'magit)
+(require 's)
+
+(defgroup my/gerrit nil
+  "Customization options for Gerrit integration with magit."
+  :group 'magit)
+
+(defcustom my/gerrit-remote "origin"
+  "Name of the git remote for Gerrit."
+  :type '(string)
+  :group 'my/gerrit)
+
+(defun my/gerrit-ref (target-branch &optional flags)
+  "Target ref to push change based on TARGET-BRANCH, with optional FLAGS."
+  (let ((flag-suffix (if flags (format "%%%s" (s-join "," flags))
+                       "")))
+    (format "HEAD:refs/for/%s%s" target-branch flag-suffix)))
+
+(transient-define-suffix my/magit-gerrit-push-for-review ()
+  "Push to Gerrit for review."
+  (interactive)
+  (magit-push-refspecs my/gerrit-remote (my/gerrit-ref (magit-main-branch)) nil))
+
+(transient-append-suffix 'magit-push "m"
+  '("R" "push to Gerrit for review" my/magit-gerrit-push-for-review))
+
+;; By appending `%wip' to the ref, we mark the change as `work in progress'.
+;; https://gerrit-review.googlesource.com/Documentation/intro-user.html#wip
+(transient-define-suffix my/magit-gerrit-push-for-review-wip ()
+  "Push to Gerrit as work in progress."
+  (interactive)
+  (magit-push-refspecs my/gerrit-remote (my/gerrit-ref (magit-main-branch) '("wip")) nil))
+
+(transient-append-suffix 'magit-push "R"
+  '("W" "push to Gerrit for review (WIP)" my/magit-gerrit-push-for-review-wip))
+
+;; By appending `%ready' to the ref, we mark the change as ready for
+;; review.
+;; https://gerrit-review.googlesource.com/Documentation/intro-user.html#wip
+(transient-define-suffix my/magit-gerrit-push-for-review-ready ()
+  "Push to Gerrit as ready."
+  (interactive)
+  (magit-push-refspecs my/gerrit-remote (my/gerrit-ref (magit-main-branch) '("ready")) nil))
+
+(transient-append-suffix 'magit-push "W"
+  '("r" "push to Gerrit for review (ready)" my/magit-gerrit-push-for-review-ready))
+
+;; For this to work, permissions need to be setup, as per
+;; https://gerrit.cloudera.org/Documentation/user-upload.html#auto_merge
+(transient-define-suffix my/magit-gerrit-submit ()
+  (interactive)
+  (magit-push-refspecs my/gerrit-remote (my/gerrit-ref (magit-main-branch) '("submit")) nil))
+
+(transient-append-suffix 'magit-push "r"
+  '("P" "push to Gerrit to submit change" my/magit-gerrit-submit))
+
+(transient-define-suffix my/magit-gerrit-shipit ()
+  "Ship it."
+  (interactive)
+  (magit-push-refspecs my/gerrit-remote (my/gerrit-ref (magit-main-branch)'("l=Code-Review+2" "publish-comments")) nil))
+
+(transient-append-suffix 'magit-push "P"
+  '("S" "Approve the change in Gerrit" my/magit-gerrit-shipit))
+
+(provide 'my-gerrit)
+
+;;; my-gerrit.el ends here