diff --git a/p4-lowlevel.el b/p4-lowlevel.el index 05615a5..f1cdca7 100644 --- a/p4-lowlevel.el +++ b/p4-lowlevel.el @@ -64,6 +64,13 @@ a portion of the error string you wish to ignore." :type '(repeat (string :tag "Error to Ignore")) :group 'p4-lowlevel) +(define-error 'p4-error + "A Perforce error occurred") + +(define-error 'p4-not-logged-in-error + "You’re not logged in to Perforce" + 'p4-error) + (defun p4-lowlevel-locate-p4 () "Attempts to locate the p4 command. Used by `vc-p4-registered' to avoid an error on systems on which the Perforce client is not installed." @@ -294,6 +301,8 @@ rather than raising an error." (setq errors (or (p4-lowlevel-errors output-alist) "Unknown error")) (kill-buffer output-buffer) (or noerror + (when (string-match (rx string-start "Perforce password (P4PASSWD) invalid or unset.") errors) + (signal 'p4-not-logged-in-error nil)) (if (not (string-match "\n" errors)) (error "P4 error: %s" errors) (setq error-buffer (p4-lowlevel-get-buffer-create @@ -772,4 +781,18 @@ already exists." (error "Clients returned non-zero exit code."))) (_ acc))) +(cl-defun p4-lowlevel-login (&key password status) + "Call ‘p4 login’ with arguments. +PASSWORD should be a string representing the password to use to +log in to Perforce. If STATUS is specified the status of the +current ticket is displayed (if there is one) instead." + (let* ((status-args (and status '("-s"))) + (args (append '("login") status-args))) + (condition-case err + (with-temp-buffer + (when password (insert password)) + (p4-lowlevel-command-or-error args (current-buffer))) + (p4-not-logged-in-error + (unless status (signal (car err) (cdr err))))))) + (provide 'p4-lowlevel) diff --git a/vc-p4.el b/vc-p4.el index b3b78ee..5b95f1f 100644 --- a/vc-p4.el +++ b/vc-p4.el @@ -980,4 +980,13 @@ The difference to vc-do-command is that this function always invokes `p4'." (list (completing-read "Client: " (p4-lowlevel-local-clients)))) (p4-lowlevel-command-or-error `("set" ,(format "P4CLIENT=%s" client)))) +(defun vc-p4-login (password) + "Call the p4 login command user PASSWORD." + (interactive (list (read-passwd "P4 Password: "))) + (p4-lowlevel-login :password password)) + +(defun vc-p4-logged-in-p () + "Check if there is an active session for Perforce." + (p4-lowlevel-login :status t)) + (provide 'vc-p4)