Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Support]: Installing local package #22

Closed
1 task done
suconakh opened this issue Oct 31, 2022 · 7 comments
Closed
1 task done

[Support]: Installing local package #22

suconakh opened this issue Oct 31, 2022 · 7 comments

Comments

@suconakh
Copy link

Emacs Version

GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw3d scroll bars)

Operating System

Linux

question

With straight i can install a local package in my user-emacsdirectory using the :local-repo keyword and straight will compile and do autoloads for me. Is it possible to do this with elpaca?

Relevant information

No response

Confirmation

  • I've read the documentation and I still am unsure.
@progfolio
Copy link
Owner

progfolio commented Oct 31, 2022

With straight i can install a local package in my user-emacsdirectory using the :local-repo keyword and straight will compile and do autoloads for me. Is it possible to do this with elpaca?

I've always found it hard to keep track of :local-repo vs :repo in straight.el.
I've just pushed some changes to make this simpler in Elpaca.

To work with a local git repository, you should now be able to specify a file path via the :repo keyword when there is no :host keyword. e.g.

;;assuming a git repository exists on disk at /tmp/example/
(elpaca (example :repo "/tmp/example/"))

I haven't really advertised the :local-repo keyword, but Elpaca currently supports it for renaming repos on disk. e.g.

;;assuming a git repository exists on disk at /tmp/example/
(elpaca (example :repo "/tmp/example/" :local-repo "renamed")) ;;clones /tmp/example/ to $REPOS/renamed

I may swap that out for another keyword or allow the :repo keyword to accept a list of the form (repo-name alias) to support renaming. The :local-repo vs :repo dance is too confusing, IMO.

In any case, testing is appreciated. You should be able to update elpaca via the elpaca-update command and restarting Emacs. Thank you.

@suconakh
Copy link
Author

suconakh commented Nov 1, 2022

Thanks, it works but not quite. It only works when you specify an absolute path, e.g. /home/user/repository. Specifying a relative home path with ~/repo does not work, and throws an error fatal: repository '~/repo' does not exist. Also, straight's :local-repo supports specifying a path that is not really a repository, but just a directory. It would be nice if elpaca supported this. Or maybe there is already a way to do it with some internal elpaca functions trickery.

@progfolio
Copy link
Owner

Specifying a relative home path with /repo does not work, and throws an error fatal: repository '/repo' does not exist.

Sorry about that. The subprocess calls git directly, sans shell. I've pushed a fix which should properly expand the file path now.

straight's :local-repo supports specifying a path that is not really a repository, but just a directory.

Can you give me some example use cases for this?

@suconakh
Copy link
Author

suconakh commented Nov 1, 2022

Sorry about that. The subprocess calls git directly, sans shell. I've pushed a fix which should properly expand the file path now.

Thank you, everything is fine now.

Can you give me some example use cases for this?

I'd like to separate some configurations from init.el into a directory next to it, and i don't want to manually write some emacs shenanigans to silently byte-compile and generate autoloads for them. I used straight to do it like this:

(straight-use-package `(suconakh :local-repo ,(locate-user-emacs-file "suconakh/")))

With the following file structure

~/.config/emacs
├── early-init.el
├── init.el
└── suconakh
    ├── ...
    └── suconakh.el

@progfolio
Copy link
Owner

progfolio commented Nov 2, 2022

Elpaca is designed to work with elisp packages and assumes they are stored in a git repostiory. That said, what your after could be possible in the future.
One would have to replace the build steps which clone and configure the repository with a function which symlinks the local directory to the appropriate location. e.g.

(defun my-symlink-repo-dir (e)
  "Symlink E's repo dir."
  (make-symbolic-link (plist-get (elpaca<-recipe e) :repo)
                      (elpaca<-repo-dir e)
                      'ok-if-exists)
  (elpaca--continue-build e))

Then that step could be used in the recipe's :build declaration in place of those steps. e.g.

(elpaca `(suconakh
          :repo ,(expand-file-name "suconakh/" user-emacs-directory)
          :build (my-symlink-repo-dir ;; replaces repo clone steps
                  elpaca--run-pre-build-commands
                  elpaca--link-build-files
                  elpaca--generate-autoloads-async
                  elpaca--byte-compile
                  elpaca--activate-package)))

This would break the elpaca-update and elpaca-update-all commands.
I may add something like a :pin recipe keyword to indicate that a package should not be considered while updating, but I still have to work out the semantics.
The following recipe should work on the current version of Elpaca if your "suconakh" directory is a git repository:

(elpaca `(suconakh :repo ,(expand-file-name "suconakh/" user-emacs-directory)))

Or, alternatively, if ~/.config/emacs is a git repository:

(elpaca `(suconakh :repo ,user-emacs-directory :files ("suconakh/*")))

@suconakh
Copy link
Author

suconakh commented Nov 2, 2022

Thanks, this is very elegant and flexible and just what I needed! Is this the correct way to tell elpaca to rebuild this package on every init?

(add-hook 'elpaca-after-init-hook (lambda () (elpaca-rebuild 'suconakh t)))

@purplg
Copy link

purplg commented Nov 25, 2023

We discussed this in Matrix recently and after spending some time experimenting with this problem and diving into the Elpaca docs, I figured this is exactly what I was looking for. While the :load-path solution works pretty well, it's bypassing the benefits of using Elpaca and still has a couple problems. For one, this requires me to independently list my package dependencies within my config instead of letting Elpaca resolve them. Also, I no longer have the ability to conveniently rebuild the local package with Elpaca, as you mentioned before.

I think it would be nice to have a keyword argument for this, like :load-path, but for now I'll probably continue using the :local-repo holdover keyword arg since that seems to solve all my problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants