use crate::config::{ModuleConfig, StarshipConfig};
use crate::configs::StarshipRootConfig;
use crate::context_env::Env;
use crate::module::Module;
use crate::utils::{create_command, exec_timeout, read_file, CommandOutput, PathExt};
use crate::modules;
use crate::utils;
use clap::Parser;
use gix::{
repository::Kind,
sec::{self as git_sec, trust::DefaultForLevel},
state as git_state, Repository, ThreadSafeRepository,
};
use once_cell::sync::OnceCell;
#[cfg(test)]
use std::collections::HashMap;
use std::collections::HashSet;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fmt::Debug;
use std::fs;
use std::marker::PhantomData;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::string::String;
use std::time::{Duration, Instant};
use terminal_size::terminal_size;
/// Context contains data or common methods that may be used by multiple modules.
/// The data contained within Context will be relevant to this particular rendering
/// of the prompt.
pub struct Context<'a> {
/// The deserialized configuration map from the user's `starship.toml` file.
pub config: StarshipConfig,
/// The current working directory that starship is being called in.
pub current_dir: PathBuf,
/// A logical directory path which should represent the same directory as current_dir,
/// though may appear different.
/// E.g. when navigating to a PSDrive in PowerShell, or a path without symlinks resolved.
pub logical_dir: PathBuf,
/// A struct containing directory contents in a lookup-optimized format.
dir_contents: OnceCell<DirContents>,
/// Properties to provide to modules.
pub properties: Properties,
/// Private field to store Git information for modules who need it
repo: OnceCell<Repo>,
/// The shell the user is assumed to be running
pub shell: Shell,
/// Which prompt to print (main, right, ...)
pub target: Target,
/// Width of terminal, or zero if width cannot be detected.
pub width: usize,
/// A HashMap of environment variable mocks
pub env: Env<'a>,
/// A HashMap of command mocks
#[cfg(test)]
pub cmd: HashMap<&'a str, Option<CommandOutput>>,
/// a mock of the root directory
#[cfg(test)]
pub root_dir: tempfile::TempDir,
#[cfg(feature = "battery")]
pub battery_info_provider: &'a (dyn crate::modules::BatteryInfoProvider + Send + Sync),
/// Starship root config
pub root_config: StarshipRootConfig,
/// Avoid issues with unused lifetimes when features are disabled
_marker: PhantomData<&'a ()>,
}
impl<'a> Context<'a> {
/// Identify the current working directory and create an instance of Context
/// for it. "logical-path" is used when a shell allows the "current working directory"
/// to be something other than a file system path (like powershell provider specific paths).
pub fn new(arguments: Properties, target: Target) -> Context<'a> {
let shell = Context::get_shell();
// Retrieve the "current directory".
// If the path argument is not set fall back to the OS current directory.
let path = arguments
.path
.clone()
.or_else(|| env::current_dir().ok())
.or_else(|| env::var("PWD").map(PathBuf::from).ok())
.or_else(|| arguments.logical_path.clone())
.unwrap_or_default();
// Retrieve the "logical directory".
// If the path argument is not set fall back to the PWD env variable set by many shells
// or to the other path.
let logical_path = arguments
.logical_path
.clone()