Function: package-vc--unpack-1

package-vc--unpack-1 is a byte-compiled function defined in package-vc.el.gz.

Signature

(package-vc--unpack-1 PKG-DESC PKG-DIR)

Documentation

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.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/package-vc.el.gz
(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 (file-name-concat pkg-dir lisp-dir))
         missing)

    ;; In case the package was installed directly from source, the
    ;; dependency list wasn't know beforehand, and they might have
    ;; to be installed explicitly.
    (let ((ignored-files
           (if (plist-get pkg-spec :ignored-files)
               (mapconcat
                (lambda (ignore)
                  (wildcard-to-regexp
                   (if (string-match-p "\\`/" ignore)
                       (concat pkg-dir ignore)
                     (concat "*/" ignore))))
                (plist-get pkg-spec :ignored-files)
                "\\|")
             regexp-unmatchable))
          (deps '()))
      (dolist (file (directory-files lisp-path t "\\.el\\'" t))
        (unless (string-match-p ignored-files file)
          (with-temp-buffer
            (insert-file-contents file)
            (when-let* ((require-lines (lm-header-multiline "package-requires")))
              (thread-last
                (mapconcat #'identity require-lines " ")
                package-read-from-string
                lm--prepare-package-dependencies
                (nconc deps)
                (setq deps))))))
      (dolist (dep deps)
        (cl-callf version-to-list (cadr dep)))
      (setf (package-desc-reqs pkg-desc) deps)
      (setf missing (package-vc-install-dependencies (delete-dups deps)))
      (setf missing (delq (assq (package-desc-name pkg-desc)
                                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
                            ,(file-name-concat lisp-dir auto-name)
                            (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 package file
      (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))

      ;; 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)))))

    ;; Update package-alist.
    (let ((new-desc (package-load-descriptor pkg-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)
        ;; 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)
        (when package-native-compile
          (package--native-compile-async new-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)))

    ;; Mark package as selected
    (let ((name (package-desc-name pkg-desc)))
      (unless (memq name package-selected-packages)
        (package--save-selected-packages
         (cons name package-selected-packages))))

    (package--quickstart-maybe-refresh)

    ;; Confirm that the installation was successful
    (let ((main-file (package-vc--main-file pkg-desc)))
      (message "VC package `%s' installed (Version %s, Revision %S).%s"
               (package-desc-name pkg-desc)
               (lm-with-file main-file
                 (package-strip-rcs-id
                  (or (lm-header "package-version")
                      (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 ", "))
                 "")))
    t))