Setup a testing beets in a don’t-change-anything configuration?

I haven’t been using beets for some years now, but I’d like to test some features out and probably even contribute a little.

I have a collection of nearly 150,000 songs, built during the past few decades and carefully fine-tuned using MusicBrainz Picard and some special plugins and tools. This amounts to roughly 2 TB of data.

All this is used productively, so I can’t simply “do a backup and restore” that easily (albeit doing backups almost every day).

Is there any easy way to set up beets in a fashion that

  • would never ever change any tag in any file (without my manual consent)?
  • would not change any file names or paths?
  • would still allow me testing many plugins and probably own changes?

With this “main music broadcasting machine”, I’m unfortunately still on Ubuntu Studio 14.04, so not everything might work. I do have some virtual machines (Linux Mint 19, Manjaro 18, MacOS 10.14 Mojave) running on this machine, so I could probably use one of those for testing. They would still access my original music folders, though.

Any recommendations, please?

N.B.: I don’t wish to “work on a smaller subset” by copying a few albums, if anyhow possible, and avoid using virtual machines if possible, because I plan to see how fast it is on a collection as big as this one, probably find some old/forgotten errors in my collection, and try out some special features like complicated selections from weird tags (like “give me the paths of all 1990s songs sung in Swedish by female-fronted Norwegian hard rock groups where the bass guitar was played by artist xy”).

I’m sure an official reply from the maintainer will be forthcoming, but afaik you can configure import to default to write=no, and most commands will use that as their default as well, i.e. modify, as they use ui.should_write(), which defaults to the input configuration unless you’ve passed the cli arg to change it.

You can also use a beets plugin to hack it if you’re especially paranoid about it, which I’ve verified works for me locally:

from __future__ import division, absolute_import, print_function

from beets.library import Item
from beets.plugins import BeetsPlugin
from beets.ui import log


class NoWritePlugin(BeetsPlugin):
    def __init__(self):
        super(NoWritePlugin, self).__init__()

        # Monkeypatch!
        def nowrite(self):
            log.warning('nowrite: ignoring attempt to write {0}'.format(self.path))

        Item.write = nowrite

E.g.

$ beet modify -w id:1 albumstatus=Official2
Modifying 1 items.
[1] Selected Ambient Works 85–92 - 01 - Aphex Twin - Xtal
  albumstatus: Official -> Official2
Really modify, move and write tags? (Yes/no/select) y

nowrite: ignoring attempt to write b'/Volumes/Data/Beets Library/Library/7digital/Aphex Twin/Selected Ambient Works 85\xe2\x80\x9392/01 - Xtal.flac'
$ beet modify -w id:1 albumstatus=Official2
Modifying 1 items.
No changes to make.
$ beet update -F albumstatus id:1
[1] Selected Ambient Works 85–92 - 01 - Aphex Twin - Xtal
  albumstatus: Official2 -> Official

Then you could do the same for move(), I expect.

This is exactly right; I have little to add. I like the idea to use a plugin to hack in a backstop to avoid writing things. Those import options should probably do it, but I’m contractually obligated to say that you should have a backup (which you have already said you do :smiley:).

Hee, hee … two backups, actually, because I’m a little overcautios. :grin: Too many years of work and too many rare albums in my collection …

Thanks for the infos, I’ll surely give it a try one of the days!

@kergoth: Many thanks again for the “nowrite” plugin sketch! This, in combination with import write=no, has really helped me along.

Great safety measures, since I’m currently meddling in MediaFile, :slightly_smiling_face:

No problem, happy to help. On a related note, I’d really love to have a log of database/tag changes, ala git log, but ideally in journal form with a way to revert / rollback to previous states, one of these years… I’ve made more than one change with an overly greedy beet-modify -y query, usually when scripting, where I wished for a damn undo command :slight_smile: At least nowrite makes it easier to make isolated workspaces for development and testing tasks without risking the library… working with a library subset is great for unit tests, not so much for integration.