patch.el 3.8 KB

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