blob: aa4aa8fa886f47c66783c3a4ff5a5965e8d951b3 [file] [log] [blame]
;; -*- lexical-binding: t -*-
;; Copyright 2020 The Chromium OS Authors. All Rights Reserved.
;; Use of this source code is governed by a BSD-style license that can be
;; found in the LICENSE file.
;; repo-transient.el --- Transient menus to use some repo commands within magit
;;
;; This file is not part of GNU Emacs.
(require 'term)
(require 'transient)
(require 'magit-process)
(define-infix-argument repo:current-project ()
:description "Current Project"
:class 'transient-switch
:key "-c"
:argument ".")
(define-infix-argument repo:all-projects ()
:description "All Projects"
:class 'transient-switch
:key "-A"
:argument "--all")
;; TODO(jrosenth): the below keybindings don't work ... might be
;; something with evil mode
(defun repo--term-insert-yes ()
(interactive)
(term-send-string (get-buffer-process (current-buffer))
"yes\n"))
(defun repo--term-insert-no ()
(interactive)
(term-send-string (get-buffer-process (current-buffer))
"no\n"))
(defvar repo-term-mode-map
(let ((map (copy-keymap magit-mode-map)))
(define-key map (kbd "y") #'repo--term-insert-yes)
(define-key map (kbd "n") #'repo--term-insert-no)
(set-keymap-parent map magit-mode-map)
map))
(define-derived-mode repo-term-mode term-mode "Repo Output"
"Derived terminal mode for repo output.")
(defun repo--run-interactively (&rest args)
(let ((buf (apply #'make-term "repo-output" "repo" nil args)))
(with-current-buffer buf
(repo-term-mode))
(magit-display-buffer buf)))
(defun repo-sync (args)
"Run a repo sync command."
(interactive (list (transient-args 'repo-sync-menu)))
(apply #'repo--run-interactively "sync" args))
(defun repo-rebase (args)
"Run a repo rebase command."
(interactive (list (transient-args 'repo-rebase-menu)))
(apply #'repo--run-interactively "rebase" args))
(define-transient-command repo-sync-menu ()
"Transient menu for repo sync."
["Project"
(repo:current-project)]
["Commands"
("y" "Sync" repo-sync)])
(define-transient-command repo-rebase-menu
"Transient menu for repo rebase."
["Project"
(repo:current-project)]
["Commands"
("r" "Rebase" repo-rebase)])
(defun repo-start (branch-name args)
"Run a repo start command."
(interactive (list "sBranch name: ")
(transient-args 'repo-start-menu))
(apply #'magit-call-process "repo" "start" args))
(defun repo-start-temp (args)
"Run a repo start command with an auto-generated branch name."
(interactive (transient-args 'repo-start-menu))
(repo-start (format-time-string "temp-%Y-%m-%dT%H:%M:%S")
args))
(define-transient-command repo-start-menu
"Transient menu for repo start."
["Project"
(repo:all-projects)]
["Commands"
("s" "Start new development branch" repo-start)
("t" "Start temporary development branch" repo-start-temp)])
(defun repo-upload (args)
"Run a repo upload command."
(cond
((and (not (member "--label=Verified+1" args))
(not (member "--label=Verified-1" args)))
(repo-upload `(,@args "--label=Verified+1")))
((and (not (member "--cbr" args))
(not (seq-some (lambda (arg)
(string-prefix-p "--br=" arg))
args)))
(repo-upload `(,@args "--cbr")))
(t (apply #'repo--run-interactively "upload" args))))
(defun repo-upload-current (args)
"Run a repo upload command in the current project."
(interactive (list (transient-args 'repo-upload-menu)))
(repo-upload (cons "." args)))
(defun repo-upload-all (args)
"Run a repo upload command for all projects."
(interactive (list (transient-args 'repo-upload-menu)))
(repo-upload args))
(define-infix-argument repo:--re ()
:description "Set reviewers"
:class 'transient-option
:key "-r"
:argument "--re=")
(define-infix-argument repo:--cc ()
:description "Set reviewers"
:class 'transient-option
:key "-c"
:argument "--cc=")
(define-infix-argument repo:--br ()
:description "Local branch to upload"
:class 'transient-option
:key "-b"
:argument "--br="
:reader 'magit-transient-read-revision)
(define-infix-argument repo:--dest ()
:description "Remote destination branch"
:class 'transient-option
:key "-D"
:argument "--dest=")
(define-infix-argument repo:--hashtag ()
:description "Hashtags"
:class 'transient-option
:key "-h"
:argument "--hashtag=")
(define-transient-command repo-upload-menu ()
"Transient menu for repo upload."
["People"
(repo:--re)
(repo:--cc)
("-E" "Don't send emails" "--no-emails")]
["Upload Hooks"
("-n" "Skip upload hooks" "--no-verify")
("-i" "Ignore failures in upload hooks" "--ignore-hooks")]
["Labels"
("-a" "Label Auto-Submit+1" "--label=Auto-Submit+1")
("-d" "Label Commit-Queue+1 (dry run)" "--label=Commit-Queue+1")
("-Q" "Label Commit-Queue+2" "--label=Commit-Queue+2")
("-B" "Label Verified-1 (BAD)" "--label=Verified-1")
("-S" "Sticky CQ+2" "--hashtag=stickycq")]
["CL Options"
("-w" "Work in Progress" "--wip")
("-p" "Private" "--private")
(repo:--hashtag)]
["Branches"
(repo:--br)
(repo:--dest)]
["Upload"
("u" "Upload current project" repo-upload-current)
("U" "Upload all projects" repo-upload-all)])
(define-transient-command repo-main-menu ()
"Transient menu for repo commands."
["Subcommands"
("y" "sync" repo-sync-menu)
("r" "rebase" repo-rebase-menu)
("s" "start" repo-start-menu)
("u" "upload" repo-upload-menu)])
(provide 'repo-transient)