1{
2 lib,
3 stdenv,
4 symlinkJoin,
5 lndir,
6 formats,
7 runCommand,
8}:
9{
10 buildAnkiAddon = lib.extendMkDerivation {
11 constructDrv = stdenv.mkDerivation;
12 extendDrvArgs =
13 finalAttrs:
14 {
15 pname,
16 version,
17 src,
18 sourceRoot ? "",
19 configurePhase ? ''
20 runHook preConfigure
21 runHook postConfigure
22 '',
23 buildPhase ? ''
24 runHook preBuild
25 runHook postBuild
26 '',
27 dontPatchELF ? true,
28 dontStrip ? true,
29 nativeBuildInputs ? [ ],
30 passthru ? { },
31 meta ? { },
32 # Script run after "user_files" folder is populated.
33 # Used when an add-on needs to process and change "user_files" based
34 # on what the user added to it.
35 processUserFiles ? "",
36 ...
37 }:
38 {
39 inherit
40 version
41 src
42 sourceRoot
43 configurePhase
44 buildPhase
45 dontPatchELF
46 dontStrip
47 nativeBuildInputs
48 ;
49
50 pname = "anki-addon-${pname}";
51
52 installPrefix = "share/anki/addons/${pname}";
53
54 installPhase = ''
55 runHook preInstall
56
57 mkdir -p "$out/$installPrefix"
58 find . -mindepth 1 -maxdepth 1 | xargs -d'\n' mv -t "$out/$installPrefix/"
59
60 runHook postInstall
61 '';
62
63 passthru = {
64 withConfig =
65 {
66 # JSON add-on config. The available options for an add-on are in its
67 # config.json file.
68 # See https://addon-docs.ankiweb.net/addon-config.html#config-json
69 config ? { },
70 # Path to a folder to be merged with the add-on "user_files" folder.
71 # See https://addon-docs.ankiweb.net/addon-config.html#user-files.
72 userFiles ? null,
73 }:
74 let
75 metaConfigFormat = formats.json { };
76 addonMetaConfig = metaConfigFormat.generate "meta.json" { inherit config; };
77 in
78 symlinkJoin {
79 pname = "${finalAttrs.pname}-with-config";
80 inherit (finalAttrs) version meta;
81
82 paths = [
83 finalAttrs.finalPackage
84 ];
85
86 postBuild = ''
87 cd $out/${finalAttrs.installPrefix}
88
89 rm -f meta.json
90 ln -s ${addonMetaConfig} meta.json
91
92 mkdir -p user_files
93 ${
94 if (userFiles != null) then
95 ''
96 ${lndir}/bin/lndir -silent "${userFiles}" user_files
97 ''
98 else
99 ""
100 }
101
102 ${processUserFiles}
103 '';
104 };
105 }
106 // passthru;
107
108 meta = {
109 platforms = lib.platforms.all;
110 }
111 // meta;
112 };
113 };
114
115 buildAnkiAddonsDir =
116 addonPackages:
117 let
118 addonDirs = map (pkg: "${pkg}/share/anki/addons") addonPackages;
119 addons = lib.concatMapStringsSep " " (p: "${p}/*") addonDirs;
120 in
121 runCommand "anki-addons" { } ''
122 mkdir $out
123 [[ '${addons}' ]] || exit 0
124 for addon in ${addons}; do
125 ln -s "$addon" $out/
126 done
127 '';
128}