Show init steps and tool precompile progress
This commit is contained in:
@@ -130,6 +130,38 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Finish precompilation during init and report each bundled tool, excluding executable aliases.
|
||||
pub async fn precompile_with_progress(
|
||||
root: &dyn sausage_vfs::Layer,
|
||||
mut progress: impl FnMut(usize, usize) + Send,
|
||||
) -> anyhow::Result<()> {
|
||||
use anyhow::Context;
|
||||
let compiler = shared()?;
|
||||
let mut paths = Vec::new();
|
||||
for folder in ["/bin", "/usr/local/bin"] {
|
||||
for entry in root.list(folder).await? {
|
||||
if !entry.directory && entry.name.ends_with(".wasm") {
|
||||
paths.push(format!("{folder}/{}", entry.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
paths.sort_by_key(|path| priority(path.rsplit('/').next().unwrap()));
|
||||
progress(0, paths.len());
|
||||
for (index, path) in paths.iter().enumerate() {
|
||||
let file = root
|
||||
.open(path, Default::default())
|
||||
.await
|
||||
.with_context(|| format!("Precompile {path} failed"))?;
|
||||
let bytes = file.read(0, file.stat().await?.size as usize).await?;
|
||||
compiler
|
||||
.get(bytes)
|
||||
.await
|
||||
.with_context(|| format!("Precompile {path} failed"))?;
|
||||
progress(index + 1, paths.len());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn priority(name: &str) -> usize {
|
||||
[
|
||||
"sh", "git", "rg", "grep", "ls", "cat", "sed", "find", "cargo",
|
||||
@@ -196,6 +228,33 @@ mod tests {
|
||||
use crate::exec::{Command, Exec, Options};
|
||||
use std::{future::Future, sync::atomic::Ordering};
|
||||
|
||||
#[tokio::test]
|
||||
async fn init_progress_counts_tools_not_aliases() -> anyhow::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let world = crate::world::World::open(dir.path())?;
|
||||
let bin = dir.path().join("world/bin");
|
||||
std::fs::create_dir_all(&bin)?;
|
||||
let mut progress = Vec::new();
|
||||
precompile_with_progress(world.root.as_ref(), |done, total| {
|
||||
progress.push((done, total))
|
||||
})
|
||||
.await?;
|
||||
assert_eq!(progress, [(0, 0)]);
|
||||
let bytes =
|
||||
wat::parse_str(r#"(module (memory (export "memory") 1) (func (export "_start")))"#)?;
|
||||
std::fs::write(bin.join("one.wasm"), &bytes)?;
|
||||
std::fs::write(dir.path().join("world/usr/local/bin/two.wasm"), &bytes)?;
|
||||
std::fs::write(bin.join("README"), "Not a program")?;
|
||||
std::os::unix::fs::symlink("one.wasm", bin.join("one"))?;
|
||||
progress.clear();
|
||||
precompile_with_progress(world.root.as_ref(), |done, total| {
|
||||
progress.push((done, total))
|
||||
})
|
||||
.await?;
|
||||
assert_eq!(progress, [(0, 2), (1, 2), (2, 2)]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn common_tools_precede_other_programs() {
|
||||
let mut names = [
|
||||
|
||||
@@ -55,7 +55,7 @@ pub mod net;
|
||||
pub fn default_script() -> Arc<dyn crate::cred::script::Script> {
|
||||
Arc::new(crate::cred::quickjs::QuickJs::default())
|
||||
}
|
||||
pub use cache::configure as configure_cache;
|
||||
pub use cache::{configure as configure_cache, precompile_with_progress};
|
||||
mod services;
|
||||
mod watcher;
|
||||
pub use watcher::Watcher;
|
||||
|
||||
Reference in New Issue
Block a user