diff --git a/pkgs/tools/audio/beets/builtin-plugins.nix b/pkgs/tools/audio/beets/builtin-plugins.nix index 2b9ee3bc5d03f..bcb22caab20c0 100644 --- a/pkgs/tools/audio/beets/builtin-plugins.nix +++ b/pkgs/tools/audio/beets/builtin-plugins.nix @@ -1,27 +1,47 @@ -{ aacgain -, ffmpeg -, flac -, imagemagick -, keyfinder-cli -, mp3gain -, mp3val -, python3Packages -, ... -}: { +{ + aacgain, + ffmpeg, + flac, + imagemagick, + keyfinder-cli, + mp3gain, + mp3val, + python3Packages, + ... +}: +{ absubmit = { deprecated = true; testPaths = [ ]; }; - - acousticbrainz.propagatedBuildInputs = [ python3Packages.requests ]; + advancedrewrite = { + testPaths = [ ]; + }; + acousticbrainz = { + deprecated = true; + propagatedBuildInputs = [ python3Packages.requests ]; + }; albumtypes = { }; aura = { - propagatedBuildInputs = with python3Packages; [ flask pillow ]; - testPaths = [ ]; + propagatedBuildInputs = with python3Packages; [ + flask + flask-cors + pillow + ]; + }; + autobpm = { + propagatedBuildInputs = with python3Packages; [ + librosa + # An optional dependency of librosa, needed for beets' autobpm + resampy + ]; }; badfiles = { testPaths = [ ]; - wrapperBins = [ mp3val flac ]; + wrapperBins = [ + mp3val + flac + ]; }; bareasc = { }; beatport.propagatedBuildInputs = [ python3Packages.requests-oauthlib ]; @@ -39,7 +59,10 @@ propagatedBuildInputs = [ python3Packages.requests ]; testPaths = [ ]; }; - discogs.propagatedBuildInputs = with python3Packages; [ discogs-client requests ]; + discogs.propagatedBuildInputs = with python3Packages; [ + discogs-client + requests + ]; duplicates.testPaths = [ ]; edit = { }; embedart = { @@ -49,7 +72,12 @@ embyupdate.propagatedBuildInputs = [ python3Packages.requests ]; export = { }; fetchart = { - propagatedBuildInputs = with python3Packages; [ requests pillow ]; + propagatedBuildInputs = with python3Packages; [ + beautifulsoup4 + langdetect + pillow + requests + ]; wrapperBins = [ imagemagick ]; }; filefilter = { }; @@ -76,11 +104,19 @@ propagatedBuildInputs = [ python3Packages.pylast ]; testPaths = [ ]; }; + limit = { }; + listenbrainz = { + testPaths = [ ]; + }; loadext = { propagatedBuildInputs = [ python3Packages.requests ]; testPaths = [ ]; }; - lyrics.propagatedBuildInputs = [ python3Packages.beautifulsoup4 ]; + lyrics.propagatedBuildInputs = with python3Packages; [ + beautifulsoup4 + langdetect + requests + ]; mbcollection.testPaths = [ ]; mbsubmit = { }; mbsync = { }; @@ -97,8 +133,12 @@ playlist.propagatedBuildInputs = [ python3Packages.requests ]; plexupdate = { }; random = { }; - replaygain.wrapperBins = [ aacgain ffmpeg mp3gain ]; - rewrite.testPaths= [ ]; + replaygain.wrapperBins = [ + aacgain + ffmpeg + mp3gain + ]; + rewrite.testPaths = [ ]; scrub.testPaths = [ ]; smartplaylist = { }; sonosupdate = { @@ -111,31 +151,22 @@ testPaths = [ ]; }; subsonicupdate.propagatedBuildInputs = [ python3Packages.requests ]; + substitute = { + testPaths = [ ]; + }; the = { }; thumbnails = { - propagatedBuildInputs = with python3Packages; [ pillow pyxdg ]; + propagatedBuildInputs = with python3Packages; [ + pillow + pyxdg + ]; wrapperBins = [ imagemagick ]; }; types.testPaths = [ "test/plugins/test_types_plugin.py" ]; unimported.testPaths = [ ]; - web.propagatedBuildInputs = [ python3Packages.flask ]; + web.propagatedBuildInputs = with python3Packages; [ + flask + flask-cors + ]; zero = { }; - limit = { }; - substitute = { - testPaths = [ ]; - }; - advancedrewrite = { - testPaths = [ ]; - }; - autobpm = { - propagatedBuildInputs = with python3Packages; [ - librosa - # An optional dependency of librosa, needed for beets' autobpm - resampy - ]; - testPaths = [ ]; - }; - listenbrainz = { - testPaths = [ ]; - }; } diff --git a/pkgs/tools/audio/beets/common.nix b/pkgs/tools/audio/beets/common.nix index c8064a6310d06..07db91eba091e 100644 --- a/pkgs/tools/audio/beets/common.nix +++ b/pkgs/tools/audio/beets/common.nix @@ -1,94 +1,104 @@ -{ 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 ? [] +{ + lib, + src, + version, + bashInteractive, + diffPlugins, + gobject-introspection, + gst_all_1, + python3Packages, + sphinxHook, + runtimeShell, + writeScript, + + # plugin deps, used indirectly by the @inputs when we `import ./builtin-plugins.nix` + aacgain, + essentia-extractor, + ffmpeg, + flac, + imagemagick, + keyfinder-cli, + mp3gain, + mp3val, + + extraPatches ? [ ], + pluginOverrides ? { }, + disableAllPlugins ? false, + disabledTests ? [ ], + extraNativeBuildInputs ? [ ], # tests -, runCommand -, beets + 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; - }; + mkPlugin = + { + name, + enable ? !disableAllPlugins, + builtin ? false, + propagatedBuildInputs ? [ ], + testPaths ? [ + "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) + 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 - ; + ) pluginOverrides; - allPlugins = lib.mapAttrs ( n: a: mkPlugin { name = n; } // a) (lib.recursiveUpdate basePlugins 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; + disabledTestPaths = lib.flatten (attrValues (lib.mapAttrs (_: v: v.testPaths) disabledPlugins)); pluginWrapperBins = concatMap (p: p.wrapperBins) (attrValues enabledPlugins); in python3Packages.buildPythonApplication { pname = "beets"; inherit src version; + pyproject = true; 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)); + build-system = [ + python3Packages.poetry-core + ]; + + dependencies = + with python3Packages; + [ + confuse + gst-python + jellyfish + mediafile + munkres + musicbrainzngs + platformdirs + pyyaml + unidecode + typing-extensions + ] + ++ (concatMap (p: p.propagatedBuildInputs) (attrValues enabledPlugins)); nativeBuildInputs = [ gobject-introspection @@ -96,15 +106,24 @@ python3Packages.buildPythonApplication { 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" ]; + 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 @@ -117,18 +136,29 @@ python3Packages.buildPythonApplication { "--prefix PATH : ${lib.makeBinPath pluginWrapperBins}" ]; - nativeCheckInputs = with python3Packages; [ - pytestCheckHook - pytest-cov - mock - rarfile - responses - ] ++ pluginWrapperBins; + nativeCheckInputs = + with python3Packages; + [ + pytestCheckHook + pytest-cov + mock + rarfile + responses + ] + ++ pluginWrapperBins; __darwinAllowLocalNetworking = true; - disabledTestPaths = lib.flatten (attrValues (lib.mapAttrs (_: v: v.testPaths) disabledPlugins)); - inherit disabledTests; + disabledTestPaths = disabledTestPaths ++ [ + # touches network + "test/plugins/test_aura.py" + ]; + disabledTests = disabledTests ++ [ + # beets.ui.UserError: unknown command 'autobpm' + "test/plugins/test_autobpm.py::TestAutoBPMPlugin::test_import" + # AssertionError: assert 0 == 117 + "test/plugins/test_autobpm.py::TestAutoBPMPlugin::test_command" + ]; # Perform extra "sanity checks", before running pytest tests. preCheck = '' @@ -152,30 +182,38 @@ python3Packages.buildPythonApplication { 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; { + 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 = { description = "Music tagger and library organizer"; homepage = "https://beets.io"; - license = licenses.mit; - maintainers = with maintainers; [ aszlig doronbehar lovesegfault pjones ]; - platforms = platforms.linux ++ platforms.darwin; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ + aszlig + doronbehar + lovesegfault + montchr + pjones + ]; + platforms = lib.platforms.linux ++ lib.platforms.darwin; mainProgram = "beet"; }; } diff --git a/pkgs/tools/audio/beets/default.nix b/pkgs/tools/audio/beets/default.nix index 85244c0e0b897..9bd644c3d1155 100644 --- a/pkgs/tools/audio/beets/default.nix +++ b/pkgs/tools/audio/beets/default.nix @@ -1,34 +1,33 @@ -{ lib -, callPackage -, fetchFromGitHub -, python3Packages +{ + lib, + callPackage, + fetchFromGitHub, + python3Packages, }: /* -** To customize the enabled beets plugins, use the pluginOverrides input to the -** derivation. -** Examples: -** -** Disabling a builtin plugin: -** beets.override { pluginOverrides = { beatport.enable = false; }; } -** -** Enabling an external plugin: -** beets.override { pluginOverrides = { -** alternatives = { enable = true; propagatedBuildInputs = [ beetsPackages.alternatives ]; }; -** }; } + ** To customize the enabled beets plugins, use the pluginOverrides input to the + ** derivation. + ** Examples: + ** + ** Disabling a builtin plugin: + ** beets.override { pluginOverrides = { beatport.enable = false; }; } + ** + ** Enabling an external plugin: + ** beets.override { pluginOverrides = { + ** alternatives = { enable = true; propagatedBuildInputs = [ beetsPackages.alternatives ]; }; + ** }; } */ lib.makeExtensible (self: { beets = self.beets-stable; beets-stable = callPackage ./common.nix rec { inherit python3Packages; - # NOTE: ./builtin-plugins.nix and ./common.nix can have some conditionals - # be removed when stable version updates - version = "2.0.0"; + version = "2.2.0"; src = fetchFromGitHub { owner = "beetbox"; repo = "beets"; rev = "v${version}"; - hash = "sha256-6pmImyopy0zFBDYoqDyWcBv61FK1kGsZwW2+7fzAnq8="; + hash = "sha256-jhwXRgUUQJgQ/PLwvY1UfHCJ9UC8DcdBpE/janao0RM="; }; extraPatches = [ # Bash completion fix for Nix @@ -40,12 +39,12 @@ lib.makeExtensible (self: { beets-unstable = callPackage ./common.nix { inherit python3Packages; - version = "2.0.0-unstable-2024-05-25"; + version = "2.2.0-unstable-2024-12-02"; src = fetchFromGitHub { owner = "beetbox"; repo = "beets"; - rev = "2130404217684f22f36de00663428602b3f96d84"; - hash = "sha256-trqF6YVBcv+i5H4Ez3PKnRQ6mV2Ly/cw3UJC7pl19og="; + rev = "f92c0ec8b14fbd59e58374fd123563123aef197b"; + hash = "sha256-jhwXRgUUQJgQ/PLwvY1UfHCJ9UC8DcdBpE/janao0RM="; }; extraPatches = [ # Bash completion fix for Nix @@ -55,5 +54,6 @@ lib.makeExtensible (self: { alternatives = callPackage ./plugins/alternatives.nix { beets = self.beets-minimal; }; copyartifacts = callPackage ./plugins/copyartifacts.nix { beets = self.beets-minimal; }; - extrafiles = callPackage ./plugins/extrafiles.nix { beets = self.beets-minimal; }; + + extrafiles = throw "extrafiles is unmaintained since 2020 and broken since beets 2.0.0"; }) diff --git a/pkgs/tools/audio/beets/plugins/alternatives.nix b/pkgs/tools/audio/beets/plugins/alternatives.nix index 440c476309a66..d2520fcaca634 100644 --- a/pkgs/tools/audio/beets/plugins/alternatives.nix +++ b/pkgs/tools/audio/beets/plugins/alternatives.nix @@ -1,4 +1,9 @@ -{ lib, fetchFromGitHub, beets, python3Packages }: +{ + lib, + fetchFromGitHub, + beets, + python3Packages, +}: python3Packages.buildPythonApplication rec { pname = "beets-alternatives"; @@ -27,10 +32,13 @@ python3Packages.buildPythonApplication rec { export HOME=$(mktemp -d) ''; - meta = with lib; { + meta = { description = "Beets plugin to manage external files"; homepage = "https://github.com/geigerzaehler/beets-alternatives"; - maintainers = with maintainers; [ aszlig lovesegfault ]; - license = licenses.mit; + maintainers = with lib.maintainers; [ + aszlig + lovesegfault + ]; + license = lib.licenses.mit; }; } diff --git a/pkgs/tools/audio/beets/plugins/copyartifacts.nix b/pkgs/tools/audio/beets/plugins/copyartifacts.nix index d9d95a9f25d97..d1a915a709150 100644 --- a/pkgs/tools/audio/beets/plugins/copyartifacts.nix +++ b/pkgs/tools/audio/beets/plugins/copyartifacts.nix @@ -1,4 +1,9 @@ -{ lib, fetchFromGitHub, beets, python3Packages }: +{ + lib, + fetchFromGitHub, + beets, + python3Packages, +}: python3Packages.buildPythonApplication rec { pname = "beets-copyartifacts"; @@ -15,6 +20,10 @@ python3Packages.buildPythonApplication rec { sed -i -e '/install_requires/,/\]/{/beets/d}' setup.py sed -i -e '/namespace_packages/d' setup.py printf 'from pkgutil import extend_path\n__path__ = extend_path(__path__, __name__)\n' >beetsplug/__init__.py + + # beets v2.1.0 compat + # + sed -i -e 's/util\.py3_path/os.fsdecode/g' tests/_common.py ''; pytestFlagsArray = [ "-r fEs" ]; diff --git a/pkgs/tools/audio/beets/plugins/extrafiles.nix b/pkgs/tools/audio/beets/plugins/extrafiles.nix deleted file mode 100644 index 829d55c257e5f..0000000000000 --- a/pkgs/tools/audio/beets/plugins/extrafiles.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ lib, fetchFromGitHub, beets, python3Packages }: - -python3Packages.buildPythonApplication { - pname = "beets-extrafiles"; - version = "unstable-2020-12-13"; - - src = fetchFromGitHub { - repo = "beets-extrafiles"; - owner = "Holzhaus"; - rev = "a1d6ef9a9682b6bf7af9483541e56a3ff12247b8"; - sha256 = "sha256-ajuEbieWjTCNjdRZuGUwvStZwjx260jmY0m+ZqNd7ec="; - }; - - postPatch = '' - sed -i -e '/install_requires/,/\]/{/beets/d}' setup.py - sed -i -e '/namespace_packages/d' setup.py - sed -i -e 's/mediafile~=0.6.0/mediafile>=0.6.0/' setup.py - ''; - - propagatedBuildInputs = with python3Packages; [ mediafile ]; - - nativeCheckInputs = [ - python3Packages.pytestCheckHook - beets - ]; - - preCheck = '' - HOME="$(mktemp -d)" - ''; - - meta = { - homepage = "https://github.com/Holzhaus/beets-extrafiles"; - description = "Plugin for beets that copies additional files and directories during the import process"; - license = lib.licenses.mit; - inherit (beets.meta) platforms; - # Upstream hasn't had commits since 2020, build is broken since beets 2.0.0 - broken = true; - }; -}