<div dir="ltr"><div>Hi jman,</div><div><br></div><div>Thanks for sharing. This looks like a great template for a melpa/use-package based setup, but I would not call it "reproducible". That usually means that you get the exact same code each time, whereas with this you can run the same setup two minutes apart and get a different combination of package versions. Melpa only has the option of downloading the latest version of a package (latest release or latest commit depending on if you are using melpa stable or not, but still only the latest of each).</div><div><br></div><div>So if you want to do truly "reproducible" installs you have to use straight, I don't think there's any other packager right now that is able to do it. It's fairly straightforward though, and you can still `use-package` in the same way</div><div><br></div><div>```</div><div>;;;; Install straight<br></div><div>(defvar bootstrap-version)<br><br>(let ((install-url "<a href="https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el">https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el</a>")<br>      (bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))<br>      (bootstrap-version 5))<br>  (unless (file-exists-p bootstrap-file)<br>    (with-current-buffer (url-retrieve-synchronously install-url 'silent 'inhibit-cookies)<br>      (goto-char (point-max))<br>      (eval-print-last-sexp)))<br></div><div>  (load bootstrap-file nil 'nomessage))<br></div><div><br></div><div>;;;; Tell it to hook into use-package<br></div><div>(straight-use-package 'use-package)<br>(setq straight-use-package-by-default t)</div><div><br></div><div>;;;; Install whatever packages you like<br></div><div>(use-package ...)</div><div>(use-package ...)</div><div>(use-package ...)</div><div><br></div><div>;;;; Create a version file if it does not yet exist<br></div><div>(when (not (file-exists-p (expand-file-name "straight/versions/default.el" straight-base-dir)))</div><div>  (straight-freeze-versions))</div><div>```</div><div><br></div><div>Straight uses melpa's recipes, but it does not actually install packages from MELPA, instead it gets them directly via git. The versions.el file contains the exact commit hash for each package, so when you use this config on a different computer you'll get the exact same code/commit/version for each package. True reproducibility!</div><div><br></div><div>If you keep your emacs config in a git repository then you can use these gitignore patterns to make sure the version file is checked in, another common approach is to keep it in a dotfiles repo and symlink it.</div><div><br></div><div>/straight/*<br>!/straight/versions</div><div><br></div><div><br></div><div>Hope that helps! This has become something I care about deeply, as I've had my emacs setup break so many times when upgrading or reinstalling. Now I finally have control over which packages are upgraded when, and most importantly if an upgrade breaks something I can easily revert.<br></div><div><br></div><div>Best wishes for 2021!</div><div>Arne<br></div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 21 Dec 2020 at 19:22, jman <<a href="mailto:emacs-berlin@storiepvtride.it">emacs-berlin@storiepvtride.it</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Hello folks!<br>
<br>
A little while ago I wanted to solve a puzzle: a complete and<br>
reproducible unattended emacs installation from scratch.<br>
This is useful to set up emacs on different machines or (in my case)<br>
provision your workstation using tools such as Ansible or Nix<br>
packages. And emacs is one of the first thing I need to have immediately<br>
available.<br>
<br>
Fermin (hi fermin!) gave some hints [0] and from there I finally reached<br>
a good enough solution. I'm using `use-package` and didn't want<br>
to also install `straight` (my config is confusing enough already ^_^).<br>
<br>
Here's the relevant snippet (commented):<br>
<br>
```<br>
;; add MELPA repository<br>
(package-initialize)<br>
(require 'package)<br>
(add-to-list 'package-archives<br>
  '("melpa" . "<a href="https://melpa.org/packages/" rel="noreferrer" target="_blank">https://melpa.org/packages/</a>") t)<br>
<br>
;; fetch the list of packages available *now*<br>
(unless package-archive-contents<br>
  (package-refresh-contents))<br>
<br>
;; if not installed, force installation of "use-package" *now*<br>
(unless (package-installed-p 'use-package)<br>
  (package-install 'use-package))<br>
<br>
;; install a new package automatically if not already present<br>
(require 'use-package-ensure)<br>
 (setq use-package-always-ensure t)<br>
```<br>
<br>
from now on any package will be downloaded and installed with:<br>
<br>
(use-package a-new-package)<br>
<br>
here's a link [1] if anyone wants to have a look (first 20<br>
lines are relevant).<br>
<br>
As usual, comments and suggestions are welcome.<br>
<br>
happy hacking!<br>
<br>
<br>
[0] <a href="https://mailb.org/pipermail/emacs-berlin/2020/000752.html" rel="noreferrer" target="_blank">https://mailb.org/pipermail/emacs-berlin/2020/000752.html</a><br>
[1] <a href="https://git.sr.ht/~jman/dotfiles/tree/master/item/emacs/.config/emacs/init.el" rel="noreferrer" target="_blank">https://git.sr.ht/~jman/dotfiles/tree/master/item/emacs/.config/emacs/init.el</a><br>
_______________________________________________<br>
emacs-berlin mailing list<br>
<a href="mailto:emacs-berlin@emacs-berlin.org" target="_blank">emacs-berlin@emacs-berlin.org</a><br>
<a href="https://mailb.org/mailman/listinfo/emacs-berlin" rel="noreferrer" target="_blank">https://mailb.org/mailman/listinfo/emacs-berlin</a><br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Arne Brasseur</div><div>Gaiwan GmbH</div><div>Phone +49 176 97468014</div><div><a href="https://lambdaisland.com" target="_blank">https://lambdaisland.com</a><br></div></div></div></div>