nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 makeWrapper,
6 makeDesktopItem,
7 yarn,
8 nodejs,
9 jq,
10 electron_37,
11 element-web,
12 sqlcipher,
13 callPackage,
14 desktopToDarwinBundle,
15 typescript,
16 useKeytar ? true,
17 # command line arguments which are always set
18 commandLineArgs ? "",
19}:
20
21let
22 pinData = import ./element-desktop-pin.nix;
23 inherit (pinData.hashes) desktopSrcHash desktopYarnHash;
24 executableName = "element-desktop";
25 electron = electron_37;
26 keytar = callPackage ./keytar {
27 inherit electron;
28 };
29 seshat = callPackage ./seshat { };
30in
31stdenv.mkDerivation (
32 finalAttrs:
33 builtins.removeAttrs pinData [ "hashes" ]
34 // {
35 pname = "element-desktop";
36 name = "${finalAttrs.pname}-${finalAttrs.version}";
37 src = fetchFromGitHub {
38 owner = "element-hq";
39 repo = "element-desktop";
40 rev = "v${finalAttrs.version}";
41 hash = desktopSrcHash;
42 };
43
44 # TODO: fetchYarnDeps currently does not deal properly with a dependency
45 # declared as a pin to a commit in a specific git repository.
46 # While it does download everything correctly, `yarn install --offline`
47 # always wants to `git ls-remote` to the repository, ignoring the local
48 # cached tarball.
49 offlineCache = callPackage ./yarn.nix {
50 inherit (finalAttrs) version src;
51 hash = desktopYarnHash;
52 };
53
54 nativeBuildInputs = [
55 nodejs
56 makeWrapper
57 jq
58 yarn
59 typescript
60 ]
61 ++ lib.optionals stdenv.hostPlatform.isDarwin [ desktopToDarwinBundle ];
62
63 inherit seshat;
64
65 # Only affects unused scripts in $out/share/element/electron/scripts. Also
66 # breaks because there are some `node`-scripts with a `npx`-shebang and
67 # this shouldn't be in the closure just for unused scripts.
68 dontPatchShebangs = true;
69
70 configurePhase = ''
71 runHook preConfigure
72
73 mkdir -p node_modules/
74 cp -r $offlineCache/node_modules/* node_modules/
75 substituteInPlace package.json --replace-fail "tsx " "node node_modules/tsx/dist/cli.mjs "
76
77 runHook postConfigure
78 '';
79
80 buildPhase = ''
81 runHook preBuild
82
83 yarn --offline run build:ts
84 node node_modules/matrix-web-i18n/scripts/gen-i18n.js
85 yarn --offline run i18n:sort
86 yarn --offline run build:res
87
88 chmod -R a+w node_modules/keytar-forked
89 rm -rf node_modules/matrix-seshat node_modules/keytar-forked
90 ${lib.optionalString useKeytar "ln -s ${keytar} node_modules/keytar-forked"}
91 ln -s $seshat node_modules/matrix-seshat
92
93 runHook postBuild
94 '';
95
96 installPhase = ''
97 runHook preInstall
98
99 # resources
100 mkdir -p "$out/share/element"
101 ln -s '${element-web}' "$out/share/element/webapp"
102 cp -r '.' "$out/share/element/electron"
103 cp -r './res/img' "$out/share/element"
104 chmod -R "a+w" "$out/share/element/electron/node_modules"
105 rm -rf "$out/share/element/electron/node_modules"
106 cp -r './node_modules' "$out/share/element/electron"
107 cp $out/share/element/electron/lib/i18n/strings/en_EN.json $out/share/element/electron/lib/i18n/strings/en-us.json
108 ln -s $out/share/element/electron/lib/i18n/strings/en{-us,}.json
109
110 # icons
111 for icon in $out/share/element/electron/build/icons/*.png; do
112 mkdir -p "$out/share/icons/hicolor/$(basename $icon .png)/apps"
113 ln -s "$icon" "$out/share/icons/hicolor/$(basename $icon .png)/apps/element.png"
114 done
115
116 # desktop item
117 mkdir -p "$out/share"
118 ln -s "${finalAttrs.desktopItem}/share/applications" "$out/share/applications"
119
120 # executable wrapper
121 # LD_PRELOAD workaround for sqlcipher not found: https://github.com/matrix-org/seshat/issues/102
122 makeWrapper '${electron}/bin/electron' "$out/bin/${executableName}" \
123 --set LD_PRELOAD ${sqlcipher}/lib/libsqlcipher.so \
124 --add-flags "$out/share/element/electron" \
125 --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \
126 --add-flags ${lib.escapeShellArg commandLineArgs}
127
128 runHook postInstall
129 '';
130
131 # The desktop item properties should be kept in sync with data from upstream:
132 # https://github.com/element-hq/element-desktop/blob/develop/package.json
133 desktopItem = makeDesktopItem {
134 name = "element-desktop";
135 exec = "${executableName} %u";
136 icon = "element";
137 desktopName = "Element";
138 genericName = "Matrix Client";
139 comment = finalAttrs.meta.description;
140 categories = [
141 "Network"
142 "InstantMessaging"
143 "Chat"
144 ];
145 startupWMClass = "Element";
146 mimeTypes = [
147 "x-scheme-handler/element"
148 "x-scheme-handler/io.element.desktop"
149 ];
150 };
151
152 postFixup = lib.optionalString stdenv.hostPlatform.isDarwin ''
153 cp build/icon.icns $out/Applications/Element.app/Contents/Resources/element.icns
154 '';
155
156 passthru = {
157 # run with: nix-shell ./maintainers/scripts/update.nix --argstr package element-desktop
158 updateScript = ./update.sh;
159
160 # TL;DR: keytar is optional while seshat isn't.
161 #
162 # This prevents building keytar when `useKeytar` is set to `false`, because
163 # if libsecret is unavailable (e.g. set to `null` or fails to build), then
164 # this package wouldn't even considered for building because
165 # "one of the dependencies failed to build",
166 # although the dependency wouldn't even be used.
167 #
168 # It needs to be `passthru` anyways because other packages do depend on it.
169 inherit keytar;
170 };
171
172 meta = with lib; {
173 description = "Feature-rich client for Matrix.org";
174 homepage = "https://element.io/";
175 changelog = "https://github.com/element-hq/element-desktop/blob/v${finalAttrs.version}/CHANGELOG.md";
176 license = licenses.asl20;
177 teams = [ teams.matrix ];
178 platforms = electron.meta.platforms ++ lib.platforms.darwin;
179 mainProgram = "element-desktop";
180 };
181 }
182)