1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
{ 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 = { 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";
};
}
|