35 rev = "d678e39350a2d243242a69f4e22f5192b04398f2";
37 src = fetchFromGitHub {
41 hash = "sha256-ap8WFDDSGonk5kgXXIsADwAwd7o6Nsy6Wxsa7r1iUIM=";
42 fetchSubmodules = true;
46 lockFile = ./Cargo.lock;
48 "linkcheck-0.4.1" = "sha256-S93J1cDzMlzDjcvz/WABmv8CEC6x78E+f7nzhsN7NkE=";
49 "percent-encoding-iri-2.2.0" = "sha256-kCBeS1PNExyJd4jWfDfctxq6iTdAq69jtxFQgCCQ8kQ=";
52 cargoDeps = rustPlatform.importCargoLock cargoLock;
54 yarnOfflineCache = fetchYarnDeps {
55 yarnLock = "${src}/yarn.lock";
56 hash = "sha256-Dbd7RtE0td7li7oqPPfBmAsbXPM8ed9NTAhM5gytpG8=";
59 anki-build-python = python3.withPackages (ps: with ps; [ mypy-protobuf ]);
61 # anki shells out to git to check its revision, and also to update submodules
62 # We don't actually need the submodules, so we stub that out
63 fakeGit = writeShellScriptBin "git" ''
65 "rev-parse --short=8 HEAD")
66 echo ${builtins.substring 0 8 rev}
68 *"submodule update "*)
72 echo "Unrecognized git: $@"
78 # We don't want to run pip-sync, it does network-io
79 fakePipSync = writeShellScriptBin "pip-sync" ''
83 offlineYarn = writeShellScriptBin "yarn" ''
84 [[ "$1" == "install" ]] && exit 0
85 exec ${yarn}/bin/yarn --offline "$@"
89 name = "anki-pyenv-${version}";
90 paths = with python3.pkgs; [
95 pathsToLink = [ "/bin" ];
98 # https://discourse.nixos.org/t/mkyarnpackage-lockfile-has-incorrect-entry/21586/3
99 anki-nodemodules = stdenv.mkDerivation {
100 pname = "anki-nodemodules";
102 inherit version src yarnOfflineCache;
104 nativeBuildInputs = [
111 export HOME=$NIX_BUILD_TOP
112 yarn config --offline set yarn-offline-mirror $yarnOfflineCache
113 fixup-yarn-lock yarn.lock
114 yarn install --offline --frozen-lockfile --ignore-scripts --no-progress --non-interactive
115 patchShebangs node_modules/
123 python3.pkgs.buildPythonApplication {
124 inherit pname version;
135 ./patches/disable-auto-update.patch
136 ./patches/remove-the-gl-library-workaround.patch
137 ./patches/skip-formatting-python-code.patch
138 # Also remove from anki/sync-server.nix on next update
139 ./patches/Cargo.lock-update-time-for-rust-1.80.patch
142 inherit cargoDeps yarnOfflineCache;
144 nativeBuildInputs = [
154 rustPlatform.cargoSetupHook
155 ] ++ lib.optional stdenv.hostPlatform.isDarwin swift;
160 ] ++ lib.optional stdenv.hostPlatform.isLinux qt6.qtwayland;
162 propagatedBuildInputs =
165 # This rather long list came from running:
166 # grep --no-filename -oE "^[^ =]*" python/{requirements.base.txt,requirements.bundle.txt,requirements.qt6_lin.txt} | \
167 # sort | uniq | grep -v "^#$"
168 # in their repo at the git tag for this version
169 # There's probably a more elegant way, but the above extracted all the
170 # names, without version numbers, of their python dependencies. The hope is
171 # that nixpkgs versions are "close enough"
172 # I then removed the ones the check phase failed on (pythonCatchConflictsPhase)
184 google-api-python-client
216 ++ lib.optionals stdenv.hostPlatform.isDarwin [
221 nativeCheckInputs = with python3.pkgs; [
227 # tests fail with to many open files
228 # TODO: verify if this is still true (I can't, no mac)
229 doCheck = !stdenv.hostPlatform.isDarwin;
232 # these two tests are flaky, see https://github.com/ankitects/anki/issues/3353
233 # Also removed from anki-sync-server when removing this.
234 "--skip=media::check::test::unicode_normalization"
235 "--skip=scheduler::answering::test::state_application"
238 dontUseNinjaInstall = false;
239 dontWrapQtApps = true;
242 # Activate optimizations
245 NODE_BINARY = lib.getExe nodejs;
246 PROTOC_BINARY = lib.getExe protobuf;
247 PYTHON_BINARY = lib.getExe python3;
248 YARN_BINARY = lib.getExe offlineYarn;
252 export RUST_BACKTRACE=1
253 export RUST_LOG=debug
255 mkdir -p out/pylib/anki .git
257 echo ${builtins.substring 0 8 rev} > out/buildhash
261 ln -vsf ${pyEnv} ./out/pyenv
262 rsync --chmod +w -avP ${anki-nodemodules}/ out/node_modules/
263 ln -vsf out/node_modules node_modules
265 export HOME=$NIX_BUILD_TOP
266 yarn config --offline set yarn-offline-mirror $yarnOfflineCache
267 fixup-yarn-lock yarn.lock
269 patchShebangs ./ninja
270 PIP_USER=1 ./ninja build wheels
273 # mimic https://github.com/ankitects/anki/blob/76d8807315fcc2675e7fa44d9ddf3d4608efc487/build/ninja_gen/src/python.rs#L232-L250
276 disabledTestsString =
279 # assumes / is not writeable, somehow fails on nix-portable brwap
283 (lib.map (test: "not ${test}"))
284 (lib.concatStringsSep " and ")
291 HOME=$TMP ANKI_TEST_MODE=1 PYTHONPATH=$PYTHONPATH:$PWD/out/pylib \
292 pytest -p no:cacheprovider pylib/tests -k ${disabledTestsString}
293 HOME=$TMP ANKI_TEST_MODE=1 PYTHONPATH=$PYTHONPATH:$PWD/out/pylib:$PWD/pylib:$PWD/out/qt \
294 pytest -p no:cacheprovider qt/tests -k ${disabledTestsString}
304 install -D -t $out/share/applications qt/bundle/lin/anki.desktop
305 install -D -t $doc/share/doc/anki README* LICENSE*
306 install -D -t $out/share/mime/packages qt/bundle/lin/anki.xml
307 install -D -t $out/share/pixmaps qt/bundle/lin/anki.{png,xpm}
308 installManPage qt/bundle/lin/anki.1
313 "''${qtWrapperArgs[@]}"
314 --prefix PATH ':' "${lame}/bin:${mpv-unwrapped}/bin"
319 # cargoLock is reused in anki-sync-server
321 tests.anki-sync-server = nixosTests.anki-sync-server;
325 description = "Spaced repetition flashcard program";
326 mainProgram = "anki";
328 Anki is a program which makes remembering things easy. Because it is a lot
329 more efficient than traditional study methods, you can either greatly
330 decrease your time spent studying, or greatly increase the amount you learn.
332 Anyone who needs to remember things in their daily life can benefit from
333 Anki. Since it is content-agnostic and supports images, audio, videos and
334 scientific markup (via LaTeX), the possibilities are endless. For example:
335 learning a language, studying for medical and law exams, memorizing
336 people's names and faces, brushing up on geography, mastering long poems,
337 or even practicing guitar chords!
339 homepage = "https://apps.ankiweb.net";
340 license = licenses.agpl3Plus;
341 inherit (mesa.meta) platforms;
342 maintainers = with maintainers; [
346 # Reported to crash at launch on darwin (as of 2.1.65)
347 broken = stdenv.hostPlatform.isDarwin;