patch.el 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. ;;; patch.el --- mail/apply a patch
  2. ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc.
  3. ;; GNU Emacs is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation; either version 2, or (at your option)
  6. ;; any later version.
  7. ;; GNU Emacs is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  13. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  14. ;; Boston, MA 02110-1301, USA.
  15. ;;; Author: Thien-Thi Nguyen <ttn@gnu.org>
  16. ;;; Version: 1
  17. ;;; Favorite-Favorite: Favorite-Favorite
  18. ;;; Commentary:
  19. ;; This file has two symmetrical usage modes, for patch creation and
  20. ;; application, respectively. The details are somewhat tuned for Guile
  21. ;; maintenance; probably we should generalize it a bit and add it to
  22. ;; Emacs proper at some point in the future. Long live free software!
  23. ;;
  24. ;; On the patch creation side of things, there are various version
  25. ;; control systems that are happy to write a diff to stdout (and
  26. ;; numerous Emacs interfaces to them all). Thus, we provide only a
  27. ;; simple `patch-send' that composes mail from the current buffer;
  28. ;; the contents of that buffer are left as an exercise for the patch
  29. ;; creator. When preparing the mail, `patch-send' scans the patch
  30. ;; for standard filename headers and sets up a skeleton change log --
  31. ;; filling this in is a good way to earn respect from maintainers (hint
  32. ;; hint). Type `C-c C-c' to send the mail when you are done. (See
  33. ;; `compose-mail' for more info.)
  34. ;;
  35. ;; TODO: Write/document patch-apply side of things.
  36. ;; TODO: Integrate w/ `ediff-patch-buffer' et al.
  37. ;;; Code:
  38. (require 'cl)
  39. (require 'update-changelog) ; for stitching
  40. ;; outgoing
  41. (defvar patch-greeting "hello guile maintainers,\n\n"
  42. "*String to insert at beginning of patch mail.")
  43. (defun patch-scan-files ()
  44. (let (files)
  45. (save-excursion
  46. (while (re-search-forward "^[+][+][+] \\(\\S-+\\)" (point-max) t)
  47. (setq files (cons (cons (match-string 1)
  48. (match-beginning 0))
  49. files))))
  50. (reverse files)))
  51. (defun patch-common-prefix (filenames)
  52. (let* ((first-file (car filenames))
  53. (prefix (and first-file (file-name-directory first-file))))
  54. (while (and prefix
  55. (not (string= "" prefix))
  56. (not (every (lambda (filename)
  57. (string-match (concat "^" prefix) filename))
  58. filenames)))
  59. (setq prefix (file-name-directory (substring prefix 0 -1))))
  60. prefix))
  61. (defun patch-changelog-skeleton ()
  62. (let* ((file-info (patch-scan-files))
  63. (fullpath-files (mapcar 'car file-info))
  64. (cut (length (patch-common-prefix fullpath-files)))
  65. (files (mapcar (lambda (fullpath-file)
  66. (substring fullpath-file cut))
  67. fullpath-files)))
  68. (mapconcat
  69. (lambda (file)
  70. (concat (make-string (length file) ?_) "\n" file "\n[writeme]"))
  71. files
  72. "\n")))
  73. (defun patch-send (buffer subject)
  74. (interactive "bBuffer: \nsSubject: ")
  75. (when (string= "" subject)
  76. (error "(empty subject)"))
  77. (compose-mail "bug-guile@gnu.org" subject)
  78. (insert (with-current-buffer buffer (buffer-string)))
  79. (mail-text)
  80. (insert patch-greeting)
  81. (save-excursion
  82. (insert "here is a patch ... [overview/observations/etc]\n\n"
  83. (patch-changelog-skeleton) "\n\n\n"
  84. (make-string 72 ?_) "\n")))
  85. ;; incoming
  86. ;;; patch.el ends here