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 <jean.gautier@ssi.gouv.fr>
This commit is contained in:
Jean Gautier 2020-04-30 10:40:56 +02:00 committed by GitHub
parent 4d55936f35
commit 02edad0c66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 32 deletions

View File

@ -7,12 +7,15 @@ function global:prompt {
# @ makes sure the result is an array even if single or no values are returned # @ makes sure the result is an array even if single or no values are returned
$jobs = @(Get-Job | Where-Object { $_.State -eq 'Running' }).Count $jobs = @(Get-Job | Where-Object { $_.State -eq 'Running' }).Count
$env:PWD = $PWD
$current_directory = (Convert-Path $PWD)
if ($lastCmd = Get-History -Count 1) { if ($lastCmd = Get-History -Count 1) {
$duration = [math]::Round(($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds) $duration = [math]::Round(($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds)
# & ensures the path is interpreted as something to execute # & 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 { } 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 # Convert stdout (array of lines) to expected return type string

View File

@ -1,5 +1,5 @@
use path_slash::PathExt; use path_slash::PathExt;
use std::path::Path; use std::path::{Path, PathBuf};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use super::{Context, Module}; use super::{Context, Module};
@ -29,7 +29,13 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
// Using environment PWD is the standard approach for determining logical path // 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 // 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 { 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 { } else {
match std::env::current_dir() { match std::env::current_dir() {
Ok(x) => Some(x), Ok(x) => Some(x),
@ -101,43 +107,25 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
/// `top_level_replacement`. /// `top_level_replacement`.
fn contract_path(full_path: &Path, top_level_path: &Path, top_level_replacement: &str) -> String { fn contract_path(full_path: &Path, top_level_path: &Path, top_level_replacement: &str) -> String {
if !full_path.starts_with(top_level_path) { 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 { if full_path == top_level_path {
return replace_c_dir(top_level_replacement.to_string()); return top_level_replacement.to_string();
} }
format!( format!(
"{replacement}{separator}{path}", "{replacement}{separator}{path}",
replacement = top_level_replacement, replacement = top_level_replacement,
separator = "/", separator = "/",
path = replace_c_dir( path = full_path
full_path .strip_prefix(top_level_path)
.strip_prefix(top_level_path) .unwrap()
.unwrap() .to_slash()
.to_slash() .unwrap()
.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 /// 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 /// 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 top_level_path = Path::new("C:\\Users\\astronaut");
let output = contract_path(full_path, top_level_path, "~"); let output = contract_path(full_path, top_level_path, "~");
assert_eq!(output, "/c/Some/Other/Path"); assert_eq!(output, "C://Some/Other/Path");
} }
#[test] #[test]
@ -232,7 +220,7 @@ mod tests {
let top_level_path = Path::new("C:\\Users\\astronaut"); let top_level_path = Path::new("C:\\Users\\astronaut");
let output = contract_path(full_path, top_level_path, "~"); let output = contract_path(full_path, top_level_path, "~");
assert_eq!(output, "/c"); assert_eq!(output, "C:/");
} }
#[test] #[test]

View File

@ -132,7 +132,7 @@ fn directory_in_root() -> io::Result<()> {
.output()?; .output()?;
let actual = String::from_utf8(output.stdout).unwrap(); 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); assert_eq!(expected, actual);
Ok(()) Ok(())
} }