* WL-MK (make-wl-news): New function.
[elisp/wanderlust.git] / WL-MK
1 ;;; -*- Emacs-Lisp -*-
2 ;;; WL-MK for byte-compile, install, uninstall
3 ;;;
4 ;;; Original by OKUNISHI Fujikazu <fuji0924@mbox.kyoto-inet.or.jp>
5 ;;; Modified by Yuuichi Teranishi <teranisi@gohome.org>
6
7 ;;;;;;;;;;;;;;;;;;;;;   DO NOT EDIT THIS FILE   ;;;;;;;;;;;;;;;;;;;;;
8 ;;;;;;;;;;;;;;;;;;;;;     INTERNAL USE ONLY     ;;;;;;;;;;;;;;;;;;;;;
9
10 ;;; Code
11
12 (defvar WLDIR "./wl")
13 (defvar ELMODIR "./elmo")
14 (defvar DOCDIR "./doc")
15 (defvar ICONDIR "./etc/icons")
16 (defvar UTILSDIR "./utils")
17 (defvar WL_PREFIX "wl")
18 (defvar ELMO_PREFIX "wl")
19
20 (defvar COMPRESS-SUFFIX-LIST '("" ".gz" ".Z" ".bz2"))
21
22 (defvar wl-install-utils nil
23   "If Non-nil, install `wl-utils-modules'.")
24
25 ;;; INFO
26 (defconst wl-ja-info "wl-ja.info")
27 (defconst wl-ja-texi "wl-ja.texi")
28 (defconst wl-en-info "wl.info")
29 (defconst wl-en-texi "wl.texi")
30
31 (defvar wl-info-lang '("ja" "en")
32   "The language of info file (\"ja\" or \"en\").")
33
34 ;;; NEWS
35 (defconst wl-news-news-file "NEWS")
36 (defconst wl-news-news-file-ja "NEWS.ja")
37 (defconst wl-news-filename "wl-news.el")
38
39 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40 \f
41 (require 'cl)
42 (defvar INFODIR nil)
43
44 (condition-case () (require 'custom) (error nil))
45 ;; for wl-vars.el
46 (unless (and (fboundp 'defgroup)
47              (fboundp 'defcustom)
48              ;; ignore broken module
49              (not (featurep 'tinycustom)))
50   (when (and (boundp 'emacs-major-version)
51              (= emacs-major-version 19)
52              (>= emacs-minor-version 29))
53     (message "%s" "
54   Warning: You don't seem to have \"new custom\" package installed.
55            See README file of APEL package for more information.
56 "))
57   (require 'backquote)
58   (defmacro defgroup (&rest args))
59   (defmacro defcustom (symbol value &optional doc &rest args)
60     (let ((doc (concat "*" (or doc ""))))
61       (` (defvar (, symbol) (, value) (, doc))))))
62
63 (load "bytecomp" nil t)
64
65 (unless (fboundp 'byte-compile-file-form-custom-declare-variable)
66   ;; Bind defcustom'ed variables.
67   (put 'custom-declare-variable 'byte-hunk-handler
68        'byte-compile-file-form-custom-declare-variable)
69   (defun byte-compile-file-form-custom-declare-variable (form)
70     (if (memq 'free-vars byte-compile-warnings)
71         (setq byte-compile-bound-variables
72               (cons (nth 1 (nth 1 form)) byte-compile-bound-variables)))
73     form))
74
75 (condition-case nil
76     (char-after)
77   (wrong-number-of-arguments
78    ;; Optimize byte code for `char-after'.
79    (put 'char-after 'byte-optimizer 'byte-optimize-char-after)
80    (defun byte-optimize-char-after (form)
81      (if (null (cdr form))
82          '(char-after (point))
83        form))))
84
85 (setq byte-compile-warnings '(free-vars unresolved callargs redefine))
86
87 ;; v18, v19
88 (if (boundp 'MULE)
89     (setq max-lisp-eval-depth 400))
90
91 ;; FIXME: it is currently needed to byte-compile with Emacs 21.
92 (setq recursive-load-depth-limit nil)
93
94 (condition-case () (require 'easymenu) (error nil))
95
96 (defvar config-wl-package-done nil)
97
98 (defun config-wl-package-subr ()
99   (unless config-wl-package-done
100     (setq config-wl-package-done t)
101     (setq load-path (cons (expand-file-name ".") load-path))
102     (setq load-path (cons (expand-file-name WLDIR)
103                           (cons (expand-file-name ELMODIR) load-path)))
104     ;; load custom file if exists.  `WL-CFG.el' override for committer.
105     (load "./WL-CFG" t nil nil)
106     ;; load-path
107     (if wl-install-utils
108         (setq load-path (cons (expand-file-name UTILSDIR) load-path)))
109     (require 'install)
110     (load "./WL-ELS" nil nil t)
111     ;; product.el version check
112     (require 'product)
113     (if (not (fboundp 'product-version-as-string))
114         (error "Please install new APEL.  See INSTALL or INSTALL.ja"))
115     ;; smtp.el version check.
116     (require 'smtp)
117     (if (not (fboundp 'smtp-send-buffer))
118         (error "Please install new FLIM.  See INSTALL or INSTALL.ja"))
119     (condition-case ()
120         (require 'mime-setup)
121       (error (error "Cannot load `mime-setup'.  Please install SEMI")))))
122
123 (defun config-wl-pixmap-dir (&optional packagedir)
124   "Examine pixmap directory where icon files should go."
125   (let ((pixmap-dir (car command-line-args-left)))
126     (defvar PIXMAPDIR
127       (if (string= pixmap-dir "NONE")
128           (if packagedir
129               (expand-file-name "etc/wl/" packagedir)
130             (expand-file-name "wl/icons/" data-directory))
131         pixmap-dir)))
132   (if PIXMAPDIR
133       (princ (format "PIXMAPDIR is %s\n" PIXMAPDIR)))
134   (setq command-line-args-left (cdr command-line-args-left)))
135
136 (defun config-wl-package ()
137   (config-wl-package-subr)
138   ;; LISPDIR check.
139   (let ((elispdir (car command-line-args-left)))
140     (if (string= elispdir "NONE")
141         (defvar LISPDIR (install-detect-elisp-directory))
142       (defvar LISPDIR elispdir)))
143   (princ (format "LISPDIR is %s\n" LISPDIR))
144   (setq command-line-args-left (cdr command-line-args-left))
145   ;; PIXMAPDIR check.
146   (config-wl-pixmap-dir)
147   (princ "\n"))
148
149 (defun update-version ()
150   "Update version number of documents."
151   (config-wl-package)
152   (load-file "elmo/elmo-version.el")
153   (let ((version (mapconcat
154                   'number-to-string
155                   (product-version (product-find 'elmo-version))
156                   ".")))
157     (princ (concat "Update version number to " version "\n"))
158     ;; generate version.tex
159     (with-temp-buffer
160       (insert "\\def\\versionnumber{" version "}\n")
161       (write-region (point-min) (point-max) (expand-file-name
162                                              "version.tex" "doc")))
163     ;; generate version.texi
164     (with-temp-buffer
165       (insert "@set VERSION " version "\n")
166       (write-region (point-min) (point-max) (expand-file-name
167                                              "version.texi" "doc")))))
168
169 (defun test-wl ()
170   "Run test suite for developer."
171   (config-wl-package)
172   (require 'lunit)
173   (let ((files (directory-files "tests" t "^test-.*\\.el$"))
174         (suite (lunit-make-test-suite)))
175     (while files
176       (if (file-regular-p (car files))
177           (progn
178             (load-file (car files))
179             (lunit-test-suite-add-test
180              suite (lunit-make-test-suite-from-class
181                     (intern (file-name-sans-extension
182                              (file-name-nondirectory (car files))))))))
183       (setq files (cdr files)))
184     (lunit suite)))
185
186 (defun check-wl ()
187   "Check user environment.  Not for developer."
188   (config-wl-package)
189   (require 'lunit)
190   (let ((files (directory-files "tests" t "^check-.*\\.el$"))
191         (suite (lunit-make-test-suite)))
192     (while files
193       (if (file-regular-p (car files))
194           (progn
195             (load-file (car files))
196             (lunit-test-suite-add-test
197              suite (lunit-make-test-suite-from-class
198                     (intern (file-name-sans-extension
199                              (file-name-nondirectory (car files))))))))
200       (setq files (cdr files)))
201     (lunit suite)))
202
203 (defun wl-scan-source (path)
204   (let (ret)
205     (mapcar
206      '(lambda (x)
207         (mapcar '(lambda (y)
208                    (setq ret (append (list y (concat y "c")) ret)))
209                 (directory-files x nil "\\(.+\\)\\.el$" t)))
210      path)
211     ret))
212
213
214 (defun wl-uninstall (objs path)
215   ;(message (mapconcat 'identity objs " "))
216   (mapcar
217    '(lambda (x)
218       (let ((filename (expand-file-name x path)))
219         (if (and (file-exists-p filename)
220                  (file-writable-p filename))
221             (progn
222               (princ (format "%s was uninstalled.\n" filename))
223               (delete-file filename)))))
224    objs))
225
226
227 (defun compile-wl-package ()
228   (config-wl-package)
229   (make-wl-news)
230   (mapcar
231    '(lambda (x)
232       (compile-elisp-modules (cdr x) (car x)))
233    modules-alist))
234
235 (defun install-wl-icons ()
236   (if (not (file-directory-p PIXMAPDIR))
237       (make-directory PIXMAPDIR t))
238   (let* ((case-fold-search t)
239          (icons (directory-files ICONDIR t
240                                  (cond ((featurep 'xemacs)
241                                         "\\.x[bp]m$")
242                                        ((and (boundp 'emacs-major-version)
243                                              (>= emacs-major-version 21))
244                                         "\\.img$\\|\\.x[bp]m$")
245                                        ((featurep 'mule)
246                                         "\\.img$\\|\\.xbm$"))))
247          icon dest)
248     (while icons
249       (setq icon (car icons)
250             icons (cdr icons)
251             dest (expand-file-name (file-name-nondirectory icon) PIXMAPDIR))
252       (princ (format "%s -> %s\n"
253                      (file-name-nondirectory icon)
254                      (substring (file-name-directory dest) 0 -1)))
255       (copy-file icon dest t))))
256
257 (defun install-wl-package ()
258   (compile-wl-package)
259   (let ((wl-install-dir (expand-file-name WL_PREFIX LISPDIR))
260         (elmo-install-dir (expand-file-name ELMO_PREFIX LISPDIR)))
261     (mapcar
262      '(lambda (x)
263         (install-elisp-modules (cdr x) (car x)
264                                (if (string= (car x) ELMODIR)
265                                    elmo-install-dir
266                                  wl-install-dir)))
267      modules-alist))
268   (if PIXMAPDIR
269       (install-wl-icons)))
270
271
272 (defun uninstall-wl-package ()
273   (config-wl-package)
274   (let ((wl-install-dir (expand-file-name WL_PREFIX
275                                           LISPDIR))
276         (elmo-install-dir (expand-file-name ELMO_PREFIX
277                                             LISPDIR)))
278     (wl-uninstall (wl-scan-source (list WLDIR UTILSDIR))
279                   wl-install-dir)
280     (wl-uninstall (wl-scan-source (list ELMODIR))
281                   elmo-install-dir))
282   (if PIXMAPDIR
283       (let* ((case-fold-search t)
284              (icons (directory-files PIXMAPDIR t "\\.x[bp]m$"))
285              icon)
286         (while icons
287           (setq icon (car icons)
288                 icons (cdr icons))
289           (if (and (file-exists-p icon)
290                    (file-writable-p icon))
291               (progn
292                 (princ (format "%s was uninstalled.\n" icon))
293                 (delete-file icon)))))))
294
295
296 (defun config-wl-package-xmas ()
297   (if (not (featurep 'xemacs))
298       (error "This directive is only for XEmacs"))
299   (config-wl-package-subr)
300   ;; PACKAGEDIR check.
301   (let (package-dir)
302     (and (setq package-dir (car command-line-args-left))
303          (if (string= "NONE" package-dir)
304              (defvar PACKAGEDIR
305                (if (boundp 'early-packages)
306                    (let ((dirs (append (if early-package-load-path
307                                            early-packages)
308                                        (if late-package-load-path
309                                            late-packages)
310                                        (if last-package-load-path
311                                            last-packages)))
312                          dir)
313                      (while (not (file-exists-p
314                                   (setq dir (car dirs))))
315                        (setq dirs (cdr dirs)))
316                      dir)))
317            (defvar PACKAGEDIR package-dir)))
318     (princ (format "PACKAGEDIR is %s\n" PACKAGEDIR))
319     (setq command-line-args-left (cdr command-line-args-left)))
320   ;; PIXMAPDIR check.
321   (config-wl-pixmap-dir PACKAGEDIR)
322   (princ "\n"))
323
324 ;; from SEMI-MK
325 (defun compile-wl-package-xmas ()
326   (config-wl-package-xmas)
327   (setq autoload-package-name "wl")
328   (add-to-list 'command-line-args-left WLDIR)
329   (batch-update-directory)
330   (add-to-list 'command-line-args-left WLDIR)
331   (Custom-make-dependencies)
332   ;; WL-AUTOLOAD-MODULES
333   (compile-elisp-modules WL-AUTOLOAD-MODULES WLDIR)
334   (mapcar
335    '(lambda (x)
336       (compile-elisp-modules (cdr x) (car x)))
337    modules-alist))
338
339 (defun install-wl-package-xmas ()
340   (compile-wl-package-xmas)
341   (let ((LISPDIR (expand-file-name "wl"
342                                     (expand-file-name "lisp"
343                                                       PACKAGEDIR)))
344         (DATADIR  (expand-file-name "wl"
345                                     (expand-file-name "etc"
346                                                       PACKAGEDIR)))
347         (INFODIR  (expand-file-name "info" PACKAGEDIR)))
348     (or (file-exists-p DATADIR)
349         (make-directory DATADIR t))
350     (or (file-exists-p INFODIR)
351         (make-directory INFODIR t))
352     ;; copy xpm files
353     (install-wl-icons)
354
355     (mapcar '(lambda (x)
356                (install-elisp-modules (cdr x) (car x) LISPDIR))
357             modules-alist)
358     ;; WL-AUTOLOAD-MODULES
359     (install-elisp-modules WL-AUTOLOAD-MODULES WLDIR LISPDIR)
360     ;;
361     (wl-texinfo-format)
362     (wl-texinfo-install)))
363
364 \f
365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366 ;;; Texinfo stuff
367
368 (defun wl-texinfo-format-file (lang)
369   (let ((infofile (symbol-value (intern (format "wl-%s-info" lang))))
370         (texifile (symbol-value (intern (format "wl-%s-texi" lang)))))
371     (require 'wl-vars) ;; for 'wl-cs-local
372     (or (file-newer-than-file-p (expand-file-name infofile DOCDIR)
373                                 (expand-file-name texifile DOCDIR))
374         (let (obuf beg)
375           ;; Support old texinfmt.el
376           (require 'ptexinfmt (expand-file-name "ptexinfmt.el" UTILSDIR))
377           (find-file (expand-file-name texifile DOCDIR))
378           (setq obuf (current-buffer))
379           ;; We can't know file names if splitted.
380           (texinfo-format-buffer t)
381           ;; Emacs20.2's default is 'raw-text-unix.
382           (and (fboundp 'set-buffer-file-coding-system)
383                (set-buffer-file-coding-system wl-cs-local))
384           (save-buffer)
385           (kill-buffer (current-buffer)) ;; info
386           (kill-buffer obuf)) ;; texi
387         )))
388
389 (defun wl-texinfo-format ()
390   (wl-detect-info-directory)
391   (cond ((listp wl-info-lang)
392          (mapcar 'wl-texinfo-format-file wl-info-lang))
393         ((stringp wl-info-lang)
394          (wl-texinfo-format-file wl-info-lang))))
395
396 (defun wl-texinfo-install-file (lang)
397   (let ((infofile (symbol-value (intern (format "wl-%s-info" lang)))))
398     (install-file infofile DOCDIR INFODIR nil 'overwrite)))
399
400 (defun wl-texinfo-install ()
401   (cond ((listp wl-info-lang)
402          (mapcar 'wl-texinfo-install-file wl-info-lang))
403         ((stringp wl-info-lang)
404          (wl-texinfo-install-file wl-info-lang))))
405
406 (defun wl-primary-info-file ()
407   "Get primary info file (for wl-detect-info-directory)."
408   (cond
409    ((listp wl-info-lang)
410     (let ((wl-info-lang (car wl-info-lang)))
411       (wl-primary-info-file)))
412    ((stringp wl-info-lang)
413     (symbol-value (intern (format "wl-%s-info" wl-info-lang))))))
414
415 (defun wl-detect-info-directory ()
416   (config-wl-package-subr)
417   ;; INFODIR check.
418   (require 'info)
419   (if (fboundp 'info-initialize)
420       (info-initialize))
421   (unless INFODIR
422     (let ((infodir (car command-line-args-left))
423           (info (wl-primary-info-file))
424           previous)
425       (setq INFODIR
426             (if (string= infodir "NONE")
427                 (if (setq previous
428                           (exec-installed-p info Info-directory-list
429                                             COMPRESS-SUFFIX-LIST))
430                     ;;(progn
431                     ;;(condition-case nil (delete-file previous))
432                     (directory-file-name (file-name-directory previous));)
433                   (car Info-directory-list))
434               infodir))
435       (setq command-line-args-left (cdr command-line-args-left))))
436   (princ (format "INFODIR is %s\n\n" INFODIR)))
437
438 (defun install-wl-info ()
439   (wl-texinfo-format)
440   (wl-texinfo-install))
441
442 \f
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;;; wl-news stuff
445
446 (defun make-wl-news ()
447   (let ((in-filename
448          (expand-file-name (concat wl-news-filename ".in") WLDIR))
449         (out-filename
450          (expand-file-name wl-news-filename WLDIR)))
451     (if (or (file-newer-than-file-p in-filename out-filename)
452             (file-newer-than-file-p wl-news-news-file out-filename)
453             (file-newer-than-file-p wl-news-news-file-ja out-filename))
454         (with-temp-buffer
455           (save-excursion
456             (insert-file-contents in-filename)
457             (goto-char (point-min))
458             (unless (re-search-forward "^;;; -\\*- news-list -\\*-" nil t)
459               (error "Invalid wl-news.el.in"))
460             (forward-line 2)
461             (insert "(defconst wl-news-news-alist\n  '")
462             (prin1 (wl-news-parse-news) (current-buffer))
463             (insert ")\n\n")
464             (insert "(defconst wl-news-news-ja-alist\n  '")
465             (prin1 (wl-news-parse-news-ja) (current-buffer))
466             (insert ")\n")
467             (write-region (point-min) (point-max) out-filename))))))
468
469 (defun wl-news-parse-news ()
470   (let (news-list)
471     (with-temp-buffer
472       (insert-file-contents wl-news-news-file)
473       (while (re-search-forward "^\\* Changes in \\([0-9.]*\\) from" nil t)
474         (let ((beg (match-beginning 0))
475               (version-tmp (split-string (match-string 1) "\\."))
476                version news-string end)
477           (while version-tmp
478             (setq version (append version (list (string-to-int (car version-tmp)))))
479             (setq version-tmp (cdr version-tmp)))
480           (re-search-forward "^\\(\\* \\|\f\\)" nil t)
481           (goto-char (- (match-beginning 0) 1))
482           (setq end (point))
483           (setq news-string (buffer-substring beg end))
484           (setq news-list
485                 (append news-list
486                         (list (cons version news-string)))))))
487     news-list))
488
489 (defun wl-news-parse-news-ja ()
490   (let (news-list)
491     (with-temp-buffer
492       (insert-file-contents wl-news-news-file-ja)
493       (while (re-search-forward "^\\* [0-9.]* \e$B$+$i\e(B \\([0-9.]*\\) \e$B$X$NJQ99E@\e(B" nil t)
494         (let ((beg (match-beginning 0))
495               (version-tmp (split-string (match-string 1) "\\."))
496                version news-string end)
497           (while version-tmp
498             (setq version (append version (list (string-to-int (car version-tmp)))))
499             (setq version-tmp (cdr version-tmp)))
500           (re-search-forward "^\\(\\* \\|\f\\)" nil t)
501           (goto-char (- (match-beginning 0) 1))
502           (setq end (point))
503           (setq news-string (buffer-substring beg end))
504           (setq news-list
505                 (append news-list
506                         (list (cons version news-string)))))))
507     news-list))
508
509
510
511 \f
512 ;;; ToDo
513 ;;; * MORE refine code (^_^;
514
515 ;;; End