nixpkgs/pkgs/tools/audio/beets/common.nix
2024-07-14 04:32:56 +02:00

179 lines
4.4 KiB
Nix

{ 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 = { name
, enable ? !disableAllPlugins
, builtin ? false
, propagatedBuildInputs ? [ ]
, testPaths ? [
# NOTE: This conditional can be removed when beets-stable is updated and
# the default plugins test path is changed
(if (lib.versions.majorMinor version) == "1.6" then
"test/test_${name}.py"
else
"test/plugins/test_${name}.py"
)
]
, wrapperBins ? [ ]
}: {
inherit name enable builtin propagatedBuildInputs testPaths wrapperBins;
};
basePlugins = lib.mapAttrs (_: a: { builtin = true; } // a) (import ./builtin-plugins.nix inputs);
pluginOverrides' = lib.mapAttrs
(plugName: lib.throwIf
(basePlugins.${plugName}.deprecated or false)
"beets evaluation error: Plugin ${plugName} was enabled in pluginOverrides, but it has been removed. Remove the override to fix evaluation."
)
pluginOverrides
;
allPlugins = lib.mapAttrs ( n: a: mkPlugin { name = n; } // a) (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
python3Packages.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" ];
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
pytest-cov
mock
rarfile
responses
] ++ pluginWrapperBins;
disabledTestPaths = lib.flatten (attrValues (lib.mapAttrs (_: v: v.testPaths) 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" <<CFG
plugins: ${lib.concatStringsSep " " (attrNames enabledPlugins)}
CFG
''}" "$out/bin/beet" config -e
env EDITOR=true "$out/bin/beet" config -e
'';
passthru.plugins = allPlugins;
passthru.tests.gstreamer = runCommand "beets-gstreamer-test" {
meta.timeout = 60;
} ''
set -euo pipefail
export HOME=$(mktemp -d)
mkdir $out
cat << EOF > $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";
};
}