Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions e2e/cli/test_config_set
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

echo '[tools.node]
version = "latest"' >mise.toml

assert "cat mise.toml" '[tools.node]
version = "latest"'

mise config set tools.node.postinstall 'corepack enable'
assert "mise config get tools.node.postinstall" "corepack enable"
assert "mise config get tools.node.version" "latest"
mise config set env._.python.venv.path '.venv'
assert "mise config get env._.python.venv.path" ".venv"
mise config set env._.python.venv.create true
assert "mise config get env._.python.venv.create" "true"
41 changes: 32 additions & 9 deletions src/cli/config/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,27 @@ impl ConfigSet {
let mut config: toml_edit::DocumentMut = std::fs::read_to_string(&file)?.parse()?;
let mut container = config.as_item_mut();
let parts = self.key.split('.').collect::<Vec<&str>>();
for key in parts.iter().take(parts.len() - 1) {
container = container.as_table_mut().unwrap().entry(key).or_insert({
let mut t = toml_edit::Table::new();
t.set_implicit(true);
toml_edit::Item::Table(t)
});
}
let last_key = parts.last().unwrap();
for (idx, key) in parts.iter().take(parts.len() - 1).enumerate() {
container = container
.as_table_like_mut()
.unwrap()
.entry(key)
.or_insert({
let mut t = toml_edit::Table::new();
t.set_implicit(true);
toml_edit::Item::Table(t)
});
// if the key is a tool with a simple value, we want to convert it to a inline table preserving the version
let is_simple_tool_version =
self.key.starts_with("tools.") && idx == 1 && !container.is_table_like();
if is_simple_tool_version {
let mut inline_table = toml_edit::InlineTable::new();
inline_table.insert("version", container.as_value().unwrap().clone());
*container =
toml_edit::Item::Value(toml_edit::Value::InlineTable(inline_table));
}
}

let type_to_use = match self.type_ {
TomlValueTypes::Infer => {
Expand All @@ -78,7 +91,10 @@ impl ConfigSet {
SettingsType::ListString => TomlValueTypes::List,
SettingsType::ListPath => TomlValueTypes::List,
},
None => TomlValueTypes::String,
None => match self.value.as_str() {
"true" | "false" => TomlValueTypes::Bool,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if we also should treat 0,1,y,n as boolean, would these even map to TOML values? mid-term the whole type inference logic should probably be moved to a package as it is also used by settings set for example

_ => TomlValueTypes::String,
},
}
}
_ => self.type_,
Expand All @@ -99,7 +115,14 @@ impl ConfigSet {
TomlValueTypes::Infer => bail!("Type not found"),
};

container.as_table_mut().unwrap().insert(last_key, value);
container
.as_table_like_mut()
.unwrap_or({
let mut t = toml_edit::Table::new();
t.set_implicit(true);
toml_edit::Item::Table(t).as_table_like_mut().unwrap()
})
.insert(last_key, value);

let raw = config.to_string();
MiseToml::from_str(&raw, &file)?;
Expand Down
Loading