R3.1: real paths without \?\ on Windows (dunce); old recent lists read plain
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1066b41cb0
commit
d0b5aede95
21 files changed
+59
-24
No files matched your search
@@ -7,6 +7,7 @@ license.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
dunce.workspace = true
|
||||
ely-platform.workspace = true
|
||||
log.workspace = true
|
||||
aes-gcm.workspace = true
|
||||
|
||||
@@ -10,12 +10,21 @@ const KEEP: usize = 20;
|
||||
|
||||
/// Recently opened paths, newest first.
|
||||
pub fn recent(file: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
match std::fs::read(file) {
|
||||
let listed: Vec<PathBuf> = match std::fs::read(file) {
|
||||
Ok(bytes) => serde_json::from_slice(&bytes)
|
||||
.map_err(|error| io::Error::other(format!("{}: {error}", file.display()))),
|
||||
Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(Vec::new()),
|
||||
Err(error) => Err(error),
|
||||
.map_err(|error| io::Error::other(format!("{}: {error}", file.display())))?,
|
||||
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(Vec::new()),
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
// Older builds wrote `\\?\` paths.
|
||||
let mut list = Vec::with_capacity(listed.len());
|
||||
for path in listed {
|
||||
let plain = dunce::simplified(&path).to_path_buf();
|
||||
if !list.contains(&plain) {
|
||||
list.push(plain);
|
||||
}
|
||||
}
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
/// Takes `root` out of the list.
|
||||
@@ -66,6 +75,13 @@ mod tests {
|
||||
assert_eq!(list[..2], [PathBuf::from("/r/10"), PathBuf::from("/r/24")]);
|
||||
forget(&file, Path::new("/r/10")).expect("forgets");
|
||||
assert_eq!(recent(&file).expect("reads")[0], PathBuf::from("/r/24"));
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let old = [r"\\?\C:\r\old", r"C:\r\old", r"\\?\C:\r\new"];
|
||||
std::fs::write(&file, serde_json::to_vec(&old).expect("json")).expect("writes");
|
||||
let plain = [PathBuf::from(r"C:\r\old"), PathBuf::from(r"C:\r\new")];
|
||||
assert_eq!(recent(&file).expect("reads"), plain);
|
||||
}
|
||||
std::fs::write(&file, "not json").expect("writes");
|
||||
assert!(
|
||||
remember(&file, Path::new("/r/1")).is_err(),
|
||||
|
||||
@@ -183,7 +183,7 @@ pub fn export(
|
||||
|
||||
/// The canonical form of a possibly missing path.
|
||||
fn resolved(path: &Path) -> io::Result<PathBuf> {
|
||||
match std::fs::canonicalize(path) {
|
||||
match dunce::canonicalize(path) {
|
||||
Ok(real) => Ok(real),
|
||||
Err(error) if error.kind() == io::ErrorKind::NotFound => {
|
||||
let name = path.file_name().ok_or_else(|| {
|
||||
@@ -192,7 +192,7 @@ fn resolved(path: &Path) -> io::Result<PathBuf> {
|
||||
format!("{} has no file name", path.display()),
|
||||
)
|
||||
})?;
|
||||
Ok(std::fs::canonicalize(parent_dir(path))?.join(name))
|
||||
Ok(dunce::canonicalize(parent_dir(path))?.join(name))
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ impl Sessions {
|
||||
/// The key of an existing file; missing fails loud.
|
||||
fn key(path: &Path) -> io::Result<Key> {
|
||||
Ok(Key {
|
||||
canonical: std::fs::canonicalize(path)?,
|
||||
canonical: dunce::canonicalize(path)?,
|
||||
id: file_id(path)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ license.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
dunce.workspace = true
|
||||
ely-ipc.workspace = true
|
||||
base64.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -74,7 +74,7 @@ impl Lok {
|
||||
|
||||
/// dlopens the LOK library and hooks with the profile URL.
|
||||
pub fn hook(install: &Path, profile_url: &str) -> io::Result<Self> {
|
||||
let install = std::fs::canonicalize(install)?;
|
||||
let install = dunce::canonicalize(install)?;
|
||||
let install = install.as_path();
|
||||
let install_str = install.to_string_lossy().into_owned();
|
||||
let install_c = cstring(&install_str)?;
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Worker {
|
||||
pub(crate) fn tile_self_check(&mut self, profile_dir: &Path) -> io::Result<bool> {
|
||||
let doc = profile_dir.join("lok-verify.fodt");
|
||||
std::fs::write(&doc, VERIFY_DOC)?;
|
||||
let url = ipc::file_url_of(&doc.canonicalize()?);
|
||||
let url = ipc::file_url_of(&dunce::canonicalize(&doc)?);
|
||||
let payload = self.request(tag::VERIFY, &Pack::new().str(&url).bytes())?;
|
||||
let red = Unpack::new(&payload).u64()?;
|
||||
Ok(red > 0)
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn run(
|
||||
output: impl Write + Send + 'static,
|
||||
) -> io::Result<()> {
|
||||
set_output(Box::new(output));
|
||||
let profile_dir = std::fs::canonicalize(profile_dir)?;
|
||||
let profile_dir = dunce::canonicalize(profile_dir)?;
|
||||
let profile_url = profile_url_of(&profile_dir);
|
||||
let _ = teardown::PROFILE.set(profile_dir.clone());
|
||||
let lok = Lok::hook(Path::new(install), &profile_url)?;
|
||||
|
||||
@@ -7,6 +7,7 @@ license.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
dunce.workspace = true
|
||||
anyhow.workspace = true
|
||||
directories.workspace = true
|
||||
ely-files.workspace = true
|
||||
|
||||
@@ -14,14 +14,14 @@ use crate::{After, Closing, Dialog, Engine, Host, Opening, Tab, Tabs, in_window,
|
||||
|
||||
/// The file a path names, links resolved.
|
||||
fn identity(path: &Path) -> io::Result<PathBuf> {
|
||||
match std::fs::canonicalize(path) {
|
||||
match dunce::canonicalize(path) {
|
||||
Ok(real) => Ok(real),
|
||||
Err(error) if error.kind() == io::ErrorKind::NotFound => {
|
||||
let parent = path.parent().unwrap_or(Path::new("."));
|
||||
let name = path
|
||||
.file_name()
|
||||
.ok_or_else(|| io::Error::other("no file name"))?;
|
||||
Ok(std::fs::canonicalize(parent)?.join(name))
|
||||
Ok(dunce::canonicalize(parent)?.join(name))
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user