## Description
I was hoping to use the functionality from `ftintitle` to set the path's
album artist as the main artist, but that wasn't possible, so I added a
template value `album_artist_no_feat`.
Catch ValueError when setting gst required version
`pytest.importorskip` is used to catch the case when beetsplug.bpd cannot
be imported. On macOS, the `gi` module was able to be imported, but when
trying to specify `gi.require_version`, a `ValueError` is raised about
Gst being unavailable. pytest does not catch this `ValueError` during
`importskip` as it is not an `ImportError`, and thus the test suite
errors during the test collection phase.
With this change, we catch the ValueError, and re-raise it as an
`ImportError` and pytest gracefully skips those tests.
Fixes#3324
pytest.importskip is used to catch the case when beetsplug.bpd cannot be
imported. On macOS, the gi module was able to be imported, but when
trying to specify `gi.require_version`, a ValueError is raised about
Gst being unavailable. pytest does not catch this ValueError during
importskip as it is not an ImportError, and thus the test suite errors
during the test collection phase.
With this change, we catch the ValueError, and re-raise it as an
ImportError and pytest gracefully skips those tests.
Following #4709 and #5447, the web plugin used single-quotes (ie. string
litteral) in the SQL query for table columns.
Thus, for instance, the query `GET /item/values/albumartist` would
return the litteral "albumartist" instead of a list of unique album
artists.
This prevents the Mopidy beets integration from working, returning the
single artist "albumartist".
Following #4709 and #5447, the web plugin used single-quotes (ie. string
litteral) in the SQL query for table columns. Thus, for instance, the query
`GET /item/values/albumartist` would return the litteral "albumartist"
instead of a list of unique album artists.
When creating a hardlink, either during import or `beet convert`, if the
origin of the hardlink was a symlink, that symlink used to be directly
copied. This could create broken symlinks if the origin symlink was
relative, and in either case, probably wasn't the user's desired
behavior.
This change de-references all symlinks before creating a hardlink, such
that the end result is a normal file with the same inode as the original
file. See #5676 for more discussion about the original issue.
Fixes#5676
As per #5652, `beet --config <path> config -e` edited the default config
path, even though that's not the config that would be used by beets.
It seems like this was the result of a deliberate short-circuit in
[`_raw_main()`](c2de6feada/beets/ui/__init__.py (L1832)).
The short-circuit prevents malformed configs from causing a crash before
opening the editor, but also prevents the setup function from loading
the custom config at all.
The solution used here is to just expose the CLI options to
`edit_config()`, so that it can use the custom config path if its set. I
also suspect that the branch in
[`config_func()`](c2de6feada/beets/ui/commands.py (L2354))
which is getting short circuited is actually unreachable, but I left it
in with a note just in case.
Fixes#5652
## To Do
- [x] ~~Documentation~~ (N/A)
- [X] Changelog
- [X] Tests
## Description
This one’s a big one 🎣 Proceed with care and a bit
of time ;)
The `ui/commands.py` file had grown into an unwieldy monolith (2000+
lines) over time, so this PR breaks it apart into a modular structure
i.e. **one file per command**, plus some cleanup and reorganization
along the way.
---
### What changed
* **Commands modularized:**
Every command (`help`, `list`, `move`, `update`, `remove`, etc.) now
lives in its own file under `ui/commands/`.
* **Support code reorganized:**
* Utility functions moved into a separate helper module.
* `commands.py` converted into `commands/__init__.py` for better import
handling.
* The `import` command (and related helpers) moved into its own folder:
* `importer/session.py` for import session logic
* `importer/display.py` for display-related functions
* **Tests cleaned up:**
* Each command’s tests now live in their own file.
* All UI-related tests were moved into a dedicated folder for clarity.
Moved tests related to ui into own folder.
Moved 'modify' command tests into own file.
Moved 'write' command tests into own file.
Moved 'fields' command tests into own file.
Moved 'do_query' test into own file.
Moved 'list' command tests into own file.
Moved 'remove' command tests into own file.
Moved 'move' command tests into own file.
Moved 'update' command tests into own file.
Moved 'show_change' test into test_import file.
Moved 'summarize_items' test into test_import file.
Moved 'completion' command test into own file.
Moved commands.py into commands/__init__.py for easier refactoring.
Moved `version` command into its own file.
Moved `help` command into its own file.
Moved `stats` command into its own file.
Moved `list` command into its own file.
Moved `config` command into its own file.
Moved `completion` command into its own file.
Moved utility functions into own file.
Moved `move` command into its own file.
Moved `fields` command into its own file.
Moved `update` command into its own file.
Moved `remove` command into its own file.
Moved `modify` command into its own file.
Moved `write` command into its own file.
Moved `import` command into its own folder, more commit following.
Moved ImportSession related functions into `importer/session.py`.
Moved import display display related functions into `importer/display.py`
Renamed import to import_ as a module cant be named import.
Fixed imports in init file.