reddit / emacs
Package management in restricted multi-platform environments?
Dekula · 2022-02-09 16:27
I'd like to have my packages be 'fixed' to a specific version, and furthermore available via cloning my emacs git repository. The latter is a function of the fact that I sometimes work in (Windows) environments where emacs will seemingly not work under the proxy no matter what I try. That's fine, in those environments I don't really need emacs connecting to the internet.
But then, what package strategy to use? The only one that seems to *somewhat* fit the bill is Borg: however,
1. It uses submodules, and I reaaaaally don't want submodules. I'd much rather use subtrees to commit in particular packages.
2. There is no dependency management via this route whatsoever. I've played around with epkg, but there doesn't seem to be a particularly good way of managing dependencies-of-dependencies, unless I'm missing something obvious?
Does anyone else have a subtree leveraging workflow and have a relatively sane way of figuring out package dependencies?
akirakom · 2022-02-09 17:46
It is possible to simply keep your ELPA directory under version control, as suggested in this comment: https://www.reddit.com/r/emacs/comments/mdjd29/why_do_we_trust_packageel/gsd272k/?utm_source=reddit&utm_medium=web2x&context=3
paretoOptimalDev · 2022-02-09 18:15
You can use Nix for this, but unless you already use it or have interest it might not be worth it for just this goal.
your_sweetpea · 2022-02-09 18:20
If it's being used on native Windows (rather than WSL), you certainly can't.
I suppose theoretically you could write a script that uses nix to provide all the packages then copies them out into your emacs directory as long as you're willing to only update packages on linux/osx, and I'm actually investigating that a little bit, but that's honestly a nonstandard usage of nix in the first place.
EDIT: [I have written a proof of concept for this theoretical script.](https://www.reddit.com/r/emacs/comments/sohl6p/package_management_in_restricted_multiplatform/hw9c9s9/)
your_sweetpea · 2022-02-09 18:45
If you're comfortable with only updating packages on MacOS/Linux (or possibly using WSL on Windows), then it may be possible to write a script that uses Nix for this -- I'm currently playing around with it a little.
The basic proof of concept goes something like this:
packages.nix
------------
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
buildEnv {
name = "emacs-packages";
pathsToLink = ["/share/emacs/site-lisp/elpa"];
paths = with emacsPackages; [
nix-mode haskell-mode yaml-mode
markdown-mode magit
];
}
then
update-packages.sh
------------------
#!/usr/bin/env bash
OUT_PATH=$(mktemp -d)
nix-build --out-link=$OUT_PATH ./packages.nix
mkdir -p ./elpa/
rm -rf ./elpa/*
cp -RL $OUT_PATH/share/emacs/site-lisp/elpa/* ./elpa/
chmod -R 755 ./elpa/
Nix manages the dependencies of emacs packages via propagatedBuildInputs so they get dragged along into the env, then you copy said elpa folder into your emacs directory.
It might be necessary to generate a subdirs.el file to ensure everything gets loaded properly, as well, and you'd probably want to manage the nixpkgs version and/or use [emacs-overlay](https://github.com/nix-community/emacs-overlay), but it's a basic proof of concept.
your_sweetpea · 2022-02-09 18:53
If you do go this route you probably also want some scaffolding to ensure autoloads get loaded and disable package.el once you've added the packages in the elpa/ directory to your load-path, which I do like this for my different but related way of configuring my emacs packages:
;; Kill package.el
;;
;; https://github.com/raxod502/straight.el/blob/af5437f2afd00936c883124d6d3098721c2d306c/straight.el#L6358
(setq package-enable-at-startup nil)
(defun package--ensure-init-file/:override ())
(advice-add #'package--ensure-init-file :override
#'package--ensure-init-file/:override)
(defun package--save-selected-packages/:override (&optional _))
(advice-add #'package--save-selected-packages :override
#'package--save-selected-packages/:override)
;; Load emacsWithPackages provided autoloads and packages
(require 'info)
(info-initialize)
(dolist (dir load-path)
;; autoloads
(dolist (autoload (file-expand-wildcards
(expand-file-name "*-autoloads.el" dir)
t))
(load autoload nil 'nomessage 'nosuffix))
;; manuals
(when (file-expand-wildcards (expand-file-name "*.info" dir) t)
(add-to-list 'Info-directory-list dir)))
paretoOptimalDev · 2022-02-09 19:06
> If it's being used on native Windows (rather than WSL), you certainly can't.
Thank you, I really should have mentioned that.
Your POC looks interesting!
jimehgeek · 2022-02-09 19:53
I think [straight.el](https://github.com/raxod502/straight.el) might do what you want. It clones all packages via git, and then builds them locally.
It also supports generating a lock file that contains the git commit SHAs for each package repo. With that you can ensure identical package lists across multiple machines, but you can also trigger git pull and rebuilds of individual packages, or all packages as you see fit. After which you can revert to the locked versions, or update the lock file.
redguardtoo · 2022-02-09 22:08
Use https://github.com/redguardtoo/elpa-mirror to create a local repo from installed packages.
7890yuiop · 2022-02-09 22:10
> I'd like to have my packages be 'fixed' to a specific version, and furthermore available via cloning my emacs git repository.
This is trivial -- simply put your config in version control. When you clone it, you'll have all your packages in the known, working state you committed them, with dependencies sorted out. No need for subtrees or anything like that. No need to go looking for fancy solutions; you already have the very simplest solution at hand which does exactly what you need.
Starlight100 · 2022-02-10 03:59
> Does anyone else have a subtree leveraging workflow
I use git submodules for my packages. 100% manually managed. I fork every package I use, so nothing can disappear on me. And it's convenient if I ever want to contribute upstream with a pull request.
> relatively sane way of figuring out package dependencies?
Grep for the comment
;;; Package-Requires
It's a convention for listing dependencies.
Also grep for **require** statements. That's the most common way to load dependencies.
You can double check on the MELPA website. They list the dependencies for every package.