mirror of
https://github.com/starship/starship.git
synced 2024-11-23 00:33:16 +01:00
fix(container): avoid detecting WSL as a systemd-container (#4593)
This commit is contained in:
parent
5f9804dd6a
commit
b47a4fe514
@ -10,7 +10,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
use super::ModuleConfig;
|
use super::ModuleConfig;
|
||||||
use crate::configs::container::ContainerConfig;
|
use crate::configs::container::ContainerConfig;
|
||||||
use crate::formatter::StringFormatter;
|
use crate::formatter::StringFormatter;
|
||||||
use crate::utils::read_file;
|
use crate::utils::{self, read_file};
|
||||||
|
|
||||||
pub fn container_name(context: &Context) -> Option<String> {
|
pub fn container_name(context: &Context) -> Option<String> {
|
||||||
use crate::utils::context_path;
|
use crate::utils::context_path;
|
||||||
@ -26,7 +26,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
return Some("OCI".into());
|
return Some("OCI".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if context_path(context, "/run/systemd/container").exists() {
|
// WSL with systemd will set the contents of this file to "wsl"
|
||||||
|
// Avoid showing the container module in that case
|
||||||
|
let systemd_path = context_path(context, "/run/systemd/container");
|
||||||
|
if utils::read_file(systemd_path)
|
||||||
|
.ok()
|
||||||
|
.filter(|s| s.trim() != "wsl")
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
// systemd
|
// systemd
|
||||||
return Some("Systemd".into());
|
return Some("Systemd".into());
|
||||||
}
|
}
|
||||||
@ -101,8 +108,9 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::test::ModuleRenderer;
|
use crate::test::ModuleRenderer;
|
||||||
|
use crate::utils;
|
||||||
use nu_ansi_term::Color;
|
use nu_ansi_term::Color;
|
||||||
use std::path::PathBuf;
|
use std::fs;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_none_if_disabled() {
|
fn test_none_if_disabled() {
|
||||||
@ -120,8 +128,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn containerenv(name: Option<&str>) -> std::io::Result<(Option<String>, Option<String>)> {
|
fn containerenv(name: Option<&str>) -> std::io::Result<(Option<String>, Option<String>)> {
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
let renderer = ModuleRenderer::new("container")
|
let renderer = ModuleRenderer::new("container")
|
||||||
// For a custom config
|
// For a custom config
|
||||||
.config(toml::toml! {
|
.config(toml::toml! {
|
||||||
@ -131,18 +137,15 @@ mod tests {
|
|||||||
|
|
||||||
let root_path = renderer.root_path();
|
let root_path = renderer.root_path();
|
||||||
|
|
||||||
let mut containerenv = PathBuf::from(root_path);
|
let containerenv = root_path.join("run/.containerenv");
|
||||||
|
|
||||||
containerenv.push("run");
|
fs::create_dir_all(containerenv.parent().unwrap())?;
|
||||||
std::fs::DirBuilder::new()
|
|
||||||
.recursive(true)
|
|
||||||
.create(&containerenv)?;
|
|
||||||
|
|
||||||
containerenv.push(".containerenv");
|
let contents = match name {
|
||||||
let mut file = std::fs::File::create(&containerenv)?;
|
Some(name) => format!("image=\"{name}\"\n"),
|
||||||
if let Some(name) = name {
|
None => String::new(),
|
||||||
file.write_all(format!("image=\"{name}\"\n").as_bytes())?;
|
};
|
||||||
}
|
utils::write_file(&containerenv, contents)?;
|
||||||
|
|
||||||
// The output of the module
|
// The output of the module
|
||||||
let actual = renderer
|
let actual = renderer
|
||||||
@ -182,6 +185,73 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn test_containerenv_systemd() -> std::io::Result<()> {
|
||||||
|
let renderer = ModuleRenderer::new("container")
|
||||||
|
// For a custom config
|
||||||
|
.config(toml::toml! {
|
||||||
|
[container]
|
||||||
|
disabled = false
|
||||||
|
});
|
||||||
|
|
||||||
|
let root_path = renderer.root_path();
|
||||||
|
|
||||||
|
let systemd_path = root_path.join("run/systemd/container");
|
||||||
|
|
||||||
|
fs::create_dir_all(systemd_path.parent().unwrap())?;
|
||||||
|
utils::write_file(&systemd_path, "systemd-nspawn\n")?;
|
||||||
|
|
||||||
|
// The output of the module
|
||||||
|
let actual = renderer
|
||||||
|
// Run the module and collect the output
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// The value that should be rendered by the module.
|
||||||
|
let expected = Some(format!(
|
||||||
|
"{} ",
|
||||||
|
Color::Red
|
||||||
|
.bold()
|
||||||
|
.dimmed()
|
||||||
|
.paint(format!("⬢ [{}]", "Systemd"))
|
||||||
|
));
|
||||||
|
|
||||||
|
// Assert that the actual and expected values are the same
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn test_containerenv_wsl() -> std::io::Result<()> {
|
||||||
|
let renderer = ModuleRenderer::new("container")
|
||||||
|
// For a custom config
|
||||||
|
.config(toml::toml! {
|
||||||
|
[container]
|
||||||
|
disabled = false
|
||||||
|
});
|
||||||
|
|
||||||
|
let root_path = renderer.root_path();
|
||||||
|
|
||||||
|
let systemd_path = root_path.join("run/systemd/container");
|
||||||
|
|
||||||
|
fs::create_dir_all(systemd_path.parent().unwrap())?;
|
||||||
|
utils::write_file(&systemd_path, "wsl\n")?;
|
||||||
|
|
||||||
|
// The output of the module
|
||||||
|
let actual = renderer
|
||||||
|
// Run the module and collect the output
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// The value that should be rendered by the module.
|
||||||
|
let expected = None;
|
||||||
|
|
||||||
|
// Assert that the actual and expected values are the same
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
@ -109,11 +109,11 @@ impl<'a> GitDiff<'a> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::utils::create_command;
|
use crate::utils::{create_command, write_file};
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{self, Error, ErrorKind, Write};
|
use std::io::{self, Error, ErrorKind, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use nu_ansi_term::Color;
|
use nu_ansi_term::Color;
|
||||||
@ -157,7 +157,7 @@ mod tests {
|
|||||||
let path = repo_dir.path();
|
let path = repo_dir.path();
|
||||||
|
|
||||||
let file_path = path.join("the_file");
|
let file_path = path.join("the_file");
|
||||||
write_file(file_path, "First Line\nSecond Line")?;
|
write_file(file_path, "First Line\nSecond Line\n")?;
|
||||||
|
|
||||||
let actual = render_metrics(path);
|
let actual = render_metrics(path);
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ mod tests {
|
|||||||
let path = repo_dir.path();
|
let path = repo_dir.path();
|
||||||
|
|
||||||
let file_path = path.join("the_file");
|
let file_path = path.join("the_file");
|
||||||
write_file(file_path, "\nSecond Line\n\nModified\nAdded")?;
|
write_file(file_path, "\nSecond Line\n\nModified\nAdded\n")?;
|
||||||
|
|
||||||
let actual = render_metrics(path);
|
let actual = render_metrics(path);
|
||||||
|
|
||||||
@ -263,16 +263,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_file(file: PathBuf, text: &str) -> io::Result<()> {
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.create(true)
|
|
||||||
.truncate(true)
|
|
||||||
.open(file)?;
|
|
||||||
writeln!(file, "{text}")?;
|
|
||||||
file.sync_all()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_repo_with_commit() -> io::Result<tempfile::TempDir> {
|
fn create_repo_with_commit() -> io::Result<tempfile::TempDir> {
|
||||||
let repo_dir = tempfile::tempdir()?;
|
let repo_dir = tempfile::tempdir()?;
|
||||||
let path = repo_dir.path();
|
let path = repo_dir.path();
|
||||||
@ -312,7 +302,7 @@ mod tests {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Write a file on master and commit it
|
// Write a file on master and commit it
|
||||||
write_file(file, "First Line\nSecond Line\nThird Line")?;
|
write_file(file, "First Line\nSecond Line\nThird Line\n")?;
|
||||||
run_git_cmd(["add", "the_file"], Some(path), true)?;
|
run_git_cmd(["add", "the_file"], Some(path), true)?;
|
||||||
run_git_cmd(
|
run_git_cmd(
|
||||||
["commit", "--message", "Commit A", "--no-gpg-sign"],
|
["commit", "--message", "Commit A", "--no-gpg-sign"],
|
||||||
|
@ -159,13 +159,12 @@ struct StateDescription<'a> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use nu_ansi_term::Color;
|
use nu_ansi_term::Color;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs::OpenOptions;
|
use std::io::{self, Error, ErrorKind};
|
||||||
use std::io::{self, Error, ErrorKind, Write};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use crate::test::ModuleRenderer;
|
use crate::test::ModuleRenderer;
|
||||||
use crate::utils::create_command;
|
use crate::utils::{create_command, write_file};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||||
@ -289,15 +288,6 @@ mod tests {
|
|||||||
let path = repo_dir.path();
|
let path = repo_dir.path();
|
||||||
let conflicted_file = repo_dir.path().join("the_file");
|
let conflicted_file = repo_dir.path().join("the_file");
|
||||||
|
|
||||||
let write_file = |text: &str| {
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.create(true)
|
|
||||||
.truncate(true)
|
|
||||||
.open(&conflicted_file)?;
|
|
||||||
write!(file, "{text}")
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize a new git repo
|
// Initialize a new git repo
|
||||||
run_git_cmd(
|
run_git_cmd(
|
||||||
[
|
[
|
||||||
@ -332,7 +322,7 @@ mod tests {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Write a file on master and commit it
|
// Write a file on master and commit it
|
||||||
write_file("Version A")?;
|
write_file(&conflicted_file, "Version A")?;
|
||||||
run_git_cmd(["add", "the_file"], Some(path), true)?;
|
run_git_cmd(["add", "the_file"], Some(path), true)?;
|
||||||
run_git_cmd(
|
run_git_cmd(
|
||||||
["commit", "--message", "Commit A", "--no-gpg-sign"],
|
["commit", "--message", "Commit A", "--no-gpg-sign"],
|
||||||
@ -342,7 +332,7 @@ mod tests {
|
|||||||
|
|
||||||
// Switch to another branch, and commit a change to the file
|
// Switch to another branch, and commit a change to the file
|
||||||
run_git_cmd(["checkout", "-b", "other-branch"], Some(path), true)?;
|
run_git_cmd(["checkout", "-b", "other-branch"], Some(path), true)?;
|
||||||
write_file("Version B")?;
|
write_file(&conflicted_file, "Version B")?;
|
||||||
run_git_cmd(
|
run_git_cmd(
|
||||||
["commit", "--all", "--message", "Commit B", "--no-gpg-sign"],
|
["commit", "--all", "--message", "Commit B", "--no-gpg-sign"],
|
||||||
Some(path),
|
Some(path),
|
||||||
@ -351,7 +341,7 @@ mod tests {
|
|||||||
|
|
||||||
// Switch back to master, and commit a third change to the file
|
// Switch back to master, and commit a third change to the file
|
||||||
run_git_cmd(["checkout", "master"], Some(path), true)?;
|
run_git_cmd(["checkout", "master"], Some(path), true)?;
|
||||||
write_file("Version C")?;
|
write_file(conflicted_file, "Version C")?;
|
||||||
run_git_cmd(
|
run_git_cmd(
|
||||||
["commit", "--all", "--message", "Commit C", "--no-gpg-sign"],
|
["commit", "--all", "--message", "Commit C", "--no-gpg-sign"],
|
||||||
Some(path),
|
Some(path),
|
||||||
|
34
src/utils.rs
34
src/utils.rs
@ -48,6 +48,40 @@ pub fn read_file<P: AsRef<Path> + Debug>(file_name: P) -> Result<String> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write a string to a file
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn write_file<P: AsRef<Path>, S: AsRef<str>>(file_name: P, text: S) -> Result<()> {
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
let file_name = file_name.as_ref();
|
||||||
|
let text = text.as_ref();
|
||||||
|
|
||||||
|
log::trace!("Trying to write {text:?} to {file_name:?}");
|
||||||
|
let mut file = match std::fs::OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(file_name)
|
||||||
|
{
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Error creating file: {:?}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match file.write_all(text.as_bytes()) {
|
||||||
|
Ok(_) => {
|
||||||
|
log::trace!("File {file_name:?} written successfully");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Error writing to file: {err:?}");
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.sync_all()
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads command output from stderr or stdout depending on to which stream program streamed it's output
|
/// Reads command output from stderr or stdout depending on to which stream program streamed it's output
|
||||||
pub fn get_command_string_output(command: CommandOutput) -> String {
|
pub fn get_command_string_output(command: CommandOutput) -> String {
|
||||||
if command.stdout.is_empty() {
|
if command.stdout.is_empty() {
|
||||||
|
Loading…
Reference in New Issue
Block a user