[Request] [---- ] D10890: rust: remove dead utils module

Alphare (Raphaël Gomès) phabricator at mercurial-scm.org
Mon Jun 21 15:29:48 UTC 2021


Alphare created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This was introduced a while back while not being imported anywhere in the
  module system. How pertinent this Facebook module was to the codebase was
  debatable at the time, nowadays with the Rust VFS layer having laid its
  foundations, it is clear that we should drop it.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10890

AFFECTED FILES
  rust/hg-core/src/utils/path.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils/path.rs b/rust/hg-core/src/utils/path.rs
deleted file mode 100644
--- a/rust/hg-core/src/utils/path.rs
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This software may be used and distributed according to the terms of the
- * GNU General Public License version 2.
- */
-
-//! Path-related utilities.
-
-use std::env;
-#[cfg(not(unix))]
-use std::fs::rename;
-use std::fs::{self, remove_file as fs_remove_file};
-use std::io::{self, ErrorKind};
-use std::path::{Component, Path, PathBuf};
-
-use anyhow::Result;
-#[cfg(not(unix))]
-use tempfile::Builder;
-
-/// Normalize a canonicalized Path for display.
-///
-/// This removes the UNC prefix `\\?\` on Windows.
-pub fn normalize_for_display(path: &str) -> &str {
-    if cfg!(windows) && path.starts_with(r"\\?\") {
-        &path[4..]
-    } else {
-        path
-    }
-}
-
-/// Similar to [`normalize_for_display`]. But work on bytes.
-pub fn normalize_for_display_bytes(path: &[u8]) -> &[u8] {
-    if cfg!(windows) && path.starts_with(br"\\?\") {
-        &path[4..]
-    } else {
-        path
-    }
-}
-
-/// Return the absolute and normalized path without accessing the filesystem.
-///
-/// Unlike [`fs::canonicalize`], do not follow symlinks.
-///
-/// This function does not access the filesystem. Therefore it can behave
-/// differently from the kernel or other library functions in corner cases.
-/// For example:
-///
-/// - On some systems with symlink support, `foo/bar/..` and `foo` can be
-///   different as seen by the kernel, if `foo/bar` is a symlink. This function
-///   always returns `foo` in this case.
-/// - On Windows, the official normalization rules are much more complicated.
-///   See https://github.com/rust-lang/rust/pull/47363#issuecomment-357069527.
-///   For example, this function cannot translate "drive relative" path like
-///   "X:foo" to an absolute path.
-///
-/// Return an error if `std::env::current_dir()` fails or if this function
-/// fails to produce an absolute path.
-pub fn absolute(path: impl AsRef<Path>) -> io::Result<PathBuf> {
-    let path = path.as_ref();
-    let path = if path.is_absolute() {
-        path.to_path_buf()
-    } else {
-        std::env::current_dir()?.join(path)
-    };
-
-    if !path.is_absolute() {
-        return Err(io::Error::new(
-            io::ErrorKind::Other,
-            format!("cannot get absoltue path from {:?}", path),
-        ));
-    }
-
-    let mut result = PathBuf::new();
-    for component in path.components() {
-        match component {
-            Component::Normal(_)
-            | Component::RootDir
-            | Component::Prefix(_) => {
-                result.push(component);
-            }
-            Component::ParentDir => {
-                result.pop();
-            }
-            Component::CurDir => (),
-        }
-    }
-    Ok(result)
-}
-
-/// Remove the file pointed by `path`.
-#[cfg(unix)]
-pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<()> {
-    fs_remove_file(path)?;
-    Ok(())
-}
-
-/// Remove the file pointed by `path`.
-///
-/// On Windows, removing a file can fail for various reasons, including if the
-/// file is memory mapped. This can happen when the repository is accessed
-/// concurrently while a background task is trying to remove a packfile. To
-/// solve this, we can rename the file before trying to remove it.
-/// If the remove operation fails, a future repack will clean it up.
-#[cfg(not(unix))]
-pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<()> {
-    let path = path.as_ref();
-    let extension = path
-        .extension()
-        .and_then(|ext| ext.to_str())
-        .map_or(".to-delete".to_owned(), |ext| ".".to_owned() + ext + "-tmp");
-
-    let dest_path = Builder::new()
-        .prefix("")
-        .suffix(&extension)
-        .rand_bytes(8)
-        .tempfile_in(path.parent().unwrap())?
-        .into_temp_path();
-
-    rename(path, &dest_path)?;
-
-    // Ignore errors when removing the file, it will be cleaned up at a later
-    // time.
-    let _ = fs_remove_file(dest_path);
-    Ok(())
-}
-
-/// Create the directory and ignore failures when a directory of the same name
-/// already exists.
-pub fn create_dir(path: impl AsRef<Path>) -> io::Result<()> {
-    match fs::create_dir(path.as_ref()) {
-        Ok(()) => Ok(()),
-        Err(e) => {
-            if e.kind() == ErrorKind::AlreadyExists && path.as_ref().is_dir() {
-                Ok(())
-            } else {
-                Err(e)
-            }
-        }
-    }
-}
-
-/// Expand the user's home directory and any environment variables references
-/// in the given path.
-///
-/// This function is designed to emulate the behavior of Mercurial's
-/// `util.expandpath` function, which in turn uses Python's
-/// `os.path.expand{user,vars}` functions. This results in behavior that is
-/// notably different from the default expansion behavior of the `shellexpand`
-/// crate. In particular:
-///
-/// - If a reference to an environment variable is missing or invalid, the
-///   reference is left unchanged in the resulting path rather than emitting an
-///   error.
-///
-/// - Home directory expansion explicitly happens after environment variable
-///   expansion, meaning that if an environment variable is expanded into a
-///   string starting with a tilde (`~`), the tilde will be expanded into the
-///   user's home directory.
-pub fn expand_path(path: impl AsRef<str>) -> PathBuf {
-    expand_path_impl(path.as_ref(), |k| env::var(k).ok(), dirs::home_dir)
-}
-
-/// Same as `expand_path` but explicitly takes closures for environment
-/// variable and home directory lookup for the sake of testability.
-fn expand_path_impl<E, H>(path: &str, getenv: E, homedir: H) -> PathBuf
-where
-    E: FnMut(&str) -> Option<String>,
-    H: FnOnce() -> Option<PathBuf>,
-{
-    // The shellexpand crate does not expand Windows environment variables
-    // like `%PROGRAMDATA%`. We'd like to expand them too. So let's do some
-    // pre-processing.
-    //
-    // XXX: Doing this preprocessing has the unfortunate side-effect that
-    // if an environment variable fails to expand on Windows, the resulting
-    // string will contain a UNIX-style environment variable reference.
-    //
-    // e.g., "/foo/%MISSING%/bar" will expand to "/foo/${MISSING}/bar"
-    //
-    // The current approach is good enough for now, but likely needs to
-    // be improved later for correctness.
-    let path = {
-        let mut new_path = String::new();
-        let mut is_starting = true;
-        for ch in path.chars() {
-            if ch == '%' {
-                if is_starting {
-                    new_path.push_str("${");
-                } else {
-                    new_path.push('}');
-                }
-                is_starting = !is_starting;
-            } else if cfg!(windows) && ch == '/' {
-                // Only on Windows, change "/" to "\" automatically.
-                // This makes sure "%include /foo" works as expected.
-                new_path.push('\\')
-            } else {
-                new_path.push(ch);
-            }
-        }
-        new_path
-    };
-
-    let path = shellexpand::env_with_context_no_errors(&path, getenv);
-    shellexpand::tilde_with_context(&path, homedir)
-        .as_ref()
-        .into()
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use std::fs::File;
-
-    use tempfile::TempDir;
-
-    #[cfg(windows)]
-    mod windows {
-        use super::*;
-
-        #[test]
-        fn test_absolute_fullpath() {
-            assert_eq!(absolute("C:/foo").unwrap(), Path::new("C:\\foo"));
-            assert_eq!(
-                absolute("x:\\a/b\\./.\\c").unwrap(),
-                Path::new("x:\\a\\b\\c")
-            );
-            assert_eq!(
-                absolute("y:/a/b\\../..\\c\\../d\\./.").unwrap(),
-                Path::new("y:\\d")
-            );
-            assert_eq!(
-                absolute("z:/a/b\\../..\\../..\\..").unwrap(),
-                Path::new("z:\\")
-            );
-        }
-    }
-
-    #[cfg(unix)]
-    mod unix {
-        use super::*;
-
-        #[test]
-        fn test_absolute_fullpath() {
-            assert_eq!(
-                absolute("/a/./b\\c/../d/.").unwrap(),
-                Path::new("/a/d")
-            );
-            assert_eq!(absolute("/a/../../../../b").unwrap(), Path::new("/b"));
-            assert_eq!(absolute("/../../..").unwrap(), Path::new("/"));
-            assert_eq!(absolute("/../../../").unwrap(), Path::new("/"));
-            assert_eq!(
-                absolute("//foo///bar//baz").unwrap(),
-                Path::new("/foo/bar/baz")
-            );
-            assert_eq!(absolute("//").unwrap(), Path::new("/"));
-        }
-    }
-
-    #[test]
-    fn test_create_dir_non_exist() -> Result<()> {
-        let tempdir = TempDir::new()?;
-        let mut path = tempdir.path().to_path_buf();
-        path.push("dir");
-        create_dir(&path)?;
-        assert!(path.is_dir());
-        Ok(())
-    }
-
-    #[test]
-    fn test_create_dir_exist() -> Result<()> {
-        let tempdir = TempDir::new()?;
-        let mut path = tempdir.path().to_path_buf();
-        path.push("dir");
-        create_dir(&path)?;
-        assert!(&path.is_dir());
-        create_dir(&path)?;
-        assert!(&path.is_dir());
-        Ok(())
-    }
-
-    #[test]
-    fn test_create_dir_file_exist() -> Result<()> {
-        let tempdir = TempDir::new()?;
-        let mut path = tempdir.path().to_path_buf();
-        path.push("dir");
-        File::create(&path)?;
-        let err = create_dir(&path).unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::AlreadyExists);
-        Ok(())
-    }
-
-    #[test]
-    fn test_path_expansion() {
-        fn getenv(key: &str) -> Option<String> {
-            match key {
-                "foo" => Some("~/a".into()),
-                "bar" => Some("b".into()),
-                _ => None,
-            }
-        }
-
-        fn homedir() -> Option<PathBuf> {
-            Some(PathBuf::from("/home/user"))
-        }
-
-        let path = "$foo/${bar}/$baz";
-        let expected = PathBuf::from("/home/user/a/b/$baz");
-
-        assert_eq!(expand_path_impl(&path, getenv, homedir), expected);
-    }
-}



To: Alphare, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mercurial-scm.org/pipermail/mercurial-patches/attachments/20210621/56e7d4b8/attachment-0001.html>


More information about the Mercurial-patches mailing list