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

emacsPackages: clean the bulk-updating scripts #351056

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions doc/languages-frameworks/elisp.section.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Emacs Lisp {#sec-emacs-lisp}

Since at least version 24, Emacs has a native package manager, `package.el`. Since its inception, many Elisp packages were created by Emacs community at large, as well as package repositories.

<!--
TODO: add a chapter about melpaBuild and the general Elisp Nix framework
-->

## Bulk Update {#sec-emacs-lisp-packages-bulk-update}

The chief Elisp package repositories are:

- [GNU ELPA](https://elpa.gnu.org/),
- [NonGNU ELPA](https://elpa.nongnu.org/), and
- [MELPA](https://melpa.org/).

Nixpkgs provides a comprehensive infrastucture that leverages the contents of these Elisp repositories as Nix packages. Here we will the bulk-updating automation tooling.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Nixpkgs provides a comprehensive infrastucture that leverages the contents of these Elisp repositories as Nix packages. Here we will the bulk-updating automation tooling.
Nixpkgs provides a comprehensive infrastucture that leverages the contents of these Elisp repositories as Nix packages. Here we will document? the bulk-updating automation tooling.


Inside the `pkgs/applications/editors/emacs/elisp-packages` subdirectory we find the following scripts:

- `update-scripts-library.sh`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add "overlay" to its name since it is tightly coupled with emacs-overlay?

  • download_packagesets is tightly coupled with emacs-overlay
  • What is the use case for commit_packagesets without involving emacs-overlay?


This script acts as a library, containing useful functions to deal with bulk updates. It can be `source`'d in both interactive and batch environments.

This library provides the following functions:

- `download_packagesets`

This function downloads from [`nix-community` Emacs Overlay](https://github.com/nix-community/emacs-overlay) the corresponding files.

It accepts any number of arguments. The only acceptable arguments are: `elpa`, `elpa-devel`, `melpa`, `melpa-stable`, `nongnu`, `nongnu-devel`.

When an argument is not recognized, the whole function bails out with an error message.

- `test_packagesets`

This function runs a simple smoke test that instantiates the corresponding package set.

It accepts multiple arguments.

The only acceptable arguments are: `elpa`, `elpa-devel`, `melpa`, `melpa-stable`, `nongnu`, `nongnu-devel`.

When an argument is not recognized, the whole function bails out with an error message.

- `commit_packagesets`

This function commits the corresponding package set, writing a short commit message.

It accepts multiple arguments.

The only acceptable arguments are: `elpa`, `elpa-devel`, `melpa`, `melpa-stable`, `nongnu`, `nongnu-devel`.

When an argument is not recognized, the whole function bails out with an error message.

- `update-package-sets`

This script updates the package sets passed to it as arguments.

It accepts multiple arguments.

The only acceptable arguments are: `elpa`, `elpa-devel`, `nongnu`, `nongnu-devel`.

When an argument is not recognized, the whole function bails out with an error message.

- `update-melpa`

This script updates `recipes-archive-melpa.json`, a JSON file that describes the MELPA package set.

It ignores the arguments.

- `update-from-overlay`

This script downloads all the packagesets from overlay, then tests and commits them.

It ignores the arguments.
1 change: 1 addition & 0 deletions doc/languages-frameworks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ dart.section.md
dhall.section.md
dlang.section.md
dotnet.section.md
elisp.section.md
emscripten.section.md
gnome.section.md
go.section.md
Expand Down
28 changes: 24 additions & 4 deletions doc/packages/emacs.section.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Emacs {#sec-emacs}

[Emacs](https://www.gnu.org/software/emacs/) is the advanced, extensible, customizable, self-documenting editor.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The page sasy

An extensible, customizable, free/libre text editor — and more.


At its core is an interpreter for Emacs Lisp (shortly, Elisp), a dialect of the Lisp programming language with extensions to support text editing.

## Configuring Emacs {#sec-emacs-config}

The Emacs package comes with some extra helpers to make it easier to configure. `emacs.pkgs.withPackages` allows you to manage packages from ELPA. This means that you will not have to install that packages from within Emacs. For instance, if you wanted to use `company` `counsel`, `flycheck`, `ivy`, `magit`, `projectile`, and `use-package` you could use this as a `~/.config/nixpkgs/config.nix` override:
Nixpkgs provides a framework that leverages Emacs via Nix.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Emacs package comes with some extra helpers to make it easier to configure.

vs

Nixpkgs provides a framework that leverages Emacs via Nix.

I find the old sentence is more easy to read/understand.

Also, a framework that leverages Emacs via Nix feels wrong to me. Maybe a framework to leverage Emacs via Nix? I am not a native English speaker though.


`emacs.pkgs.withPackages` allows managing packages from various Elisp package repositories (ELPA, MELPA etc.) and even third-party stand-alone packages from Nix, without relying on Emacs to download and install them.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ELPA" is Emacs Lisp Package Archive.

https://elpa.gnu.org/ is GNU Emacs Lisp Package Archive (or GNU ELPA), an ELPA run by GNU.

Maybe we can use more precise words here.


For instance, by writing the code below at `~/.config/nixpkgs/config.nix`, the Elisp packages `company`, `counsel`, `flycheck`, `ivy`,`magit`, `projectile`, and `use-package` are installed:

```nix
{
Expand All @@ -20,7 +28,15 @@ The Emacs package comes with some extra helpers to make it easier to configure.
}
```

You can install it like any other packages via `nix-env -iA myEmacs`. However, this will only install those packages. It will not `configure` them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provides a `default.el` file in `/share/emacs/site-start/`. Emacs knows to load this file automatically when it starts.
This custom package can be installed like any other one, via `nix-env -iA myEmacs`.

However, this expression merely installs the package; no configuration happens here. Such a configuration requires an Elisp file crafted for this purpose.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to provide a configuration file.

vs

Such a configuration requires an Elisp file crafted for this purpose.

I find the old sentence is more clear.


Luckily, it is possible to do this from within Nix!

By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provides a `default.el` file in `/share/emacs/site-start/` -- since Emacs loads this file automatically when it starts.

Let's modify the example above:

```nix
{
Expand Down Expand Up @@ -97,9 +113,13 @@ You can install it like any other packages via `nix-env -iA myEmacs`. However, t
}
```

This provides a fairly full Emacs start file. It will load in addition to the user's personal config. You can always disable it by passing `-q` to the Emacs command.
This provides a fairly full Emacs start file. It will be loaded in addition to the user's personal config. Further, it can be disabled at will: Emacs accepts the command-line argument `--no-init-file` (short form `-q`) to not load the init files.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can be disabled at will ... -q) to not load the init files

This is a bit confusing.

Presumably, it refers to default.el. However, -q makes Emacs not load both default.el and init.el.

We should first mention that inhibit-default-init in init.el can prevents default.el from being loaded. Then we mention -q make both of them not be loaded.


Sometimes `emacs.pkgs.withPackages` is not enough, as this package set imposes some priorities over their packages (with the lowest priority assigned to GNU-devel ELPA, and the highest for packages manually defined in `pkgs/applications/editors/emacs/elisp-packages/manual-packages`).

However it is not possible to control these priorities when some package is installed as a dependency. In principle, the overrides can be done on a per-package-basis, providing all the required dependencies manually. However this procedure is tedious and error-prone, since there is the possibility that an unwanted dependency sneaks in through some other package.

Sometimes `emacs.pkgs.withPackages` is not enough, as this package set has some priorities imposed on packages (with the lowest priority assigned to GNU-devel ELPA, and the highest for packages manually defined in `pkgs/applications/editors/emacs/elisp-packages/manual-packages`). But you can't control these priorities when some package is installed as a dependency. You can override it on a per-package-basis, providing all the required dependencies manually, but it's tedious and there is always a possibility that an unwanted dependency will sneak in through some other package. To completely override such a package, you can use `overrideScope`.
A complete and pervasive override for such a package can be done via `overrideScope`.

```nix
let
Expand Down
6 changes: 6 additions & 0 deletions doc/redirects.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit (doc/redirects.json: add emacs lisp links) should be merged into the previous one (doc/languages-frameworks/elisp.section.md: init).

Original file line number Diff line number Diff line change
Expand Up @@ -3899,6 +3899,12 @@
"sec-emacs-config": [
"index.html#sec-emacs-config"
],
"sec-emacs-lisp": [
"index.html#sec-emacs-lisp"
],
"sec-emacs-lisp-packages-bulk-update": [
"index.html#sec-emacs-lisp-packages-bulk-update"
],
"sec-firefox": [
"index.html#sec-firefox"
],
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Bash lacks serious data structures, I am using a JSON file as database.

Bash does have dict which called "associative array". Maybe it is easier to use/read than jq.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"elpa": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/elpa/elpa-generated.nix",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make it configurable so that we can use a specific commit hash. This is useful when someones create an elisp bump PR and you want to verify that they does not change anything from emacs-overlay.

I used to do it by manually change one url of the update-from-overlay script. Now I have to change multiple urls.

"generated_file": "elpa-generated.nix",
"nix_attribute": "emacsPackages.elpaPackages"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emacsPackages is a deprecated alias for emacs.pkgs.

Suggested change
"nix_attribute": "emacsPackages.elpaPackages"
"nix_attribute": "emacs.pkgs.elpaPackages"

},
"elpa-devel": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/elpa/elpa-devel-generated.nix",
"generated_file": "elpa-devel-generated.nix",
"nix_attribute": "emacsPackages.elpaDevelPackages"
},
"melpa": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/melpa/recipes-archive-melpa.json",
"generated_file": "recipes-archive-melpa.json",
"nix_attribute": "emacsPackages.melpaPackages"
},
"melpa-stable": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/melpa/recipes-archive-melpa.json",
"generated_file": "recipes-archive-melpa.json",
"nix_attribute": "emacsPackages.melpaStablePackages"
},
"nongnu": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/nongnu/nongnu-generated.nix",
"generated_file": "nongnu-generated.nix",
"nix_attribute": "emacsPackages.nongnuPackages"
},
"nongnu-devel": {
"overlay_url": "https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos/nongnu/nongnu-devel-generated.nix",
"generated_file": "nongnu-devel-generated.nix",
"nix_attribute": "emacsPackages.nongnuDevelPackages"
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,3 @@
/*
# Updating
To update the list of packages from ELPA,
1. Run `./update-elpa-devel`.
2. Check for evaluation errors:
# "../../../../../" points to the default.nix from root of Nixpkgs tree
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate ../../../../../ -A emacs.pkgs.elpaDevelPackages
3. Run `git commit -m "elpa-devel-packages $(date -Idate)" -- elpa-devel-generated.nix`
## Update from overlay
Alternatively, run the following command:
./update-from-overlay
It will update both melpa and elpa packages using
https://github.com/nix-community/emacs-overlay. It's almost instantaneous and
formats commits for you.
*/

{ lib, pkgs, buildPackages }:

self: let
Expand Down
24 changes: 0 additions & 24 deletions pkgs/applications/editors/emacs/elisp-packages/elpa-packages.nix
Original file line number Diff line number Diff line change
@@ -1,27 +1,3 @@
/*

# Updating

To update the list of packages from ELPA,

1. Run `./update-elpa`.
2. Check for evaluation errors:
# "../../../../../" points to the default.nix from root of Nixpkgs tree
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate ../../../../../ -A emacs.pkgs.elpaPackages
3. Run `git commit -m "elpa-packages $(date -Idate)" -- elpa-generated.nix`

## Update from overlay

Alternatively, run the following command:

./update-from-overlay

It will update both melpa and elpa packages using
https://github.com/nix-community/emacs-overlay. It's almost instantaneous and
formats commits for you.

*/

{ lib, pkgs, buildPackages }:

self: let
Expand Down
25 changes: 0 additions & 25 deletions pkgs/applications/editors/emacs/elisp-packages/melpa-packages.nix
Original file line number Diff line number Diff line change
@@ -1,28 +1,3 @@
/*

# Updating

To update the list of packages from MELPA,

1. Run `./update-melpa`
2. Check for evaluation errors:
# "../../../../../" points to the default.nix from root of Nixpkgs tree
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate --show-trace ../../../../../ -A emacs.pkgs.melpaStablePackages
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate --show-trace ../../../../../ -A emacs.pkgs.melpaPackages
3. Run `git commit -m "melpa-packages $(date -Idate)" recipes-archive-melpa.json`

## Update from overlay

Alternatively, run the following command:

./update-from-overlay

It will update both melpa and elpa packages using
https://github.com/nix-community/emacs-overlay. It's almost instantenous and
formats commits for you.

*/

let
# Read ./recipes-archive-melpa.json in an outer let to make sure we only do this once.
defaultArchive = builtins.fromJSON (builtins.readFile ./recipes-archive-melpa.json);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
/*
# Updating
To update the list of packages from nongnu devel (ELPA),
1. Run `./update-nongnu-devel`.
2. Check for evaluation errors:
# "../../../../../" points to the default.nix from root of Nixpkgs tree
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate ../../../../../ -A emacs.pkgs.nongnuDevelPackages
3. Run `git commit -m "nongnu-devel-packages $(date -Idate)" -- nongnu-devel-generated.nix`
*/

{
lib,
pkgs,
Expand Down
14 changes: 0 additions & 14 deletions pkgs/applications/editors/emacs/elisp-packages/nongnu-packages.nix
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
/*
# Updating
To update the list of packages from nongnu (ELPA),
1. Run `./update-nongnu`.
2. Check for evaluation errors:
# "../../../../../" points to the default.nix from root of Nixpkgs tree
env NIXPKGS_ALLOW_BROKEN=1 nix-instantiate ../../../../../ -A emacs.pkgs.nongnuPackages
3. Run `git commit -m "nongnu-packages $(date -Idate)" -- nongnu-generated.nix`
*/

{ lib, pkgs, buildPackages }:

self: let
Expand Down
8 changes: 5 additions & 3 deletions pkgs/applications/editors/emacs/elisp-packages/update
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$( cd "$(dirname "$0")" ; pwd -P )"
cd "$SCRIPT_DIR"
# Classic "where I am" block
# https://www.binaryphile.com/bash/2020/01/12/determining-the-location-of-your-script-in-bash.html
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); cd -P $(dirname $(readlink ${BASH_SOURCE[0]} || echo .)); pwd)
cd "${SCRIPT_DIR}"

./update-from-overlay

./update-manual
git commit -m "emacs.pkgs.manualPackages: $(date --iso)" -- .
git commit -m "emacsPackages.manualPackages: updated at $(date --iso) (non-interactively)" -- .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use emacs.pkgs instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-interactively

Is there a "interactive" version?

6 changes: 0 additions & 6 deletions pkgs/applications/editors/emacs/elisp-packages/update-elpa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emacs-overlay needs to handle both the new way and the old way of updating.

This file was deleted.

This file was deleted.

52 changes: 11 additions & 41 deletions pkgs/applications/editors/emacs/elisp-packages/update-from-overlay
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tasks executed by the update-from-overlay script are very useful for
interactive as well as batch update sessions.

Just curious, what is your interactive use case?

Original file line number Diff line number Diff line change
@@ -1,49 +1,19 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p curl nix coreutils
set -euxo pipefail
set -euo pipefail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is -x removed?


# This script piggybacks on the automatic code generation done by the nix-community emacs overlay
# You can use this to avoid running lengthy code generation jobs locally
# This script relies on the automatic code generation done by the emacs overlay
# kept by nix-community
# You can use this to avoid running time-consuming code generation jobs locally
Comment on lines -5 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I do not think this change is necessary and am slightly for keep it unchanged.


export NIXPKGS_ALLOW_BROKEN=1
source ./update-scripts-library.sh

download_change() {
local FILE_LOCATION="$1"
# The loops are unrolled as follows because either all packagesets should be
# updated, or none of them should. Therefore, if any of them fails, all the
# process should be aborted as soon as possible.

local BASEURL="https://raw.githubusercontent.com/nix-community/emacs-overlay/master/repos"
download_packagesets "elpa" "elpa-devel" "melpa" "nongnu" "nongnu-devel"

curl -s -O "${BASEURL}/${FILE_LOCATION}"
}
test_packagesets "elpa" "elpa-devel" "melpa" "melpa-stable" "nongnu" "nongnu-devel"

commit_change() {
local MESSAGE="$1"
local FILENAME="$2"

git diff --exit-code "${FILENAME}" > /dev/null || \
git commit -m "${MESSAGE}: updated $(date --iso) (from overlay)" -- "${FILENAME}"
}

test_packageset(){
local PKGSET="$1"

nix-instantiate --show-trace ../../../../../ -A "emacs.pkgs.$PKGSET"
}

download_change "elpa/elpa-generated.nix"
download_change "elpa/elpa-devel-generated.nix"
download_change "melpa/recipes-archive-melpa.json"
download_change "nongnu/nongnu-generated.nix"
download_change "nongnu/nongnu-devel-generated.nix"

test_packageset "nongnuPackages"
test_packageset "nongnuDevelPackages"
test_packageset "elpaPackages"
test_packageset "elpaDevelPackages"
test_packageset "melpaStablePackages"
test_packageset "melpaPackages"

commit_change "elpa-packages" "elpa-generated.nix"
commit_change "elpa-devel-packages" "elpa-devel-generated.nix"
commit_change "melpa-packages" "recipes-archive-melpa.json"
commit_change "nongnu-packages" "nongnu-generated.nix"
commit_change "nongnu-devel-packages" "nongnu-devel-generated.nix"
commit_packagesets "elpa" "elpa-devel" "melpa" "nongnu" "nongnu-devel"
Loading