diff options
| -rw-r--r-- | Cargo.lock | 23 | ||||
| -rw-r--r-- | crates/vcs_data/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/vcs_data/src/data/local.rs | 88 |
3 files changed, 96 insertions, 19 deletions
@@ -1405,7 +1405,7 @@ dependencies = [ "tokio", "uuid", "vcs_docs", - "winapi-util", + "winapi", ] [[package]] @@ -1513,15 +1513,28 @@ dependencies = [ ] [[package]] -name = "winapi-util" -version = "0.1.11" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "windows-sys 0.61.2", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] name = "windows-core" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/crates/vcs_data/Cargo.toml b/crates/vcs_data/Cargo.toml index b06984f..de83b7b 100644 --- a/crates/vcs_data/Cargo.toml +++ b/crates/vcs_data/Cargo.toml @@ -30,5 +30,5 @@ dirs = "6.0.0" # Time chrono = "0.4.42" -# Win API -winapi-util = "0.1.11" +# Windows API +winapi = { version = "0.3.9", features = ["fileapi", "winbase", "winnt"] }
\ No newline at end of file diff --git a/crates/vcs_data/src/data/local.rs b/crates/vcs_data/src/data/local.rs index 76711a7..cbf41ba 100644 --- a/crates/vcs_data/src/data/local.rs +++ b/crates/vcs_data/src/data/local.rs @@ -78,18 +78,8 @@ impl LocalWorkspace { fs::write(local_path.join(CLIENT_FILE_TODOLIST), readme_content).await?; // On Windows, set the .jv directory as hidden - #[cfg(target_os = "windows")] - { - use std::os::windows::fs::MetadataExt; - use winapi_util::file::set_hidden; - - let jv_dir = local_path.join(".jv"); - if jv_dir.exists() { - if let Err(e) = set_hidden(&jv_dir, true) { - eprintln!("Warning: Failed to set .jv directory as hidden: {}", e); - } - } - } + let jv_dir = local_path.join(".jv"); + let _ = hide_folder::hide_folder(&jv_dir); Ok(()) } @@ -147,3 +137,77 @@ impl LocalWorkspace { Ok(local_sheet) } } + +mod hide_folder { + use std::io; + use std::path::Path; + + #[cfg(windows)] + use std::os::windows::ffi::OsStrExt; + #[cfg(windows)] + use winapi::um::fileapi::{GetFileAttributesW, SetFileAttributesW, INVALID_FILE_ATTRIBUTES}; + + pub fn hide_folder(path: &Path) -> io::Result<()> { + if !path.is_dir() { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Path must be a directory", + )); + } + + if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { + if !file_name.starts_with('.') { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Directory name must start with '.'", + )); + } + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Invalid directory name", + )); + } + + hide_folder_impl(path) + } + + #[cfg(windows)] + fn hide_folder_impl(path: &Path) -> io::Result<()> { + // Convert to Windows wide string format + let path_str: Vec<u16> = path.as_os_str() + .encode_wide() + .chain(Some(0)) + .collect(); + + // Get current attributes + let attrs = unsafe { GetFileAttributesW(path_str.as_ptr()) }; + if attrs == INVALID_FILE_ATTRIBUTES { + return Err(io::Error::last_os_error()); + } + + // Add hidden attribute flag + let new_attrs = attrs | winapi::um::winnt::FILE_ATTRIBUTE_HIDDEN; + + // Set new attributes + let success = unsafe { SetFileAttributesW(path_str.as_ptr(), new_attrs) }; + if success == 0 { + return Err(io::Error::last_os_error()); + } + + Ok(()) + } + + #[cfg(unix)] + fn hide_folder_impl(_path: &Path) -> io::Result<()> { + Ok(()) + } + + #[cfg(not(any(windows, unix)))] + fn hide_folder_impl(_path: &Path) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Unsupported, + "Unsupported operating system", + )) + } +}
\ No newline at end of file |
