2

I am using :ensure t of use-package to install "go-prjectile" package which depends on "go-rename". But I would like to use a local version of "go-rename" and its path is already added to load-path.

My configuration:

(use-package go-rename
   :load-path "lisp/go-rename")

(use-package go-projectile
   :ensure t)

But every time when "go-projectile" is installed, the "go-rename" is also installed from melpa too.

Is there any way to only install "go-projectile" without install its dependencies?

Enze Chi
  • 1,410
  • 12
  • 28

4 Answers4

2

I think the cleanest solution is to tell package.el that you have already lsp-mode mode. You can do it in two different ways:

  1. If you have installed lsp-mode in a format/layout that package.el can understand (most importantly it contains both <pkg>-autoloads.els and <pkg>-pkg.el), then just make sure that it is in one of the directories mentioned in package-directory-list).

  2. If you installed it using a different format/layout, then use something like:

    (add-to-list 'package--builtin-versions `(go-rename 1 2 1))
    

    It is important to do this early, i.e. before package-activate-all or package-initialize is called, so in Emacs≥27, you will want to put it into your early-init.el.

Stefan
  • 26,154
  • 3
  • 46
  • 84
1

See http://blog.binchen.org/posts/how-to-manage-emacs-packages-effectively.html which provides complete solution for Emacs 23.4, 24.3, 24.4, 25.

In your case, the easiest way is to setup your own package repository localelpa:

Step 1, create directory ~/.emacs.d/localelpa

Step 2, create file ~/.emacs.d/localelpa/archive-contents with below content

(1
 (go-rename . [(1 2 1) nil "This is go-rename, blah blah" single])
)

Step 3, place go-rename-1.2.1.el at ~/.emacs.d/localelpa

Step 4, insert below code into ~/.emacs.d/init.el and restart Emacs:

(add-to-list 'package-archives '("localelpa" . "~/.emacs.d/localelpa"))

Now you will see package goname-1.2.1 after M-x list-packages, in Emacs 24.4 you can tweak package-pinned-packages to pin that package (https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html)

What about Emacs 24.3, 23.4? Well, why not change version from 1.2.1 to 99.9.9? ;)

chen bin
  • 4,781
  • 18
  • 36
  • the 4 steps solution seems a lot of work. I have read your blog posts. The whitelist one sounds great. Is it possible to have a blacklist version? Will that work depended packages? – Enze Chi Jul 01 '16 at 10:18
  • This is the minimum setup. Once you setup localelpa, you can use it for other packages. Surely you can use blacklist strategy. It's just boolean expression in package-filter-function. – chen bin Jul 02 '16 at 02:16
1

I had this exact problem. I was trying to use a local version of lsp-mode but packages which depended on it were installing lsp-mode from melpa. @chenbin's solution would successfully filter out lsp-mode from the package list (i.e. when you M-x list-packages) but it would still be installed when installing any packages for which it was a dependency.

I'm using (use-package) to specify the load path of my manually installed packages. Adding this code before (package-initialize) is called works for me:

(defvar local-only-packages
  '(lsp-mode)
  "Don't install these packages as dependencies, I will install them manually.")

;; When determining dependencies to install, filter out any packages you will
;; handle manually.
(advice-add
 'package-compute-transaction
 :filter-return
 (lambda (packages)
   (seq-filter (lambda (it)
         (not (memq (package-desc-name it) local-only-packages)))
           packages)))


;; When creating package-descriptions that will be initialized by
;; package.el, filter out the dependncies that are handled manually. 
(advice-add
 'package-desc-from-define
 :filter-return
 (lambda (pkg-desc)
   (setf (package-desc-reqs pkg-desc)
     (seq-filter (lambda (it)
               (not (memq (car it) local-only-packages)))
             (package-desc-reqs pkg-desc)))
   pkg-desc))
0

First thanks for the answer from @chenbin. All the following ideas from his answer and blog post.

Maybe I have some mis-understand on the 4 step way to create local elpa. For me to manually maintain it is painful (For example, package from git repo, keep updating).

After some googling about "local elpa" I steal code (Makefile, package-build.el) from "melpa" which would build local elpa packages and archive-contents from recipes.

Then I only need to maintain recipes something like below (use ob-go as example)

(ob-go
 :fetcher github
 :repo "pope/ob-go")

The make file would cache the package from Github and create archive-contents to packages directory.

Then I just need to add ("local-elpa" . "~/.emacs.d/packages") to package-archives and pin it to local-elpa.

If local elpa packages has updates, just make the packages and archive-contents, then update packages as usual.

Enze Chi
  • 1,410
  • 12
  • 28
  • You might be reinventing [quelpa](https://github.com/quelpa/quelpa) – npostavs Jul 06 '16 at 11:06
  • @npostavs, that looks great, but does it support `pin` package to avoid to the package is installed on `melpa` if it is a dependency package whose version on `melpa` is higher than my forked repo's one? – Enze Chi Jul 07 '16 at 01:47
  • AFAIK, it creates a normal package archive, so pinning works as usual (I'm not a user, so I can't say for sure though). – npostavs Jul 07 '16 at 10:28