1 ;; issue-tracker.el --- SXEmacs Bug Reporting/Tracking
3 ;; Copyright (C) 2005 Steve Youngs
5 ;; Author: Steve Youngs <steve@sxemacs.org>
6 ;; Maintainer: Steve Youngs <steve@sxemacs.org>
7 ;; Created: <2005-01-10>
8 ;; Homepage: http://www.sxemacs.org/
9 ;; Keywords: bugs issues
11 ;; This file is part of SXEmacs.
13 ;; Redistribution and use in source and binary forms, with or without
14 ;; modification, are permitted provided that the following conditions
17 ;; 1. Redistributions of source code must retain the above copyright
18 ;; notice, this list of conditions and the following disclaimer.
20 ;; 2. Redistributions in binary form must reproduce the above copyright
21 ;; notice, this list of conditions and the following disclaimer in the
22 ;; documentation and/or other materials provided with the distribution.
24 ;; 3. Neither the name of the author nor the names of any contributors
25 ;; may be used to endorse or promote products derived from this
26 ;; software without specific prior written permission.
28 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
29 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 ;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
38 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ;; This will hopefully turn into an interface to the SXEmacs issue
43 ;; tracker. For now, it is basically a clone of xemacsbug with a
44 ;; couple of things changed to suit SXEmacs conditions.
48 ;; Interface to our issue tracker.
56 (defvar mh-before-send-letter-hook))
58 (defgroup sxemacsbug nil
59 "Sending SXEmacs bug reports."
63 ;; >> These should be addresses which are accessible to your machine,
64 ;; >> otherwise you can't use this file. It will only work on the
65 ;; >> internet with this address.
67 (defcustom report-sxemacs-bug-address "SXEmacs Devel <sxemacs-devel@sxemacs.org>"
68 "*Address of mailing list for SXEmacs bugs."
72 (defcustom report-sxemacs-bug-extra-headers nil
73 "*An alist of mail-header value pairs for SXEmacs bugs.
75 It takes the format (HEADER . VALUE) where both HEADER and VALUE are
76 strings. See `compose-mail'."
79 (cons (string :tag "Header")
80 (string :tag "Value"))))
82 (defcustom report-sxemacs-bug-beta-address "SXEmacs Devel <sxemacs-devel@sxemacs.org>"
83 "*Address of mailing list for SXEmacs beta bugs."
87 (defcustom report-sxemacs-bug-beta-extra-headers nil
88 "*An alist of mail-header value pairs for SXEmacs beta bugs.
90 It takes the format (HEADER . VALUE) where both HEADER and VALUE are
91 strings. See `compose-mail'."
94 (cons (string :tag "Header")
95 (string :tag "Value"))))
97 (defvar report-sxemacs-bug-orig-text nil
98 "The automatically-created initial text of bug report.")
100 (defcustom report-sxemacs-bug-no-confirmation nil
101 "*If non-nil, suppress the confirmations asked for the sake of novice users."
105 (defcustom report-sxemacs-bug-no-explanations nil
106 "*If non-nil, suppress the explanations given for the sake of novice users."
110 (defcustom report-sxemacs-bug-send-init nil
111 "*If non-nil, include the user's init.el file in the bug report."
115 (defconst report-sxemacs-bug-help
116 "\nThis bug report will be sent to the SXEmacs Development Team,
117 not to your local site managers!!
119 Please write in English, because the SXEmacs maintainers do not have
120 translators to read other languages for them.
122 Please describe as succinctly as possible:
124 \t- What you thought should have happened.
125 \t- Precisely what you were doing at the time.
127 Also include a reliable recipe for triggering the bug, as well as
128 any C and lisp back-traces that you may have.
129 \(setq stack-trace-on-error t\), or \(setq debug-on-error t\) if you
130 are familiar with the debugger, to get a lisp back-trace.
131 To get a core file for the C back-trace on a GNU/Linux system do
132 'ulimit -c unlimited' in the shell prior to starting SXEmacs.
134 Type \\[report-sxemacs-bug-info] to visit in Info the SXEmacs Manual section
135 about when and how to write a bug report,
136 and what information to supply so that the bug can be fixed.
137 Type SPC to scroll through this section and its subsections.
139 You are very welcome to scan through the bug report and remove any
140 potentially sensitive data.
142 Turn off this help buffer permanently by adding:
144 \t \(setq report-sxemacs-bug-no-explanations t\)
146 To your `user-init-file'")
148 (defun report-sxemacs-bug-help ()
149 "Display the help buffer for `report-sxemacs-bug'."
153 (define-key (current-local-map) "\C-c\C-i" 'report-sxemacs-bug-info)
154 (princ (substitute-command-keys report-sxemacs-bug-help)) nil) "*Bug Help*")))
156 (defun report-sxemacs-bug-packages-list ()
157 "Insert into the current buffer a list of installed packages."
158 (let ((pkgs packages-package-list))
161 (format "(%s ver: %s upstream: %s)\n"
165 (setq pkgs (cdr pkgs)))))
167 (defun report-sxemacs-bug-via-email (topic &optional recent-keys)
168 "Report a bug in SXEmacs.
169 Prompts for bug subject. Leaves you in a mail buffer."
170 ;; This strange form ensures that (recent-keys) is the value before
171 ;; the bug subject string is read.
172 (interactive (reverse (list (recent-keys) (read-string "Bug Subject: "))))
174 (setq topic (concat "[Bug: " emacs-program-version "] " topic))
176 (compose-mail report-sxemacs-bug-beta-address
178 report-sxemacs-bug-beta-extra-headers)
179 (compose-mail report-sxemacs-bug-address
181 report-sxemacs-bug-extra-headers))
182 ;; The rest of this does not execute
183 ;; if the user was asked to confirm and said no.
184 (goto-char (point-min))
185 (re-search-forward "^--text follows this line--$")
187 (insert "================================================================\n")
188 (insert "Dear Bug Team!\n\n")
189 (setq user-point (point))
190 (insert "\n\n================================================================\n
191 System Info to help track down your bug:
192 ---------------------------------------\n\n")
193 ;; Insert the output of 'describe-installation'.
194 (insert (symbol-value 'Installation-string))
195 ;; Load-path shadows can cause some grief.
196 (flet ((append-message
199 (&optional label frame stdout-p no-restore)
201 (insert "\n\nLoad-Path Lisp Shadows:\n"
202 "----------------------\n")
203 (let ((before-shadows (point)))
206 (find-emacs-lisp-shadows load-path)))
208 (narrow-to-region before-shadows (point))
211 ;; Insert a list of installed packages.
212 (insert "\n\nInstalled SXEmacs Packages:\n"
213 "--------------------------\n")
214 (report-sxemacs-bug-packages-list)
216 ;; Insert a list of installed modules.
217 (if (fboundp 'list-modules)
219 (insert "\n\nInstalled Modules:\n"
220 "-----------------\n")
221 (let* ((mods (list-modules)))
223 (cl-prettyprint (cdr (car mods)))
224 (setq mods (cdr mods))))))
225 ;; Insert a list of loaded features
226 (let ((before-features (point)))
228 (format "\n\nFeatures:\n--------\n\n%s" (symbol-value 'features)))
230 (narrow-to-region before-features (point))
233 ;; Insert recent keystrokes.
235 "Recent keystrokes:\n-----------------\n\n")
236 (let ((before-keys (point)))
237 (insert (key-description recent-keys))
239 (narrow-to-region before-keys (point))
240 (goto-char before-keys)
241 (while (progn (move-to-column 50) (not (eobp)))
242 (search-forward " " nil t)
244 ;; Insert recent minibuffer messages.
245 (insert "\n\n\nRecent messages (most recent first):\n"
246 "-----------------------------------\n")
247 (let ((standard-output (current-buffer)))
248 (print-recent-messages 20)
250 ;; Insert the contents of the user's init file if it exists.
251 (if report-sxemacs-bug-send-init
252 (if (file-readable-p user-init-file)
254 (goto-char (point-max))
256 (insert "\n\nUser Init File:\n--------------\n\n")
257 (insert-file-contents user-init-file))))
258 ;; This is so the user has to type something
259 ;; in order to send easily.
260 (use-local-map (let ((map (make-sparse-keymap)))
261 (set-keymap-parents map (current-local-map))
263 (define-key (current-local-map) "\C-c\C-i" 'report-sxemacs-bug-info)
264 ;; Make it less likely people will send empty messages.
266 ((eq mail-user-agent 'sendmail-user-agent)
267 (make-local-variable 'mail-send-hook)
268 (add-hook 'mail-send-hook 'report-sxemacs-bug-hook))
269 ((eq mail-user-agent 'message-user-agent)
270 (make-local-variable 'message-send-hook)
271 (add-hook 'message-send-hook 'report-sxemacs-bug-hook))
272 ((eq mail-user-agent 'mh-e-user-agent)
273 (make-local-variable 'mh-before-send-letter-hook)
274 (add-hook 'mh-before-send-letter-hook 'report-sxemacs-bug-hook))
276 (make-local-variable 'mail-send-hook)
277 (add-hook 'mail-send-hook 'report-sxemacs-bug-hook)))
279 (goto-char (point-max))
280 (skip-chars-backward " \t\n")
281 (make-local-variable 'report-sxemacs-bug-orig-text)
282 (setq report-sxemacs-bug-orig-text (buffer-substring (point-min) (point))))
283 (goto-char user-point))
284 (delete-other-windows)
285 (unless report-sxemacs-bug-no-explanations
286 (report-sxemacs-bug-help)
288 ((eq mail-user-agent 'sendmail-user-agent)
289 (message (substitute-command-keys
290 "Type \\[mail-send-and-exit] to send the bug report, \\[kill-buffer] to cancel.")))
291 ((eq mail-user-agent 'message-user-agent)
292 (message (substitute-command-keys
293 "Type \\[message-send-and-exit] to send the bug report, \\[kill-buffer] to cancel.")))
294 ((eq mail-user-agent 'mh-e-user-agent)
295 (message (substitute-command-keys
296 "Type \\[mh-send-letter] to send the bug report, \\[kill-buffer] to cancel.")))
298 (message (substitute-command-keys
299 "Type \\[mail-send-and-exit] to send the bug report, \\[kill-buffer] to cancel."))))))
301 (defun report-sxemacs-bug-info ()
302 "Go to the Info node on reporting SXEmacs bugs."
304 (Info-goto-node "(xemacs)Bugs"))
306 (defun report-sxemacs-bug-hook ()
307 "Hook run before sending a bug report."
309 (goto-char (point-max))
310 (skip-chars-backward " \t\n")
311 (if (and (= (- (point) (point-min))
312 (length report-sxemacs-bug-orig-text))
313 (equal (buffer-substring (point-min) (point))
314 report-sxemacs-bug-orig-text))
315 (error "No text entered in bug report"))
317 ;; The last warning for novice users.
318 (if (or report-sxemacs-bug-no-confirmation
320 "Send this bug report to the SXEmacs maintainers? "))
321 ;; Just send the current mail.
323 (goto-char (point-min))
324 (let* ((top (point)))
325 (re-search-forward "^--text follows this line--$")
327 (narrow-to-region top (point))
328 (goto-char (point-min))
329 (if (re-search-forward "^To: " (eobp) t)
332 (delete-region pos (point))))
333 (goto-char (point-min))
334 (if (re-search-forward "^Cc: " (eobp) t)
337 (delete-region pos (point))))))
339 ((eq mail-user-agent 'sendmail-user-agent)
340 (kill-local-variable 'mail-send-hook))
341 ((eq mail-user-agent 'message-user-agent)
342 (kill-local-variable 'message-send-hook))
343 ((eq mail-user-agent 'mh-e-user-agent)
344 (kill-local-variable 'mh-before-send-letter-hook))
346 (kill-local-variable 'mail-send-hook)))
347 (unless report-sxemacs-bug-no-explanations
352 You invoked the command M-x report-sxemacs-bug,
353 but you decided not to mail the bug report to the SXEmacs maintainers.
355 If you want to mail it to someone else instead,
356 please insert the proper e-mail address after \"To: \",
357 and send the mail again.") nil) "*Bug Help*")))
358 (error "Sending Bug Report Cancelled"))))
360 (defun report-sxemacs-backtraces ()
361 "Save C and lisp backtrace buffers to files.
363 This is a convenience for reporting SXEmacs issues at
364 http://issues.sxemacs.org/. Returns t if any backtrace buffers are
365 found and saved, nil otherwise."
366 (let ((ctrace (or (get-buffer (concat "*gdb-sxemacs-"
367 emacs-program-version
369 (get-buffer "*gdb-sxemacs*")))
370 (ltrace (get-buffer "*Backtrace*")))
374 (write-region (point-min) (point-max)
375 (expand-file-name "c-backtrace"
380 (write-region (point-min) (point-max)
381 (expand-file-name "lisp-backtrace"
383 (and (or ctrace ltrace) t)))
385 (defun report-sxemacs-save-installation ()
386 "Save `Installation-string' to file.
388 This is a convenience for reporting SXEmacs issues at
389 http://issues.sxemacs.org/. Returns t on success, nil otherwise."
390 (let ((file (expand-file-name "Installation" (temp-directory)))
391 (str (and (boundp 'Installation-string)
392 (stringp Installation-string)
393 Installation-string)))
398 (write-region (point-min) (point-max) file))
402 (defconst report-sxemacs-bugzilla-notrace
403 "Thank you very much for taking the time to report a problem with SXEmacs
404 ========================================================================
406 Unfortunately we haven't been able to find any backtraces that could
407 help us track your problem down. Please try very hard to produce a
408 backtrace. One way you can do this is...
410 If you are not familar with SXEmacs debugging and/or gdb, you can simply
411 `M-: \(setq stack-trace-on-error t\)' or `stack-trace-on-signal'. Then
412 you just reproduce the bug/problem and a *Backtrace* buffer should pop
413 up. Once you have a backtrace, run `M-x report-sxemacs-bug' again and
414 it will be automatically saved to a file so you can attach it to your
415 bug at http://issues.sxemacs.org/.
417 OK, that was for a lisp backtrace, but don't forget a C trace as well.
418 Sometimes they are just as useful, if not more so, as the lisp trace.
419 If you have the XEmacs package \"debug\" installed, the commands `M-x
420 gdb' and `M-x gdb-with-core' are very useful. It runs gdb inside a
421 SXEmacs buffer. If `report-sxemacs-bug' finds a gdb buffer, it will
422 be saved to a file for you to attach to your bug also.
424 For some useful tips on debugging SXEmacs with gdb, see Q2.1.2, and
425 Q2.1.15 of the FAQ \(`C-h F'\).
428 "Message to user trying to report bugs without traces.")
430 (defconst report-sxemacs-bugzilla-instructions
431 "Thank you very much for reporting a problem with SXEmacs
432 ========================================================
434 SXEmacs bug and issue tracking is handled by our BugZilla installation
435 at http://issues.sxemacs.org/. To complete your report, you will have
436 to submit the bug/issue there.
439 for files named `Installation', `c-backtrace', and `lisp-backtrace' and
440 attach those to your bug. They will help us greatly in finding/fixing
443 When you fill in the description of your bug, please give as much
444 information as possible. Especially include specific steps required
445 to reproduce the bug. If none of the SXEmacs developers can reproduce
446 your bug it will be very difficult to track down or fix. Ideally, the
447 instructions for reproducing the bug should start with:
449 \"Step 1 -- sxemacs -no-autoloads\" or \"sxemacs -vanilla\"
451 This will reduce the likelihood of local settings being the cause of your bug.
453 Once you have submitted your bug, you should hear from somebody within
454 24 to 48 hours. If you don't, please give us a reminder on the SXEmacs
455 Devel <sxemacs-devel@sxemacs.org> mailing list.
458 "Bug reporting instructions.")
460 (defun report-sxemacs-bugzilla-instructions ()
461 "Display issue reporting instructions."
462 (let ((blurb (format report-sxemacs-bugzilla-instructions (temp-directory))))
463 (report-sxemacs-save-installation)
464 (with-displaying-help-buffer
470 (defun report-sxemacs-bug ()
471 "SXEmacs bug reporter."
473 (if (report-sxemacs-backtraces)
474 (report-sxemacs-bugzilla-instructions)
475 (window-configuration-to-register ?S)
476 (with-output-to-temp-buffer "Reporting Bugs"
477 (set-buffer standard-output)
478 (insert report-sxemacs-bugzilla-notrace)
480 (pop-to-buffer (get-buffer "Reporting Bugs"))
482 nil #'(lambda (&rest not-used-buffer)
483 (kill-buffer (get-buffer "Reporting Bugs"))
484 (jump-to-register ?S)
485 (when (y-or-n-p "No traces found, continue with issue report anyway? ")
486 (report-sxemacs-bugzilla-instructions)))))))
490 (load "xemacsbug" nil 'nomessage)
491 (eval-after-load "xemacsbug"
492 (defalias 'report-xemacs-bug 'report-sxemacs-bug)
493 (defalias 'report-emacs-bug 'report-sxemacs-bug)))
495 (provide 'issue-tracker)
496 ;;; issue-tracker.el ends here