diff options
| author | Stefan Monnier | 2007-06-20 06:44:35 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2007-06-20 06:44:35 +0000 |
| commit | 77b5d4581188a3efb0e3f33eaa579fef235ab97c (patch) | |
| tree | 6d2adfce24eb6609435d66bf3dfa84b8594033b7 | |
| parent | 248c66458e495ed4851f93811b43c47e151d9814 (diff) | |
| download | emacs-77b5d4581188a3efb0e3f33eaa579fef235ab97c.tar.gz emacs-77b5d4581188a3efb0e3f33eaa579fef235ab97c.zip | |
(vc-bzr-with-process-environment, vc-bzr-std-process-invocation): New macros.
(vc-bzr-command, vc-bzr-command*): Use them.
(vc-bzr-with-c-locale): Remove.
(vc-bzr-dir-state): Replace its use with vc-bzr-command.
(vc-bzr-buffer-nonblank-p): New function.
(vc-bzr-state-words): New const.
(vc-bzr-state): Look for `bzr status` keywords in output.
Display everything else as a warning message to the user.
Fix status report with bzr >= 0.15.
| -rw-r--r-- | lisp/ChangeLog | 13 | ||||
| -rw-r--r-- | lisp/vc-bzr.el | 147 |
2 files changed, 104 insertions, 56 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 225f212b6e2..6c0935b982c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2007-06-20 Riccardo Murri <riccardo.murri@gmail.com> | ||
| 2 | |||
| 3 | * vc-bzr.el (vc-bzr-with-process-environment) | ||
| 4 | (vc-bzr-std-process-invocation): New macros. | ||
| 5 | (vc-bzr-command, vc-bzr-command*): Use them. | ||
| 6 | (vc-bzr-with-c-locale): Remove. | ||
| 7 | (vc-bzr-dir-state): Replace its use with vc-bzr-command. | ||
| 8 | (vc-bzr-buffer-nonblank-p): New function. | ||
| 9 | (vc-bzr-state-words): New const. | ||
| 10 | (vc-bzr-state): Look for `bzr status` keywords in output. | ||
| 11 | Display everything else as a warning message to the user. | ||
| 12 | Fix status report with bzr >= 0.15. | ||
| 13 | |||
| 1 | 2007-06-20 Dan Nicolaescu <dann@ics.uci.edu> | 14 | 2007-06-20 Dan Nicolaescu <dann@ics.uci.edu> |
| 2 | 15 | ||
| 3 | * vc-hg.el (vc-hg-global-switches): Simplify. | 16 | * vc-hg.el (vc-hg-global-switches): Simplify. |
diff --git a/lisp/vc-bzr.el b/lisp/vc-bzr.el index e5481b5f405..e3076c714cf 100644 --- a/lisp/vc-bzr.el +++ b/lisp/vc-bzr.el | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | ;; Author: Dave Love <fx@gnu.org>, Riccardo Murri <riccardo.murri@gmail.com> | 10 | ;; Author: Dave Love <fx@gnu.org>, Riccardo Murri <riccardo.murri@gmail.com> |
| 11 | ;; Keywords: tools | 11 | ;; Keywords: tools |
| 12 | ;; Created: Sept 2006 | 12 | ;; Created: Sept 2006 |
| 13 | ;; Version: 2007-01-17 | 13 | ;; Version: 2007-05-24 |
| 14 | ;; URL: http://launchpad.net/vc-bzr | 14 | ;; URL: http://launchpad.net/vc-bzr |
| 15 | 15 | ||
| 16 | ;; This file is free software; you can redistribute it and/or modify | 16 | ;; This file is free software; you can redistribute it and/or modify |
| @@ -36,13 +36,23 @@ | |||
| 36 | 36 | ||
| 37 | ;; See <URL:http://bazaar-vcs.org/> concerning bzr. | 37 | ;; See <URL:http://bazaar-vcs.org/> concerning bzr. |
| 38 | 38 | ||
| 39 | ;; Load this library to register bzr support in VC. The support is | 39 | ;; Load this library to register bzr support in VC. It covers basic VC |
| 40 | ;; preliminary and incomplete, adapted from my darcs version. Lightly | 40 | ;; functionality, but was only lightly exercised with a few Emacs/bzr |
| 41 | ;; exercised with bzr 0.8 and Emacs 21, and bzr 0.11 on Emacs 22. See | 41 | ;; version combinations, namely those current on the authors' PCs. |
| 42 | ;; various Fixmes below. | 42 | ;; See various Fixmes below. |
| 43 | 43 | ||
| 44 | ;; This should be suitable for direct inclusion in Emacs if someone | 44 | |
| 45 | ;; can persuade rms. | 45 | ;; Known bugs |
| 46 | ;; ========== | ||
| 47 | |||
| 48 | ;; When edititing a symlink and *both* the symlink and its target | ||
| 49 | ;; are bzr-versioned, `vc-bzr` presently runs `bzr status` on the | ||
| 50 | ;; symlink, thereby not detecting whether the actual contents | ||
| 51 | ;; (that is, the target contents) are changed. | ||
| 52 | ;; See https://bugs.launchpad.net/vc-bzr/+bug/116607 | ||
| 53 | |||
| 54 | ;; For an up-to-date list of bugs, please see: | ||
| 55 | ;; https://bugs.launchpad.net/vc-bzr/+bugs | ||
| 46 | 56 | ||
| 47 | 57 | ||
| 48 | ;;; Code: | 58 | ;;; Code: |
| @@ -96,9 +106,26 @@ if running `vc-bzr-program' doesn't produce the expected output." | |||
| 96 | First argument VERS is a list of the form (X Y Z), as returned by `vc-bzr-version'." | 106 | First argument VERS is a list of the form (X Y Z), as returned by `vc-bzr-version'." |
| 97 | (version-list-<= vers (vc-bzr-version))) | 107 | (version-list-<= vers (vc-bzr-version))) |
| 98 | 108 | ||
| 109 | (eval-when-compile | ||
| 110 | (defmacro vc-bzr-with-process-environment (envspec &rest body) | ||
| 111 | "Prepend the contents of ENVSPEC to `process-environment', then execute BODY." | ||
| 112 | `(let ((process-environment process-environment)) | ||
| 113 | (mapcar (lambda (var) (add-to-list 'process-environment var)) ,envspec) | ||
| 114 | ,@body)) | ||
| 115 | |||
| 116 | (defmacro vc-bzr-std-process-invocation (&rest body) | ||
| 117 | `(vc-bzr-with-process-environment | ||
| 118 | '("BZR_PROGRESS_BAR=none" ; suppress progress output (bzr >=0.9) | ||
| 119 | "LC_ALL=C") ; force English output | ||
| 120 | ;; bzr may attempt some kind of user interaction if its stdin/stdout | ||
| 121 | ;; is connected to a PTY; therefore, ask Emacs to use a pipe to | ||
| 122 | ;; communicate with it. | ||
| 123 | (let ((process-connection-type nil)) | ||
| 124 | ,@body)))) | ||
| 125 | |||
| 99 | ;; XXX: vc-do-command is tailored for RCS and assumes that command-line | 126 | ;; XXX: vc-do-command is tailored for RCS and assumes that command-line |
| 100 | ;; options precede the file name (ci -something file); with bzr, we need | 127 | ;; options precede the file name (e.g., "ci -something file"); with bzr, |
| 101 | ; to pass options *after* the subcommand, e.g. bzr ls --versioned. | 128 | ;; we need to pass options *after* the subcommand, e.g. "bzr ls --versioned". |
| 102 | (defun vc-bzr-do-command* (buffer okstatus command &rest args) | 129 | (defun vc-bzr-do-command* (buffer okstatus command &rest args) |
| 103 | "Execute bzr COMMAND, notifying user and checking for errors. | 130 | "Execute bzr COMMAND, notifying user and checking for errors. |
| 104 | This is a wrapper around `vc-do-command', which see for detailed | 131 | This is a wrapper around `vc-do-command', which see for detailed |
| @@ -120,16 +147,16 @@ you can mix options and file names in any order." | |||
| 120 | (defun vc-bzr-command (bzr-command buffer okstatus file &rest args) | 147 | (defun vc-bzr-command (bzr-command buffer okstatus file &rest args) |
| 121 | "Wrapper round `vc-do-command' using `vc-bzr-program' as COMMAND. | 148 | "Wrapper round `vc-do-command' using `vc-bzr-program' as COMMAND. |
| 122 | Invoke the bzr command adding `BZR_PROGRESS_BAR=none' to the environment." | 149 | Invoke the bzr command adding `BZR_PROGRESS_BAR=none' to the environment." |
| 123 | (let ((process-environment (cons "BZR_PROGRESS_BAR=none" process-environment))) | 150 | (vc-bzr-std-process-invocation |
| 124 | (apply 'vc-do-command buffer okstatus vc-bzr-program | 151 | (apply 'vc-do-command buffer okstatus vc-bzr-program |
| 125 | file bzr-command (append vc-bzr-program-args args)))) | 152 | file bzr-command (append vc-bzr-program-args args)))) |
| 126 | 153 | ||
| 127 | (defun vc-bzr-command* (bzr-command buffer okstatus file &rest args) | 154 | (defun vc-bzr-command* (bzr-command buffer okstatus file &rest args) |
| 128 | "Wrapper round `vc-bzr-do-command*' using `vc-bzr-program' as COMMAND. | 155 | "Wrapper round `vc-bzr-do-command*' using `vc-bzr-program' as COMMAND. |
| 129 | Invoke the bzr command adding `BZR_PROGRESS_BAR=none' to the environment. | 156 | Invoke the bzr command adding `BZR_PROGRESS_BAR=none' to the environment. |
| 130 | First argument BZR-COMMAND is passed as the first optional argument to | 157 | First argument BZR-COMMAND is passed as the first optional argument to |
| 131 | `vc-bzr-do-command*'." | 158 | `vc-bzr-do-command*'." |
| 132 | (let ((process-environment (cons "BZR_PROGRESS_BAR=none" process-environment))) | 159 | (vc-bzr-std-process-invocation |
| 133 | (apply 'vc-bzr-do-command* buffer okstatus vc-bzr-program | 160 | (apply 'vc-bzr-do-command* buffer okstatus vc-bzr-program |
| 134 | bzr-command (append vc-bzr-program-args args))))) | 161 | bzr-command (append vc-bzr-program-args args))))) |
| 135 | 162 | ||
| @@ -171,19 +198,6 @@ First argument BZR-COMMAND is passed as the first optional argument to | |||
| 171 | 198 | ||
| 172 | (add-hook 'vc-post-command-functions 'vc-bzr-post-command-function))) | 199 | (add-hook 'vc-post-command-functions 'vc-bzr-post-command-function))) |
| 173 | 200 | ||
| 174 | ;; Fixme: If we're only interested in status messages, we only need | ||
| 175 | ;; to set LC_MESSAGES, and we might need finer control of this. This | ||
| 176 | ;; is moot anyhow, since bzr doesn't appear to be localized at all | ||
| 177 | ;; (yet?). | ||
| 178 | (eval-when-compile | ||
| 179 | (defmacro vc-bzr-with-c-locale (&rest body) | ||
| 180 | "Run BODY with LC_ALL=C in the process environment. | ||
| 181 | This ensures that messages to be matched come out as expected." | ||
| 182 | `(let ((process-environment (cons "LC_ALL=C" process-environment))) | ||
| 183 | ,@body))) | ||
| 184 | (put 'vc-bzr-with-c-locale 'edebug-form-spec t) | ||
| 185 | (put 'vc-bzr-with-c-locale 'lisp-indent-function 0) | ||
| 186 | |||
| 187 | (defun vc-bzr-bzr-dir (file) | 201 | (defun vc-bzr-bzr-dir (file) |
| 188 | "Return the .bzr directory in the hierarchy above FILE. | 202 | "Return the .bzr directory in the hierarchy above FILE. |
| 189 | Return nil if there isn't one." | 203 | Return nil if there isn't one." |
| @@ -206,36 +220,57 @@ Return nil if there isn't one." | |||
| 206 | (if (vc-bzr-bzr-dir file) ; short cut | 220 | (if (vc-bzr-bzr-dir file) ; short cut |
| 207 | (vc-bzr-state file))) ; expensive | 221 | (vc-bzr-state file))) ; expensive |
| 208 | 222 | ||
| 209 | (defun vc-bzr-state (file) | 223 | (defun vc-bzr-buffer-nonblank-p (&optional buffer) |
| 210 | (let (ret state conflicts pending-merges) | 224 | "Return non-nil if BUFFER contains any non-blank characters." |
| 211 | (with-temp-buffer | 225 | (or (> (buffer-size buffer) 0) |
| 212 | (cd (file-name-directory file)) | ||
| 213 | (setq ret (vc-bzr-with-c-locale (vc-bzr-command "status" t 255 file))) | ||
| 214 | (goto-char 1) | ||
| 215 | (save-excursion | ||
| 216 | (when (re-search-forward "^conflicts:" nil t) | ||
| 217 | (message "Warning -- conflicts in bzr branch"))) | ||
| 218 | (save-excursion | 226 | (save-excursion |
| 219 | (when (re-search-forward "^pending merges:" nil t) | 227 | (set-buffer (or buffer (current-buffer))) |
| 220 | (message "Warning -- pending merges in bzr branch"))) | 228 | (goto-char (point-min)) |
| 221 | (setq state | 229 | (re-search-forward "[^ \t\n]" (point-max) t)))) |
| 222 | (cond ((not (equal ret 0)) nil) | 230 | |
| 223 | ((looking-at "added\\|renamed\\|modified\\|removed") 'edited) | 231 | (defconst vc-bzr-state-words |
| 224 | ;; Fixme: Also get this in a non-registered sub-directory. | 232 | "added\\|ignored\\|modified\\|removed\\|renamed\\|unknown" |
| 225 | ((looking-at "^$") 'up-to-date) | 233 | "Regexp matching file status words as reported in `bzr' output.") |
| 226 | ;; if we're seeing this as first line of text, | 234 | |
| 227 | ;; then the status is up-to-date, | 235 | ;; FIXME: Also get this in a non-registered sub-directory. |
| 228 | ;; but bzr output only gives the warning to users. | 236 | (defun vc-bzr-state (file) |
| 229 | ((looking-at "conflicts\\|pending") 'up-to-date) | 237 | (with-temp-buffer |
| 230 | ((looking-at "unknown\\|ignored") nil) | 238 | (cd (file-name-directory file)) |
| 231 | (t (error "Unrecognized output from `bzr status'")))) | 239 | (let ((ret (vc-bzr-command "status" t 255 file)) |
| 232 | (when (or conflicts pending-merges) | 240 | (state 'up-to-date)) |
| 233 | (message | 241 | ;; the only secure status indication in `bzr status' output |
| 234 | (concat "Warning -- " | 242 | ;; is a couple of lines following the pattern:: |
| 235 | (if conflicts "conflicts ") | 243 | ;; | <status>: |
| 236 | (if (and conflicts pending-merges) "and ") | 244 | ;; | <file name> |
| 237 | (if pending-merges "pending merges ") | 245 | ;; if the file is up-to-date, we get no status report from `bzr', |
| 238 | "in bzr branch"))) | 246 | ;; so if the regexp search for the above pattern fails, we consider |
| 247 | ;; the file to be up-to-date. | ||
| 248 | (goto-char (point-min)) | ||
| 249 | (when | ||
| 250 | (re-search-forward | ||
| 251 | (concat "^\\(" vc-bzr-state-words "\\):[ \t\n]+" | ||
| 252 | (file-name-nondirectory file) "[ \t\n]*$") | ||
| 253 | (point-max) t) | ||
| 254 | (let ((start (match-beginning 0)) | ||
| 255 | (end (match-end 0))) | ||
| 256 | (goto-char start) | ||
| 257 | (setq state | ||
| 258 | (cond | ||
| 259 | ((not (equal ret 0)) nil) | ||
| 260 | ((looking-at "added\\|renamed\\|modified\\|removed") 'edited) | ||
| 261 | ((looking-at "unknown\\|ignored") nil))) | ||
| 262 | ;; erase the status text that matched | ||
| 263 | (delete-region start end))) | ||
| 264 | (when (vc-bzr-buffer-nonblank-p) | ||
| 265 | ;; "bzr" will output some warnings and informational messages | ||
| 266 | ;; to the user to stderr; due to Emacs' `vc-do-command' (and, | ||
| 267 | ;; it seems, `start-process' itself), we cannot catch stderr | ||
| 268 | ;; and stdout into different buffers. So, if there's anything | ||
| 269 | ;; left in the buffer after removing the above status | ||
| 270 | ;; keywords, let us just presume that any other message from | ||
| 271 | ;; "bzr" is a user warning, and display it. | ||
| 272 | (message "Warnings in `bzr' output: %s" | ||
| 273 | (buffer-substring (point-min) (point-max)))) | ||
| 239 | (when state | 274 | (when state |
| 240 | (vc-file-setprop file 'vc-workfile-version | 275 | (vc-file-setprop file 'vc-workfile-version |
| 241 | (vc-bzr-workfile-version file)) | 276 | (vc-bzr-workfile-version file)) |
| @@ -502,7 +537,7 @@ Optional argument LOCALP is always ignored." | |||
| 502 | ;; `bzr status' reports on added/modified/renamed and unknown/ignored files | 537 | ;; `bzr status' reports on added/modified/renamed and unknown/ignored files |
| 503 | (set 'at-start t) | 538 | (set 'at-start t) |
| 504 | (with-temp-buffer | 539 | (with-temp-buffer |
| 505 | (vc-bzr-with-c-locale (vc-bzr-command "status" t 0 nil)) | 540 | (vc-bzr-command "status" t 0 nil) |
| 506 | (goto-char (point-min)) | 541 | (goto-char (point-min)) |
| 507 | (while (or at-start | 542 | (while (or at-start |
| 508 | (eq 0 (forward-line))) | 543 | (eq 0 (forward-line))) |