mise 2026.4.11

The front-end to your dev env
use crate::cli::exec::Exec;
use std::path::PathBuf;

use crate::env;

/// Starts a new shell with the mise environment built from the current configuration
///
/// This is an alternative to `mise activate` that allows you to explicitly start a mise session.
/// It will have the tools and environment variables in the configs loaded.
/// Note that changing directories will not update the mise environment.
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct En {
    /// Directory to start the shell in
    #[clap(default_value = ".", verbatim_doc_comment, value_hint = clap::ValueHint::DirPath)]
    pub dir: PathBuf,

    /// Shell to start
    ///
    /// Defaults to $SHELL
    #[clap(verbatim_doc_comment, long, short = 's')]
    pub shell: Option<String>,
}

impl En {
    pub async fn run(self) -> eyre::Result<()> {
        env::set_current_dir(&self.dir)?;
        let shell = self.shell.unwrap_or((*env::SHELL).clone());
        let command = shell_words::split(&shell).map_err(|e| eyre::eyre!(e))?;

        Exec {
            tool: vec![],
            raw: false,
            jobs: None,
            c: None,
            command: Some(command),
            no_prepare: false,
            fresh_env: false,
            deny_all: false,
            deny_read: false,
            deny_write: false,
            deny_net: false,
            deny_env: false,
            allow_read: vec![],
            allow_write: vec![],
            allow_net: vec![],
            allow_env: vec![],
        }
        .run()
        .await
    }
}

static AFTER_LONG_HELP: &str = color_print::cstr!(
    r#"<bold><underline>Examples:</underline></bold>

    $ <bold>mise en .</bold>
    $ <bold>node -v</bold>
    v20.0.0

    Skip loading bashrc:
    $ <bold>mise en -s "bash --norc"</bold>

    Skip loading zshrc:
    $ <bold>mise en -s "zsh -f"</bold>
"#
);