mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-11-28 15:56:28 +00:00
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:
parent
4d55936f35
commit
02edad0c66
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user