1ddfa2fdb87dc16ccb7243e1a000c79d37b91230
[packages] / xemacs-packages / build / build-report.el
1 ;;; build-report.el --- Automatically formatted build reports for XEmacs
2
3 ;; Copyright (C) 1997-2003 Adrian Aichner
4
5 ;; Author: Adrian Aichner <adrian@xemacs.org>
6 ;; Date: $Date: 2009-10-01 18:39:57 $
7 ;; Version: $Revision: 1.50 $
8 ;; Keywords: internal
9
10 ;; This file is part of XEmacs.
11
12 ;; XEmacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING.  If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 ;; 02111-1307, USA.
26
27 ;;; Synched up with: Not synched.
28
29 ;;; Commentary:
30
31 ;; The Idea:
32 ;; Let XEmacs report interesting aspects of how it was built.
33
34 ;; The Concept:
35 ;; User creates an XEmacs Build Report by just calling
36 ;; M-x build-report
37 ;; which will initialize a mail buffer with relevant information
38 ;; derived from the XEmacs build process. Point is left at the
39 ;; beginning of the report for user to input some personal notes and
40 ;; send the report.
41
42 ;; The Status:
43 ;; This is the first `Proof of Concept'.
44
45 ;; The Author:
46 ;; Adrian Aichner, Teradyne GmbH Munich, Sun., Apr. 20, 1997.
47
48 ;;; Code:
49
50 (require 'config)
51 (require 'custom)
52 (require 'cl)
53 (provide 'build-report)
54
55 (eval-when-compile (when (eq 'list (symbol-function 'values))
56                      (define-compiler-macro values (&rest args)
57                        `(list ,@args))))
58
59 ;;; Constant definitions used internally by `build-report'.  These are not
60 ;;; anticipated to be changed by users of `build-report'.
61 ;;; If users do need to change the value of any of these, they need to do
62 ;;; it after `build-report' has been loaded (not just required).  Please
63 ;;; report it to the maintainers of `build-report' when you think you
64 ;;; need to do this.
65 (defconst build-report-installation-version-regexp
66   "XEmacs\\s-+\\([0-9]+\\)\\.\\([0-9]+\\)\\(\\(-b\\|\\.\\)\\([0-9]+\\)\\)?\\s-+\\\\?\"\\([^\\\"]+\\)\\\\?\"\\s-+\\(.*\\)?configured\\s-+for\\s-+`\\(.+\\)'\\."
67   "*REGEXP matching XEmacs Beta Version string in
68 `build-report-installation-file' file.  This variable is used by
69 `build-report-installation-data'.")
70
71 (defconst build-report-version-file-regexp
72   "emacs_major_version\\s-*=\\s-*\\([0-9]+\\)
73 emacs_minor_version\\s-*=\\s-*\\([0-9]+\\)
74 emacs_beta_version\\s-*=\\s-*\\([0-9]+\\)?
75 xemacs_codename\\s-*=\\s-*\"\\([^\"]+\\)\"\\(
76 xemacs_extra_name\\s-*=\\s-*\"\\([^\"]+\\)\"\\)?"
77   "*REGEXP matching XEmacs Beta Version variable assignments in
78 `build-report-version-file' file.  This variable is used by
79 `build-report-version-file-data'.")
80
81 (defconst build-report-installation-srcdir-regexp
82   "\\s-*Where should the build process find the source code\\?\\s-*\\(.*\\)$"
83   "REGEXP matching XEmacs Beta srcdir as the first substring match in
84 `build-report-installation-file' file.  This variable is used by
85 `build-report-installation-data'.")
86
87 ;;; Customization support for build-report starts here.
88
89 (defgroup build-report nil
90   "Standardizes the Creation of XEmacs Build Reports."
91   :load 'build-report
92   :group 'build)
93
94 (defcustom build-report-destination
95   (list
96    "XEmacs Build Reports List <xemacs-buildreports@xemacs.org>"
97    "XEmacs Beta List <xemacs-beta@xemacs.org>")
98   "*The list of mail addresses XEmacs Build Reports should most likely
99 go to."
100   :type '(repeat
101           :custom-show t
102           :documentation-shown t
103           string)
104   :group 'build-report)
105
106 (defcustom build-report-keep-regexp
107   (list
108    "^\\(cd\\|n?make\\)\\s-"
109    "errors?"
110    "warnings?"
111    "pure.*\\(space\\|size\\)"
112    "hides\\b"
113    "strange"
114    "shadowings"
115    "^Compil\\(ing\\s-+in\\|ation\\)"
116    "^Using"
117    "not\\s-+found"
118    "^While\\s-+compiling.*\\(\n\\s-+.+\\)*"
119    "^Note:"
120    "Installing"
121    "[Ff]ile(s) copied"
122    "\\s-+tests\\s-+"
123    "^[A-Z] [^ ]+$"
124    "^Wrong number of arguments:"
125    "^  \\*\\* "
126    "^\\(FAIL\\|SKIP\\):")
127   "*Regexp of make process output lines to keep in the report."
128   :type '(repeat
129           :custom-show t
130           :documentation-shown t
131           regexp)
132   :group 'build-report)
133
134 (defcustom build-report-delete-regexp
135   (list
136    "confl.*with.*auto-inlining"
137    "^Formatting:"
138    "^\\s-*0 .*\\(failure\\|error\\)s?"
139    "^PASS:"
140    "(100%) tests successful")
141   "*Regexp of make process output lines to delete from the report."
142   :type '(repeat
143           :custom-show t
144           :documentation-shown t
145           regexp)
146   :group 'build-report)
147
148 (defcustom build-report-make-output-dir
149   (cond 
150    ((equal system-type 'windows-nt)
151     (expand-file-name "nt"
152                       (gethash 'blddir (config-value-hash-table))))
153    (t
154     (gethash 'blddir (config-value-hash-table))))
155   "*Directory where the build report file is found.
156   If this is empty or nil, the default, it is replaced by the value of
157   the XEmacs build directory."
158   :type '(directory
159           :custom-show t
160           :documentation-shown t)
161   :group 'build-report)
162
163 (defcustom build-report-make-output-files
164   (list
165    "beta.err"
166    "xemacs-make-all.err" 
167    "xemacs-make-check-temacs.err"
168    "xemacs-make-check.err"
169    "xemacs-make-install.err")
170   "*List of Filenames where stdout and stderr of XEmacs make process
171 have been stored.  These are relative to
172 `build-report-make-output-dir`.  You'll have to run make with output
173 redirection or use the `build' XEmacs package to save this output. You
174 may use following alias
175
176 alias mk 'make \!* >>&\! \!$.err &'
177
178 under csh, so that you get beta.err when you run `mk beta'."
179   :type '(repeat
180           :custom-show t
181           :documentation-shown t
182           file)
183   :group 'build-report)
184
185 (defcustom build-report-installation-file
186   (expand-file-name "Installation"
187                     (gethash 'blddir (config-value-hash-table)))
188   "*Installation file produced by XEmacs configure process."
189   :type '(file
190           :custom-show t
191           :documentation-shown t)
192   :group 'build-report)
193
194 (defcustom build-report-version-file
195   (expand-file-name
196    "version.sh"
197    (gethash 'blddir (config-value-hash-table)))
198   "*version.sh file identifying XEmacs (Beta) Distribution."
199   :type '(file
200           :custom-show t
201           :documentation-shown t)
202   :group 'build-report)
203
204 (defcustom build-report-installation-insert-all
205   nil
206   "*Tell build-report to insert the whole Installation file
207   instead of just the last report."
208   :type 'boolean
209   :group 'build-report)
210
211 (defcustom build-report-subject
212   (concat "[%s] " emacs-version " on " system-configuration)
213   "*XEmacs Build Report Subject Line. %s-sequences will be substituted
214   with user input through `build-report' according to
215   `build-report-prompts' using `format'."
216   :type '(string
217           :custom-show t
218           :documentation-shown t)
219   :group 'build-report)
220
221 (defcustom build-report-prompts
222   (quote (("Status?: "  ("Success" "Failure"))))
223   "*XEmacs Build Report Prompt(s). This is a list of prompt-string
224   lists used by `build-report' in conjunction with
225   `build-report-subject'. Each list consists of a prompt string
226   followed by any number of strings which can be chosen via the history
227   mechanism."
228   :type '(repeat
229           :custom-show t
230           :documentation-shown t
231           (list
232            :tag "Prompt"
233            string
234            (repeat
235             :tag "Values"
236             string)))
237   :group 'build-report)
238
239 (defcustom build-report-file-encoding
240   "7bit"
241   "*XEmacs Build Report File Encoding to be used when MIME support is
242   available."
243   :group 'build-report)
244
245 ;; Symbol Name mappings from TM to SEMI serving as Compatibility
246 ;; Bandaid
247 (when (featurep 'mime-setup)
248   ;; No (defvaralias ...) so far. Thanks to "Didier Verna"
249   ;; <didier@xemacs.org> for reporting my incorrect defvaraliasing of
250   ;; `mime-editor/insert-tag'.
251   ;; Thanks to Jens-Ulrik Holger Petersen
252   ;; <petersen@kurims.kyoto-u.ac.jp> for suggesting the conditional
253   ;; aliasing of SEMI functions.
254   (unless (fboundp 'mime-edit-content-beginning)
255     (defalias 'mime-edit-content-beginning 'mime-editor/content-beginning))
256   (unless (fboundp 'mime-edit-insert-tag)
257     (defalias 'mime-edit-insert-tag 'mime-editor/insert-tag))
258   (unless (fboundp 'mime-edit-insert-binary-file)
259     (defalias 'mime-edit-insert-binary-file
260       'mime-editor/insert-binary-file)))
261
262 (defun build-report-make-output-get ()
263   "Return the filename the XEmacs make output is saved in."
264   (interactive)
265   (if (or (string-equal build-report-make-output-dir "")
266           (null build-report-make-output-dir))
267       (mapcar
268        (function
269         (lambda (f)
270           (expand-file-name
271            f
272            (file-name-as-directory
273             (gethash 'blddir (config-value-hash-table))))))
274        build-report-make-output-files)
275     (mapcar
276      (function
277       (lambda (f)
278         (expand-file-name
279          f
280          (file-name-as-directory build-report-make-output-dir))))
281      build-report-make-output-files)))
282
283 ;;;###autoload
284 (defun build-report (&rest args)
285   "Report build information including Installation and make output.
286
287 Prompts for status (usually \"Success\" or \"Failure\").  Then uses
288 `compose-mail' to create a mail message.  The Subject header contains
289 status and version information.  Point is left at the beginning of the
290 mail text.  Add some notes if you like, and send the report.
291
292 Looks for Installation and the make output file (`beta.err' by
293 default, customizable via `build-report-make-output-files') in the
294 build directory of the running XEmacs by default (customizable via
295 `build-report-make-output-dir').  The output from make is filtered
296 through `build-report-keep-regexp' and `build-report-delete-regexp'
297 before including in the message.
298
299 See also `mail-user-agent', `build-report-destination', and
300 `build-report-installation-file'."
301   ;; `interactive' form returns value for formal parameter `args'.
302   (interactive
303    (let (prompt
304          hist
305          arg
306          (prompts build-report-prompts))
307      (progn
308        (while prompts
309          (defvar hist)
310          (setq prompt (caar prompts))
311          (setq hist (cdar prompts))
312          ;; `build-report-prompts' used to be a list of lists, the
313          ;; first element of each list being the prompt, the rest being
314          ;; the history.  The history is now in a separate list.  We
315          ;; better check for that.
316          (if (listp (car hist))
317              (setq hist (car hist)))
318          (setq prompts (cdr prompts))
319          (setq arg (cons (read-string prompt "" 'hist) arg)))
320        arg)))
321   (save-excursion
322     (if (file-exists-p build-report-installation-file)
323         (multiple-value-bind
324             (major minor beta codename extraname configuration)
325             (build-report-installation-data build-report-installation-file)
326           (setq build-report-subject
327                 (format "[%%s] XEmacs %s.%s%s \"%s\" %s%s"
328                         major minor beta codename extraname configuration)))
329       (multiple-value-bind
330           (major minor beta codename extraname)
331           (build-report-version-file-data build-report-version-file)
332         (setq build-report-subject
333               (format "[%%s] XEmacs %s.%s%s \"%s\" %s%s"
334                       major minor beta codename extraname system-configuration))))
335     (compose-mail
336      ;; `build-report-destination' used to be a single string, so
337      ;; let's test if we really get a list of destinations.
338      (if (listp build-report-destination)
339          (read-string
340           "Build Report Destination: "
341           (car build-report-destination)
342           'build-report-destination)
343        (read-string
344         "Build Report Destination: "
345         build-report-destination)
346        )
347      (apply 'format build-report-subject args)
348      nil
349      nil
350      nil
351      nil
352      nil)
353     (let* ((report-begin (point))
354            (files (reverse (build-report-make-output-get)))
355            (file (car files)))
356       (while file
357         (if (file-exists-p file)
358             (insert (build-report-insert-make-output report-begin file))
359           (insert (format "%s not found!\n" file)))
360         (insert "\n")
361         (setq files (cdr files))
362         (setq file (car files)))
363       (if (file-exists-p build-report-installation-file)
364           (insert (build-report-insert-installation-file
365                    report-begin
366                    build-report-installation-insert-all))
367         (insert (format "%s not found!\n" build-report-installation-file)))
368 ;;;       (when (and (>= major 21) (>= minor 2) (or (null beta) (>= beta 32)))
369 ;;;         (insert "\n")
370 ;;;         (insert (build-report-insert-config-inc report-begin)))
371       (insert "\n")
372       (insert (build-report-insert-header report-begin))
373       (goto-char report-begin))))
374
375 (defun build-report-insert-header (where)
376   "Inserts the build-report-header at the point specified by `where'."
377   (goto-char where)
378   (with-temp-buffer
379     (insert
380      (format "
381 > XEmacs Build Report generated by emacs-version
382 > %s
383 > with system-configuration
384 > %s
385 > follows:\n\n" emacs-version system-configuration))
386     (buffer-string)))
387
388 (defun build-report-insert-make-output (where file)
389   "Inserts the output of the XEmacs Beta make run in the
390 current buffer at position WHERE.
391 The make process output must have been saved in
392 `build-report-make-output-files' during the XEmacs Beta building."
393   (goto-char where)
394   (with-temp-buffer
395     (if (file-exists-p file)
396         (progn
397           (if (featurep 'mime-setup)
398               (progn
399                 (mime-edit-insert-tag
400                  "text"
401                  "plain"
402                  (concat
403                   "\nContent-Disposition: attachment;"
404                   " filename=\""
405                   (file-name-nondirectory
406                    file)
407                   "\""))
408                 (mime-edit-insert-binary-file
409                  file
410                  build-report-file-encoding))
411             (insert-file-contents file))
412           (when build-report-keep-regexp
413             (goto-char (point-min))
414             (delete-non-matching-lines (build-report-keep)))
415           (when build-report-delete-regexp
416             (goto-char (point-min))
417             (delete-matching-lines (build-report-delete)))
418           (goto-char (point-min))
419           (if build-report-keep-regexp
420               (insert
421                (format
422                 "> keeping lines matching
423 > \"%s\"
424 "
425                 (build-report-keep))))
426           (if build-report-delete-regexp
427               (insert
428                (format
429                 "> %sdeleting lines matching
430 > \"%s\"
431 "
432                 (if build-report-keep-regexp
433                     "and then "
434                   "")
435                 (build-report-delete))))
436           (insert "\n")
437           (goto-char (point-min))
438           (insert
439            (format "> Contents of %s\n" file)))
440       (insert "> " file
441               " does not exist!\n\n"))
442     (buffer-string)))
443
444 (defun build-report-insert-installation-file (where all)
445   "Inserts the contents of the `build-report-installation-file'
446 created by the XEmacs Beta configure process."
447   (goto-char where)
448   (with-temp-buffer
449     (if (file-exists-p build-report-installation-file)
450         (let (file-begin last-configure)
451           (insert "> Contents of "
452                   build-report-installation-file
453                   ":\n")
454           (insert
455            (format
456             "> (Output from %s of ./configure)\n\n"
457             (if all "all runs" "most recent run")))
458           (if (featurep 'mime-setup)
459               (progn
460                 (mime-edit-insert-tag
461                  "text"
462                  "plain"
463                  (concat
464                   "\nContent-Disposition: attachment;"
465                   " filename=\""
466                   (file-name-nondirectory
467                    build-report-installation-file)
468                   "\""))
469                 (mime-edit-insert-binary-file
470                  build-report-installation-file
471                  build-report-file-encoding)
472                 (setq file-begin (mime-edit-content-beginning)))
473             (setq file-begin (point))
474             (insert-file-contents
475              build-report-installation-file))
476           (unless all
477             (setq last-configure
478                   (search-backward-regexp
479                    "^\\(uname.*\\|osversion\\|OS\\):\\s-+" file-begin t))
480             (if (and file-begin last-configure)
481                 (delete-region file-begin last-configure))))
482       (insert "> " build-report-installation-file
483               " does not exist!\n\n"))
484     (buffer-string)))
485
486 (defun build-report-keep ()
487   "Concatenate elements of `build-report-keep-regexp' and a general
488 MIME tag REGEXP.  The result is a REGEXP string matching either of the
489 REGEXPs in `build-report-keep-regexp' or a general MIME tag REGEXP."
490   (mapconcat #'identity
491              (cons "^--\\[\\[\\|\\]\\]$" build-report-keep-regexp) "\\|"))
492
493 (defun build-report-delete ()
494   "Concatenate elements of `build-report-delete-regexp' and a general
495 MIME tag REGEXP.  The result is a REGEXP string matching either of the
496 REGEXPs in `build-report-delete-regexp' or a general MIME tag REGEXP."
497   (mapconcat '(lambda (item) item)
498              build-report-delete-regexp "\\|"))
499
500 (defun build-report-installation-data (&optional file)
501   "Return a list of XEmacs installation data containing MAJOR_NUMBER
502 MINOR_NUMBER BETA_STRING CODENAME CONFIGURATION SRCDIR from FILE,
503 which defaults to `build-report-installation-file'."
504   (interactive "fInstallation file: ")
505   (unless file
506     (setq file build-report-installation-file))
507   (let
508       (major minor beta codename extraname configuration srcdir)
509     (save-window-excursion
510       (find-file-read-only file)
511       (goto-char (point-min))
512       (while (< (point) (point-max))
513         (cond
514          ((looking-at build-report-installation-version-regexp)
515           (goto-char (match-end 0))
516           (setq major (or (match-string 1) ""))
517           (setq minor (or (match-string 2) ""))
518           (setq beta (or (match-string 3) ""))
519           (setq codename (or (match-string 6) ""))
520           (setq extraname (or (match-string 7) ""))
521           (setq configuration (or (match-string 8) "")))
522          ((looking-at build-report-installation-srcdir-regexp)
523           (goto-char (match-end 0))
524           (setq srcdir (or (match-string 1) "")))
525          ;; We avoid matching a potentially zero-length string to avoid
526          ;; infinite looping.
527          ((looking-at
528            "^.+$")
529           (goto-char (match-end 0)))
530          ((looking-at "\n")
531           (goto-char (match-end 0)))))
532       (values major minor (or beta "") codename extraname configuration srcdir))))
533
534 (defun build-report-version-file-data (&optional file)
535   "Return a list of XEmacs version information containing
536 MAJOR_NUMBER MINOR_NUMBER BETA_STRING CODENAME from FILE, which
537 defaults to `build-report-version-file'." 
538   (interactive "fversion.sh file: ")
539   (unless file
540     (setq file build-report-version-file))
541   (let
542       (major minor beta codename extraname)
543     (save-window-excursion
544       (find-file-read-only file)
545       (goto-char (point-min))
546       (while (< (point) (point-max))
547         (cond
548          ((looking-at build-report-version-file-regexp)
549           (goto-char (match-end 0))
550           (setq major (or (match-string 1) ""))
551           (setq minor (or (match-string 2) ""))
552           (setq beta (or (match-string 3) ""))
553           (setq codename (or (match-string 4) ""))
554           (setq extraname (or (match-string 6) "")))
555          ;; We avoid matching a potentially zero-length string to avoid
556          ;; infinite looping.
557          ((looking-at
558            "^.+$")
559           (goto-char (match-end 0)))
560          ((looking-at "\n")
561           (goto-char (match-end 0)))))
562       (values major minor (or beta "") codename extraname))))
563
564 ;;; build-report.el ends here