Conversation
Replaces #12300. This makes the same change, but opts to refactor the `open_that` function such that it now takes a `Url` which would have avoided the origional mistake. The main fix is that the origional usage of `.to_str_lossy` never added a `file://` protocol, which making use of `Url::from_file_path` does.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
There was a problem hiding this comment.
Pull request overview
This PR refactors the open_that function to accept a Url type instead of a string, aiming to prevent the bug fixed in #12300 where filesystem paths weren't properly converted to file:// URLs on Linux. The refactor ensures that all callers must provide a properly formed URL, making the API safer.
Changes:
- Refactored
open_thatto accept&Urlparameter instead of&str - Updated
open_urlto parse the string toUrlbefore callingopen_that - Modified
show_in_finderon Linux to useUrl::from_file_pathto convert paths to file:// URLs
Comments suppressed due to low confidence (1)
crates/but-api/src/legacy/open.rs:22
- The "file" scheme is missing from the allowed URL schemes list. Since this PR adds file:// URL support via
Url::from_file_path, you need to add "file" to this whitelist, otherwise all file URLs will be rejected with "Invalid path scheme: file".
if ![
"http",
"https",
"mailto",
"vscode",
"vscodium",
"vscode-insiders",
"zed",
"windsurf",
"cursor",
"trae",
]
.contains(&target_url.scheme())
| let parent_str = parent.to_string_lossy(); | ||
| open_that(&parent_str) | ||
| open_that(&Url::from_file_path(&parent_str)) | ||
| .with_context(|| format!("Failed to open parent directory of '{path}' in file manager",))?; |
There was a problem hiding this comment.
parent.to_string_lossy() returns a Cow<str>, not a &str or String. When passing this to Url::from_file_path, you should convert it to a proper path type. Consider using parent directly instead of converting to string and back:
let url = Url::from_file_path(parent)
.map_err(|_| anyhow::anyhow!("Invalid file path: {}", path))?;
open_that(&url)| open_that(&Url::from_file_path(&path)) | ||
| .with_context(|| format!("Failed to open directory '{path}' in file manager"))?; |
There was a problem hiding this comment.
Url::from_file_path returns Result<Url, ()>, not Url. This code will fail to compile because you're trying to pass a Result to a function that expects a reference to a Url. You need to handle the error, for example:
let url = Url::from_file_path(&path)
.map_err(|_| anyhow::anyhow!("Invalid file path: {}", path))?;
open_that(&url)| open_that(&Url::from_file_path(&parent_str)) | ||
| .with_context(|| format!("Failed to open parent directory of '{path}' in file manager",))?; |
There was a problem hiding this comment.
Url::from_file_path returns Result<Url, ()>, not Url. This code will fail to compile. You need to unwrap or handle the Result before passing to open_that.
| open_that(&Url::from_file_path(&path)) | ||
| .with_context(|| format!("Failed to open '{path}' in file manager"))?; |
There was a problem hiding this comment.
Url::from_file_path returns Result<Url, ()>, not Url. This code will fail to compile. You need to unwrap or handle the Result before passing to open_that.
| let mut cmd_errors = Vec::new(); | ||
|
|
||
| for mut cmd in open::commands(path) { | ||
| for mut cmd in open::commands(target_url.path()) { |
There was a problem hiding this comment.
Using target_url.path() extracts only the path component of the URL. For HTTP/HTTPS URLs like https://example.com/page, this would incorrectly pass /page instead of the full URL to open::commands(). For file URLs, this might work on Linux with xdg-open, but it's inconsistent. Consider using target_url.as_str() to pass the complete URL string to the open crate.
| for mut cmd in open::commands(target_url.path()) { | |
| for mut cmd in open::commands(target_url.as_str()) { |
Replaces #12300.
This makes the same change, but opts to refactor the
open_thatfunction such that it now takes aUrlwhich would have avoided the origional mistake.The main fix is that the origional usage of
.to_str_lossynever added afile://protocol, which making use ofUrl::from_file_pathdoes.