ee46aa8a13
Before, an unstable version of melpaBuild has to be in MELPA format,
which has some disadvantages:
- existing update scripts cannot be reused[1]
- it causes inconsistence.
This patch fixes that by allowing an unstable version to be in Nix
format.
We heuristically detect if it is an unstable version in Nix format.
If so, we convert it to MELPA format.
This does not bring evaluation performance overhead. Here is my
benchmark result using hyperfine-1.18.0 and nix-2.18.1.
Without this patch:
Benchmark 1: NIXPKGS_ALLOW_BROKEN=1 nix eval --include nixpkgs=$PWD --file . emacs.pkgs.melpaPackages --apply 'pkgSet: map (drv: drv.drvPath) (builtins.filter (p: p.type or null == "derivation") (builtins.attrValues pkgSet))' --no-eval-cache >/dev/null
Time (mean ± σ): 9.126 s ± 0.048 s [User: 6.531 s, System: 0.997 s]
Range (min … max): 9.056 s … 9.186 s 10 runs
With this patch applied:
Benchmark 1: NIXPKGS_ALLOW_BROKEN=1 nix eval --include nixpkgs=$PWD --file . emacs.pkgs.melpaPackages --apply 'pkgSet: map (drv: drv.drvPath) (builtins.filter (p: p.type or null == "derivation") (builtins.attrValues pkgSet))' --no-eval-cache >/dev/null
Time (mean ± σ): 9.124 s ± 0.057 s [User: 6.522 s, System: 1.011 s]
Range (min … max): 9.040 s … 9.220 s 10 runs
[1]: 177c9eddad/pkgs/applications/editors/emacs/elisp-packages/manual-packages/lsp-bridge/default.nix (L93-L108)
144 lines
3.6 KiB
Nix
144 lines
3.6 KiB
Nix
# builder for Emacs packages built for packages.el
|
|
# using MELPA package-build.el
|
|
|
|
{ lib, stdenv, fetchFromGitHub, emacs, texinfo, writeText, gcc }:
|
|
|
|
let
|
|
genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; };
|
|
|
|
packageBuild = stdenv.mkDerivation {
|
|
name = "package-build";
|
|
src = fetchFromGitHub {
|
|
owner = "melpa";
|
|
repo = "package-build";
|
|
rev = "c48aa078c01b4f07b804270c4583a0a58ffea1c0";
|
|
sha256 = "sha256-MzPj375upIiYXdQR+wWXv3A1zMqbSrZlH0taLuxx/1M=";
|
|
};
|
|
|
|
patches = [ ./package-build-dont-use-mtime.patch ];
|
|
|
|
dontConfigure = true;
|
|
dontBuild = true;
|
|
|
|
installPhase = "
|
|
mkdir -p $out
|
|
cp -r * $out
|
|
";
|
|
};
|
|
|
|
in
|
|
|
|
{ /*
|
|
pname: Nix package name without special symbols and without version or
|
|
"emacs-" prefix.
|
|
*/
|
|
pname
|
|
/*
|
|
ename: Original Emacs package name, possibly containing special symbols.
|
|
Default: pname
|
|
*/
|
|
, ename ? pname
|
|
/*
|
|
version: Either a stable version such as "1.2" or an unstable version.
|
|
An unstable version can use either Nix format (preferred) such as
|
|
"1.2-unstable-2024-06-01" or MELPA format such as "20240601.1230".
|
|
*/
|
|
, version
|
|
/*
|
|
commit: Optional package history commit.
|
|
Default: src.rev or "unknown"
|
|
This will be written into the generated package but it is not needed during
|
|
the build process.
|
|
*/
|
|
, commit ? (args.src.rev or "unknown")
|
|
/*
|
|
files: Optional recipe property specifying the files used to build the package.
|
|
If null, do not set it in recipe, keeping the default upstream behaviour.
|
|
Default: null
|
|
*/
|
|
, files ? null
|
|
/*
|
|
recipe: Optional MELPA recipe.
|
|
Default: a minimally functional recipe
|
|
*/
|
|
, recipe ? (writeText "${pname}-recipe" ''
|
|
(${ename} :fetcher git :url ""
|
|
${lib.optionalString (files != null) ":files ${files}"})
|
|
'')
|
|
, meta ? {}
|
|
, ...
|
|
}@args:
|
|
|
|
genericBuild ({
|
|
|
|
elpa2nix = ./elpa2nix.el;
|
|
melpa2nix = ./melpa2nix.el;
|
|
|
|
inherit packageBuild commit ename recipe;
|
|
|
|
melpaVersion =
|
|
let
|
|
parsed = lib.flip builtins.match version
|
|
# match <version>-unstable-YYYY-MM-DD format
|
|
"^.*-unstable-([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})$";
|
|
unstableVersionInNixFormat = parsed != null; # heuristics
|
|
date = builtins.concatStringsSep "" parsed;
|
|
time = "0"; # unstable version in nix format lacks this info
|
|
in
|
|
if unstableVersionInNixFormat
|
|
then date + "." + time
|
|
else version;
|
|
|
|
preUnpack = ''
|
|
mkdir -p "$NIX_BUILD_TOP/recipes"
|
|
if [ -n "$recipe" ]; then
|
|
cp "$recipe" "$NIX_BUILD_TOP/recipes/$ename"
|
|
fi
|
|
|
|
ln -s "$packageBuild" "$NIX_BUILD_TOP/package-build"
|
|
|
|
mkdir -p "$NIX_BUILD_TOP/packages"
|
|
'';
|
|
|
|
postUnpack = ''
|
|
mkdir -p "$NIX_BUILD_TOP/working"
|
|
ln -s "$NIX_BUILD_TOP/$sourceRoot" "$NIX_BUILD_TOP/working/$ename"
|
|
'';
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
|
|
cd "$NIX_BUILD_TOP"
|
|
|
|
emacs --batch -Q \
|
|
-L "$NIX_BUILD_TOP/package-build" \
|
|
-l "$melpa2nix" \
|
|
-f melpa2nix-build-package \
|
|
$ename $melpaVersion $commit
|
|
|
|
runHook postBuild
|
|
'';
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
|
|
archive="$NIX_BUILD_TOP/packages/$ename-$melpaVersion.el"
|
|
if [ ! -f "$archive" ]; then
|
|
archive="$NIX_BUILD_TOP/packages/$ename-$melpaVersion.tar"
|
|
fi
|
|
|
|
emacs --batch -Q \
|
|
-l "$elpa2nix" \
|
|
-f elpa2nix-install-package \
|
|
"$archive" "$out/share/emacs/site-lisp/elpa"
|
|
|
|
runHook postInstall
|
|
'';
|
|
|
|
meta = {
|
|
homepage = args.src.meta.homepage or "https://melpa.org/#/${pname}";
|
|
} // meta;
|
|
}
|
|
|
|
// removeAttrs args [ "meta" ])
|