Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 308 lines 8.0 kB view raw
1{ 2 lib, 3 stdenv, 4 5 writableTmpDirAsHomeHook, 6 buildEnv, 7 cargo, 8 fetchFromGitHub, 9 installShellFiles, 10 lame, 11 mpv-unwrapped, 12 ninja, 13 callPackage, 14 nixosTests, 15 nodejs, 16 jq, 17 protobuf, 18 python3, 19 qt6, 20 rsync, 21 rustPlatform, 22 writeShellScriptBin, 23 yarn, 24 yarn-berry_4, 25 26 swift, 27 28 mesa, 29}: 30 31let 32 yarn-berry = yarn-berry_4; 33 34 pname = "anki"; 35 version = "25.02.5"; 36 rev = "29192d156ae60d6ce35e80ccf815a8331c9db724"; 37 38 srcHash = "sha256-lx3tK57gcQpwmiqUzO6iU7sE31LPFp6s80prYaB2jHE="; 39 cargoHash = "sha256-BPCfeUiZ23FdZaF+zDUrRZchauNZWQ3gSO+Uo9WRPes="; 40 yarnHash = "sha256-3G+9N3xOzog3XDCKDQJCY/6CB3i6oXixRgxEyv7OG3U="; 41 42 src = fetchFromGitHub { 43 owner = "ankitects"; 44 repo = "anki"; 45 rev = version; 46 hash = srcHash; 47 fetchSubmodules = true; 48 }; 49 50 cargoDeps = rustPlatform.fetchCargoVendor { 51 inherit pname version src; 52 hash = cargoHash; 53 }; 54 55 # a wrapper for yarn to skip 'install' 56 # We do this because we need to patchShebangs after install, so we do it 57 # ourselves beforehand. 58 # We also, confusingly, have to use yarn-berry to handle the lockfile (anki's 59 # lockfile is too new for yarn), but have to use 'yarn' here, because anki's 60 # build system uses yarn-1 style flags and such. 61 # I think what's going on here is that yarn-1 in anki's normal build system 62 # ends up noticing the yarn-file is too new and shelling out to yarn-berry 63 # itself. 64 noInstallYarn = writeShellScriptBin "yarn" '' 65 [[ "$1" == "install" ]] && exit 0 66 exec ${yarn}/bin/yarn "$@" 67 ''; 68 69 anki-build-python = python3.withPackages (ps: with ps; [ mypy-protobuf ]); 70 71 pyEnv = buildEnv { 72 name = "anki-pyenv-${version}"; 73 paths = with python3.pkgs; [ 74 pip 75 anki-build-python 76 ]; 77 pathsToLink = [ "/bin" ]; 78 }; 79in 80python3.pkgs.buildPythonApplication rec { 81 format = "setuptools"; 82 inherit pname version; 83 84 outputs = [ 85 "out" 86 "doc" 87 "man" 88 ]; 89 90 inherit src; 91 92 patches = [ 93 ./patches/disable-auto-update.patch 94 ./patches/remove-the-gl-library-workaround.patch 95 ./patches/skip-formatting-python-code.patch 96 # Used in with-addons.nix 97 ./patches/allow-setting-addons-folder.patch 98 ]; 99 100 inherit cargoDeps; 101 102 missingHashes = ./missing-hashes.json; 103 yarnOfflineCache = yarn-berry.fetchYarnBerryDeps { 104 inherit missingHashes; 105 yarnLock = "${src}/yarn.lock"; 106 hash = yarnHash; 107 }; 108 109 nativeBuildInputs = [ 110 cargo 111 installShellFiles 112 jq 113 ninja 114 nodejs 115 qt6.wrapQtAppsHook 116 rsync 117 rustPlatform.cargoSetupHook 118 writableTmpDirAsHomeHook 119 yarn-berry_4.yarnBerryConfigHook 120 ] 121 ++ lib.optional stdenv.hostPlatform.isDarwin swift; 122 123 buildInputs = [ 124 qt6.qtbase 125 qt6.qtsvg 126 ] 127 ++ lib.optional stdenv.hostPlatform.isLinux qt6.qtwayland; 128 129 propagatedBuildInputs = with python3.pkgs; [ 130 # This rather long list came from running: 131 # grep --no-filename -oE "^[^ =]*" python/{requirements.base.txt,requirements.bundle.txt,requirements.qt6_lin.txt} | \ 132 # sort | uniq | grep -v "^#$" 133 # in their repo at the git tag for this version 134 # There's probably a more elegant way, but the above extracted all the 135 # names, without version numbers, of their python dependencies. The hope is 136 # that nixpkgs versions are "close enough" 137 # I then removed the ones the check phase failed on (pythonCatchConflictsPhase) 138 attrs 139 beautifulsoup4 140 blinker 141 build 142 certifi 143 charset-normalizer 144 click 145 colorama 146 decorator 147 flask 148 flask-cors 149 google-api-python-client 150 idna 151 importlib-metadata 152 itsdangerous 153 jinja2 154 jsonschema 155 markdown 156 markupsafe 157 orjson 158 packaging 159 pip 160 pip-system-certs 161 pip-tools 162 protobuf 163 pyproject-hooks 164 pyqt6 165 pyqt6-sip 166 pyqt6-webengine 167 pyrsistent 168 pysocks 169 requests 170 send2trash 171 setuptools 172 soupsieve 173 tomli 174 urllib3 175 waitress 176 werkzeug 177 wheel 178 wrapt 179 zipp 180 ]; 181 182 nativeCheckInputs = with python3.pkgs; [ 183 pytest 184 mock 185 astroid 186 ]; 187 188 # tests fail with too many open files 189 # TODO: verify if this is still true (I can't, no mac) 190 doCheck = !stdenv.hostPlatform.isDarwin; 191 192 checkFlags = [ 193 # this test is flaky, see https://github.com/ankitects/anki/issues/3619 194 # also remove from anki-sync-server when removing this 195 "--skip=deckconfig::update::test::should_keep_at_least_one_remaining_relearning_step" 196 ]; 197 198 dontUseNinjaInstall = false; 199 dontWrapQtApps = true; 200 201 env = { 202 # Activate optimizations 203 RELEASE = true; 204 205 # https://github.com/ankitects/anki/blob/24.11/docs/linux.md#packaging-considerations 206 OFFLINE_BUILD = "1"; 207 NODE_BINARY = lib.getExe nodejs; 208 PROTOC_BINARY = lib.getExe protobuf; 209 PYTHON_BINARY = lib.getExe python3; 210 }; 211 212 buildPhase = '' 213 export RUST_BACKTRACE=1 214 export RUST_LOG=debug 215 216 mkdir -p out/pylib/anki .git 217 218 echo ${builtins.substring 0 8 rev} > out/buildhash 219 220 ln -vsf ${pyEnv} ./out/pyenv 221 222 mv node_modules out 223 224 # Run everything else 225 patchShebangs ./ninja 226 227 # Necessary for yarn to not complain about 'corepack' 228 jq 'del(.packageManager)' package.json > package.json.tmp && mv package.json.tmp package.json 229 YARN_BINARY="${lib.getExe noInstallYarn}" PIP_USER=1 ./ninja build wheels 230 ''; 231 232 # mimic https://github.com/ankitects/anki/blob/76d8807315fcc2675e7fa44d9ddf3d4608efc487/build/ninja_gen/src/python.rs#L232-L250 233 checkPhase = 234 let 235 disabledTestsString = 236 lib.pipe 237 [ 238 # assumes / is not writeable, somehow fails on nix-portable brwap 239 "test_create_open" 240 ] 241 [ 242 (lib.map (test: "not ${test}")) 243 (lib.concatStringsSep " and ") 244 lib.escapeShellArg 245 ]; 246 247 in 248 '' 249 runHook preCheck 250 HOME=$TMP ANKI_TEST_MODE=1 PYTHONPATH=$PYTHONPATH:$PWD/out/pylib \ 251 pytest -p no:cacheprovider pylib/tests -k ${disabledTestsString} 252 HOME=$TMP ANKI_TEST_MODE=1 PYTHONPATH=$PYTHONPATH:$PWD/out/pylib:$PWD/pylib:$PWD/out/qt \ 253 pytest -p no:cacheprovider qt/tests -k ${disabledTestsString} 254 runHook postCheck 255 ''; 256 257 preInstall = '' 258 mkdir dist 259 mv out/wheels/* dist 260 ''; 261 262 postInstall = '' 263 install -D -t $out/share/applications qt/bundle/lin/anki.desktop 264 install -D -t $doc/share/doc/anki README* LICENSE* 265 install -D -t $out/share/mime/packages qt/bundle/lin/anki.xml 266 install -D -t $out/share/pixmaps qt/bundle/lin/anki.{png,xpm} 267 installManPage qt/bundle/lin/anki.1 268 ''; 269 270 preFixup = '' 271 makeWrapperArgs+=( 272 "''${qtWrapperArgs[@]}" 273 --prefix PATH ':' "${lame}/bin:${mpv-unwrapped}/bin" 274 ) 275 ''; 276 277 passthru = { 278 withAddons = ankiAddons: callPackage ./with-addons.nix { inherit ankiAddons; }; 279 tests.anki-sync-server = nixosTests.anki-sync-server; 280 }; 281 282 meta = with lib; { 283 description = "Spaced repetition flashcard program"; 284 mainProgram = "anki"; 285 longDescription = '' 286 Anki is a program which makes remembering things easy. Because it is a lot 287 more efficient than traditional study methods, you can either greatly 288 decrease your time spent studying, or greatly increase the amount you learn. 289 290 Anyone who needs to remember things in their daily life can benefit from 291 Anki. Since it is content-agnostic and supports images, audio, videos and 292 scientific markup (via LaTeX), the possibilities are endless. For example: 293 learning a language, studying for medical and law exams, memorizing 294 people's names and faces, brushing up on geography, mastering long poems, 295 or even practicing guitar chords! 296 ''; 297 homepage = "https://apps.ankiweb.net"; 298 license = licenses.agpl3Plus; 299 inherit (mesa.meta) platforms; 300 maintainers = with maintainers; [ 301 euank 302 junestepp 303 oxij 304 ]; 305 # Reported to crash at launch on darwin (as of 2.1.65) 306 broken = stdenv.hostPlatform.isDarwin; 307 }; 308}