diff options
| author | Glenn Morris | 2015-06-30 14:59:04 -0400 |
|---|---|---|
| committer | Glenn Morris | 2015-06-30 14:59:04 -0400 |
| commit | 5200c2baefbc855d36c07e2d6a9c1adeb693a542 (patch) | |
| tree | e2c67a0c9e71041a150b38fec60cedeb2d69fe7d | |
| parent | 0dfea4562e19f5cc90c77ff5f9a96f9e94caf57c (diff) | |
| download | emacs-5200c2baefbc855d36c07e2d6a9c1adeb693a542.tar.gz emacs-5200c2baefbc855d36c07e2d6a9c1adeb693a542.zip | |
Improve reproducibility of generated loaddefs file.
* lisp/emacs-lisp/autoload.el (autoload-generate-file-autoloads):
Make the return value the modtime of the input file (if no autoloads).
(update-directory-autoloads): In the "no autoloads" section,
use "most recent modtime" rather than "current time".
; http://lists.gnu.org/archive/html/emacs-devel/2015-06/msg00688.html
| -rw-r--r-- | lisp/emacs-lisp/autoload.el | 281 |
1 files changed, 144 insertions, 137 deletions
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index a6fefebf3f5..9d1abdddb2b 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el | |||
| @@ -522,116 +522,119 @@ If OUTFILE is non-nil and FILE specifies a `generated-autoload-file' | |||
| 522 | different from OUTFILE, then OUTBUF is ignored. | 522 | different from OUTFILE, then OUTBUF is ignored. |
| 523 | 523 | ||
| 524 | Return non-nil if and only if FILE adds no autoloads to OUTFILE | 524 | Return non-nil if and only if FILE adds no autoloads to OUTFILE |
| 525 | \(or OUTBUF if OUTFILE is nil)." | 525 | \(or OUTBUF if OUTFILE is nil). The actual return value is |
| 526 | (catch 'done | 526 | FILE's modification time." |
| 527 | (let (load-name | 527 | (let (load-name |
| 528 | (print-length nil) | 528 | (print-length nil) |
| 529 | (print-level nil) | 529 | (print-level nil) |
| 530 | (print-readably t) ; This does something in Lucid Emacs. | 530 | (print-readably t) ; This does something in Lucid Emacs. |
| 531 | (float-output-format nil) | 531 | (float-output-format nil) |
| 532 | (visited (get-file-buffer file)) | 532 | (visited (get-file-buffer file)) |
| 533 | (otherbuf nil) | 533 | (otherbuf nil) |
| 534 | (absfile (expand-file-name file)) | 534 | (absfile (expand-file-name file)) |
| 535 | ;; nil until we found a cookie. | 535 | ;; nil until we found a cookie. |
| 536 | output-start) | 536 | output-start) |
| 537 | (with-current-buffer (or visited | 537 | (when |
| 538 | ;; It is faster to avoid visiting the file. | 538 | (catch 'done |
| 539 | (autoload-find-file file)) | 539 | (with-current-buffer (or visited |
| 540 | ;; Obey the no-update-autoloads file local variable. | 540 | ;; It is faster to avoid visiting the file. |
| 541 | (unless no-update-autoloads | 541 | (autoload-find-file file)) |
| 542 | (or noninteractive (message "Generating autoloads for %s..." file)) | 542 | ;; Obey the no-update-autoloads file local variable. |
| 543 | (setq load-name | 543 | (unless no-update-autoloads |
| 544 | (if (stringp generated-autoload-load-name) | 544 | (or noninteractive (message "Generating autoloads for %s..." file)) |
| 545 | generated-autoload-load-name | 545 | (setq load-name |
| 546 | (autoload-file-load-name absfile))) | 546 | (if (stringp generated-autoload-load-name) |
| 547 | ;; FIXME? Comparing file-names for equality with just equal | 547 | generated-autoload-load-name |
| 548 | ;; is fragile, eg if one has an automounter prefix and one | 548 | (autoload-file-load-name absfile))) |
| 549 | ;; does not, but both refer to the same physical file. | 549 | ;; FIXME? Comparing file-names for equality with just equal |
| 550 | (when (and outfile | 550 | ;; is fragile, eg if one has an automounter prefix and one |
| 551 | (not | 551 | ;; does not, but both refer to the same physical file. |
| 552 | (if (memq system-type '(ms-dos windows-nt)) | 552 | (when (and outfile |
| 553 | (equal (downcase outfile) | 553 | (not |
| 554 | (downcase (autoload-generated-file))) | 554 | (if (memq system-type '(ms-dos windows-nt)) |
| 555 | (equal outfile (autoload-generated-file))))) | 555 | (equal (downcase outfile) |
| 556 | (setq otherbuf t)) | 556 | (downcase (autoload-generated-file))) |
| 557 | (save-excursion | 557 | (equal outfile (autoload-generated-file))))) |
| 558 | (save-restriction | 558 | (setq otherbuf t)) |
| 559 | (widen) | 559 | (save-excursion |
| 560 | (when autoload-builtin-package-versions | 560 | (save-restriction |
| 561 | (let ((version (lm-header "version")) | 561 | (widen) |
| 562 | package) | 562 | (when autoload-builtin-package-versions |
| 563 | (and version | 563 | (let ((version (lm-header "version")) |
| 564 | (setq version (ignore-errors (version-to-list version))) | 564 | package) |
| 565 | (setq package (or (lm-header "package") | 565 | (and version |
| 566 | (file-name-sans-extension | 566 | (setq version (ignore-errors (version-to-list version))) |
| 567 | (file-name-nondirectory file)))) | 567 | (setq package (or (lm-header "package") |
| 568 | (setq output-start (autoload--setup-output | 568 | (file-name-sans-extension |
| 569 | otherbuf outbuf absfile load-name)) | 569 | (file-name-nondirectory file)))) |
| 570 | (let ((standard-output (marker-buffer output-start)) | 570 | (setq output-start (autoload--setup-output |
| 571 | (print-quoted t)) | 571 | otherbuf outbuf absfile load-name)) |
| 572 | (princ `(push (purecopy | 572 | (let ((standard-output (marker-buffer output-start)) |
| 573 | ',(cons (intern package) version)) | 573 | (print-quoted t)) |
| 574 | package--builtin-versions)) | 574 | (princ `(push (purecopy |
| 575 | (princ "\n"))))) | 575 | ',(cons (intern package) version)) |
| 576 | 576 | package--builtin-versions)) | |
| 577 | (goto-char (point-min)) | 577 | (princ "\n"))))) |
| 578 | (while (not (eobp)) | 578 | |
| 579 | (skip-chars-forward " \t\n\f") | 579 | (goto-char (point-min)) |
| 580 | (cond | 580 | (while (not (eobp)) |
| 581 | ((looking-at (regexp-quote generate-autoload-cookie)) | 581 | (skip-chars-forward " \t\n\f") |
| 582 | ;; If not done yet, figure out where to insert this text. | 582 | (cond |
| 583 | (unless output-start | 583 | ((looking-at (regexp-quote generate-autoload-cookie)) |
| 584 | (setq output-start (autoload--setup-output | 584 | ;; If not done yet, figure out where to insert this text. |
| 585 | otherbuf outbuf absfile load-name))) | 585 | (unless output-start |
| 586 | (autoload--print-cookie-text output-start load-name file)) | 586 | (setq output-start (autoload--setup-output |
| 587 | ((looking-at ";") | 587 | otherbuf outbuf absfile load-name))) |
| 588 | ;; Don't read the comment. | 588 | (autoload--print-cookie-text output-start load-name file)) |
| 589 | (forward-line 1)) | 589 | ((looking-at ";") |
| 590 | (t | 590 | ;; Don't read the comment. |
| 591 | (forward-sexp 1) | 591 | (forward-line 1)) |
| 592 | (forward-line 1)))))) | 592 | (t |
| 593 | 593 | (forward-sexp 1) | |
| 594 | (when output-start | 594 | (forward-line 1)))))) |
| 595 | (let ((secondary-autoloads-file-buf | 595 | |
| 596 | (if otherbuf (current-buffer)))) | 596 | (when output-start |
| 597 | (with-current-buffer (marker-buffer output-start) | 597 | (let ((secondary-autoloads-file-buf |
| 598 | (save-excursion | 598 | (if otherbuf (current-buffer)))) |
| 599 | ;; Insert the section-header line which lists the file name | 599 | (with-current-buffer (marker-buffer output-start) |
| 600 | ;; and which functions are in it, etc. | 600 | (save-excursion |
| 601 | (goto-char output-start) | 601 | ;; Insert the section-header line which lists the file name |
| 602 | (let ((relfile (file-relative-name absfile))) | 602 | ;; and which functions are in it, etc. |
| 603 | (autoload-insert-section-header | 603 | (goto-char output-start) |
| 604 | (marker-buffer output-start) | 604 | (let ((relfile (file-relative-name absfile))) |
| 605 | () load-name relfile | 605 | (autoload-insert-section-header |
| 606 | (if secondary-autoloads-file-buf | 606 | (marker-buffer output-start) |
| 607 | ;; MD5 checksums are much better because they do not | 607 | () load-name relfile |
| 608 | ;; change unless the file changes (so they'll be | 608 | (if secondary-autoloads-file-buf |
| 609 | ;; equal on two different systems and will change | 609 | ;; MD5 checksums are much better because they do not |
| 610 | ;; less often than time-stamps, thus leading to fewer | 610 | ;; change unless the file changes (so they'll be |
| 611 | ;; unneeded changes causing spurious conflicts), but | 611 | ;; equal on two different systems and will change |
| 612 | ;; using time-stamps is a very useful optimization, | 612 | ;; less often than time-stamps, thus leading to fewer |
| 613 | ;; so we use time-stamps for the main autoloads file | 613 | ;; unneeded changes causing spurious conflicts), but |
| 614 | ;; (loaddefs.el) where we have special ways to | 614 | ;; using time-stamps is a very useful optimization, |
| 615 | ;; circumvent the "random change problem", and MD5 | 615 | ;; so we use time-stamps for the main autoloads file |
| 616 | ;; checksum in secondary autoload files where we do | 616 | ;; (loaddefs.el) where we have special ways to |
| 617 | ;; not need the time-stamp optimization because it is | 617 | ;; circumvent the "random change problem", and MD5 |
| 618 | ;; already provided by the primary autoloads file. | 618 | ;; checksum in secondary autoload files where we do |
| 619 | (md5 secondary-autoloads-file-buf | 619 | ;; not need the time-stamp optimization because it is |
| 620 | ;; We'd really want to just use | 620 | ;; already provided by the primary autoloads file. |
| 621 | ;; `emacs-internal' instead. | 621 | (md5 secondary-autoloads-file-buf |
| 622 | nil nil 'emacs-mule-unix) | 622 | ;; We'd really want to just use |
| 623 | (nth 5 (file-attributes relfile)))) | 623 | ;; `emacs-internal' instead. |
| 624 | (insert ";;; Generated autoloads from " relfile "\n"))) | 624 | nil nil 'emacs-mule-unix) |
| 625 | (insert generate-autoload-section-trailer)))) | 625 | (nth 5 (file-attributes relfile)))) |
| 626 | (or noninteractive | 626 | (insert ";;; Generated autoloads from " relfile "\n"))) |
| 627 | (message "Generating autoloads for %s...done" file))) | 627 | (insert generate-autoload-section-trailer)))) |
| 628 | (or visited | 628 | (or noninteractive |
| 629 | ;; We created this buffer, so we should kill it. | 629 | (message "Generating autoloads for %s...done" file))) |
| 630 | (kill-buffer (current-buffer)))) | 630 | (or visited |
| 631 | (or (not output-start) | 631 | ;; We created this buffer, so we should kill it. |
| 632 | ;; If the entries were added to some other buffer, then the file | 632 | (kill-buffer (current-buffer)))) |
| 633 | ;; doesn't add entries to OUTFILE. | 633 | (or (not output-start) |
| 634 | otherbuf)))) | 634 | ;; If the entries were added to some other buffer, then the file |
| 635 | ;; doesn't add entries to OUTFILE. | ||
| 636 | otherbuf)) | ||
| 637 | (nth 5 (file-attributes absfile))))) | ||
| 635 | 638 | ||
| 636 | (defun autoload-save-buffers () | 639 | (defun autoload-save-buffers () |
| 637 | (while autoload-modified-buffers | 640 | (while autoload-modified-buffers |
| @@ -757,7 +760,7 @@ write its autoloads into the specified file instead." | |||
| 757 | t files-re)) | 760 | t files-re)) |
| 758 | dirs))) | 761 | dirs))) |
| 759 | (done ()) | 762 | (done ()) |
| 760 | (this-time (current-time)) | 763 | (last-time) |
| 761 | ;; Files with no autoload cookies or whose autoloads go to other | 764 | ;; Files with no autoload cookies or whose autoloads go to other |
| 762 | ;; files because of file-local autoload-generated-file settings. | 765 | ;; files because of file-local autoload-generated-file settings. |
| 763 | (no-autoloads nil) | 766 | (no-autoloads nil) |
| @@ -782,14 +785,14 @@ write its autoloads into the specified file instead." | |||
| 782 | ;; There shouldn't be more than one such entry. | 785 | ;; There shouldn't be more than one such entry. |
| 783 | ;; Remove the obsolete section. | 786 | ;; Remove the obsolete section. |
| 784 | (autoload-remove-section (match-beginning 0)) | 787 | (autoload-remove-section (match-beginning 0)) |
| 785 | (let ((last-time (nth 4 form))) | 788 | (setq last-time (nth 4 form)) |
| 786 | (dolist (file file) | 789 | (dolist (file file) |
| 787 | (let ((file-time (nth 5 (file-attributes file)))) | 790 | (let ((file-time (nth 5 (file-attributes file)))) |
| 788 | (when (and file-time | 791 | (when (and file-time |
| 789 | (not (time-less-p last-time file-time))) | 792 | (not (time-less-p last-time file-time))) |
| 790 | ;; file unchanged | 793 | ;; file unchanged |
| 791 | (push file no-autoloads) | 794 | (push file no-autoloads) |
| 792 | (setq files (delete file files))))))) | 795 | (setq files (delete file files)))))) |
| 793 | ((not (stringp file))) | 796 | ((not (stringp file))) |
| 794 | ((or (not (file-exists-p file)) | 797 | ((or (not (file-exists-p file)) |
| 795 | ;; Remove duplicates as well, just in case. | 798 | ;; Remove duplicates as well, just in case. |
| @@ -811,24 +814,28 @@ write its autoloads into the specified file instead." | |||
| 811 | (push file done) | 814 | (push file done) |
| 812 | (setq files (delete file files))))) | 815 | (setq files (delete file files))))) |
| 813 | ;; Elements remaining in FILES have no existing autoload sections yet. | 816 | ;; Elements remaining in FILES have no existing autoload sections yet. |
| 814 | (dolist (file files) | 817 | (let ((no-autoloads-time (or last-time '(0 0 0 0))) file-time) |
| 815 | (cond | 818 | (dolist (file files) |
| 816 | ((member (expand-file-name file) autoload-excludes) nil) | 819 | (cond |
| 817 | ;; Passing nil as second argument forces | 820 | ((member (expand-file-name file) autoload-excludes) nil) |
| 818 | ;; autoload-generate-file-autoloads to look for the right | 821 | ;; Passing nil as second argument forces |
| 819 | ;; spot where to insert each autoloads section. | 822 | ;; autoload-generate-file-autoloads to look for the right |
| 820 | ((autoload-generate-file-autoloads file nil buffer-file-name) | 823 | ;; spot where to insert each autoloads section. |
| 821 | (push file no-autoloads)))) | 824 | ((setq file-time |
| 822 | 825 | (autoload-generate-file-autoloads file nil buffer-file-name)) | |
| 823 | (when no-autoloads | 826 | (push file no-autoloads) |
| 824 | ;; Sort them for better readability. | 827 | (if (time-less-p no-autoloads-time file-time) |
| 825 | (setq no-autoloads (sort no-autoloads 'string<)) | 828 | (setq no-autoloads-time file-time))))) |
| 826 | ;; Add the `no-autoloads' section. | 829 | |
| 827 | (goto-char (point-max)) | 830 | (when no-autoloads |
| 828 | (search-backward "\f" nil t) | 831 | ;; Sort them for better readability. |
| 829 | (autoload-insert-section-header | 832 | (setq no-autoloads (sort no-autoloads 'string<)) |
| 830 | (current-buffer) nil nil no-autoloads this-time) | 833 | ;; Add the `no-autoloads' section. |
| 831 | (insert generate-autoload-section-trailer)) | 834 | (goto-char (point-max)) |
| 835 | (search-backward "\f" nil t) | ||
| 836 | (autoload-insert-section-header | ||
| 837 | (current-buffer) nil nil no-autoloads no-autoloads-time) | ||
| 838 | (insert generate-autoload-section-trailer))) | ||
| 832 | 839 | ||
| 833 | (let ((version-control 'never)) | 840 | (let ((version-control 'never)) |
| 834 | (save-buffer)) | 841 | (save-buffer)) |