diff --git a/gerrit.el b/gerrit.el index b4b922f..0e91d83 100644 --- a/gerrit.el +++ b/gerrit.el @@ -148,13 +148,42 @@ gerrit-download is used." ;; -> The test-transient allows one to cycle over all settings C-M-p / C-M-n ;; and also over all the infix history +;; this variable is used in `gerrit-download-format-change' +(defvar gerrit-change-singleline-columns + '(number branch subject) + "List of columns that should be displayed in functions that ask the user to select a change from a list of changes." + "Currently supported columns are:" + "'number (the change number)" + "'branch (the branch of the change)" + "'subject (the subject of the commit msg)" + "'project (the project name)" + ) + +;; TODO document this variable +;; (setq gerrit-project-to-local-workspace-alist +;; '( +;; (("software/pro1" . "branch1") . "~/sandbox/pro1") +;; (("software/pro2" . "branch2") . "~/sandbox/pro2") +;; )) +(defvar gerrit-project-to-local-workspace-alist nil) + +;; TODO docs missing +;; mention (project:A OR project:B OR project:C) +(defvar gerrit-interesting-open-changes-filter "is:open") + (defun gerrit-download-format-change (change) - (concat - (propertize (number-to-string (alist-get '_number change)) 'face 'magit-hash) - " " - (propertize (alist-get 'branch change) 'face 'magit-branch-remote) - " " - (propertize (alist-get 'subject change) 'face 'magit-section-highlight))) + (let (columns) + ;; can this be implemented in an easier way? + (when (member 'number gerrit-change-singleline-columns) + (add-to-list 'columns (propertize (number-to-string + (alist-get '_number change)) 'face 'magit-hash))) + (when (member 'project gerrit-change-singleline-columns) + (add-to-list 'columns (propertize (alist-get 'project change) 'face 'magit-branch-remote))) + (when (member 'branch gerrit-change-singleline-columns) + (add-to-list 'columns (propertize (alist-get 'branch change) 'face 'magit-branch-remote))) + (when (member 'subject gerrit-change-singleline-columns) + (add-to-list 'columns (propertize (alist-get 'subject change) 'face 'magit-section-highlight))) + (s-join " " (nreverse columns)))) (defun gerrit-download--get-refspec (change-metadata) "Return the refspec of a gerrit change from CHANGE-METADATA. @@ -198,6 +227,7 @@ This refspec is a string of the form 'refs/changes/xx/xx/x'. ;; (e.g. if ssh-add was not called) this async call runs ;; magit-process-password-prompt-regexps (used in magit-process-filter) ;; which is called in magit-start-process + ;; (see https://github.com/magit/magit/issues/4323) (magit-run-git-async "fetch" (gerrit-get-remote) (gerrit-download--get-refspec change-metadata)) @@ -1196,25 +1226,62 @@ gerrit-upload: (current cmd: %(concat (gerrit-upload-create-git-review-cmd))) +(defun gerrit--select-change-from-matching-changes (search-string) + ;; see https://gerrit-review.googlesource.com/Documentation/user-search.html + ;; clients can let-bind `gerrit-change-singleline-columns' + (let* ((open-changes (seq-map #'reviewgerrit-download-format-change + (gerrit-rest-change-query + (or search-string "is:open") + ))) + (selected-line (completing-read + "Download Change: " open-changes nil nil)) + (changenr (car (s-split " " (s-trim selected-line))))) + changenr)) + (defun gerrit-download (changenr) "Download change with CHANGENR from the gerrit server." (interactive (list - (let* ((open-changes - (seq-map #'gerrit-download-format-change (gerrit-rest-change-query - (concat "status:open project:" - (gerrit-get-current-project))))) - (selected-line (completing-read - "Download Change: " open-changes nil nil)) - (changenr (car (s-split " " (s-trim selected-line))))) - changenr - ))) + (let + ((gerrit-change-singleline-columns '(number branch project subject))) + (gerrit--select-change-from-matching-changes + (concat "status:open project:" + (gerrit-get-current-project)))))) (gerrit--init-accounts) (if gerrit-use-gitreview-interface (gerrit-download--gitreview changenr) (gerrit-download--new changenr))) +;; TODO split this up into two parts (one that downloads the change and one that opens the overview page using magit-show-commit +(defun gerrit-download-and-open-overview (changenr) + ;; since a simple "is:open" query might return a lot of gerrit-changes, it + ;; is possible to filter the returned results by setting an variable + ;; called `gerrit-interesting-open-changes-filter'. + (interactive (list (gerrit--select-change-from-matching-changes + gerrit-interesting-open-changes-filter))) + + ;; 1) get change metadata + ;; 2) determine workspace directory (based on branch and projectname) + ;; 3) switch to workspace + ;; 4) download change + ;; 5) display commit + (let* ((change-metadata (car (gerrit-rest-change-query changenr))) + (project-name (alist-get 'project change-metadata)) + (branch (alist-get 'branch change-metadata)) + (workspace-directory (or (cdr (assoc (cons project-name branch) + gerrit-project-to-local-workspace-alist)) + ;; TODO completion + write them to file + (read-directory-name + (format "Enter directory for project %s" project-name))))) + (let ((default-directory workspace-directory)) + (message "changeinfo: name: %s, branch: %s -> workspace: %s" + project-name branch workspace-directory) + (gerrit-download changenr) ;; this is async + ;; TODO run magit-show-commit + ;; only when the above change is downloaded to avoid window-flickering + (magit-show-commit "HEAD")))) + (defun gerrit-upload () (interactive) (if gerrit-use-gitreview-interface