Skip to content

Commit 6496be0

Browse files
paxbundjc
authored andcommitted
feat(cli/self-update): add support for PowerShell on Unix systems
1 parent d6d6ecb commit 6496be0

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

src/cli/self_update.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ This is usually done by running one of the following (note the leading DOT):
401401
source "{cargo_home}/env.fish" # For fish
402402
source $"{cargo_home_nushell}/env.nu" # For nushell
403403
source "{cargo_home}/env.tcsh" # For tcsh
404+
. "{cargo_home}/env.ps1" # For pwsh
404405
"#
405406
};
406407
}

src/cli/self_update/env.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# rustup shell setup
2+
if (-not ":${env:PATH}:".Contains(":{cargo_bin}:")) {
3+
${env:PATH} = "{cargo_bin}:${env:PATH}";
4+
}

src/cli/self_update/shell.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn cargo_home_str_with_home(home: &str, process: &Process) -> Result<Cow<'static
5858
}
5959

6060
// TODO: Tcsh (BSD)
61-
// TODO?: Make a decision on Ion Shell, Power Shell, Nushell
61+
// TODO?: Make a decision on Ion Shell
6262
// Cross-platform non-POSIX shells have not been assessed for integration yet
6363
fn enumerate_shells() -> Vec<Shell> {
6464
vec![
@@ -68,6 +68,7 @@ fn enumerate_shells() -> Vec<Shell> {
6868
Box::new(Fish),
6969
Box::new(Nu),
7070
Box::new(Tcsh),
71+
Box::new(Pwsh),
7172
]
7273
}
7374

@@ -368,6 +369,82 @@ impl UnixShell for Tcsh {
368369
}
369370
}
370371

372+
struct Pwsh;
373+
374+
impl UnixShell for Pwsh {
375+
fn does_exist(&self, process: &Process) -> bool {
376+
matches!(process.var("SHELL"), Ok(sh) if sh.contains("pwsh"))
377+
|| utils::find_cmd(&["pwsh"], process).is_some()
378+
}
379+
380+
fn rcfiles(&self, process: &Process) -> Vec<PathBuf> {
381+
let mut paths = vec![];
382+
383+
let Some(mut config_dir) = process.home_dir() else {
384+
return paths;
385+
};
386+
config_dir.extend([".config", "powershell"]);
387+
388+
// PowerShell provides many kinds of user-specific and host-specific
389+
// profile files. When the system has multiple profiles, PowerShell
390+
// executes them in a defined order.
391+
//
392+
// For more details, please refer to:
393+
// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles
394+
//
395+
// `~/.config/powershell/profile.ps1` is the "Current User, All Hosts"
396+
// profile file. It affects all PowerShell hosts of the current user.
397+
paths.push(config_dir.join("profile.ps1"));
398+
399+
let Ok(config_dir) = config_dir.read_dir() else {
400+
return paths;
401+
};
402+
403+
// Some editors like Visual Studio Code or PowerShell ISE use their
404+
// own dedicated profile files, whose file names are
405+
// `<Host Profile ID>_profile.ps1`. Such customization may use
406+
// PowerShell Editor Services for IDE integration.
407+
// https://github.com/PowerShell/PowerShellEditorServices
408+
for host_profile in config_dir {
409+
let Ok(host_profile) = host_profile else {
410+
continue;
411+
};
412+
let host_profile_path = host_profile.path();
413+
if !host_profile_path.is_file() {
414+
continue;
415+
}
416+
if host_profile_path.ends_with("_profile.ps1") {
417+
paths.push(host_profile_path);
418+
}
419+
}
420+
421+
paths
422+
}
423+
424+
fn update_rcs(&self, process: &Process) -> Vec<PathBuf> {
425+
let mut paths = vec![];
426+
// Always modify the "Current User, All Hosts" profile.
427+
let Some(mut profile) = process.home_dir() else {
428+
return paths;
429+
};
430+
431+
profile.extend([".config", "powershell", "profile.ps1"]);
432+
paths.push(profile);
433+
paths
434+
}
435+
436+
fn env_script(&self) -> ShellScript {
437+
ShellScript {
438+
name: "env.ps1",
439+
content: include_str!("env.ps1"),
440+
}
441+
}
442+
443+
fn source_string(&self, process: &Process) -> Result<String> {
444+
Ok(format!(r#". "{}/env.ps1""#, self.cargo_home_str(process)?))
445+
}
446+
}
447+
371448
pub(crate) fn legacy_paths(process: &Process) -> impl Iterator<Item = PathBuf> + '_ {
372449
let zprofiles = Zsh::zdotdir(process)
373450
.into_iter()

0 commit comments

Comments
 (0)