Skip to content

Use absolute instead of canonicalize for relative root-dir#2008

Merged
thomas-zahner merged 3 commits intolycheeverse:masterfrom
rina-forks:absolute
Jan 27, 2026
Merged

Use absolute instead of canonicalize for relative root-dir#2008
thomas-zahner merged 3 commits intolycheeverse:masterfrom
rina-forks:absolute

Conversation

@katrinafyi
Copy link
Member

it's a rare thing but canonicalise replaces all symbolic links with their destinations. this can unexpectedly change the root-dir location, which is a problem given relative link resolution works very much based on location, and users will be expecting that the root-dir they give is the root-dir that is used.

in this change, we have to do a separate check for file existence - canonicalize did that implicitly.

it's a rare thing but canonicalise replaces all symbolic links
with their destinations. this can unexpectedly change the root-dir
location, which is a problem given relative link resolution works
very much based on location, and users will be expecting that the
root-dir they give is the root-dir that is used.

in this change, we just have to do a separate check for file existence -
canonicalize did that implicitly.
Copy link
Member

@thomas-zahner thomas-zahner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, that's better!

Comment on lines +78 to +84
Some(root_dir) => {
let root_dir_exists = root_dir.read_dir().map(|_| ());
let root_dir = root_dir_exists
.and_then(|()| std::path::absolute(&root_dir))
.map_err(|e| ErrorKind::InvalidRootDir(root_dir, e))?;
Some(root_dir)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nitpicky, but I find the mapping to () a bit weird, though I'd also be fine with it.
If you agree we could use the following, otherwise I'm fine with your version.

Suggested change
Some(root_dir) => {
let root_dir_exists = root_dir.read_dir().map(|_| ());
let root_dir = root_dir_exists
.and_then(|()| std::path::absolute(&root_dir))
.map_err(|e| ErrorKind::InvalidRootDir(root_dir, e))?;
Some(root_dir)
}
Some(root_dir) => Some(
root_dir
.read_dir()
.and_then(|_| std::path::absolute(&root_dir))
.map_err(|e| ErrorKind::InvalidRootDir(root_dir, e))?,
),

Copy link
Member Author

@katrinafyi katrinafyi Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya it's a bit weird. I like it, though, because it makes it clear that we're ignoring the value of read_dir aside from the error. So the reader of the code doesn't think we're actually reading the directory at this point.

If you chain read_dir directly into and_then, it looks like it's doing something with the result of read_dir.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True it might be more explicit and obvious

@thomas-zahner thomas-zahner merged commit 82eb925 into lycheeverse:master Jan 27, 2026
7 checks passed
@mre mre mentioned this pull request Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants