mirror of
https://github.com/edera-dev/sprout.git
synced 2026-11-05 00:12:20 +00:00
feat(sprout): generator variants (#105)
Generators can now declare variant axes. Every generated entry is multiplied by each combination of choices, one per axis. A choice sets the axis name to the choice name and inserts its own values, and the entry name is suffixed with the choice names. Generators can also declare exclude rules, which remove generated entries whose values match every glob pattern in a rule. This covers unwanted variant combinations and entries like BLS rescue kernels. Entry matching for default-entry and the bootloader interface now accepts `*` anywhere in the pattern instead of only at the end, so generated entry names can be matched regardless of the kernel version in the middle of the name. The BLS generator gains a pin-names option (default true, the existing behavior). Two BLS generators reading the same directory previously produced entries with identical names; disabling pin-names prefixes them with the generator name instead. Sprout now warns when more than one entry has the same name. * docs(config): note that variants suffix pinned BLS entry names Pinned BLS entry names match the BLS entry ids, but variants still append their choice names, so those entries need a pattern like <id>-* to be selected.
This commit is contained in:
9 files changed
+419
-26
No files matched your search
+22
-10
@@ -2,6 +2,7 @@ use crate::context::SproutContext;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::string::{String, ToString};
|
||||
use edera_sprout_config::entries::EntryDeclaration;
|
||||
use edera_sprout_parsing::glob_match;
|
||||
|
||||
/// Represents an entry that is stamped and ready to be booted.
|
||||
#[derive(Clone)]
|
||||
@@ -105,18 +106,29 @@ impl BootableEntry {
|
||||
}
|
||||
|
||||
/// Determine if this entry matches `needle` by comparing to the name or title of the entry.
|
||||
/// If `needle` ends with *, we will match a partial match.
|
||||
/// The `needle` is a glob pattern, where `*` matches any sequence of characters.
|
||||
/// A `needle` without any `*` must equal the name or title exactly.
|
||||
pub fn is_match(&self, needle: &str) -> bool {
|
||||
// If the needle ends with '*', we will accept a partial match.
|
||||
if needle.ends_with("*") {
|
||||
// Strip off any '*' at the end.
|
||||
let partial = needle.trim_end_matches("*");
|
||||
// Check if the name or title start with the partial match.
|
||||
return self.name.starts_with(partial) || self.title.starts_with(partial);
|
||||
}
|
||||
glob_match(needle, &self.name) || glob_match(needle, &self.title)
|
||||
}
|
||||
|
||||
// Standard quality matching rules.
|
||||
self.name == needle || self.title == needle
|
||||
/// Create a variant of this entry, with the name suffixed by `suffix` and using `context`.
|
||||
/// The actions of the entry are stamped with `context`, the same as the list generator.
|
||||
/// Variants of the same entry keep the sort key of this entry, so they stay grouped
|
||||
/// together in the order they were created in.
|
||||
pub fn variant(&self, suffix: &str, context: Rc<SproutContext>) -> Self {
|
||||
let mut entry = self.clone();
|
||||
entry.name.push_str(suffix);
|
||||
entry.declaration.actions = context
|
||||
.stamp_iter(entry.declaration.actions.iter())
|
||||
.collect();
|
||||
// Without any sort key, the name is used to sort, which differs between variants.
|
||||
// Pin the sort key to the name of this entry to keep the variants together.
|
||||
if entry.sort_key.is_none() && entry.declaration.sort_key.is_none() {
|
||||
entry.sort_key = Some(self.name.clone());
|
||||
}
|
||||
entry.context = context;
|
||||
entry
|
||||
}
|
||||
|
||||
/// Set the sort key of the entry. This is used to sort entries via version comparison.
|
||||
|
||||
Reference in new issue
Block a user