{ stdenv , fetchpatch , bashInteractive , diffPlugins , glibcLocales , gobject-introspection , gst_all_1 , lib , python3Packages , sphinxHook , runtimeShell , writeScript # plugin deps , aacgain , essentia-extractor , ffmpeg , flac , imagemagick , keyfinder-cli , mp3gain , mp3val , src , version , extraPatches ? [ ] , pluginOverrides ? { } , disableAllPlugins ? false , disabledTests ? [] , extraNativeBuildInputs ? [] # tests , runCommand , beets }@inputs: let inherit (lib) attrNames attrValues concatMap; mkPlugin = { enable ? !disableAllPlugins, builtin ? false, propagatedBuildInputs ? [ ], testPaths ? [ ], wrapperBins ? [ ] }: { inherit enable builtin propagatedBuildInputs testPaths wrapperBins; }; basePlugins = lib.mapAttrs (_: a: { builtin = true; } // a) (import ./builtin-plugins.nix inputs); allPlugins = lib.mapAttrs (_: mkPlugin) (lib.recursiveUpdate basePlugins pluginOverrides); builtinPlugins = lib.filterAttrs (_: p: p.builtin) allPlugins; enabledPlugins = lib.filterAttrs (_: p: p.enable) allPlugins; disabledPlugins = lib.filterAttrs (_: p: !p.enable) allPlugins; pluginWrapperBins = concatMap (p: p.wrapperBins) (attrValues enabledPlugins); in python3Packages.buildPythonApplication { pname = "beets"; inherit src version; patches = extraPatches; propagatedBuildInputs = with python3Packages; [ confuse gst-python jellyfish mediafile munkres musicbrainzngs mutagen pygobject3 pyyaml reflink unidecode typing-extensions ] ++ (concatMap (p: p.propagatedBuildInputs) (attrValues enabledPlugins)); nativeBuildInputs = [ gobject-introspection sphinxHook ] ++ extraNativeBuildInputs; buildInputs = [ ] ++ (with gst_all_1; [ gst-plugins-base gst-plugins-good gst-plugins-ugly ]); outputs = [ "out" "doc" "man" ]; sphinxBuilders = [ "html" "man" ]; 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 pluginWrapperBins}" ]; nativeCheckInputs = with python3Packages; [ pytestCheckHook mock rarfile responses ] ++ pluginWrapperBins; disabledTestPaths = lib.flatten (attrValues (lib.mapAttrs (n: v: v.testPaths ++ [ "test/test_${n}.py" ]) disabledPlugins)); inherit disabledTests; # 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 (attrNames builtinPlugins) "plugins_available"} export BEETS_TEST_SHELL="${bashInteractive}/bin/bash --norc" export HOME="$(mktemp -d)" 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 = with lib; { description = "Music tagger and library organizer"; homepage = "https://beets.io"; license = licenses.mit; maintainers = with maintainers; [ aszlig doronbehar lovesegfault pjones ]; platforms = platforms.linux; mainProgram = "beet"; }; }