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
This commit is contained in:
parent
0dfea4562e
commit
5200c2baef
1 changed files with 141 additions and 134 deletions
|
@ -522,116 +522,119 @@ If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
|
||||||
different from OUTFILE, then OUTBUF is ignored.
|
different from OUTFILE, then OUTBUF is ignored.
|
||||||
|
|
||||||
Return non-nil if and only if FILE adds no autoloads to OUTFILE
|
Return non-nil if and only if FILE adds no autoloads to OUTFILE
|
||||||
\(or OUTBUF if OUTFILE is nil)."
|
\(or OUTBUF if OUTFILE is nil). The actual return value is
|
||||||
(catch 'done
|
FILE's modification time."
|
||||||
(let (load-name
|
(let (load-name
|
||||||
(print-length nil)
|
(print-length nil)
|
||||||
(print-level nil)
|
(print-level nil)
|
||||||
(print-readably t) ; This does something in Lucid Emacs.
|
(print-readably t) ; This does something in Lucid Emacs.
|
||||||
(float-output-format nil)
|
(float-output-format nil)
|
||||||
(visited (get-file-buffer file))
|
(visited (get-file-buffer file))
|
||||||
(otherbuf nil)
|
(otherbuf nil)
|
||||||
(absfile (expand-file-name file))
|
(absfile (expand-file-name file))
|
||||||
;; nil until we found a cookie.
|
;; nil until we found a cookie.
|
||||||
output-start)
|
output-start)
|
||||||
(with-current-buffer (or visited
|
(when
|
||||||
;; It is faster to avoid visiting the file.
|
(catch 'done
|
||||||
(autoload-find-file file))
|
(with-current-buffer (or visited
|
||||||
;; Obey the no-update-autoloads file local variable.
|
;; It is faster to avoid visiting the file.
|
||||||
(unless no-update-autoloads
|
(autoload-find-file file))
|
||||||
(or noninteractive (message "Generating autoloads for %s..." file))
|
;; Obey the no-update-autoloads file local variable.
|
||||||
(setq load-name
|
(unless no-update-autoloads
|
||||||
(if (stringp generated-autoload-load-name)
|
(or noninteractive (message "Generating autoloads for %s..." file))
|
||||||
generated-autoload-load-name
|
(setq load-name
|
||||||
(autoload-file-load-name absfile)))
|
(if (stringp generated-autoload-load-name)
|
||||||
;; FIXME? Comparing file-names for equality with just equal
|
generated-autoload-load-name
|
||||||
;; is fragile, eg if one has an automounter prefix and one
|
(autoload-file-load-name absfile)))
|
||||||
;; does not, but both refer to the same physical file.
|
;; FIXME? Comparing file-names for equality with just equal
|
||||||
(when (and outfile
|
;; is fragile, eg if one has an automounter prefix and one
|
||||||
(not
|
;; does not, but both refer to the same physical file.
|
||||||
(if (memq system-type '(ms-dos windows-nt))
|
(when (and outfile
|
||||||
(equal (downcase outfile)
|
(not
|
||||||
(downcase (autoload-generated-file)))
|
(if (memq system-type '(ms-dos windows-nt))
|
||||||
(equal outfile (autoload-generated-file)))))
|
(equal (downcase outfile)
|
||||||
(setq otherbuf t))
|
(downcase (autoload-generated-file)))
|
||||||
(save-excursion
|
(equal outfile (autoload-generated-file)))))
|
||||||
(save-restriction
|
(setq otherbuf t))
|
||||||
(widen)
|
(save-excursion
|
||||||
(when autoload-builtin-package-versions
|
(save-restriction
|
||||||
(let ((version (lm-header "version"))
|
(widen)
|
||||||
package)
|
(when autoload-builtin-package-versions
|
||||||
(and version
|
(let ((version (lm-header "version"))
|
||||||
(setq version (ignore-errors (version-to-list version)))
|
package)
|
||||||
(setq package (or (lm-header "package")
|
(and version
|
||||||
(file-name-sans-extension
|
(setq version (ignore-errors (version-to-list version)))
|
||||||
(file-name-nondirectory file))))
|
(setq package (or (lm-header "package")
|
||||||
(setq output-start (autoload--setup-output
|
(file-name-sans-extension
|
||||||
otherbuf outbuf absfile load-name))
|
(file-name-nondirectory file))))
|
||||||
(let ((standard-output (marker-buffer output-start))
|
(setq output-start (autoload--setup-output
|
||||||
(print-quoted t))
|
otherbuf outbuf absfile load-name))
|
||||||
(princ `(push (purecopy
|
(let ((standard-output (marker-buffer output-start))
|
||||||
',(cons (intern package) version))
|
(print-quoted t))
|
||||||
package--builtin-versions))
|
(princ `(push (purecopy
|
||||||
(princ "\n")))))
|
',(cons (intern package) version))
|
||||||
|
package--builtin-versions))
|
||||||
|
(princ "\n")))))
|
||||||
|
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(while (not (eobp))
|
(while (not (eobp))
|
||||||
(skip-chars-forward " \t\n\f")
|
(skip-chars-forward " \t\n\f")
|
||||||
(cond
|
(cond
|
||||||
((looking-at (regexp-quote generate-autoload-cookie))
|
((looking-at (regexp-quote generate-autoload-cookie))
|
||||||
;; If not done yet, figure out where to insert this text.
|
;; If not done yet, figure out where to insert this text.
|
||||||
(unless output-start
|
(unless output-start
|
||||||
(setq output-start (autoload--setup-output
|
(setq output-start (autoload--setup-output
|
||||||
otherbuf outbuf absfile load-name)))
|
otherbuf outbuf absfile load-name)))
|
||||||
(autoload--print-cookie-text output-start load-name file))
|
(autoload--print-cookie-text output-start load-name file))
|
||||||
((looking-at ";")
|
((looking-at ";")
|
||||||
;; Don't read the comment.
|
;; Don't read the comment.
|
||||||
(forward-line 1))
|
(forward-line 1))
|
||||||
(t
|
(t
|
||||||
(forward-sexp 1)
|
(forward-sexp 1)
|
||||||
(forward-line 1))))))
|
(forward-line 1))))))
|
||||||
|
|
||||||
(when output-start
|
(when output-start
|
||||||
(let ((secondary-autoloads-file-buf
|
(let ((secondary-autoloads-file-buf
|
||||||
(if otherbuf (current-buffer))))
|
(if otherbuf (current-buffer))))
|
||||||
(with-current-buffer (marker-buffer output-start)
|
(with-current-buffer (marker-buffer output-start)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
;; Insert the section-header line which lists the file name
|
;; Insert the section-header line which lists the file name
|
||||||
;; and which functions are in it, etc.
|
;; and which functions are in it, etc.
|
||||||
(goto-char output-start)
|
(goto-char output-start)
|
||||||
(let ((relfile (file-relative-name absfile)))
|
(let ((relfile (file-relative-name absfile)))
|
||||||
(autoload-insert-section-header
|
(autoload-insert-section-header
|
||||||
(marker-buffer output-start)
|
(marker-buffer output-start)
|
||||||
() load-name relfile
|
() load-name relfile
|
||||||
(if secondary-autoloads-file-buf
|
(if secondary-autoloads-file-buf
|
||||||
;; MD5 checksums are much better because they do not
|
;; MD5 checksums are much better because they do not
|
||||||
;; change unless the file changes (so they'll be
|
;; change unless the file changes (so they'll be
|
||||||
;; equal on two different systems and will change
|
;; equal on two different systems and will change
|
||||||
;; less often than time-stamps, thus leading to fewer
|
;; less often than time-stamps, thus leading to fewer
|
||||||
;; unneeded changes causing spurious conflicts), but
|
;; unneeded changes causing spurious conflicts), but
|
||||||
;; using time-stamps is a very useful optimization,
|
;; using time-stamps is a very useful optimization,
|
||||||
;; so we use time-stamps for the main autoloads file
|
;; so we use time-stamps for the main autoloads file
|
||||||
;; (loaddefs.el) where we have special ways to
|
;; (loaddefs.el) where we have special ways to
|
||||||
;; circumvent the "random change problem", and MD5
|
;; circumvent the "random change problem", and MD5
|
||||||
;; checksum in secondary autoload files where we do
|
;; checksum in secondary autoload files where we do
|
||||||
;; not need the time-stamp optimization because it is
|
;; not need the time-stamp optimization because it is
|
||||||
;; already provided by the primary autoloads file.
|
;; already provided by the primary autoloads file.
|
||||||
(md5 secondary-autoloads-file-buf
|
(md5 secondary-autoloads-file-buf
|
||||||
;; We'd really want to just use
|
;; We'd really want to just use
|
||||||
;; `emacs-internal' instead.
|
;; `emacs-internal' instead.
|
||||||
nil nil 'emacs-mule-unix)
|
nil nil 'emacs-mule-unix)
|
||||||
(nth 5 (file-attributes relfile))))
|
(nth 5 (file-attributes relfile))))
|
||||||
(insert ";;; Generated autoloads from " relfile "\n")))
|
(insert ";;; Generated autoloads from " relfile "\n")))
|
||||||
(insert generate-autoload-section-trailer))))
|
(insert generate-autoload-section-trailer))))
|
||||||
(or noninteractive
|
(or noninteractive
|
||||||
(message "Generating autoloads for %s...done" file)))
|
(message "Generating autoloads for %s...done" file)))
|
||||||
(or visited
|
(or visited
|
||||||
;; We created this buffer, so we should kill it.
|
;; We created this buffer, so we should kill it.
|
||||||
(kill-buffer (current-buffer))))
|
(kill-buffer (current-buffer))))
|
||||||
(or (not output-start)
|
(or (not output-start)
|
||||||
;; If the entries were added to some other buffer, then the file
|
;; If the entries were added to some other buffer, then the file
|
||||||
;; doesn't add entries to OUTFILE.
|
;; doesn't add entries to OUTFILE.
|
||||||
otherbuf))))
|
otherbuf))
|
||||||
|
(nth 5 (file-attributes absfile)))))
|
||||||
|
|
||||||
(defun autoload-save-buffers ()
|
(defun autoload-save-buffers ()
|
||||||
(while autoload-modified-buffers
|
(while autoload-modified-buffers
|
||||||
|
@ -757,7 +760,7 @@ write its autoloads into the specified file instead."
|
||||||
t files-re))
|
t files-re))
|
||||||
dirs)))
|
dirs)))
|
||||||
(done ())
|
(done ())
|
||||||
(this-time (current-time))
|
(last-time)
|
||||||
;; Files with no autoload cookies or whose autoloads go to other
|
;; Files with no autoload cookies or whose autoloads go to other
|
||||||
;; files because of file-local autoload-generated-file settings.
|
;; files because of file-local autoload-generated-file settings.
|
||||||
(no-autoloads nil)
|
(no-autoloads nil)
|
||||||
|
@ -782,14 +785,14 @@ write its autoloads into the specified file instead."
|
||||||
;; There shouldn't be more than one such entry.
|
;; There shouldn't be more than one such entry.
|
||||||
;; Remove the obsolete section.
|
;; Remove the obsolete section.
|
||||||
(autoload-remove-section (match-beginning 0))
|
(autoload-remove-section (match-beginning 0))
|
||||||
(let ((last-time (nth 4 form)))
|
(setq last-time (nth 4 form))
|
||||||
(dolist (file file)
|
(dolist (file file)
|
||||||
(let ((file-time (nth 5 (file-attributes file))))
|
(let ((file-time (nth 5 (file-attributes file))))
|
||||||
(when (and file-time
|
(when (and file-time
|
||||||
(not (time-less-p last-time file-time)))
|
(not (time-less-p last-time file-time)))
|
||||||
;; file unchanged
|
;; file unchanged
|
||||||
(push file no-autoloads)
|
(push file no-autoloads)
|
||||||
(setq files (delete file files)))))))
|
(setq files (delete file files))))))
|
||||||
((not (stringp file)))
|
((not (stringp file)))
|
||||||
((or (not (file-exists-p file))
|
((or (not (file-exists-p file))
|
||||||
;; Remove duplicates as well, just in case.
|
;; Remove duplicates as well, just in case.
|
||||||
|
@ -811,24 +814,28 @@ write its autoloads into the specified file instead."
|
||||||
(push file done)
|
(push file done)
|
||||||
(setq files (delete file files)))))
|
(setq files (delete file files)))))
|
||||||
;; Elements remaining in FILES have no existing autoload sections yet.
|
;; Elements remaining in FILES have no existing autoload sections yet.
|
||||||
(dolist (file files)
|
(let ((no-autoloads-time (or last-time '(0 0 0 0))) file-time)
|
||||||
(cond
|
(dolist (file files)
|
||||||
((member (expand-file-name file) autoload-excludes) nil)
|
(cond
|
||||||
;; Passing nil as second argument forces
|
((member (expand-file-name file) autoload-excludes) nil)
|
||||||
;; autoload-generate-file-autoloads to look for the right
|
;; Passing nil as second argument forces
|
||||||
;; spot where to insert each autoloads section.
|
;; autoload-generate-file-autoloads to look for the right
|
||||||
((autoload-generate-file-autoloads file nil buffer-file-name)
|
;; spot where to insert each autoloads section.
|
||||||
(push file no-autoloads))))
|
((setq file-time
|
||||||
|
(autoload-generate-file-autoloads file nil buffer-file-name))
|
||||||
|
(push file no-autoloads)
|
||||||
|
(if (time-less-p no-autoloads-time file-time)
|
||||||
|
(setq no-autoloads-time file-time)))))
|
||||||
|
|
||||||
(when no-autoloads
|
(when no-autoloads
|
||||||
;; Sort them for better readability.
|
;; Sort them for better readability.
|
||||||
(setq no-autoloads (sort no-autoloads 'string<))
|
(setq no-autoloads (sort no-autoloads 'string<))
|
||||||
;; Add the `no-autoloads' section.
|
;; Add the `no-autoloads' section.
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(search-backward "\f" nil t)
|
(search-backward "\f" nil t)
|
||||||
(autoload-insert-section-header
|
(autoload-insert-section-header
|
||||||
(current-buffer) nil nil no-autoloads this-time)
|
(current-buffer) nil nil no-autoloads no-autoloads-time)
|
||||||
(insert generate-autoload-section-trailer))
|
(insert generate-autoload-section-trailer)))
|
||||||
|
|
||||||
(let ((version-control 'never))
|
(let ((version-control 'never))
|
||||||
(save-buffer))
|
(save-buffer))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue