beets/beetsplug
Johann Fot 70bf57baf6
Add native support for multiple genres per album/track
Simplify multi-genre implementation based on maintainer feedback (PR #6169).

Changes:
- Remove multi_value_genres and genre_separator config options
- Replace complex sync_genre_fields() with ensure_first_value('genre', 'genres')
- Update all plugins (Beatport, MusicBrainz, LastGenre) to always write genres as lists
- Add automatic migration for comma/semicolon/slash-separated genre strings
- Add 'beet migrate genres' command for explicit batch migration with --pretend flag
- Update all tests to reflect simplified approach (44 tests passing)
- Update documentation

Implementation aligns with maintainer vision of always using multi-value genres
internally with automatic backward-compatible sync to the genre field via
ensure_first_value(), eliminating configuration complexity.

Migration strategy avoids problems from #5540:
- Automatic lazy migration on item access (no reimport/mbsync needed)
- Optional batch migration command for user control
- No endless rewrite loops due to proper field synchronization
2026-02-23 05:11:36 +00:00
..
_utils Set default release/recording includes in MusicBrainzAPI 2026-02-22 02:09:25 +00:00
bpd Make MusicBrainzAPI logs visible 2026-02-07 22:36:43 +00:00
discogs Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
lastgenre Add native support for multiple genres per album/track 2026-02-23 05:11:36 +00:00
metasync Address RUF012 2026-01-13 20:55:40 +00:00
web
_typing.py
absubmit.py
acousticbrainz.py Address RUF012 2026-01-13 20:55:40 +00:00
advancedrewrite.py
albumtypes.py Configure future-annotations 2026-01-13 20:55:40 +00:00
aura.py Configure future-annotations 2026-01-13 20:55:40 +00:00
autobpm.py
badfiles.py fix: wrong count in badfiles log message 2026-02-12 22:50:32 +01:00
bareasc.py
beatport.py Add native support for multiple genres per album/track 2026-02-23 05:11:36 +00:00
bench.py
bpm.py
bpsync.py Enable RUF rules 2026-01-13 20:55:40 +00:00
bucket.py
chroma.py Configure future-annotations 2026-01-13 20:55:40 +00:00
convert.py Update convert.py 2026-01-15 15:46:01 +00:00
deezer.py Address RUF012 2026-01-13 20:55:40 +00:00
duplicates.py
edit.py Handle DelimitedString fields as native lists in edit plugin 2026-02-23 00:33:24 +00:00
embedart.py
embyupdate.py
export.py Enable RUF rules 2026-01-13 20:55:40 +00:00
fetchart.py Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
filefilter.py
fish.py fish: complete files in more places 2026-01-20 13:07:03 -08:00
freedesktop.py
fromfilename.py Enable RUF rules 2026-01-13 20:55:40 +00:00
ftintitle.py ftintitle: fix changelog conflict 2026-01-08 12:20:25 -08:00
fuzzy.py
hook.py
ihate.py
importadded.py
importfeeds.py
importsource.py importsource: fix potential prevent_suggest_removal crash 2025-12-21 13:07:02 +01:00
info.py
inline.py
ipfs.py
keyfinder.py Enable RUF rules 2026-01-13 20:55:40 +00:00
kodiupdate.py
lastimport.py
limit.py
listenbrainz.py Type MusicBrainzAPI properly 2026-01-06 09:54:02 +00:00
loadext.py
lyrics.py Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
mbcollection.py Type MusicBrainzAPI properly 2026-01-06 09:54:02 +00:00
mbpseudo.py Configure future-annotations 2026-01-13 20:55:40 +00:00
mbsubmit.py Enable RUF rules 2026-01-13 20:55:40 +00:00
mbsync.py Enable RUF rules 2026-01-13 20:55:40 +00:00
missing.py Address RUF012 2026-01-13 20:55:40 +00:00
mpdstats.py Address RUF012 2026-01-13 20:55:40 +00:00
mpdupdate.py
musicbrainz.py Add native support for multiple genres per album/track 2026-02-23 05:11:36 +00:00
parentwork.py Migrate parentwork to use MusicBrainzAPI 2026-01-06 00:27:36 +00:00
permissions.py
play.py
playlist.py Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
plexupdate.py
random.py Fix grouping for list fields and stabilize equal-chance order 2026-01-30 00:30:46 +00:00
replace.py Configure future-annotations 2026-01-13 20:55:40 +00:00
replaygain.py Fix mp3gain/aacgain paths on Windows 2026-02-21 16:52:26 +00:00
rewrite.py
scrub.py
smartplaylist.py Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
sonosupdate.py
spotify.py Address RUF012 2026-01-13 20:55:40 +00:00
subsonicplaylist.py
subsonicupdate.py
substitute.py
the.py Address RUF012 2026-01-13 20:55:40 +00:00
thumbnails.py
titlecase.py Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
types.py
unimported.py
zero.py