diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1,6 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. - [[package]] name = "adler" version = "0.2.3" @@ -67,6 +66,12 @@ ] [[package]] +name = "bumpalo" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" + +[[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -282,6 +287,26 @@ ] [[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -357,6 +382,17 @@ ] [[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", +] + +[[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -380,9 +416,9 @@ "clap", "crossbeam-channel 0.4.4", "derive_more", + "directories", "flate2", "format-bytes", - "home", "im-rc", "itertools", "lazy_static", @@ -417,15 +453,6 @@ ] [[package]] -name = "home" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" -dependencies = [ - "winapi", -] - -[[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -467,6 +494,15 @@ ] [[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -691,7 +727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.15", "libc", "rand_chacha", "rand_core", @@ -714,7 +750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.15", ] [[package]] @@ -785,6 +821,25 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall 0.2.10", +] + +[[package]] name = "regex" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -818,15 +873,15 @@ "chrono", "clap", "derive_more", + "directories", "env_logger", "format-bytes", "hg-core", - "home", "lazy_static", "log", "micro-timer", "regex", - "users", + "whoami", ] [[package]] @@ -887,9 +942,9 @@ [[package]] name = "syn" -version = "1.0.54" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" dependencies = [ "proc-macro2", "quote", @@ -905,7 +960,7 @@ "cfg-if 0.1.10", "libc", "rand", - "redox_syscall", + "redox_syscall 0.1.57", "remove_dir_all", "winapi", ] @@ -978,16 +1033,6 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] -name = "users" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" -dependencies = [ - "libc", - "log", -] - -[[package]] name = "vcpkg" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1018,6 +1063,80 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d595b2e146f36183d6a590b8d41568e2bc84c922267f43baf61c956330eeb436" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1050,18 +1169,18 @@ [[package]] name = "zstd" -version = "0.5.3+zstd.1.4.5" +version = "0.5.4+zstd.1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8" +checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "2.0.5+zstd.1.4.5" +version = "2.0.6+zstd.1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055" +checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e" dependencies = [ "libc", "zstd-sys", @@ -1069,9 +1188,9 @@ [[package]] name = "zstd-sys" -version = "1.4.17+zstd.1.4.5" +version = "1.4.18+zstd.1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b" +checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81" dependencies = [ "cc", "glob", diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -12,7 +12,7 @@ bytes-cast = "0.2" byteorder = "1.3.4" derive_more = "0.99" -home = "0.5" +directories = "4.0.1" im-rc = "15.0.*" itertools = "0.9" lazy_static = "1.4.0" diff --git a/rust/hg-core/src/config/config.rs b/rust/hg-core/src/config/config.rs --- a/rust/hg-core/src/config/config.rs +++ b/rust/hg-core/src/config/config.rs @@ -13,6 +13,7 @@ ConfigError, ConfigLayer, ConfigOrigin, ConfigValue, }; use crate::utils::files::get_bytes_from_os_str; +use directories::{BaseDirs, UserDirs}; use format_bytes::{write_bytes, DisplayBytes}; use std::collections::HashSet; use std::env; @@ -192,13 +193,20 @@ } } - #[cfg(unix)] // TODO: other platforms fn add_system_config(&mut self) -> Result<(), ConfigError> { + // TODO: Windows, check this registry key + // - HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial + // - or HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial for 32bit + // Python on 64bit Windows. + let mut add_for_prefix = |prefix: &Path| -> Result<(), ConfigError> { - let etc = prefix.join("etc").join("mercurial"); - self.add_trusted_file(&etc.join("hgrc"))?; - self.add_trusted_dir(&etc.join("hgrc.d")) + #[cfg(unix)] + let prefix = prefix.join("etc").join("mercurial"); + + self.add_trusted_file(&prefix.join("hgrc"))?; + self.add_trusted_dir(&prefix.join("hgrc.d")) }; + let root = Path::new("/"); // TODO: use `std::env::args_os().next().unwrap()` a.k.a. argv[0] // instead? TODO: can this be a relative path? @@ -211,20 +219,28 @@ add_for_prefix(&installation_prefix)? } } + + #[cfg(unix)] add_for_prefix(root)?; + Ok(()) } - #[cfg(unix)] // TODO: other plateforms fn add_user_config(&mut self) -> Result<(), ConfigError> { - let opt_home = home::home_dir(); + let opt_home = UserDirs::new() + .map(|user_dirs| user_dirs.home_dir().to_path_buf()); if let Some(home) = &opt_home { - self.add_trusted_file(&home.join(".hgrc"))? + self.add_trusted_file(&home.join(".hgrc"))?; + + #[cfg(windows)] + self.add_trusted_file(&home.join("Mercurial.ini"))?; } + + let unix = cfg!(target_os = "unix"); let darwin = cfg!(any(target_os = "macos", target_os = "ios")); - if !darwin { - if let Some(config_home) = env::var_os("XDG_CONFIG_HOME") - .map(PathBuf::from) + if unix && !darwin { + if let Some(config_home) = BaseDirs::new() + .map(|base_dirs| base_dirs.config_dir().to_path_buf()) .or_else(|| opt_home.map(|home| home.join(".config"))) { self.add_trusted_file(&config_home.join("hg").join("hgrc"))? diff --git a/rust/hg-core/src/dirstate/entry.rs b/rust/hg-core/src/dirstate/entry.rs --- a/rust/hg-core/src/dirstate/entry.rs +++ b/rust/hg-core/src/dirstate/entry.rs @@ -107,16 +107,27 @@ } // TODO: other platforms - #[cfg(unix)] pub fn mode_changed( &self, + #[cfg_attr(windows, allow(unused_variables))] filesystem_metadata: &std::fs::Metadata, ) -> bool { - use std::os::unix::fs::MetadataExt; - const EXEC_BIT_MASK: u32 = 0o100; - let dirstate_exec_bit = (self.mode as u32) & EXEC_BIT_MASK; - let fs_exec_bit = filesystem_metadata.mode() & EXEC_BIT_MASK; - dirstate_exec_bit != fs_exec_bit + #[cfg(unix)] + { + use std::os::unix::fs::MetadataExt; + const EXEC_BIT_MASK: u32 = 0o100; + let dirstate_exec_bit = (self.mode as u32) & EXEC_BIT_MASK; + let fs_exec_bit = filesystem_metadata.mode() & EXEC_BIT_MASK; + dirstate_exec_bit != fs_exec_bit + } + + #[cfg(windows)] + { + // According to this SO, Mercurial only tracks executable bits on + // files, which it isn't able to do on Windows systems. + // https://stackoverflow.com/a/18926911 + false + } } /// Returns a `(state, mode, size, mtime)` tuple as for diff --git a/rust/hg-core/src/dirstate_tree/status.rs b/rust/hg-core/src/dirstate_tree/status.rs --- a/rust/hg-core/src/dirstate_tree/status.rs +++ b/rust/hg-core/src/dirstate_tree/status.rs @@ -682,13 +682,25 @@ } } -#[cfg(unix)] // TODO +// TODO: Support other systems fn mtime_seconds(metadata: &std::fs::Metadata) -> i64 { // Going through `Metadata::modified()` would be portable, but would take // care to construct a `SystemTime` value with sub-second precision just // for us to throw that away here. - use std::os::unix::fs::MetadataExt; - metadata.mtime() + #[cfg(unix)] + { + use std::os::unix::fs::MetadataExt; + metadata.mtime() + } + + #[cfg(windows)] + { + use std::os::windows::fs::MetadataExt; + let ticks = metadata.last_write_time(); + + use crate::utils::files::from_win_filetime; + from_win_filetime(ticks) as i64 + } } struct DirEntry { diff --git a/rust/hg-core/src/filepatterns.rs b/rust/hg-core/src/filepatterns.rs --- a/rust/hg-core/src/filepatterns.rs +++ b/rust/hg-core/src/filepatterns.rs @@ -234,13 +234,13 @@ [b'*', b'?', b'[', b']', b'{', b'}', b'\\']; /// TODO support other platforms -#[cfg(unix)] pub fn normalize_path_bytes(bytes: &[u8]) -> Vec { if bytes.is_empty() { return b".".to_vec(); } - let sep = b'/'; + let sep = std::path::MAIN_SEPARATOR as u8; + let mut initial_slashes = bytes.iter().take_while(|b| **b == sep).count(); if initial_slashes > 2 { // POSIX allows one or two initial slashes, but treats three or more diff --git a/rust/hg-core/src/utils.rs b/rust/hg-core/src/utils.rs --- a/rust/hg-core/src/utils.rs +++ b/rust/hg-core/src/utils.rs @@ -205,20 +205,41 @@ } } -#[cfg(unix)] pub fn shell_quote(value: &[u8]) -> Vec { // TODO: Use the `matches!` macro when we require Rust 1.42+ - if value.iter().all(|&byte| match byte { - b'a'..=b'z' - | b'A'..=b'Z' - | b'0'..=b'9' - | b'.' - | b'_' - | b'/' - | b'+' - | b'-' => true, - _ => false, - }) { + let valid_chars; + #[cfg(unix)] + { + valid_chars = |&byte| match byte { + b'a'..=b'z' + | b'A'..=b'Z' + | b'0'..=b'9' + | b'.' + | b'_' + | b'/' + | b'+' + | b'-' => true, + _ => false, + }; + } + + #[cfg(windows)] + { + valid_chars = |&byte| match byte { + b'a'..=b'z' + | b'A'..=b'Z' + | b'0'..=b'9' + | b'.' + | b'_' + | b'/' + | b'\\' + | b'+' + | b'-' => true, + _ => false, + }; + } + + if value.iter().all(valid_chars) { value.to_owned() } else { let mut quoted = Vec::with_capacity(value.len() + 2); diff --git a/rust/hg-core/src/utils/files.rs b/rust/hg-core/src/utils/files.rs --- a/rust/hg-core/src/utils/files.rs +++ b/rust/hg-core/src/utils/files.rs @@ -23,40 +23,62 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; -pub fn get_os_str_from_bytes(bytes: &[u8]) -> &OsStr { - let os_str; +// TODO Handle other platforms +pub fn get_os_str_from_bytes(bytes: &[u8]) -> OsString { #[cfg(unix)] { use std::os::unix::ffi::OsStrExt; - os_str = std::ffi::OsStr::from_bytes(bytes); + let os_str = OsStr::from_bytes(bytes); + os_str.to_os_string() } - // TODO Handle other platforms - // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). - // Perhaps, the return type would have to be Result. - os_str + + #[cfg(windows)] + { + use std::os::windows::ffi::OsStringExt; + // TODO: convert from WTF8 to Windows MBCS (ANSI encoding) + let wide_bytes: Vec = bytes.iter().map(|b| *b as u16).collect(); + OsString::from_wide(wide_bytes.as_slice()) + } } -pub fn get_path_from_bytes(bytes: &[u8]) -> &Path { - Path::new(get_os_str_from_bytes(bytes)) +pub fn get_path_from_bytes(bytes: &[u8]) -> PathBuf { + Path::new(&get_os_str_from_bytes(bytes)).to_path_buf() } // TODO: need to convert from WTF8 to MBCS bytes on Windows. // that's why Vec is returned. -#[cfg(unix)] pub fn get_bytes_from_path(path: impl AsRef) -> Vec { get_bytes_from_os_str(path.as_ref()) } -#[cfg(unix)] pub fn get_bytes_from_os_str(str: impl AsRef) -> Vec { - use std::os::unix::ffi::OsStrExt; - str.as_ref().as_bytes().to_vec() + #[cfg(unix)] + { + use std::os::unix::ffi::OsStrExt; + str.as_ref().as_bytes().to_vec() + } + + #[cfg(windows)] + { + use std::os::windows::ffi::OsStrExt; + // TODO: convert from WTF8 to Windows MBCS (ANSI encoding) + // If the conversion from u16 to u8 is lossy then issues will + // occur elsewhere. + str.as_ref().encode_wide().map(|b| b as u8).collect() + } } -#[cfg(unix)] pub fn get_bytes_from_os_string(str: OsString) -> Vec { - use std::os::unix::ffi::OsStringExt; - str.into_vec() + #[cfg(unix)] + { + use std::os::unix::ffi::OsStringExt; + str.into_vec() + } + + #[cfg(windows)] + { + get_bytes_from_os_str(str.as_os_str()) + } } /// An iterator over repository path yielding itself and its ancestors. @@ -213,6 +235,45 @@ } } +#[cfg(windows)] +impl HgMetadata { + pub fn from_metadata(metadata: Metadata) -> Self { + use std::os::windows::fs::MetadataExt; + + let mode = match metadata.permissions().readonly() { + true => 0o400, + false => 0o600, + }; + + Self { + st_dev: 0, + st_mode: mode, + st_nlink: 0, + st_size: metadata.len(), + st_mtime: from_win_filetime(metadata.last_write_time()) as i64, + // Last status change time -- windows doesn't have corresponding + st_ctime: from_win_filetime(metadata.last_write_time()) as i64, + } + } + + pub fn is_symlink(&self) -> bool { + // ? + false + } +} + +#[cfg(windows)] +/// Converts Windows' FILETIME (100 ns from Jan. 1, 1601) to seconds from +/// the standard 1970 epoch. +pub fn from_win_filetime(ticks: u64) -> u64 { + match ticks { + 0 => 0, + // See from_intervals() implemented in + // https://github.com/alexcrichton/filetime/blob/master/src/windows.rs + n => n / 1_000_000_000 / 100, + } +} + /// Returns the canonical path of `name`, given `cwd` and `root` pub fn canonical_path( root: impl AsRef, diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -5,6 +5,7 @@ // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. +use crate::utils::files; use crate::utils::SliceExt; use std::borrow::Borrow; use std::borrow::Cow; @@ -489,14 +490,7 @@ hg_path: P, ) -> Result { hg_path.as_ref().check_state()?; - let os_str; - #[cfg(unix)] - { - use std::os::unix::ffi::OsStrExt; - os_str = std::ffi::OsStr::from_bytes(&hg_path.as_ref().as_bytes()); - } - // TODO Handle other platforms - // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). + let os_str = files::get_os_str_from_bytes(&hg_path.as_ref().as_bytes()); Ok(os_str.to_os_string()) } @@ -509,15 +503,9 @@ pub fn os_string_to_hg_path_buf>( os_string: S, ) -> Result { - let buf; - #[cfg(unix)] - { - use std::os::unix::ffi::OsStrExt; - buf = HgPathBuf::from_bytes(&os_string.as_ref().as_bytes()); - } - // TODO Handle other platforms - // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). - + let buf = HgPathBuf::from_bytes(&files::get_bytes_from_os_str( + os_string.as_ref(), + )); buf.check_state()?; Ok(buf) } @@ -525,16 +513,7 @@ pub fn path_to_hg_path_buf>( path: P, ) -> Result { - let buf; - let os_str = path.as_ref().as_os_str(); - #[cfg(unix)] - { - use std::os::unix::ffi::OsStrExt; - buf = HgPathBuf::from_bytes(&os_str.as_bytes()); - } - // TODO Handle other platforms - // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). - + let buf = HgPathBuf::from_bytes(&files::get_bytes_from_path(path)); buf.check_state()?; Ok(buf) } diff --git a/rust/hg-cpython/src/dirstate/status.rs b/rust/hg-cpython/src/dirstate/status.rs --- a/rust/hg-cpython/src/dirstate/status.rs +++ b/rust/hg-cpython/src/dirstate/status.rs @@ -205,7 +205,7 @@ let pattern = pattern.data(py); let source = k.get_item(py, 2)?.extract::(py)?; let source = get_path_from_bytes(source.data(py)); - let new = IgnorePattern::new(syntax, pattern, source); + let new = IgnorePattern::new(syntax, pattern, &source); Ok(new) }) .collect(); diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml --- a/rust/rhg/Cargo.toml +++ b/rust/rhg/Cargo.toml @@ -12,11 +12,13 @@ chrono = "0.4.19" clap = "2.33.1" derive_more = "0.99" -home = "0.5.3" +directories = "4.0.1" lazy_static = "1.4.0" log = "0.4.11" micro-timer = "0.3.1" regex = "1.3.9" env_logger = "0.7.1" format-bytes = "0.2.1" -users = "0.11.0" + +# The 1.1 series does not compile on rust 1.41, requires 1.43 +whoami = "1.0.3" \ No newline at end of file diff --git a/rust/rhg/src/blackbox.rs b/rust/rhg/src/blackbox.rs --- a/rust/rhg/src/blackbox.rs +++ b/rust/rhg/src/blackbox.rs @@ -112,8 +112,7 @@ impl ConfiguredBlackbox<'_> { fn log(&self, date_time: &DateTime, message: &[u8]) { let date = format_bytes::Utf8(date_time.format(self.date_format)); - let user = users::get_current_username().map(get_bytes_from_os_str); - let user = user.as_deref().unwrap_or(b"???"); + let user = get_bytes_from_os_str(&whoami::username_os()); let rev = format_bytes::Utf8(match self.repo.dirstate_parents() { Ok(parents) if parents.p2 == hg::revlog::node::NULL_NODE => { format!("{:x}", parents.p1) diff --git a/rust/rhg/src/commands/status.rs b/rust/rhg/src/commands/status.rs --- a/rust/rhg/src/commands/status.rs +++ b/rust/rhg/src/commands/status.rs @@ -160,15 +160,19 @@ let repo = invocation.repo?; let mut dmap = repo.dirstate_map_mut()?; + let check_exec = if cfg!(target_os = "windows") { + false + } else { + true + }; + let options = StatusOptions { // TODO should be provided by the dirstate parsing and // hence be stored on dmap. Using a value that assumes we aren't // below the time resolution granularity of the FS and the // dirstate. last_normal_time: 0, - // we're currently supporting file systems with exec flags only - // anyway - check_exec: true, + check_exec, list_clean: display_states.clean, list_unknown: display_states.unknown, list_ignored: display_states.ignored, diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs +++ b/rust/rhg/src/main.rs @@ -4,6 +4,7 @@ use clap::AppSettings; use clap::Arg; use clap::ArgMatches; +use directories::UserDirs; use format_bytes::{format_bytes, join}; use hg::config::{Config, ConfigSource}; use hg::exit_codes; @@ -105,7 +106,7 @@ let early_args = EarlyArgs::parse(std::env::args_os()); let initial_current_dir = early_args.cwd.map(|cwd| { - let cwd = get_path_from_bytes(&cwd); + let cwd = &get_path_from_bytes(&cwd); std::env::current_dir() .and_then(|initial| { std::env::set_current_dir(cwd)?; @@ -212,7 +213,8 @@ let non_repo_config_val = { let non_repo_val = non_repo_config.get(b"paths", &repo_arg); match &non_repo_val { - Some(val) if val.len() > 0 => home::home_dir() + Some(val) if val.len() > 0 => UserDirs::new() + .map(|user_dirs| user_dirs.home_dir().to_path_buf()) .unwrap_or_else(|| PathBuf::from("~")) .join(get_path_from_bytes(val)) .canonicalize() @@ -333,7 +335,7 @@ let mut args = std::env::args_os(); let executable_path = get_path_from_bytes(&executable); let this_executable = args.next().expect("exepcted argv[0] to exist"); - if executable_path == &PathBuf::from(this_executable) { + if executable_path == PathBuf::from(this_executable) { // Avoid spawning infinitely many processes until resource // exhaustion. let _ = ui.write_stderr(&format_bytes!(