大家都是用什么方法自动更新emacs依赖(包)的?

我想让我的 emacs 的那些 melpa 依赖能隔段时间自动更新,网上研究了一下,发现现在有这几种:

  1. auto-package-update.el,我用了两三个星期,遇到一个问题,就是每次自动更新后,有些包会没有掉,导致启动后加载这些包失败。不知道是不是这个包里的 auto-package-update-delete-old-versions 还是什么实现导致了这个 bug。
  2. epm ( Emacs Package Manager),没试过,但是感觉如果要做自动更新的话,感觉要结合外部的东西(比如说 systemd 来定时的运行)。
  3. 用其他emacs的包管理,然后用那些包管理的机制更新。

大家有没有什么简单好一些的,可以自动的更新的emacs依赖(包)的方法?

手动更新的路过。自动更新是没有灵魂的

3 个赞

定时doom update完事儿

2 个赞

手动或者自动centaur-update

1 个赞

我是使用自己写的maple-package + makefile

EMACS= /usr/bin/emacs --batch
INITFILE=~/.emacs.d/init.el
EMACSPATH=~/.emacs.d

upgrade:
	@$(EMACS) --load $(INITFILE) --eval '(maple-package-upgrade)'

使用makefile相比直接emacs里运行命令可以异步更新而不影响已打开的emacs

自动更新可以考虑使用crond + makefile,不过我都是手动更新的

1 个赞

也是用 auto-package-update,auto-package-update-at-time 定在 13:20, auto-package-update-interval 置为每过两天更新一次

这样基本上不影响日常使用

1 个赞

auto-package-update 没有遇到过无缘无故掉包的问题,我没有设置为删除旧版本。

我是重度 use-package 用户,绝大部分配置都是用 use-package 引入,包括内置的包(:ensure nil)和 elpa 中没有的(quelpa-use-package)包,甚至是依赖的软件(system-packages)。为了防止有时候手工装了一些包忘记用 use-package,有空时会把 quelpa 和 elpa 目录删除,然后重启 emacs,确保配置始终有效,因为有时候开机想用 emacs 干些紧急工作却发现emacs配置加载不完整,真的是超级尴尬😓

1 个赞

之前用过auto-package-update,后来自己写了一个:当emacs idle一段时间后自动检查并安装ELPA更新,并且不会阻塞emacs。也可以M-x package-upgrade手动更新

(defun dump-into-file (data filename)
  "Dump DATA to FILENAME."
  (when (file-writable-p filename)
    (with-temp-file filename
      (insert (let (print-length) (prin1-to-string data))))))

(defun load-from-file (filename)
  "Load data from FILENAME."
  (with-demoted-errors
      "Error during file read: %S"
    (when (file-exists-p filename)
      (with-temp-buffer
        (insert-file-contents filename)
        ;; this will blow up if the contents of the file aren't
        ;; lisp data structures
        (read (buffer-string))))))

(defun package-upgrade-internal ()
  "Upgrade and remove all outdated ELPA packages, and return a
list of upgraded packages."
  (let (upgrades)
    (cl-flet ((get-version
               (name where)
               (let ((pkg (cadr (assq name where))))
                 (when pkg
                   (package-desc-version pkg)))))
      (dolist (package (mapcar #'car package-alist))
        (let ((in-archive (get-version package package-archive-contents)))
          (when (and in-archive
                     (version-list-< (get-version package package-alist)
                                     in-archive))
            (push (cadr (assq package package-archive-contents))
                  upgrades)))))
    (save-window-excursion
      (dolist (package-desc upgrades)
        (let ((old-package
               (cadr (assq (package-desc-name package-desc)
                           package-alist))))
          (package-install package-desc)
          (package-delete  old-package))))
    upgrades))

(defun package-do-upgrade ()
  (unwind-protect
      (let ((upgrades (package-upgrade-internal)))
        (if upgrades
            (let ((num (length upgrades)))
              (message "Upgraded %d package%s (%s)" num
                       (if (= num 1) "" "s")
                       (mapconcat #'package-desc-full-name
                                  upgrades ", ")))
          (message "All packages are up to date")))
    (remove-hook 'package--post-download-archives-hook
                 #'package-do-upgrade)))

(defun package-upgrade (&optional async)
  "Refresh and upgrade all installed ELPA packages, and display
the upgraded packages in the echo area. Optional argument ASYNC
specifies whether to perform the downloads in the background."
  (interactive)
  (message "Package refresh started")
  (add-hook 'package--post-download-archives-hook
            #'package-do-upgrade t)
  (package-refresh-contents async))

(defconst package-upgrade-check-interval 14400
  "Interval to perform ELPA packages upgrade check.")

(defconst package-upgrade-check-stamp
  (expand-file-name "package-upgrade-check-stamp"
                    user-emacs-directory)
  "Filename that store the timestamp that last ELPA packages
upgrade check is performed.")

(add-hook 'after-init-hook
          #'(lambda ()
              (run-with-idle-timer
               900 t
               #'(lambda ()
                   (let* ((now (round (float-time)))
                          (last (or (load-from-file package-upgrade-check-stamp)
                                    0))
                          (elapsed (- now last)))
                     (when (>= elapsed package-upgrade-check-interval)
                       (package-upgrade t)
                       (dump-into-file
                        now package-upgrade-check-stamp))))
               )) t)
(let ((default-directory user-emacs-directory)
             (current-prefix-arg t))
         (magit-submodule-update (magit-module-confirm "Update" 'magit-module-worktree-p)
                                 '("--remote")))

用submodule管理,配合magit一键升级