mirror of
https://github.com/YaLTeR/niri.git
synced 2025-12-23 05:36:51 +00:00
Implement include optional=true (#3022)
* feat(niri): support `include optional=true "filename.kdl"` * chore: warn if optional include ENOENT * chore: validate include directive arguments and properties Add proper validation to reject: - Extra arguments beyond the path - Unknown properties (other than "optional") - Unexpected child nodes * docs: implement suggested typographical/prose changes * fixes --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
parent
c4462d0c7f
commit
7a237e519c
2 changed files with 79 additions and 5 deletions
|
|
@ -114,6 +114,30 @@ window-rule {
|
|||
}
|
||||
```
|
||||
|
||||
### Optional includes
|
||||
|
||||
<sup>Since: next release</sup>
|
||||
|
||||
By default, including a nonexistent file will cause an error.
|
||||
You can allow nonexistent includes by setting `optional=true`:
|
||||
|
||||
```kdl,must-fail
|
||||
// Won't fail if this file doesn't exist.
|
||||
include optional=true "optional-config.kdl"
|
||||
|
||||
// Regular include, will fail if the file doesn't exist.
|
||||
include "required-config.kdl"
|
||||
```
|
||||
|
||||
When an optional include file is missing, niri will emit a warning in the logs on every config reload.
|
||||
This reminds you that the file is missing while still loading the config successfully.
|
||||
|
||||
The optional file is still watched for changes, so if you create it later, the config will automatically reload and apply the new settings.
|
||||
|
||||
Note that `optional` only affects whether a missing file causes an error.
|
||||
If the file exists but contains invalid syntax or other errors, those errors will still cause a parsing failure.
|
||||
|
||||
|
||||
### Merging
|
||||
|
||||
Most config sections are merged between includes, meaning that you can set only a few properties, and only those properties will change.
|
||||
|
|
|
|||
|
|
@ -291,7 +291,51 @@ where
|
|||
}
|
||||
|
||||
"include" => {
|
||||
let path: PathBuf = utils::parse_arg_node("include", node, ctx)?;
|
||||
// Parse the path argument
|
||||
let mut iter_args = node.arguments.iter();
|
||||
let path_val = iter_args.next().ok_or_else(|| {
|
||||
DecodeError::missing(
|
||||
node,
|
||||
"additional argument for include path is required",
|
||||
)
|
||||
})?;
|
||||
let path: PathBuf = knuffel::traits::DecodeScalar::decode(path_val, ctx)?;
|
||||
|
||||
// Check for extra arguments
|
||||
if let Some(val) = iter_args.next() {
|
||||
ctx.emit_error(DecodeError::unexpected(
|
||||
&val.literal,
|
||||
"argument",
|
||||
"unexpected argument",
|
||||
));
|
||||
}
|
||||
|
||||
// Parse the optional property
|
||||
let mut optional = false;
|
||||
for (name, val) in &node.properties {
|
||||
match &***name {
|
||||
"optional" => {
|
||||
optional = knuffel::traits::DecodeScalar::decode(val, ctx)?;
|
||||
}
|
||||
name_str => {
|
||||
ctx.emit_error(DecodeError::unexpected(
|
||||
name,
|
||||
"property",
|
||||
format!("unexpected property `{}`", name_str.escape_default()),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for unexpected children
|
||||
for child in node.children() {
|
||||
ctx.emit_error(DecodeError::unexpected(
|
||||
child,
|
||||
"node",
|
||||
format!("unexpected node `{}`", child.node_name.escape_default()),
|
||||
));
|
||||
}
|
||||
|
||||
let base = ctx.get::<BasePath>().unwrap();
|
||||
let path = base.0.join(path);
|
||||
|
||||
|
|
@ -369,10 +413,16 @@ where
|
|||
}
|
||||
}
|
||||
Err(err) => {
|
||||
ctx.emit_error(DecodeError::missing(
|
||||
node,
|
||||
format!("failed to read included config from {path:?}: {err}"),
|
||||
));
|
||||
if optional && err.kind() == std::io::ErrorKind::NotFound {
|
||||
// Warn about missing optional includes
|
||||
warn!("optional include not found: {path:?}");
|
||||
} else {
|
||||
// Report all other errors normally
|
||||
ctx.emit_error(DecodeError::missing(
|
||||
node,
|
||||
format!("failed to read included config from {path:?}: {err}"),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue