mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-20 00:40:18 +00:00
feat(options): --boot now supports selecting by entry name or index, not just title
This commit is contained in:
55
src/main.rs
55
src/main.rs
@@ -2,6 +2,7 @@
|
||||
#![feature(uefi_std)]
|
||||
|
||||
use crate::context::{RootContext, SproutContext};
|
||||
use crate::entries::BootableEntry;
|
||||
use crate::options::SproutOptions;
|
||||
use crate::options::parser::OptionsRepresentable;
|
||||
use crate::phases::phase;
|
||||
@@ -109,61 +110,73 @@ fn main() -> Result<()> {
|
||||
// Execute the late phase.
|
||||
phase(context.clone(), &config.phases.startup).context("unable to execute startup phase")?;
|
||||
|
||||
let mut staged_entries = Vec::new();
|
||||
let mut entries = Vec::new();
|
||||
|
||||
// Insert all the static entries from the configuration into the entry list.
|
||||
for (_name, entry) in config.entries {
|
||||
for (name, entry) in config.entries {
|
||||
// Associate the main context with the static entry.
|
||||
staged_entries.push((context.clone(), entry));
|
||||
entries.push(BootableEntry::new(
|
||||
name,
|
||||
context.stamp(&entry.title),
|
||||
context.clone(),
|
||||
entry,
|
||||
));
|
||||
}
|
||||
|
||||
// Run all the generators declared in the configuration.
|
||||
for (_name, generator) in config.generators {
|
||||
for (name, generator) in config.generators {
|
||||
let context = context.fork().freeze();
|
||||
|
||||
// We will prefix all entries with [name]-.
|
||||
let prefix = format!("{}-", name);
|
||||
|
||||
// Add all the entries generated by the generator to the entry list.
|
||||
// The generator specifies the context associated with the entry.
|
||||
for entry in generators::generate(context.clone(), &generator)? {
|
||||
staged_entries.push(entry);
|
||||
for mut entry in generators::generate(context.clone(), &generator)? {
|
||||
entry.prepend_name_prefix(&prefix);
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Build a list of all the final boot entries.
|
||||
let mut final_entries = Vec::new();
|
||||
for (context, entry) in staged_entries {
|
||||
for entry in &mut entries {
|
||||
let mut context = context.fork();
|
||||
// Insert the values from the entry configuration into the
|
||||
// sprout context to use with the entry itself.
|
||||
context.insert(&entry.values);
|
||||
context.insert(&entry.declaration().values);
|
||||
let context = context.finalize().freeze();
|
||||
|
||||
// Insert the entry configuration into final boot entries with the extended context.
|
||||
final_entries.push((context, entry));
|
||||
// Provide the new context to the bootable entry.
|
||||
entry.swap_context(context);
|
||||
// Restamp the title with any values.
|
||||
entry.restamp_title();
|
||||
}
|
||||
|
||||
// TODO(azenla): Implement boot menu here.
|
||||
// For now, we just print all of the entries.
|
||||
info!("entries:");
|
||||
for (index, (context, entry)) in final_entries.iter().enumerate() {
|
||||
let title = context.stamp(&entry.title);
|
||||
info!(" entry {}: {}", index + 1, title);
|
||||
for (index, entry) in entries.iter().enumerate() {
|
||||
let title = context.stamp(&entry.declaration().title);
|
||||
info!(" entry {} [{}]: {}", index, entry.name(), title);
|
||||
}
|
||||
|
||||
// Execute the late phase.
|
||||
phase(context.clone(), &config.phases.late).context("unable to execute late phase")?;
|
||||
|
||||
// Use the boot option if possible, otherwise pick the first entry.
|
||||
let (context, entry) = if let Some(ref boot) = context.root().options().boot {
|
||||
final_entries
|
||||
let entry = if let Some(ref boot) = context.root().options().boot {
|
||||
entries
|
||||
.iter()
|
||||
.find(|(_context, entry)| &entry.title == boot)
|
||||
.enumerate()
|
||||
.find(|(index, entry)| {
|
||||
entry.name() == boot || entry.title() == boot || &index.to_string() == boot
|
||||
})
|
||||
.context(format!("unable to find entry: {boot}"))?
|
||||
.1 // select the bootable entry.
|
||||
} else {
|
||||
final_entries.first().context("no entries found")?
|
||||
entries.first().context("no entries found")?
|
||||
};
|
||||
|
||||
// Execute all the actions for the selected entry.
|
||||
for action in &entry.actions {
|
||||
for action in &entry.declaration().actions {
|
||||
let action = context.stamp(action);
|
||||
actions::execute(context.clone(), &action)
|
||||
.context(format!("unable to execute action '{}'", action))?;
|
||||
|
||||
Reference in New Issue
Block a user