/* ** To customize the enabled beets plugins, use the pluginOverrides input to the ** derivation. ** Examples: ** ** Disabling a builtin plugin: ** python3.pkgs.beets.override { ** pluginOverrides = { ** beatport.enable = false; ** }; ** } ** ** Enabling an external plugin: ** python3.pkgs.beets.override { ** pluginOverrides = { ** alternatives = { ** enable = true; ** propagatedBuildInputs = [ beets-alternatives ]; ** }; ** }; ** } */ { lib, stdenv, buildPythonPackage, fetchFromGitHub, beets, # build-system poetry-core, poetry-dynamic-versioning, # dependencies confuse, gst-python, jellyfish, mediafile, munkres, musicbrainzngs, platformdirs, pyyaml, unidecode, reflink, typing-extensions, lap, # native gobject-introspection, sphinxHook, sphinx-design, sphinx-copybutton, pydata-sphinx-theme, # buildInputs gst_all_1, # plugin deps aacgain, beautifulsoup4, chromaprint, discogs-client, ffmpeg, flac, flask, flask-cors, imagemagick, keyfinder-cli, langdetect, librosa, mp3gain, mp3val, mpd2, pyacoustid, pylast, pyxdg, requests, requests-oauthlib, resampy, soco, # configurations extraPatches ? [ ], pluginOverrides ? { }, disableAllPlugins ? false, extraDisabledTests ? [ ], extraNativeBuildInputs ? [ ], # tests pytestCheckHook, pytest-cov-stub, mock, rarfile, responses, requests-mock, pillow, writableTmpDirAsHomeHook, # preCheck bashInteractive, diffPlugins, runtimeShell, writeScript, # passthru.tests runCommand, }: let # Avoid using `rec`, so that using e.g `passthru` or any other attributes # defined inside, will have to be done via the beets argument, which can be # overriden. Until `finalAttrs` support reaches `buildPythonPackage`, there # is no way to avoid this. See: # # https://github.com/NixOS/nixpkgs/issues/258246 version = "2.5.1"; in buildPythonPackage { pname = "beets"; version = "2.5.1"; src = fetchFromGitHub { owner = "beetbox"; repo = "beets"; tag = "v${version}"; hash = "sha256-H3jcEHyK13+RHVlV4zp+8M3LZ0Jc2FdmAbLpekGozLA="; }; pyproject = true; patches = [ # Bash completion fix for Nix ./bash-completion-always-print.patch ] ++ extraPatches; build-system = [ poetry-core poetry-dynamic-versioning ]; dependencies = [ confuse gst-python jellyfish mediafile munkres musicbrainzngs platformdirs pyyaml unidecode # Can be built without it, but is useful on btrfs systems, and doesn't # add too much to the closure. See: # https://github.com/NixOS/nixpkgs/issues/437308 reflink typing-extensions lap ] ++ (lib.concatMap (p: p.propagatedBuildInputs) (lib.attrValues beets.passthru.plugins.enabled)); nativeBuildInputs = [ gobject-introspection sphinxHook sphinx-design sphinx-copybutton pydata-sphinx-theme ] ++ extraNativeBuildInputs; buildInputs = with gst_all_1; [ gst-plugins-base gst-plugins-good gst-plugins-ugly ]; outputs = [ "out" "doc" "man" ]; sphinxBuilders = [ "html" "man" ]; # Causes an installManPage error. Not clear why this directory gets generated # with the manpages. The same directory is observed correctly in # $doc/share/doc/beets-${version}/html preInstallSphinx = '' rm -r .sphinx/man/man/_sphinx_design_static ''; postInstall = '' mkdir -p $out/share/zsh/site-functions cp extra/_beet $out/share/zsh/site-functions/ ''; makeWrapperArgs = [ "--set GI_TYPELIB_PATH \"$GI_TYPELIB_PATH\"" "--set GST_PLUGIN_SYSTEM_PATH_1_0 \"$GST_PLUGIN_SYSTEM_PATH_1_0\"" "--prefix PATH : ${lib.makeBinPath beets.passthru.plugins.wrapperBins}" ]; nativeCheckInputs = [ pytestCheckHook pytest-cov-stub mock rarfile responses requests-mock pillow writableTmpDirAsHomeHook ] ++ beets.passthru.plugins.wrapperBins; __darwinAllowLocalNetworking = true; disabledTestPaths = beets.passthru.plugins.disabledTestPaths ++ [ # touches network "test/plugins/test_aura.py" ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ # Flaky: several tests fail randomly with: # if not self._poll(timeout): # raise Empty # _queue.Empty "test/plugins/test_bpd.py" ] ++ lib.optionals stdenv.hostPlatform.isLinux [ # fail on Hydra with `RuntimeError: image cannot be obtained without artresizer backend` "test/plugins/test_art.py::AlbumArtOperationConfigurationTest::test_enforce_ratio" "test/plugins/test_art.py::AlbumArtOperationConfigurationTest::test_enforce_ratio_with_percent_margin" "test/plugins/test_art.py::AlbumArtOperationConfigurationTest::test_enforce_ratio_with_px_margin" "test/plugins/test_art.py::AlbumArtOperationConfigurationTest::test_minwidth" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_deinterlaced" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_deinterlaced_and_resized" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_file_not_resized" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_file_resized" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_file_resized_and_scaled" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_file_resized_but_not_scaled" "test/plugins/test_art.py::AlbumArtPerformOperationTest::test_resize" ]; disabledTests = extraDisabledTests ++ [ # touches network "test_merge_duplicate_album" # The existence of the dependency reflink (see comment above), causes this # test to be run, and it fails in the sandbox. "test_successful_reflink" ]; # Perform extra "sanity checks", before running pytest tests. preCheck = '' # Check for undefined plugins find beetsplug -mindepth 1 \ \! -path 'beetsplug/__init__.py' -a \ \( -name '*.py' -o -path 'beetsplug/*/__init__.py' \) -print \ | sed -n -re 's|^beetsplug/([^/.]+).*|\1|p' \ | sort -u > plugins_available ${diffPlugins (lib.attrNames beets.passthru.plugins.builtins) "plugins_available"} export BEETS_TEST_SHELL="${lib.getExe bashInteractive} --norc" env EDITOR="${writeScript "beetconfig.sh" '' #!${runtimeShell} cat > "$1" < $out/config.yaml replaygain: backend: gstreamer EOF ${beets}/bin/beet -c $out/config.yaml > /dev/null ''; }; }; meta = { description = "Music tagger and library organizer"; homepage = "https://beets.io"; license = lib.licenses.mit; maintainers = with lib.maintainers; [ astratagem doronbehar lovesegfault pjones ]; platforms = lib.platforms.linux ++ lib.platforms.darwin; mainProgram = "beet"; }; }