diff --git a/docs/tasks/file-tasks.md b/docs/tasks/file-tasks.md index 2a60c0aed3..cebe08a36e 100644 --- a/docs/tasks/file-tasks.md +++ b/docs/tasks/file-tasks.md @@ -103,3 +103,20 @@ Completions will now be enabled for your task. In this example, `mise run build will show `debug` and `release` as options. The `--user` flag will also show completions generated by the output of `mycli users`. (Note that cli and markdown help for tasks is not yet implemented in mise as of this writing but that is planned.) + +## CWD + +mise sets the current working directory to the directory of `mise.toml` before running tasks. +This can be overridden by setting `dir="{{cwd}}"` in the task header: + +```bash +#!/usr/bin/env bash +#MISE dir="{{cwd}}" +``` + +Also, the original working directory is available in the `MISE_ORIGINAL_CWD` environment variable: + +```bash +#!/usr/bin/env bash +cd "$MISE_ORIGINAL_CWD" +``` diff --git a/docs/tasks/index.md b/docs/tasks/index.md index 147f54b92a..391125014d 100644 --- a/docs/tasks/index.md +++ b/docs/tasks/index.md @@ -65,3 +65,14 @@ as `~/src/work/myproject/mise.local.toml` and they will be used inside tasks of As of this writing vars are only supported in TOML tasks. I want to add support for file tasks, but I don't want to turn all file tasks into tera templates just for this feature. + +## Environment variables passed to tasks + +The following environment variables are passed to the task: + +- `MISE_ORIGINAL_CWD`: The original working directory from where the task was run. +- `MISE_CONFIG_ROOT`: The directory containing the `mise.toml` file where the task was defined. +- `MISE_PROJECT_ROOT`: The root of the project. +- `MISE_TASK_NAME`: The name of the task being run. +- `MISE_TASK_DIR`: The directory containing the task script. +- `MISE_TASK_FILE`: The full path to the task script. diff --git a/src/cli/run.rs b/src/cli/run.rs index 5759ed181c..033fa17c35 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -207,6 +207,9 @@ impl Run { ..Default::default() })?; let mut env = ts.env_with_path(&CONFIG)?; + if let Some(cwd) = &*dirs::CWD { + env.insert("MISE_ORIGINAL_CWD".into(), cwd.display().to_string()); + } if let Some(root) = &CONFIG.project_root { env.insert("MISE_PROJECT_ROOT".into(), root.display().to_string()); env.insert("root".into(), root.display().to_string()); @@ -300,6 +303,16 @@ impl Run { return Ok(()); } + let mut env = env.clone(); + env.insert("MISE_TASK_NAME".into(), task.name.clone()); + let task_file = task.file.as_ref().unwrap_or(&task.config_source); + env.insert("MISE_TASK_FILE".into(), task_file.display().to_string()); + if let Some(dir) = task_file.parent() { + env.insert("MISE_TASK_DIR".into(), dir.display().to_string()); + } + if let Some(config_root) = &task.config_root { + env.insert("MISE_CONFIG_ROOT".into(), config_root.display().to_string()); + } let string_env: Vec<(String, String)> = task .env .iter() @@ -417,7 +430,9 @@ impl Run { trace!("using shell: {}", shell.join(" ")); let mut full_args = shell.clone(); let mut script = script.to_string(); - if shell[0] == "sh" || shell[0] == "bash" || shell[0] == "zsh" { + if script.lines().count() > 1 + && (shell[0] == "sh" || shell[0] == "bash" || shell[0] == "zsh") + { script = format!("set -e\n{}", script); } if !args.is_empty() { diff --git a/src/task/mod.rs b/src/task/mod.rs index cb1c89f406..e0ecc15752 100644 --- a/src/task/mod.rs +++ b/src/task/mod.rs @@ -49,7 +49,7 @@ pub struct Task { #[serde(default)] pub env: BTreeMap, #[serde(default)] - pub dir: Option, + pub dir: Option, #[serde(default)] pub hide: bool, #[serde(default)] @@ -313,13 +313,12 @@ impl Task { if let Some(dir) = &self.dir { // TODO: memoize // let dir = self.dir_rendered.get_or_try_init(|| -> Result { - let dir = dir.to_string_lossy().to_string(); let mut tera = get_tera(self.config_root.as_deref()); let mut ctx = BASE_CONTEXT.clone(); if let Some(config_root) = &self.config_root { ctx.insert("config_root", config_root); } - let dir = tera.render_str(&dir, &ctx)?; + let dir = tera.render_str(dir, &ctx)?; let dir = file::replace_path(&dir); if dir.is_absolute() { Ok(Some(dir.to_path_buf()))