1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-13 01:20:28 -08:00

Fix upgrading, rebuilding, and logging of VC packages

There are a few issues addressed in this patch:

1.  Compilation (including native compilation) should happen in
directory that contains package's Lisp code.

2.  After installing a package with
`package-vc-install-from-checkout' and subsequently upgrading it
with `package-vc-upgrade' the pkg-desc for the package becomes
corrupted.  After the upgrade the pkg-desc's dir (a.k.a
`pkg-dir') points to checkout directory.  This will cause the
subsequent `package-delete' to delete the checkout directory and
leaving incorrect forwarding autoloads file in
`package-user-directory'.

3. The detection of package's Lisp directory has been not
effective for packages installed with `package-vc-install' and
not existent for packages installed with
`package-install-from-checkout'.

4. Deduction of VC backend has been not working when called from
outside of deducing context.

5. Extract maintainers and store them in a package description
file when installing a package from a checkout.

* lisp/emacs-lisp/package-vc.el (package-vc--checkout-dir): New
function to determine the real checkout of a VC
package.
(package-vc--url-scheme): Define scheme for `:url' property.
(package-vc--generate-description-file): Extract maintainers
from main package file and store them in generated description
file.
(package-vc--save-selected-packages): Refactor new helper
function out of 'package-vc--unpack' to modify
'package-vc-selected-packages'.
(package-vc--checkout-dir): Use `pcase' to extract checkout
directory from `pkg-spec'.  Detect standard lisp sub directory
if called with non-nil `lisp-dir'.
(package-vc-commit, package-vc--main-file)
(package-vc--build-documentation, package-vc-prepare-patch): Use
'package-vc--checkout-dir'.
(package-vc--unpack-1): Remove superfluous `pkg-dir' argument.
Remove elc files before compilation.  Use a `package' with
`:dir' pointing to where package code is.  When `checkout-dir'
is different than `pkg-dir' then call `package--add-info-node'
and after calling `package-activate-1' reload source files in
case when `lisp-dir' is a sub directory.  Use the right
directories in the right places.
(package-vc-install-from-checkout): Remove superfluous
`package-vc-selected-packages' binding.  Remove `pkg-dir'
argument from `package-vc--unpack-1' calls.
(package-vc--unpack): Remove `lisp-dir' variable and convert to
`let*'.  Remove superfluous Lisp code sub directory detection -
logic moved to `package-vc--checkout-dir'.  Remove `pkg-dir'
argument from `package-vc--unpack-1' call. Use
'package-vc--save-selected-packages'.
(package-vc-upgrade, package-vc-rebuild): Remove `pkg-dir'
argument from `package-vc--unpack-1' calls. Use
'package-vc--checkout-dir'.
(package-vc-log-incoming): Set `vc-deduce-backend-nonvc-modes'
to t.  Use 'package-vc--checkout-dir'.
* lisp/emacs-lisp/package.el (package--add-info-node): New
function to install info node for package.  Extracted from
`package-activate-1'.
(package-activate-1): Call `package--add-info-node'.

Co-developed-by: Philip Kaludercic <philipk@posteo.net>

