Skip to content

Commit

Permalink
feat: allow _.file in vars
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Dec 15, 2024
1 parent 59ac1d5 commit e1d36a5
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 328 deletions.
9 changes: 9 additions & 0 deletions docs/tasks/task-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,12 @@ e2e_args = '--headless'
[tasks.test]
run = './scripts/test-e2e.sh {{vars.e2e_args}}'
```

Like `[env]`, vars can also be read in as a file:

```toml
[vars]
_.file = ".env"
```

[Secrets](/environments/secrets) are also supported as vars.
14 changes: 13 additions & 1 deletion e2e/tasks/test_task_vars
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,17 @@ cat <<EOF >mise.toml
tasks.a.run = "echo foo: {{vars.foo}}"
vars.foo = "bar"
EOF

assert "mise run a" "foo: bar"

cat <<EOF >mise.toml
tasks.a.run = "echo foo: {{vars.foo}}"
vars.foo = "{{cwd}}"
EOF
assert "mise run a" "foo: $(pwd)"

echo '{ "SECRET": "123" }' >.env.json
cat <<EOF >mise.toml
tasks.a.run = "echo foo: {{vars.SECRET}}"
vars._.file = ".env.json"
EOF
assert "mise run a" "foo: 123"
7 changes: 4 additions & 3 deletions src/cli/test_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::cli::args::ToolArg;
use crate::config::Config;
use crate::file::display_path;
use crate::registry::REGISTRY;
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::tera::get_tera;
use crate::toolset::{InstallOptions, ToolsetBuilder};
use crate::ui::time;
use crate::{dirs, env, file};
Expand Down Expand Up @@ -129,7 +129,8 @@ impl TestTool {
return Ok(());
};
let backend = tv.backend()?;
let env = ts.env_with_path(&Config::get())?;
let config = Config::get();
let env = ts.env_with_path(&config)?;
let mut which_parts = cmd.split_whitespace().collect::<Vec<_>>();
let cmd = which_parts.remove(0);
let mut which_cmd = backend.which(&tv, cmd)?.unwrap_or(PathBuf::from(cmd));
Expand Down Expand Up @@ -170,7 +171,7 @@ impl TestTool {
}
None => return Err(eyre!("command failed: terminated by signal")),
}
let mut ctx = BASE_CONTEXT.clone();
let mut ctx = config.tera_ctx.clone();
ctx.insert("version", &tv.version);
let mut tera = get_tera(dirs::CWD.as_ref().map(|d| d.as_path()));
let expected = tera.render_str(expected, &ctx)?;
Expand Down
10 changes: 5 additions & 5 deletions src/config/config_file/mise_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub struct MiseToml {
#[serde(default)]
watch_files: Vec<WatchFile>,
#[serde(default)]
vars: IndexMap<String, String>,
vars: EnvList,
#[serde(default)]
settings: SettingsPartial,
}
Expand Down Expand Up @@ -293,6 +293,10 @@ impl ConfigFile for MiseToml {
Ok(all)
}

fn vars_entries(&self) -> eyre::Result<Vec<EnvDirective>> {
Ok(self.vars.0.clone())
}

fn tasks(&self) -> Vec<&Task> {
self.tasks.0.values().collect()
}
Expand Down Expand Up @@ -486,10 +490,6 @@ impl ConfigFile for MiseToml {
.flatten()
.collect())
}

fn vars(&self) -> eyre::Result<&IndexMap<String, String>> {
Ok(&self.vars)
}
}

/// Returns a [`toml_edit::Key`] from the given `key`.
Expand Down
20 changes: 5 additions & 15 deletions src/config/config_file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::sync::{Mutex, Once};

use eyre::{eyre, Result};
use idiomatic_version::IdiomaticVersionFile;
use indexmap::IndexMap;
use once_cell::sync::Lazy;
use path_absolutize::Absolutize;
use serde_derive::Deserialize;
Expand All @@ -25,7 +24,6 @@ use crate::hash::hash_to_str;
use crate::hooks::Hook;
use crate::redactions::Redactions;
use crate::task::Task;
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::toolset::{ToolRequest, ToolRequestSet, ToolSource, ToolVersionList, Toolset};
use crate::ui::{prompt, style};
use crate::watch_files::WatchFile;
Expand Down Expand Up @@ -70,10 +68,13 @@ pub trait ConfigFile: Debug + Send + Sync {
fn config_root(&self) -> PathBuf {
config_root(self.get_path())
}
fn plugins(&self) -> eyre::Result<HashMap<String, String>> {
fn plugins(&self) -> Result<HashMap<String, String>> {
Ok(Default::default())
}
fn env_entries(&self) -> eyre::Result<Vec<EnvDirective>> {
fn env_entries(&self) -> Result<Vec<EnvDirective>> {
Ok(Default::default())
}
fn vars_entries(&self) -> Result<Vec<EnvDirective>> {
Ok(Default::default())
}
fn tasks(&self) -> Vec<&Task> {
Expand All @@ -93,21 +94,10 @@ pub trait ConfigFile: Debug + Send + Sync {
Ok(Default::default())
}

fn tera(&self) -> (tera::Tera, tera::Context) {
let tera = get_tera(Some(&self.config_root()));
let mut ctx = BASE_CONTEXT.clone();
ctx.insert("config_root", &self.config_root());
(tera, ctx)
}

fn task_config(&self) -> &TaskConfig {
static DEFAULT_TASK_CONFIG: Lazy<TaskConfig> = Lazy::new(TaskConfig::default);
&DEFAULT_TASK_CONFIG
}
fn vars(&self) -> Result<&IndexMap<String, String>> {
static DEFAULT_VARS: Lazy<IndexMap<String, String>> = Lazy::new(IndexMap::new);
Ok(&DEFAULT_VARS)
}

fn redactions(&self) -> &Redactions {
static DEFAULT_REDACTIONS: Lazy<Redactions> = Lazy::new(Redactions::default);
Expand Down
7 changes: 5 additions & 2 deletions src/config/env_directive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;

use crate::config::config_file::{config_root, trust_check};
use crate::config::Config;
use crate::dirs;
use crate::env_diff::EnvMap;
use crate::file::display_path;
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::tera::get_tera;
use eyre::{eyre, Context};
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer};
Expand Down Expand Up @@ -141,6 +142,7 @@ impl Display for EnvDirective {
}
}

#[derive(Default)]
pub struct EnvResults {
pub env: IndexMap<String, (String, PathBuf)>,
pub env_remove: BTreeSet<String>,
Expand All @@ -151,7 +153,8 @@ pub struct EnvResults {

impl EnvResults {
pub fn resolve(initial: &EnvMap, input: Vec<(EnvDirective, PathBuf)>) -> eyre::Result<Self> {
let mut ctx = BASE_CONTEXT.clone();
let config = Config::get();
let mut ctx = config.tera_ctx.clone();
// trace!("resolve: input: {:#?}", &input);
let mut env = initial
.iter()
Expand Down
73 changes: 59 additions & 14 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::hook_env::WatchFilePattern;
use crate::hooks::Hook;
use crate::plugins::PluginType;
use crate::redactions::Redactions;
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::watch_files::WatchFile;
use crate::wildcard::Wildcard;
pub use settings::SETTINGS;
Expand All @@ -46,13 +47,13 @@ type AliasMap = IndexMap<String, Alias>;
type ConfigMap = IndexMap<PathBuf, Box<dyn ConfigFile>>;
pub type EnvWithSources = IndexMap<String, (String, PathBuf)>;

#[derive(Default)]
pub struct Config {
pub config_files: ConfigMap,
pub project_root: Option<PathBuf>,
pub all_aliases: AliasMap,
pub repo_urls: HashMap<String, String>,
pub vars: IndexMap<String, String>,
pub tera_ctx: tera::Context,
aliases: AliasMap,
env: OnceCell<EnvResults>,
env_with_sources: OnceCell<EnvWithSources>,
Expand Down Expand Up @@ -105,13 +106,31 @@ impl Config {
let config_files = load_all_config_files(&config_paths, &idiomatic_files)?;
time!("load config_files");

let vars_results = load_vars(&config_files)?;
let vars = vars_results
.env
.iter()
.map(|(k, (v, _))| (k.clone(), v.clone()))
.collect();
let mut tera_ctx = BASE_CONTEXT.clone();
tera_ctx.insert("vars", &vars);

let mut config = Self {
aliases: load_aliases(&config_files)?,
project_root: get_project_root(&config_files),
repo_urls: load_plugins(&config_files)?,
vars: load_vars(&config_files)?,
tera_ctx,
vars,
config_files,
..Default::default()
env: OnceCell::new(),
env_with_sources: OnceCell::new(),
redactions: OnceCell::new(),
shorthands: OnceLock::new(),
hooks: OnceCell::new(),
tasks: OnceCell::new(),
tool_request_set: OnceCell::new(),
toolset: OnceCell::new(),
all_aliases: Default::default(),
};
time!("load build");

Expand Down Expand Up @@ -185,7 +204,7 @@ impl Config {
Ok(env)
})
}
pub fn env_results(&self) -> eyre::Result<&EnvResults> {
pub fn env_results(&self) -> Result<&EnvResults> {
self.env.get_or_try_init(|| self.load_env())
}
pub fn path_dirs(&self) -> eyre::Result<&Vec<PathBuf>> {
Expand Down Expand Up @@ -548,7 +567,7 @@ impl Config {
Ok(())
}

fn load_env(&self) -> eyre::Result<EnvResults> {
fn load_env(&self) -> Result<EnvResults> {
time!("load_env start");
let entries = self
.config_files
Expand Down Expand Up @@ -629,14 +648,21 @@ impl Config {
.collect())
}

fn tera(&self, config_root: &Path) -> (tera::Tera, tera::Context) {
let tera = get_tera(Some(config_root));
let mut ctx = self.tera_ctx.clone();
ctx.insert("config_root", &config_root);
(tera, ctx)
}

pub fn redactions(&self) -> Result<&IndexSet<String>> {
self.redactions.get_or_try_init(|| {
let mut redactions = Redactions::default();
for cf in self.config_files.values() {
let r = cf.redactions();
if !r.is_empty() {
let mut r = r.clone();
let (tera, ctx) = cf.tera();
let (tera, ctx) = self.tera(&cf.config_root());
r.render(&mut tera.clone(), &ctx)?;
redactions.merge(r);
}
Expand Down Expand Up @@ -1041,15 +1067,28 @@ fn load_plugins(config_files: &ConfigMap) -> Result<HashMap<String, String>> {
Ok(plugins)
}

fn load_vars(config_files: &ConfigMap) -> Result<IndexMap<String, String>> {
let mut vars = IndexMap::new();
for config_file in config_files.values() {
for (k, v) in config_file.vars()?.clone() {
vars.insert(k, v);
}
fn load_vars(config_files: &ConfigMap) -> Result<EnvResults> {
time!("load_vars start");
let entries = config_files
.iter()
.rev()
.map(|(source, cf)| {
cf.vars_entries()
.map(|ee| ee.into_iter().map(|e| (e, source.clone())))
})
.collect::<Result<Vec<_>>>()?
.into_iter()
.flatten()
.collect();
// trace!("load_vars: entries: {:#?}", entries);
let vars_results = EnvResults::resolve(&env::PRISTINE_ENV, entries)?;
time!("load_vars done");
if log::log_enabled!(log::Level::Trace) {
trace!("{vars_results:#?}");
} else {
debug!("{vars_results:?}");
}
trace!("load_vars: {}", vars.len());
Ok(vars)
Ok(vars_results)
}

impl Debug for Config {
Expand Down Expand Up @@ -1077,6 +1116,12 @@ impl Debug for Config {
if !env_results.env_files.is_empty() {
s.field("Path Dirs", &env_results.env_paths);
}
if !env_results.env_scripts.is_empty() {
s.field("Scripts", &env_results.env_scripts);
}
if !env_results.env_files.is_empty() {
s.field("Files", &env_results.env_files);
}
}
if !self.aliases.is_empty() {
s.field("Aliases", &self.aliases);
Expand Down
7 changes: 4 additions & 3 deletions src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::config::Config;
use crate::task::task_script_parser::{
has_any_args_defined, replace_template_placeholders_with_args, TaskScriptParser,
};
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::tera::get_tera;
use crate::ui::tree::TreeItem;
use crate::{dirs, file};
use console::{truncate_str, Color};
Expand Down Expand Up @@ -368,7 +368,7 @@ impl Task {
{
let config_root = self.config_root.clone().unwrap_or_default();
let mut tera = get_tera(Some(&config_root));
let mut tera_ctx = BASE_CONTEXT.clone();
let mut tera_ctx = config.tera_ctx.clone();
tera_ctx.insert("config_root", &config_root);
let dir = tera.render_str(&dir, &tera_ctx)?;
let dir = file::replace_path(&dir);
Expand Down Expand Up @@ -404,8 +404,9 @@ impl Task {
}

pub fn render(&mut self, config_root: &Path) -> Result<()> {
let config = Config::get();
let mut tera = get_tera(Some(config_root));
let mut tera_ctx = BASE_CONTEXT.clone();
let mut tera_ctx = config.tera_ctx.clone();
tera_ctx.insert("config_root", &config_root);
for a in &mut self.aliases {
*a = tera.render_str(a, &tera_ctx)?;
Expand Down
9 changes: 5 additions & 4 deletions src/task/task_script_parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::{Config, SETTINGS};
use crate::shell::ShellType;
use crate::task::Task;
use crate::tera::{get_tera, BASE_CONTEXT};
use crate::tera::get_tera;
use eyre::Result;
use indexmap::IndexMap;
use itertools::Itertools;
Expand Down Expand Up @@ -271,12 +271,13 @@ impl TaskScriptParser {
}
}
});
let mut ctx = BASE_CONTEXT.clone();
let config = Config::get();
let mut ctx = config.tera_ctx.clone();
ctx.insert("config_root", config_root);
let mut vars = IndexMap::new();
ctx.insert("vars", &vars);
for (k, v) in &Config::get().vars {
vars.insert(k.clone(), tera.render_str(v, &ctx).unwrap());
for (k, v) in &config.vars {
vars.insert(k.clone(), v.to_string());
ctx.insert("vars", &vars);
}
let scripts = scripts
Expand Down
Loading

0 comments on commit e1d36a5

Please sign in to comment.