From 02edad0c66474758d145ac17e36ba28836d1eced Mon Sep 17 00:00:00 2001 From: Jean Gautier Date: Thu, 30 Apr 2020 10:40:56 +0200 Subject: [PATCH] fix(directory): avoid confusing modules with PowerShell paths (#1114) * Avoid confusing modules with PowerShell paths * Avoid confusing modules with PowerShell paths Powershell supports PSDrives (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-psdrive?view=powershell-7) that allow to create "logical" drives mapped to actual Windows drives. * Preserve Windows directories * Preserve logical paths for Powershell * Fix formating with cargo fmt * Fix directory_in_root test Co-authored-by: Jean Gautier --- src/init/starship.ps1 | 7 ++++-- src/modules/directory.rs | 46 +++++++++++++----------------------- tests/testsuite/directory.rs | 2 +- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/init/starship.ps1 b/src/init/starship.ps1 index 0ae42c789..15b8a3598 100644 --- a/src/init/starship.ps1 +++ b/src/init/starship.ps1 @@ -7,12 +7,15 @@ function global:prompt { # @ makes sure the result is an array even if single or no values are returned $jobs = @(Get-Job | Where-Object { $_.State -eq 'Running' }).Count + $env:PWD = $PWD + $current_directory = (Convert-Path $PWD) + if ($lastCmd = Get-History -Count 1) { $duration = [math]::Round(($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds) # & ensures the path is interpreted as something to execute - $out = @(&::STARSHIP:: prompt "--path=$PWD" --status=$lastexitcode --jobs=$jobs --cmd-duration=$duration) + $out = @(&::STARSHIP:: prompt "--path=$current_directory" --status=$lastexitcode --jobs=$jobs --cmd-duration=$duration) } else { - $out = @(&::STARSHIP:: prompt "--path=$PWD" --status=$lastexitcode --jobs=$jobs) + $out = @(&::STARSHIP:: prompt "--path=$current_directory" --status=$lastexitcode --jobs=$jobs) } # Convert stdout (array of lines) to expected return type string diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 61484c17d..16cee2f39 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -1,5 +1,5 @@ use path_slash::PathExt; -use std::path::Path; +use std::path::{Path, PathBuf}; use unicode_segmentation::UnicodeSegmentation; use super::{Context, Module}; @@ -29,7 +29,13 @@ pub fn module<'a>(context: &'a Context) -> Option> { // Using environment PWD is the standard approach for determining logical path // If this is None for any reason, we fall back to reading the os-provided path let physical_current_dir = if config.use_logical_path { - None + match std::env::var("PWD") { + Ok(x) => Some(PathBuf::from(x)), + Err(e) => { + log::debug!("Error getting PWD environment variable: {}", e); + None + } + } } else { match std::env::current_dir() { Ok(x) => Some(x), @@ -101,43 +107,25 @@ pub fn module<'a>(context: &'a Context) -> Option> { /// `top_level_replacement`. fn contract_path(full_path: &Path, top_level_path: &Path, top_level_replacement: &str) -> String { if !full_path.starts_with(top_level_path) { - return replace_c_dir(full_path.to_slash().unwrap()); + return full_path.to_slash().unwrap(); } if full_path == top_level_path { - return replace_c_dir(top_level_replacement.to_string()); + return top_level_replacement.to_string(); } format!( "{replacement}{separator}{path}", replacement = top_level_replacement, separator = "/", - path = replace_c_dir( - full_path - .strip_prefix(top_level_path) - .unwrap() - .to_slash() - .unwrap() - ) + path = full_path + .strip_prefix(top_level_path) + .unwrap() + .to_slash() + .unwrap() ) } -/// Replaces "C://" with "/c/" within a Windows path -/// -/// On non-Windows OS, does nothing -#[cfg(target_os = "windows")] -fn replace_c_dir(path: String) -> String { - path.replace("C:/", "/c") -} - -/// Replaces "C://" with "/c/" within a Windows path -/// -/// On non-Windows OS, does nothing -#[cfg(not(target_os = "windows"))] -const fn replace_c_dir(path: String) -> String { - path -} - /// Takes part before contracted path and replaces it with fish style path /// /// Will take the first letter of each directory before the contracted path and @@ -222,7 +210,7 @@ mod tests { let top_level_path = Path::new("C:\\Users\\astronaut"); let output = contract_path(full_path, top_level_path, "~"); - assert_eq!(output, "/c/Some/Other/Path"); + assert_eq!(output, "C://Some/Other/Path"); } #[test] @@ -232,7 +220,7 @@ mod tests { let top_level_path = Path::new("C:\\Users\\astronaut"); let output = contract_path(full_path, top_level_path, "~"); - assert_eq!(output, "/c"); + assert_eq!(output, "C:/"); } #[test] diff --git a/tests/testsuite/directory.rs b/tests/testsuite/directory.rs index e30e3d531..c236dff80 100644 --- a/tests/testsuite/directory.rs +++ b/tests/testsuite/directory.rs @@ -132,7 +132,7 @@ fn directory_in_root() -> io::Result<()> { .output()?; let actual = String::from_utf8(output.stdout).unwrap(); - let expected = format!("in {} ", Color::Cyan.bold().paint("/c")); + let expected = format!("in {} ", Color::Cyan.bold().paint("C:/")); assert_eq!(expected, actual); Ok(()) }