straight.el icon indicating copy to clipboard operation
straight.el copied to clipboard

Signal warning if ~/.emacs.d/elpa exists

Open raxod502 opened this issue 2 years ago • 2 comments

Due to behavior of Emacs that we can't change, if the user has installed package(s) via package.el in the past, then they will be loaded at init, even if the user intends to use straight.el instead to manage packages. This behavior can be disabled with (setq package-enable-at-startup nil) in early-init.el, but the cause of the issue is often unclear.

Given that loading packages from both package.el and straight.el in parallel is not a common use case to my knowledge, I suggest that straight.el should signal a warning by default if ~/.emacs.d/elpa exists, notifying the user that they may wish to delete or move that directory to avoid unexpected (versions of) packages being loaded. I suggest also that there be some configuration option which can be used to suppress the warning if the user for some reason does desire this dual loading behavior.

See, e.g.: https://github.com/radian-software/straight.el/issues/1019#issuecomment-1368578607

raxod502 avatar Jan 06 '23 16:01 raxod502

I wonder if the warning should be conditioned on the presence of the package feature instead. This would catch more cases and should be simpler to test. e.g.

(when (and straight-warn-if-other-package-manger (featurep 'package))
  (warn "Loading package.el alongside straight.el may cause conflicts"))

Or, an alternative, extensible approach:

(defcustom straight-incompatibility-warnings
  `((,(apply-partially #'featurep 'package) .
     "Loading package.el alongside straight.el may cause conflicts"))

  "Alist of form: (PREDICATE . WARNING).
Each element is tested for when loading straight.el.
If PREDICATE returns non-nil, WARNING is issued.
Setting this to nil will disable all such warnings."
  :type 'alist)

;; when loading straight.el
(cl-loop for (pred . warning) in straight-incompatibility-warnings
         when (funcall pred) do (warn warning))

progfolio avatar Jan 06 '23 16:01 progfolio

Ah, sure, that seems reasonable. I guess per this code in startup.el:

  ;; If any package directory exists, initialize the package system.
  (and user-init-file
       package-enable-at-startup
       (not (bound-and-true-p package--activated))
       (catch 'package-dir-found
	 (let ((dirs (cons package-user-dir package-directory-list)))
	   (dolist (dir dirs)
	     (when (file-directory-p dir)
	       (dolist (subdir (directory-files dir))
		 (when (let ((subdir (expand-file-name subdir dir)))
                         (and (file-directory-p subdir)
                              (file-exists-p
                               (expand-file-name
                                (package--description-file subdir)
                                subdir))))
		   (throw 'package-dir-found t)))))))
       (package-activate-all))

The package feature is only loaded when the directory exists. The warning should probably explain that the simplest way to disable package.el in most cases is to delete ~/.emacs.d/elpa, but conditioning it on the feature rather than the directory seems sensible.

raxod502 avatar Jan 06 '23 17:01 raxod502