关于melpa包与非melpa包的冲突

我一直用懒猫大大的sdcv包查字典,今天突然发现不工作了,感觉很奇怪。调查一番后发现,之前我都是用quelpa直接从github上把sdcv包拖到本地使用的,但不知在什么时候melpa上也多了一个同名的sdcv包。问题在于,我本地的版本在我不知情的情况下被替换成了这个melpa上的版本。这个melpa上的sdcv包仔细一看其实还是懒猫写的,只不过是一个很老的版本,难怪无法正常工作了。

那么,如果出现melpa的包和本地包同名冲突的情况,如何防止melpa包覆盖本地包呢?

melpa 上的不知道是谁上传的,负责上传不负责维护。

最新版sdcv,社区开发者利用了 sdcv 输出 json 格式的接口基本上重写了sdcv.el的逻辑,更加清晰了。

建议用 popweb 来翻译哈,我现在都用 popweb 来替代 sdcv 了,比较爽,偶尔遇到不会读的单词还可以听一听发音。

不会无缘无故的覆盖。应该是你曾经有明确(手动或代码)从 melpa 安装/更新,但是你不记得了。

如果你的确很担心不知什么时候被覆盖,可参考我的方式(正好跟你相反,我就怕 melpa 更新。所以锁定某个旧版,一旦更新则弹警告):

(let ((pkg-info (cadr (assoc 'sdcv package-alist))))
  (unless (assoc 'pos-tip (package-desc-reqs pkg-info))
    (warn "[sdcv] Current version %s is not terminal friendly. Last stable version is %s"
          (package-desc-version pkg-info)
          '(20190610.732))))

Update:

严格来说,我锁定的不是版本,而是 pos-tip,因为终端下没有 childframe

刚刚看了一下,melpa 上这个包的最近版本号是 (20220210 1412),仅仅是更换了项目地址,功能上个版本无二。

谢谢你的建议,我回忆了一下可能是我某次更新melpa上所有包时把这个包也顺带更新了。但问题可能也就是这一点:本地有一个名字为A的包,melpa上后来也出现了一个名字为A的包,更新包时,系统就会认为melpa上的这个包是本地包的新版本,然后就覆盖了。 :rofl:

或直接在 package-install 拦截:

(defvar package-install-skip-list '(sdcv))

(define-advice package-install (:around (orig-fn pkg &optional dont-select) skip)
  (if (memq pkg package-install-skip-list)
      (message "==> [package-install] skipped: %s" pkg)
    (funcall orig-fn pkg dont-select)))

这样就不用担心批量更新了。

2 个赞

如果你用的是 use-package + quelpa, 可以自定义quelpa关键字

(defun use-package-handler/:quelpa (name _keyword args rest state)
  "NAME KEYWORD ARGS REST STATE."
  (use-package-concat
   `((unless (or (locate-library ,(format "%s" name))
                 (package-installed-p ',(pcase (car args)
                                          ((pred listp)   (caar args))
                                          ((pred symbolp) (car args)))))
       (apply 'quelpa ',args)))
   (use-package-process-keywords name rest state)))

先检查本地目录是否有sdcv这个包,然后检查是否安装了这个包,都没有才会使用 quelpa 下载,我本地有十几个自己维护的包就是这么用的

https://github.com/honmaple/maple-emacs/blob/master/site-lisp/maple/maple-use-package.el#L204

melpa 确实不应该接受非 maintainer 的 package 提交请求. (当然了, 这样做不违背自由软件的精神, 只是实践操作起来容易引起不必要的麻烦)

发行版打包别人开发的软件, 背后的逻辑是, 用户用发行版里面的包, 应该先向发行版汇报问题, 然后发行版里面的 maintainer 再找包的开发者交流. 而 MELPA 不管这东西, 最后用户还是得找原作者.

社区版的sdcv在哪里下载啊?popweb在melpa上有维护吗?

在我的github,我的包从来不上传melpa

批量更新也要防。

melpa 这个版本的 sdcv 自分叉以后一直是 @stardiviner 独立维护。不过这样写会让人感觉原作者还是第一维护者:

;; Maintainer: Andy Stewart <[email protected]>, stardiviner([email protected]>