(Bug#79188)
This commit is contained in:
Przemysław Kryger 2025-09-26 14:00:54 +01:00 committed by Philip Kaludercic
parent 8a0217ebbc
commit 573acd97e5
No known key found for this signature in database
2 changed files with 225 additions and 119 deletions

View file

@ -31,8 +31,7 @@
;; aren't interested in activating a package, you can use
;; `package-vc-checkout' instead, which will prompt you for a target
;; directory. If you wish to reuse an existing checkout, the command
;; `package-vc-install-from-checkout' will create a symbolic link and
;; prepare the package.
;; `package-vc-install-from-checkout' will prepare the package.
;;
;; If you make local changes that you wish to share with an upstream
;; maintainer, the command `package-vc-prepare-patch' can prepare
@ -85,6 +84,12 @@ the `clone' VC function."
(defvar package-vc-selected-packages) ; pacify byte-compiler
(defconst package-vc--url-scheme
(if (memq system-type '(ms-dos windows-nt cygwin))
"file:///"
"file://")
"Scheme for `:url' property in package spec.")
;;;###autoload
(defun package-vc-install-selected-packages ()
"Ensure packages specified in `package-vc-selected-packages' are installed."
@ -173,6 +178,47 @@ name for PKG-DESC."
(mapcar #'cdr package-vc--archive-spec-alists))))
'() nil #'string=))
(defun package-vc--checkout-dir (pkg-desc &optional lisp-dir)
"Return the directory of the actual VC checkout for PKG-DESC.
For most packages this is the same as `package-desc-dir', unless the
package has been installed via `package-vc-install-from-checkout'. In
that case the package redirects to the actual VC checkout. If the
optional LISP-DIR argument is non-nil, then check if a related package
specification has a `:lisp-dir' field to indicate that Lisp files are
located in a sub directory of the checkout, or the checkout has a sub
directory named \"lisp\" or \"src\" that contains .el files and return
that instead."
(let* ((pkg-spec (package-vc--desc->spec pkg-desc))
(pkg-dir (pcase (plist-get pkg-spec :url)
((rx (literal package-vc--url-scheme)
(let checkout-dir (+ any)))
checkout-dir)
(_ (package-desc-dir pkg-desc)))))
(expand-file-name
(or (and lisp-dir
(or (plist-get pkg-spec :lisp-dir)
;; When nothing is specified about a `lisp-dir', then
;; should heuristically check if there is a
;; sub-directory with lisp files. These are
;; conventionally just called "lisp" or "src". If
;; this directory exists and contains non-zero number
;; of lisp files, we will use that instead of
;; `pkg-dir'.
(catch 'done
(dolist (name '("lisp" "src"))
(when-let* ((dir (expand-file-name name pkg-dir))
((file-directory-p dir))
((directory-files
dir nil "\\`[^.].+\\.el\\'" t 1)))
;; We won't use `dir', since dir is an absolute
;; path and we don't want `lisp-dir' to depend
;; on the current location of the package
;; installation, ie. to break if moved around
;; the file system or between installations.
(throw 'done name))))))
".")
pkg-dir)))
(defun package-vc--read-archive-data (archive)
"Update `package-vc--archive-spec-alists' for ARCHIVE.
This function is meant to be used as a hook for `package-read-archive-hook'."
@ -219,9 +265,7 @@ asynchronously."
;; FIXME: vc should be extended to allow querying the commit of a
;; directory (as is possible when dealing with git repositories).
;; This should be a fallback option.
(cl-loop with dir = (let ((pkg-spec (package-vc--desc->spec pkg-desc)))
(or (plist-get pkg-spec :lisp-dir)
(package-desc-dir pkg-desc)))
(cl-loop with dir = (package-vc--checkout-dir pkg-desc 'lisp-dir)
for file in (directory-files dir t "\\.el\\'" t)
when (vc-working-revision file) return it
finally return "unknown"))
@ -243,10 +287,7 @@ asynchronously."
(cl-assert (package-vc-p pkg-desc))
(let* ((pkg-spec (package-vc--desc->spec pkg-desc))
(name (symbol-name (package-desc-name pkg-desc)))
(directory (expand-file-name
(or (plist-get pkg-spec :lisp-dir) ".")
(or (package-desc-dir pkg-desc)
(expand-file-name name package-user-dir))))
(directory (package-vc--checkout-dir pkg-desc 'lisp-dir))
(file (expand-file-name
(or (plist-get pkg-spec :main-file)
(concat name ".el"))
@ -272,7 +313,9 @@ asynchronously."
(defun package-vc--generate-description-file (pkg-desc pkg-file)
"Generate a package description file for PKG-DESC and write it to PKG-FILE."
(let ((name (package-desc-name pkg-desc)))
(let ((name (package-desc-name pkg-desc))
(main-file (let ((file (package-vc--main-file pkg-desc)))
(and (file-exists-p file) file))))
(when (equal (package-desc-summary pkg-desc) package--default-summary)
;; We unset the package description if it is just the default
;; summary, so that the following heuristic can take effect.
@ -280,13 +323,12 @@ asynchronously."
;; Infer the package description if missing.
(unless (package-desc-summary pkg-desc)
(setf (package-desc-summary pkg-desc)
(let ((main-file (package-vc--main-file pkg-desc)))
(or (package-desc-summary pkg-desc)
(and-let* ((pkg (cadr (assq name package-archive-contents))))
(package-desc-summary pkg))
(and main-file (file-exists-p main-file)
(lm-summary main-file))
package--default-summary))))
(or (package-desc-summary pkg-desc)
(and-let* ((pkg (cadr (assq name package-archive-contents))))
(package-desc-summary pkg))
(and main-file
(lm-summary main-file))
package--default-summary)))
(let ((print-level nil)
(print-quoted t)
(print-length nil))
@ -316,6 +358,16 @@ asynchronously."
(let ((extras (copy-alist (package-desc-extras pkg-desc))))
(setf (alist-get :commit extras)
(package-vc-commit pkg-desc))
(when-let* (((null (alist-get :maintainer extras)))
(main-file)
(maintainers (lm-maintainers main-file)))
;; Like in `pakcage-buffer-info', for backward
;; compatibility, use a single cons-cell if there's
;; only one maintainer.
(setf (alist-get :maintainer extras)
(if (cdr maintainers)
maintainers
(car maintainers))))
extras)
)))
"\n")
@ -361,7 +413,8 @@ to `package-vc-install' directly."
"Process :make and :shell-command in PKG-SPEC.
PKG-DESC is the package descriptor for the package that is being
prepared."
(let ((target (plist-get pkg-spec :make))
(let ((default-directory (package-vc--checkout-dir pkg-desc))
(target (plist-get pkg-spec :make))
(cmd (plist-get pkg-spec :shell-command))
(buf (format " *package-vc make %s*" (package-desc-name pkg-desc)))
(makexe (or package-vc-make-program
@ -381,7 +434,7 @@ prepared."
FILE can be an Org file, indicated by its \".org\" extension,
otherwise it's assumed to be an Info file."
(let* ((pkg-name (package-desc-name pkg-desc))
(default-directory (package-desc-dir pkg-desc))
(default-directory (package-vc--checkout-dir pkg-desc))
(docs-directory (file-name-directory (expand-file-name file)))
(output (expand-file-name (format "%s.info" (file-name-base file))))
(log-buffer (get-buffer-create (format " *package-vc doc: %s*" pkg-name)))
@ -467,15 +520,25 @@ this function successfully installs all given dependencies)."
(mapc #'package-install-from-archive to-install)
missing))
(defun package-vc--unpack-1 (pkg-desc pkg-dir)
"Prepare PKG-DESC that is already checked-out in PKG-DIR.
This includes downloading missing dependencies, generating
autoloads, generating a package description file (used to
identify a package as a VC package later on), building
documentation and marking the package as installed."
(let* ((pkg-spec (package-vc--desc->spec pkg-desc))
(lisp-dir (plist-get pkg-spec :lisp-dir))
(lisp-path (expand-file-name (or lisp-dir ".") pkg-dir))
(defun package-vc--unpack-1 (pkg-desc)
"Prepare PKG-DESC that is already checked-out.
When there's a relevant pkg-spec it is used for checkout directory.
Otherwise `dir' slot of PKG-SPEC is used. This includes downloading
missing dependencies, generating autoloads, generating a package
description file (used to identify a package as a VC package later on),
building documentation and marking the package as installed."
(let* (;; Main package directory, under `package-user-dir'. This is
;; the same `checkout-dir' when package has been installed with
;; `package-vc-install'.
(pkg-dir (package-desc-dir pkg-desc))
(pkg-spec (package-vc--desc->spec pkg-desc))
;; Directory where the package repository has been checked out.
;; This is the `dir' argument of
;; `package-vc-install-from-checkout'.
(checkout-dir (package-vc--checkout-dir pkg-desc))
;; Directory where package's Lisp code resides. It may be
;; equal to `checkout-dir' or be a subdirectory of it.
(lisp-dir (package-vc--checkout-dir pkg-desc 'lisp-dir))
missing)
;; In case the package was installed directly from source, the
@ -487,13 +550,13 @@ documentation and marking the package as installed."
(lambda (ignore)
(wildcard-to-regexp
(if (string-match-p "\\`/" ignore)
(concat pkg-dir ignore)
(concat checkout-dir ignore)
(concat "*/" ignore))))
(plist-get pkg-spec :ignored-files)
"\\|")
regexp-unmatchable))
(deps '()))
(dolist (file (directory-files lisp-path t "\\.el\\'" t))
(dolist (file (directory-files lisp-dir t "\\.el\\'" t))
(unless (string-match-p ignored-files file)
(with-temp-buffer
(insert-file-contents file)
@ -512,59 +575,111 @@ documentation and marking the package as installed."
missing)
missing)))
(let ((default-directory (file-name-as-directory pkg-dir))
(pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir)))
;; Generate autoloads
(let* ((name (package-desc-name pkg-desc))
(auto-name (format "%s-autoloads.el" name)))
(package-generate-autoloads name lisp-path)
(when lisp-dir
(write-region
(with-temp-buffer
(insert ";; Autoload indirection for package-vc\n\n")
(prin1 `(load (expand-file-name
,(expand-file-name auto-name lisp-dir)
(or (and load-file-name
(file-name-directory load-file-name))
(car load-path))))
(current-buffer))
(buffer-string))
nil (expand-file-name auto-name pkg-dir))))
;; Generate autoloads
(let* ((name (package-desc-name pkg-desc))
(auto-name (format "%s-autoloads.el" name)))
(package-generate-autoloads name lisp-dir)
;; There are two cases when we wish to "indirect" the loading of
;; autoload files:
;;
;; 1. a package specification has a `:lisp-dir' entry listing
;; indicting that the actual Lisp code is located in a
;; subdirectory of the checkout,
;;
;; 2. the package has been installed using
;; `package-vc-install-from-checkout' and we want to load the
;; other directory instead -- which is outside of the checkout.
;; We can therefore take file inequality as a sign that we have to
;; set up an indirection.
(unless (file-equal-p lisp-dir pkg-dir)
(write-region
(concat
";; Autoload indirection for package-vc\n\n"
(prin1-to-string
;; The indirection is just a single load statement to the
;; actual file (we don't want to use symbolic links due to
;; portability reasons). Detecting which of the two cases
;; mentioned above we are setting up can be done by checking
;; if the directory with the lisp code is a subdirectory of
;; the package directory.
`(load ,(if (file-in-directory-p lisp-dir pkg-dir)
`(expand-file-name
,(file-relative-name
(expand-file-name auto-name lisp-dir)
pkg-dir)
(or (and load-file-name
(file-name-directory load-file-name))
(car load-path)))
(expand-file-name auto-name lisp-dir)))))
nil (expand-file-name auto-name pkg-dir))))
;; Generate package file
(package-vc--generate-description-file pkg-desc pkg-file)
;; Generate package file
(let ((pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir)))
(package-vc--generate-description-file pkg-desc pkg-file))
;; Process :make and :shell-command arguments before building documentation
(when (or (eq package-vc-allow-build-commands t)
(memq (package-desc-name pkg-desc)
package-vc-allow-build-commands))
(package-vc--make pkg-spec pkg-desc))
;; Process :make and :shell-command arguments before building documentation
(when (or (eq package-vc-allow-build-commands t)
(memq (package-desc-name pkg-desc)
package-vc-allow-build-commands))
(package-vc--make pkg-spec pkg-desc))
;; Detect a manual
(when (executable-find "install-info")
(dolist (doc-file (ensure-list (plist-get pkg-spec :doc)))
(package-vc--build-documentation pkg-desc doc-file))))
;; Detect a manual
(when (executable-find "install-info")
(dolist (doc-file (ensure-list (plist-get pkg-spec :doc)))
(package-vc--build-documentation pkg-desc doc-file)))
;; Remove any previous instance of PKG-DESC from `package-alist'
(let ((pkgs (assq (package-desc-name pkg-desc) package-alist)))
(when pkgs
(setf (cdr pkgs) (seq-remove #'package-vc-p (cdr pkgs)))))
;; Remove all compiled files to allow for macros to be used from
;; source files, regardless of order of source files compilation and
;; load ordering. As a side effect there are no compiled files for
;; source files that no longer exist.
(dolist (elc-file (directory-files-recursively
lisp-dir
(rx string-start
(not ".") (zero-or-more any) ".elc"
string-end)
nil
(lambda (dir)
(and (file-accessible-directory-p dir)
(not (string-prefix-p "." dir))))))
(delete-file elc-file))
;; Update package-alist.
(let ((new-desc (package-load-descriptor pkg-dir)))
(let* ((new-desc (package-load-descriptor pkg-dir))
(compile-desc (package-desc-create :name (package-desc-name new-desc)
:dir lisp-dir)))
;; Activation has to be done before compilation, so that if we're
;; upgrading and macros have changed we load the new definitions
;; before compiling.
(when (package-activate-1 new-desc :reload :deps)
;; `package-activate-1' will reload all necessary package files
;; as long as their stems are relative to of `pkg-dir'. If
;; that's not the case (for example for packages with different
;; `checkout-dir' or with source files in a sub directory of
;; `pkg-dir'), we want to reload package files from the
;; `lisp-dir' before compilation.
(unless (file-equal-p lisp-dir pkg-dir)
(package--reload-previously-loaded compile-desc))
;; `package-activate-1' will add info node as long as dir file
;; exists in `pkg-dir'. We need to manually add it when
;; `checkout-dir' is in different location.
(unless (file-equal-p checkout-dir pkg-dir)
(package--add-info-node checkout-dir))
;; FIXME: Compilation should be done as a separate, optional, step.
;; E.g. for multi-package installs, we should first install all packages
;; and then compile them.
(package--compile new-desc)
(package--compile compile-desc)
(when package-native-compile
(package--native-compile-async new-desc))
(package--native-compile-async compile-desc))
;; After compilation, load again any files loaded by
;; `activate-1', so that we use the byte-compiled definitions.
(package--reload-previously-loaded new-desc)))
;; `package-activate-1', so that we use the byte-compiled
;; definitions. This time we'll use `compile-desc' straight
;; away.
(package--reload-previously-loaded compile-desc)))
;; Mark package as selected
(let ((name (package-desc-name pkg-desc)))
@ -584,12 +699,12 @@ documentation and marking the package as installed."
(lm-header "version"))))
(vc-working-revision main-file)
(if missing
(format
" Failed to install the following dependencies: %s"
(mapconcat
(lambda (p)
(format "%s (%s)" (car p) (cadr p)))
missing ", "))
(format
" Failed to install the following dependencies: %s"
(mapconcat
(lambda (p)
(format "%s (%s)" (car p) (cadr p)))
missing ", "))
"")))
t))
@ -634,6 +749,14 @@ This list is used by `package-vc--unpack' to better check if the
user is fetching code from a repository that does not contain any
Emacs Lisp files.")
(defun package-vc--save-selected-packages (name pkg-spec)
"Save the package specification PKG-SPEC for a package NAME."
(customize-save-variable
'package-vc-selected-packages
(cons (cons name pkg-spec)
(seq-remove (lambda (spec) (string= name (car spec)))
package-vc-selected-packages))))
(defun package-vc--unpack (pkg-desc pkg-spec &optional rev)
"Install the package described by PKG-DESC.
PKG-SPEC is a package specification, a property list describing
@ -644,10 +767,9 @@ checkout. This overrides the `:branch' attribute in PKG-SPEC."
(let ((copy (copy-package-desc pkg-desc)))
(setf (package-desc-kind copy) 'vc
pkg-desc copy)))
(pcase-let* (((map :lisp-dir) pkg-spec)
(name (package-desc-name pkg-desc))
(dirname (package-desc-full-name pkg-desc))
(pkg-dir (file-name-as-directory (expand-file-name dirname package-user-dir))))
(let* ((name (package-desc-name pkg-desc))
(dirname (package-desc-full-name pkg-desc))
(pkg-dir (file-name-as-directory (expand-file-name dirname package-user-dir))))
(when (string-empty-p name)
(user-error "Empty package name"))
(setf (package-desc-dir pkg-desc) pkg-dir)
@ -668,33 +790,11 @@ abort installation?" name))
(delete-directory pkg-dir t)
(user-error "Installation aborted")))
;; When nothing is specified about a `lisp-dir', then should
;; heuristically check if there is a sub-directory with lisp
;; files. These are conventionally just called "lisp" or "src".
;; If this directory exists and contains non-zero number of lisp
;; files, we will use that instead of `pkg-dir'.
(catch 'done
(dolist (name '("lisp" "src"))
(when-let* (((null lisp-dir))
(dir (expand-file-name name pkg-dir))
((file-directory-p dir))
((directory-files dir nil "\\`[^.].+\\.el\\'" t 1)))
;; We won't use `dir', since dir is an absolute path and we
;; don't want `lisp-dir' to depend on the current location of
;; the package installation, ie. to break if moved around the
;; file system or between installations.
(throw 'done (setq lisp-dir name)))))
;; Ensure we have a copy of the package specification
(unless (seq-some (lambda (alist) (equal (alist-get name (cdr alist)) pkg-spec))
package-vc--archive-spec-alists)
(customize-save-variable
'package-vc-selected-packages
(cons (cons name pkg-spec)
(seq-remove (lambda (spec) (string= name (car spec)))
package-vc-selected-packages))))
(when (null (package-vc--desc->spec pkg-desc name))
(package-vc--save-selected-packages name pkg-spec))
(package-vc--unpack-1 pkg-desc pkg-dir)))
(package-vc--unpack-1 pkg-desc)))
(defun package-vc--read-package-name (prompt &optional allow-url installed)
"Query the user for a VC package and return a name with PROMPT.
@ -762,7 +862,7 @@ with the remote repository state."
;;
;; If there is a better way to do this, it should be done.
(cl-assert (package-vc-p pkg-desc))
(letrec ((pkg-dir (package-desc-dir pkg-desc))
(letrec ((checkout-dir (package-vc--checkout-dir pkg-desc))
(vc-flags)
(vc-filter-command-function
(lambda (command file-or-list flags)
@ -770,18 +870,19 @@ with the remote repository state."
(list command file-or-list flags)))
(post-upgrade
(lambda (_command _file-or-list flags)
(when (and (file-equal-p pkg-dir default-directory)
(when (and (file-equal-p checkout-dir default-directory)
(eq flags vc-flags))
(unwind-protect
(with-demoted-errors "Failed to activate: %S"
(package-vc--unpack-1 pkg-desc pkg-dir))
(package-vc--unpack-1 pkg-desc))
(remove-hook 'vc-post-command-functions post-upgrade))))))
(add-hook 'vc-post-command-functions post-upgrade)
(with-demoted-errors "Failed to fetch: %S"
(require 'vc-dir)
(with-current-buffer (vc-dir-prepare-status-buffer
(format " *package-vc-dir: %s*" pkg-dir)
pkg-dir (vc-responsible-backend pkg-dir))
(format " *package-vc-dir: %s*" checkout-dir)
checkout-dir
(vc-responsible-backend checkout-dir))
(vc-pull)))))
(defun package-vc--archives-initialize ()
@ -946,21 +1047,22 @@ interactively), DIR must be an absolute file name."
(package-vc--archives-initialize)
(let* ((dir (if interactive dir (expand-file-name dir))) ;avoid double expansion
(name (or name (file-name-base (directory-file-name dir))))
(pkg-dir (file-name-concat package-user-dir name))
(package-vc-selected-packages
(cons (list name :lisp-dir dir)
package-vc-selected-packages)))
(pkg-dir (file-name-concat package-user-dir name)))
(when (file-exists-p pkg-dir)
(if (yes-or-no-p (format "Overwrite previous checkout for package `%s'?" name))
(package--delete-directory pkg-dir)
(error "There already exists a checkout for %s" name)))
(make-directory pkg-dir t)
;; We store a custom package specification so that it is available
;; for `package-vc--unpack-1' as well as `package-vc--checkout-dir'
;; can later retrieve the actual checkout.
(package-vc--save-selected-packages
name (list :url (concat package-vc--url-scheme dir)))
(package-vc--unpack-1
(package-desc-create
:name (intern name)
:dir pkg-dir
:kind 'vc)
(file-name-as-directory pkg-dir))))
:kind 'vc))))
;;;###autoload
(defun package-vc-rebuild (pkg-desc)
@ -972,7 +1074,7 @@ command does not fetch new revisions from a remote server. That
is the responsibility of `package-vc-upgrade'. Interactively,
prompt for the name of the package to rebuild."
(interactive (list (package-vc--read-package-desc "Rebuild package: " t)))
(package-vc--unpack-1 pkg-desc (package-desc-dir pkg-desc)))
(package-vc--unpack-1 pkg-desc))
;;;###autoload
(defun package-vc-prepare-patch (pkg-desc subject revisions)
@ -992,7 +1094,7 @@ See also `vc-prepare-patch'."
(and (not vc-prepare-patches-separately)
(read-string "Subject: " "[PATCH] " nil nil t))
(vc-prepare-patch-prompt-revisions)))
(let ((default-directory (package-desc-dir pkg-desc)))
(let ((default-directory (package-vc--checkout-dir pkg-desc)))
(vc-prepare-patch (package-maintainers pkg-desc t)
subject revisions)))
@ -1000,7 +1102,8 @@ See also `vc-prepare-patch'."
"Call `vc-log-incoming' for the package PKG-DESC."
(interactive
(list (package-vc--read-package-desc "Incoming log for package: " t)))
(let ((default-directory (package-desc-dir pkg-desc)))
(let ((default-directory (package-vc--checkout-dir pkg-desc))
(vc-deduce-backend-nonvc-modes t))
(call-interactively #'vc-log-incoming)))
(provide 'package-vc)

View file

@ -905,6 +905,14 @@ sexps)."
(mapc (lambda (c) (load (car c) nil t))
(sort result (lambda (x y) (< (cdr x) (cdr y))))))))
(defun package--add-info-node (pkg-dir)
"Add info node located in PKG-DIR."
(when (file-exists-p (expand-file-name "dir" pkg-dir))
;; FIXME: not the friendliest, but simple.
(require 'info)
(info-initialize)
(add-to-list 'Info-directory-list pkg-dir)))
(defun package-activate-1 (pkg-desc &optional reload deps)
"Activate package given by PKG-DESC, even if it was already active.
If DEPS is non-nil, also activate its dependencies (unless they
@ -936,12 +944,7 @@ correspond to previously loaded files."
The following files have already been loaded: %S")))
(with-demoted-errors "Error loading autoloads: %s"
(load (package--autoloads-file-name pkg-desc) nil t)))
;; Add info node.
(when (file-exists-p (expand-file-name "dir" pkg-dir))
;; FIXME: not the friendliest, but simple.
(require 'info)
(info-initialize)
(add-to-list 'Info-directory-list pkg-dir))
(package--add-info-node pkg-dir)
(push name package-activated-list)
;; Don't return nil.
t)))