diff --git a/app-misc/anki/Manifest b/app-misc/anki/Manifest index baeb3f2a49b83..10360697336a2 100644 --- a/app-misc/anki/Manifest +++ b/app-misc/anki/Manifest @@ -10,7 +10,12 @@ DIST android-tzdata-0.1.1.crate 7674 BLAKE2B 4385a4875aadaacd5284a9ca7d1bf8a7bf1 DIST android_system_properties-0.1.5.crate 5243 BLAKE2B 86f68ec3bdabf8c6ec47881d794970f08a9eefc7417fc8a2bf4fe9faf9bdd2a2024a94adb0cbf96673409f5fbbd4d0111a1ac371339e7a90a277b6cd5003524e SHA512 b09f51339f9772c0e2e4241b36cf51573c6b96b19ffc1fbbc94b1c1d1d2fdfe8eac3134af54174a675ab05d18ef4f6bcb2c7fcc20114bbeef6e17e3692202191 DIST anes-0.1.6.crate 23857 BLAKE2B 9ef464a964709b408c7d7846b9b1e54e52d6ae8f21f22ccfe509ef7197d4694f439084dbdb01fdf88829d181965ea9d1452253789a46fdf6d0520e3413c50d61 SHA512 f9dfaaca9ca327881ec30efaf24e208daae668b1e9d6963c8b0ca9f9fd13be777c793076a87980429f0dfa4db28ef5331ce6652a76da4d5a87485b23fc2fde29 DIST anki-24.11.gh.tar.gz 2422141 BLAKE2B 1892e09d6154e5caf8f66a67e6289ea169afecb14f0f9c772b431d8d152e1bc1e98ebbd39c67718bae1aa1e079531e8ccd76e5fc7969fec7e2e06abb83a213d1 SHA512 b3ca07e1fac4367ee2ec45911d6c4ba51cfe5a004d393ce1bdcaf677ab11dcf96e926108569f929aaf70326351b224042efeccfd98dd4533e1acd6cc60945690 +DIST anki-25.02-crates.tar.xz 57556076 BLAKE2B 0e462ffb783c1f0b53b351731a533e9960c4a99112cbbea6295503fe67815dc98702c6e3f66ba4804b6b1490a28b5ef6194579afee07c78e1685b5dcd8b9f260 SHA512 e7aa3051e6d8284318b8391923005a8327fd5cd67737a63625fde457ca9f8a1755e84e4e16cac6e8214e38bff12c04c52e77ecd2915932d258ace5d345a06e8f +DIST anki-25.02-node_modules.tar.xz 64214728 BLAKE2B 544741219f34785f11410db34ebedf15ef8abcf59bcee3cc8ebe847ee260901d70a601fbf681c3d48bd1cc1819ed6198a9e6092e504baca5c1be007cb4325127 SHA512 d144e7c7e4431220eab9fdf55312aa5eb56f53990472add261273a5f7377ee6b813e5ca64ae8782763c6ef1eb550c7e034eecfc3c5656fa13366761d46dc328c +DIST anki-25.02.gh.tar.gz 2428530 BLAKE2B b9318b453b2b706b44ae42f43f62b84070cde45a3d5ee053b7836dc408731cf5953007a907731fd18d06ed8a3372c32b57896b997c17a8db0d7e361202868a92 SHA512 57806830936e73b0d785075616b71f7b471f49aff2bde589f790b1c8f48c75477423e42eee4761c3001fac12c0412ec011f2661ea3e94813040631ef5fafddfc +DIST anki-core-i18n-0fe0162f4a18e8ef2fbac1d9a33af8e38cf7260e.gh.tar.gz 1521578 BLAKE2B 101505d871df70316222db08f2bc85fdd00be81320600c64c76bb51565a88c13fa6fdd9e059ed404931f2dc97611cf2a954650d10d6556cd181427dbffc4f1a6 SHA512 c72eaea9e0f350d092a44f7623a7cfdcb74ff99a97ca4b53c51b1b26af387c9c6cd64bfca3dc4577c14c3ee4040b8ce1a7a50f2e209b0fa47c5297f97c92a910 DIST anki-core-i18n-e1545f7f0ddeb617eeb1ca86e82862e552843578.gh.tar.gz 1455590 BLAKE2B 5db3638bd39db7a0703026d68b8325ba9158715598fc0bdb9f039080ba0695026b6d57f61eb71d2f3f485f19b19d4a1e29d90c27a111494898037dc29900f0e5 SHA512 aeb24c9f39ccbaeaf524b343432f4748a6297cf04e3ad6673a7b6e090e6363949e3d26dbc1695551098fa997fc0dcbf63aca878ceac7d04683a75dc384f3fba6 +DIST anki-desktop-ftl-17216b03db7249600542e388bd4ea124478400e5.gh.tar.gz 235720 BLAKE2B 0e1a454dbfa5f0f8750000c86b1468c7cfde99e53e6e7683820f5523963c4187e76ef40c4be4c2ef7037cc269f258fe3270ba99006912fb2844ba6cc18dc91d3 SHA512 6d91607c6b0805e6dfce8a93dbf46ac945e9b1631aa054cb98e513d7a6da64d905035b8da8ea5d10c0d700a0aa96b056748d956342fe4ddf7232f7f7540ee88a DIST anki-desktop-ftl-e0f9724f75f6248f4e74558b25c3182d4f348bce.gh.tar.gz 234275 BLAKE2B e41ed5cfab4fc034705998460599fbe0c316f103ceb63090fce8208b2827f5451e483f92086906e0278a200b865d3698b6ad3f7051119da930b0215e35fc9598 SHA512 e6bc5a8a6832a8dfd5d43684a196f340623402c77d071809aa51c2ac894f92f599d53f87b435fc009c684e28b5a5ab8ba4fbe6ca01f2576f4cb5fc773cb14ffd DIST anki-node_modules-67e7bf166027c4e9e0c5bb7fd778d38f44038512.tar.xz 78193296 BLAKE2B 238843c11453aaea533afa60ebde7c8028ef833f12e3ff9257a264d33977f62f7d0ab7ab0101f3baec302b5b3014ce9ad1e0d431476ee9d7e833720efc189e75 SHA512 aca609f1ee010968ad8653d33e2d12f95d3e6280c71952ba8e25cdf4173273c68ed7403cbb9009ea66418266f8775571c8b4b653f992e770a1a0776a0393a7ed DIST anstream-0.6.15.crate 29231 BLAKE2B cc4cf0f381c210fecc20b5796fe872b533419e5f957021b0c3be3cdc23fb84ce029fbef6f9b6f174a76ad713c07f0811145a70572de7c24cfab060fdd990f49a SHA512 1cb01a0293b4c9bcc010909707e71c464416d3ec6fc9789060b7aa9fe4cc04424fefa8013cc8765ccdae6dfd9a1c50a11f7b30b39a32c4aeaf525f28167ddb92 diff --git a/app-misc/anki/anki-25.02.ebuild b/app-misc/anki/anki-25.02.ebuild new file mode 100644 index 0000000000000..731449d3aec77 --- /dev/null +++ b/app-misc/anki/anki-25.02.ebuild @@ -0,0 +1,312 @@ +# Copyright 2022-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DISTUTILS_EXT=1 +DISTUTILS_OPTIONAL=1 +DISTUTILS_SINGLE_IMPL=1 +DISTUTILS_USE_PEP517=no +PYTHON_COMPAT=( python3_{11..13} ) + +declare -A GIT_CRATES=( + [linkcheck]='https://github.com/ankitects/linkcheck;184b2ca50ed39ca43da13f0b830a463861adb9ca;linkcheck-%commit%' + [percent-encoding-iri]='https://github.com/ankitects/rust-url;bb930b8d089f4d30d7d19c12e54e66191de47b88;rust-url-%commit%/percent_encoding' +) +RUST_MIN_VER="1.82.0" + +inherit cargo desktop distutils-r1 eapi9-ver multiprocessing ninja-utils \ + optfeature readme.gentoo-r1 toolchain-funcs xdg + +DESCRIPTION="A spaced-repetition memory training program (flash cards)" +HOMEPAGE="https://apps.ankiweb.net/" + +declare -A COMMITS=( + [anki]="038d85b1d9e1896e93a3e4a26f600c79ddc33611" + [ftl-core]="0fe0162f4a18e8ef2fbac1d9a33af8e38cf7260e" + [ftl-desktop]="17216b03db7249600542e388bd4ea124478400e5" +) +SRC_URI="${CARGO_CRATE_URIS} + https://github.com/ankitects/anki/archive/refs/tags/${PV}.tar.gz -> ${P}.gh.tar.gz + https://github.com/ankitects/anki-core-i18n/archive/${COMMITS[ftl-core]}.tar.gz + -> anki-core-i18n-${COMMITS[ftl-core]}.gh.tar.gz + https://github.com/ankitects/anki-desktop-ftl/archive/${COMMITS[ftl-desktop]}.tar.gz + -> anki-desktop-ftl-${COMMITS[ftl-desktop]}.gh.tar.gz + https://github.com/gentoo-crate-dist/anki/releases/download/${PV}/${P}-crates.tar.xz + gui? ( + https://git.sr.ht/~antecrescent/gentoo-files/blob/main/app-misc/anki/${P}-node_modules.tar.xz + ) +" +# How to get an up-to-date summary of runtime JS libs' licenses: +# ./node_modules/.bin/license-checker-rseidelsohn --production --excludePackages anki --summary +LICENSE="AGPL-3+ BSD public-domain gui? ( 0BSD CC-BY-4.0 GPL-3+ )" +# Dependent crate licenses +LICENSE+=" + Apache-2.0 Apache-2.0-with-LLVM-exceptions BSD-2 CC0-1.0 ISC MIT + MPL-2.0 Unicode-3.0 Unicode-DFS-2016 Unlicense ZLIB +" +# Manually added crate licenses +LICENSE+=" openssl" +SLOT="0" +KEYWORDS="~amd64 ~x86" + +IUSE="+gui" +REQUIRED_USE="gui? ( ${PYTHON_REQUIRED_USE} )" +RESTRICT="!gui? ( test ) !test? ( test )" + +# Dependencies: +# Python: python/requirements.{anki,aqt}.in +# If ENABLE_QT5_COMPAT is set at runtime +# additionally depend on PyQt6[dbus,printsupport]. +# Qt: qt/{aqt/{sound.py,qt/*.py},tools/build_ui.py} +# app-misc/certificates: The rust backend library is built against +# rustls-native-certs to use the native certificate store. +# No ${PYTHON_DEPS} in DEPEND despite external module because it doesn't link +# against libpython + +DEPEND=" + >=app-arch/zstd-1.5.5:= + dev-db/sqlite:3 +" +GUI_RDEPEND=" + ${PYTHON_DEPS} + dev-qt/qtsvg:6 + $(python_gen_cond_dep ' + dev-python/beautifulsoup4[${PYTHON_USEDEP}] + dev-python/distro[${PYTHON_USEDEP}] + dev-python/decorator[${PYTHON_USEDEP}] + dev-python/flask[${PYTHON_USEDEP}] + dev-python/flask-cors[${PYTHON_USEDEP}] + dev-python/jsonschema[${PYTHON_USEDEP}] + dev-python/markdown[${PYTHON_USEDEP}] + dev-python/protobuf[${PYTHON_USEDEP}] + >=dev-python/pyqt6-6.6.1[gui,network,opengl,quick,webchannel,widgets,${PYTHON_USEDEP}] + >=dev-python/pyqt6-sip-13.6.0[${PYTHON_USEDEP}] + >=dev-python/pyqt6-webengine-6.6.0[widgets,${PYTHON_USEDEP}] + dev-python/requests[${PYTHON_USEDEP}] + dev-python/send2trash[${PYTHON_USEDEP}] + dev-python/waitress[${PYTHON_USEDEP}] + ') +" +RDEPEND=" + ${DEPEND} + app-misc/ca-certificates + gui? ( ${GUI_RDEPEND} ) +" + +BDEPEND=" + >=app-arch/zstd-1.5.5:= + dev-libs/protobuf[protoc(+)] + virtual/pkgconfig + gui? ( + ${PYTHON_DEPS} + app-alternatives/ninja + >=net-libs/nodejs-20.12.1 + sys-apps/yarn + $(python_gen_cond_dep ' + dev-python/pyqt6[${PYTHON_USEDEP}] + dev-python/wheel[${PYTHON_USEDEP}] + ') + ) + test? ( + ${RDEPEND} + app-text/dvipng + app-text/texlive + dev-libs/openssl + dev-util/cargo-nextest + $(python_gen_cond_dep 'dev-python/mock[${PYTHON_USEDEP}]') + ) +" + +distutils_enable_sphinx python/sphinx \ + dev-python/sphinx-autoapi \ + dev-python/sphinx-rtd-theme + +distutils_enable_tests pytest + +PATCHES=( + "${FILESDIR}"/24.06.3/remove-yarn.patch + "${FILESDIR}"/24.04.1/remove-mypy-protobuf.patch + "${FILESDIR}"/24.04.1/revert-cert-store-hack.patch + "${FILESDIR}"/23.12.1/ninja-rules-for-cargo.patch +) + +QA_FLAGS_IGNORED="usr/bin/anki-sync-server + usr/lib/python.*/site-packages/anki/_rsbridge.so" + +pkg_setup() { + export PROTOC_BINARY="${BROOT}"/usr/bin/protoc + export LIBSQLITE3_SYS_USE_PKG_CONFIG=1 + export ZSTD_SYS_USE_PKG_CONFIG=1 + rust_pkg_setup + use gui && python-single-r1_pkg_setup +} + +python_prepare_all() { + mv "${WORKDIR}"/node_modules out || die + + # Expected files and directories + mkdir .git out/env || die + mkdir -p out/pyenv/bin || die + ln -s "${PYTHON}" out/pyenv/bin/python || die + + if use doc; then + sed "/^REPO_ROOT/s|=.*|= \"${S}\"|" -i python/sphinx/conf.py || die + fi + + # Unpin Yarn + sed -e '/"type": "module"/s/,//' \ + -e '/packageManager/d' -i package.json || die + + # Not running the black formatter on generated files saves a dependency + sed '/subprocess/d' -i pylib/tools/hookslib.py || die + + # Fix hardcoded runner location + export CARGO_TARGET_DIR="${S}"/out/rust + cbuild_dir="$(CHOST=${CBUILD:-${CHOST}} cargo_target_dir)" + sed "s,rust/release,${cbuild_dir##*out/}," \ + -i build/ninja_gen/src/render.rs || die + # Separate src_configure from runner build + sed '/ConfigureBuild/d' -i build/ninja_gen/src/build.rs || die + distutils-r1_python_prepare_all +} + +src_prepare() { + default + rm -r ftl/{core,qt}-repo || die + ln -s "${WORKDIR}"/anki-core-i18n-${COMMITS[ftl-core]} ftl/core-repo || die + ln -s "${WORKDIR}"/anki-desktop-ftl-${COMMITS[ftl-desktop]} ftl/qt-repo || die + + mkdir out || die + echo -e "${COMMITS[anki]:0:8}" > out/buildhash || die + + # None of our ninja implementations are n2 + sed 's/which::which("n2").*/false,/' -i build/ninja_gen/src/build.rs || die + + use gui && distutils-r1_src_prepare +} + +_cbuild_cargo_build() { + CHOST=${CBUILD:-${CHOST}} cargo_src_compile "${@}" +} + +python_configure_all() { + tc-env_build _cbuild_cargo_build -p configure + + local -x NODE_BINARY="${BROOT}"/usr/bin/node \ + YARN_BINARY="${BROOT}"/usr/bin/yarn \ + OFFLINE_BUILD=1 + if ! use debug; then + if tc-is-lto; then + local -x RELEASE=2 + else + local -x RELEASE=1 + fi + fi + cargo_env "${cbuild_dir}"/configure || die + unset cbuild_dir +} + +src_configure() { + cargo_gen_config + cargo_src_configure + use gui && distutils-r1_src_configure +} + +python_compile() { + tc-env_build _cbuild_cargo_build -p runner + cargo_env eninja -f out/build.ninja wheels + local w + for w in out/wheels/*.whl; do + distutils_wheel_install "${BUILD_DIR}"/install ${w} + done +} + +src_compile() { + if use gui; then + distutils-r1_src_compile + else + cargo_src_compile -p anki-sync-server + fi +} + +python_test() { + epytest qt + epytest pylib +} + +python_test_all() { + local nextest_opts=( + cargo-verbose + failure-output=immediate + status-level=all + test-threads=$(get_makeopts_jobs) + ) + if [[ ! ${CARGO_TERM_COLOR} ]]; then + [[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && nextest_opts+=( color=never ) + fi + nextest_opts=( ${nextest_opts[@]/#/--} ) + cargo_env cargo nextest run ${nextest_opts[@]} || die + + eninja -f out/build.ninja check_vitest +} + +src_test() { + local -x ANKI_TEST_MODE=1 + distutils-r1_src_test +} + +python_install_all() { + local DOC_CONTENTS="Users with add-ons that still rely on Anki's Qt5 GUI + can temporarily set the environment variable ENABLE_QT5_COMPAT to 1 to have + Anki install the previous compatibility code. This option has additional + runtime dependencies. Please take a look at this package's optional runtime + features for a complete listing. + \n\nENABLE_QT5_COMPAT may be removed in the future, so this is not a + long-term solution. + \n\nAnki's user manual is located online at https://docs.ankiweb.net/ + \nAnki's add-on developer manual is located online at + https://addon-docs.ankiweb.net/" + + readme.gentoo_create_doc + pushd qt/bundle/lin > /dev/null || die + doman anki.1 + doicon anki.{png,xpm} + domenu anki.desktop + insinto /usr/share/mime/packages + doins anki.xml + popd || die + python_newscript - anki <<-EOF + #!${EPREFIX}/usr/bin/python + import sys + from aqt import run + sys.exit(run()) + EOF + distutils-r1_python_install_all +} + +src_install() { + if use gui; then + distutils-r1_src_install + else + cargo_src_install --path rslib/sync + fi +} + +pkg_postinst() { + ver_replacing -lt 24.06.3-r1 && local FORCE_PRINT_ELOG=1 + readme.gentoo_print_elog + if use gui; then + xdg_pkg_postinst + optfeature "LaTeX in cards" "app-text/texlive[extra] app-text/dvipng" + optfeature "sound support" media-video/mpv media-video/mplayer + optfeature "recording support" "media-sound/lame[frontend] dev-python/pyqt6[multimedia]" + optfeature "faster database operations" dev-python/orjson + optfeature "compatibility with Qt5-dependent add-ons" dev-python/pyqt6[dbus,printsupport] + optfeature "Vulkan driver" "media-libs/vulkan-loader dev-qt/qtbase:6[vulkan] + dev-qt/qtdeclarative:6[vulkan] dev-qt/qtwebengine:6[vulkan]" + + einfo "You can customize the LaTeX header for your cards to fit your needs:" + einfo "Notes > Manage Note Types > [select a note type] > Options" + fi +}