anvil-editor: init at 0.4
[NixPkgs.git] / pkgs / applications / editors / emacs / build-support / melpa.nix
bloba6e6e7c5d4b1b20e70bfe4e0a8dce5aa5886b46a
1 # builder for Emacs packages built for packages.el
2 # using MELPA package-build.el
4 { lib, stdenv, fetchFromGitHub, emacs, texinfo, writeText }:
6 let
7   genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText; };
8   libBuildHelper = import ./lib-build-helper.nix;
10   packageBuild = stdenv.mkDerivation {
11     name = "package-build";
12     src = fetchFromGitHub {
13       owner = "melpa";
14       repo = "package-build";
15       rev = "d5661f1f1996a893fbcbacb4d290c57acab4fb0e";
16       hash = "sha256-zVhFR2kLLkCKC+esPBbIk3qOa033YND1HF9GiNI4JM8=";
17     };
19     patches = [ ./package-build-dont-use-mtime.patch ];
21     dontConfigure = true;
22     dontBuild = true;
24     installPhase = "
25       mkdir -p $out
26       cp -r * $out
27     ";
28   };
32 libBuildHelper.extendMkDerivation' genericBuild (finalAttrs:
34 { /*
35     pname: Nix package name without special symbols and without version or
36     "emacs-" prefix.
37   */
38   pname
39   /*
40     ename: Original Emacs package name, possibly containing special symbols.
41     Default: pname
42   */
43 , ename ? pname
44   /*
45     version: Either a stable version such as "1.2" or an unstable version.
46     An unstable version can use either Nix format (preferred) such as
47     "1.2-unstable-2024-06-01" or MELPA format such as "20240601.1230".
48   */
49 , version
50   /*
51     commit: Optional package history commit.
52     Default: src.rev or "unknown"
53     This will be written into the generated package but it is not needed during
54     the build process.
55   */
56 , commit ? (finalAttrs.src.rev or "unknown")
57   /*
58     files: Optional recipe property specifying the files used to build the package.
59     If null, do not set it in recipe, keeping the default upstream behaviour.
60     Default: null
61   */
62 , files ? null
63   /*
64     recipe: Optional MELPA recipe.
65     Default: a minimally functional recipe
66     This can be a path of a recipe file, a string of the recipe content or an empty string.
67     The default value is used if it is an empty string.
68   */
69 , recipe ? ""
70 , preUnpack ? ""
71 , postUnpack ? ""
72 , meta ? {}
73 , ...
74 }@args:
78   elpa2nix = args.elpa2nix or ./elpa2nix.el;
79   melpa2nix = args.melpa2nix or ./melpa2nix.el;
81   inherit commit ename files recipe;
83   packageBuild = args.packageBuild or packageBuild;
85   melpaVersion = args.melpaVersion or (
86     let
87       parsed = lib.flip builtins.match version
88         # match <version>-unstable-YYYY-MM-DD format
89         "^.*-unstable-([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})$";
90       unstableVersionInNixFormat = parsed != null; # heuristics
91       date = builtins.concatStringsSep "" parsed;
92       time = "0"; # unstable version in nix format lacks this info
93     in
94     if unstableVersionInNixFormat
95     then date + "." + time
96     else finalAttrs.version);
98   preUnpack = ''
99     mkdir -p "$NIX_BUILD_TOP/recipes"
100     recipeFile="$NIX_BUILD_TOP/recipes/$ename"
101     if [ -r "$recipe" ]; then
102       ln -s "$recipe" "$recipeFile"
103       nixInfoLog "link recipe"
104     elif [ -n "$recipe" ]; then
105       printf "%s" "$recipe" > "$recipeFile"
106       nixInfoLog "write recipe"
107     else
108       cat > "$recipeFile" <<'EOF'
109 (${finalAttrs.ename} :fetcher git :url "" ${lib.optionalString (finalAttrs.files != null) ":files ${finalAttrs.files}"})
111       nixInfoLog "use default recipe"
112     fi
113     nixInfoLog "recipe content:" "$(< $recipeFile)"
114     unset -v recipeFile
116     ln -s "$packageBuild" "$NIX_BUILD_TOP/package-build"
118     mkdir -p "$NIX_BUILD_TOP/packages"
119   '' + preUnpack;
121   postUnpack = ''
122     mkdir -p "$NIX_BUILD_TOP/working"
123     ln -s "$NIX_BUILD_TOP/$sourceRoot" "$NIX_BUILD_TOP/working/$ename"
124   '' + postUnpack;
126   buildPhase = args.buildPhase or ''
127     runHook preBuild
129     # This is modified from stdenv buildPhase. foundMakefile is used in stdenv checkPhase.
130     if [[ ! ( -z "''${makeFlags-}" && -z "''${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ) ]]; then
131       foundMakefile=1
132     fi
134     pushd "$NIX_BUILD_TOP"
136     emacs --batch -Q \
137         -L "$NIX_BUILD_TOP/package-build" \
138         -l "$melpa2nix" \
139         -f melpa2nix-build-package \
140         $ename $melpaVersion $commit
142     popd
144     runHook postBuild
145     '';
147   installPhase = args.installPhase or ''
148     runHook preInstall
150     archive="$NIX_BUILD_TOP/packages/$ename-$melpaVersion.el"
151     if [ ! -f "$archive" ]; then
152         archive="$NIX_BUILD_TOP/packages/$ename-$melpaVersion.tar"
153     fi
155     emacs --batch -Q \
156         -l "$elpa2nix" \
157         -f elpa2nix-install-package \
158         "$archive" "$out/share/emacs/site-lisp/elpa"
160     runHook postInstall
161   '';
163   meta = {
164     homepage = args.src.meta.homepage or "https://melpa.org/#/${pname}";
165   } // meta;