Skip to content

convert: Relative symlinks broken upon convert with -H #5676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Alch-Emi opened this issue Mar 18, 2025 · 2 comments · May be fixed by #5684
Open

convert: Relative symlinks broken upon convert with -H #5676

Alch-Emi opened this issue Mar 18, 2025 · 2 comments · May be fixed by #5684
Labels

Comments

@Alch-Emi
Copy link
Contributor

Alch-Emi commented Mar 18, 2025

When converting with the hardlink option, existing relative symlinks in the original beets library will be converted to broken symlinks in the destination.

Problem

With the configuration:

directory: ~/BugDemo
library: ~/BugDemo/beets.db
plugins: convert
convert:
    never_convert_lossy_files: yes

Run the following commands:

# Setting up the initial library
cd ~
mkdir -p BugDemo/MyArtist/MyAlbum
ln -s ../../../MyTrack.ogg BugDemo/MyArtist/MyAlbum/ # This should be a real, lossy music file, and a relative symlink

tree BugDemo/
# BugDemo/
# └── MyArtist
#     └── MyAlbum
#         └── MyTrack.ogg -> ../../../MyTrack.ogg

beet import -CW BugDemo/ # metadata is irrelevant

# Running the transcode
beet -vv convert -Hyd ./path/to/Destination/

# user configuration: /home/myuser/.config/beets/config.yaml
# data directory: /home/myuser/.config/beets
# plugin paths: 
# Sending event: pluginload
# library database: /home/myuser/BugDemo/beets.db
# library directory: /home/myuser/BugDemo
# Sending event: library_opened
# Parsed query: AndQuery([TrueQuery()])
# Parsed sort: NullSort()
# MyArtist - MyAlbum - MyTrack
# Parsed query: AndQuery([NoneQuery('album_id', True)])
# Parsed sort: NullSort()
# Parsed query: AndQuery([BooleanQuery('comp', 1, fast=True)])
# Parsed sort: NullSort()
# convert: Hardlinking /home/myuser/BugDemo/MyArtist/MyAlbum/01 MyTrack.ogg
# Sending event: write
# Sending event: after_write
# Sending event: after_convert
# Sending event: cli_exit

# The Result
ls -l ./path/to/Destination/MyArtist/MyAlbum/
# lrwxrwxrwx 2 myuser users 86 Mar 18 16:26 '01 MyTrack.ogg' -> '../../../MyTrack.ogg'

Notice that this symlink now points to nothing, as the original MyTrack.ogg would be at ../../../../../MyTrack.ogg. In other words, the relative path pointed to by the symlink was not updated to its new location.

The behavior that I would expect is either:

  • Before creating the new symlink, convert the referent to an absolute path, so that the new symlink points to the same file as the original
  • Or, even better, dereference the symlink and hardlink the referent to the new location

Setup

  • OS: NixOS 24.11
  • Python version: 3.12.8
  • beets version: 2.1.0 (from Nix package manager)
  • Turning off (other) plugins made problem go away: no
@Alch-Emi
Copy link
Contributor Author

Alch-Emi commented Mar 19, 2025

I imagine this could be fixed with either inserting a call to Path.resolve() in either convert_item() or util.hardlink().

The former would be a fix just for this module, while I would expect that the latter would fix the issue elsewhere in the codebase too, if it shows up anywhere. While I imagine that there shouldn't be any adverse consequences to that, I'm not familiar enough with the codebase to say for sure. If any devs want to weigh in, I'll write up the PR.

@Alch-Emi
Copy link
Contributor Author

Having identified that, another manifestation of the same bug exists with the importer:

With the config:

directory: ~/TestLib
library: ~/TestLib/beets.db
import:
    hardlink: true

Run beet import with almost any relative symlink, and the resulting library will be invalid.

Alch-Emi added a commit to Alch-Emi/beets that referenced this issue Mar 23, 2025
@Alch-Emi Alch-Emi linked a pull request Mar 23, 2025 that will close this issue
3 tasks
@snejus snejus added the convert label May 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants