//! Fresh worlds provide a Git identity and resolve conventional tool names through which. use sausage::{ exec::{Command, Options, Stream}, world::World, }; #[tokio::test(flavor = "current_thread")] async fn default_identity_and_which() -> anyhow::Result<()> { let repo = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".."); let userland = repo.join("userland"); assert!( std::process::Command::new("nu") .args(["--no-config-file", "cwd-init/build.nu"]) .current_dir(&userland) .status()? .success() ); assert!( std::process::Command::new("cargo") .args([ "build", "--release", "-p", "git", "-p", "sausage-exec-tools", "--locked" ]) .current_dir(&userland) .status()? .success() ); let target = std::path::PathBuf::from(std::env::var("CARGO_TARGET_DIR")?); let bundle = tempfile::tempdir()?; std::fs::create_dir_all(bundle.path().join("bin"))?; std::fs::create_dir_all(bundle.path().join("src"))?; for name in ["git", "which"] { std::fs::copy( target.join(format!("wasm32-wasip2/release/{name}.wasm")), bundle.path().join(format!("bin/{name}.wasm")), )?; } let dir = tempfile::tempdir()?; let world = World::open_with_userland(dir.path(), Some(bundle.path()))?; std::fs::create_dir_all(dir.path().join("world/repo"))?; std::fs::write(dir.path().join("world/repo/file.txt"), "base\n")?; let exec = sausage::process::exec(World { root: world.root.clone(), host_dir: world.host_dir.clone(), processes: world.processes.clone(), })?; for (argv, expected) in [ (vec!["git", "-C", "/repo", "init", "-q", "-b", "main"], ""), ( vec!["git", "-C", "/repo", "config", "--get", "user.name"], "Sausage\n", ), ( vec!["git", "-C", "/repo", "config", "--get", "user.email"], "sausage@localhost\n", ), (vec!["git", "-C", "/repo", "add", "."], ""), (vec!["git", "-C", "/repo", "commit", "-q", "-m", "base"], ""), (vec!["which", "git"], "/bin/git\n"), (vec!["which", "-a", "git"], "/bin/git\n/bin/git.wasm\n"), ] { let mut stdout = Vec::new(); let mut stderr = Vec::new(); let code = exec .exec( Command::Argv(argv.iter().map(|s| (*s).into()).collect()), Options::default(), &mut |stream, bytes| match stream { Stream::Stdout => stdout.extend_from_slice(bytes), Stream::Stderr => stderr.extend_from_slice(bytes), }, ) .await?; assert_eq!(code, 0, "{argv:?}: {}", String::from_utf8_lossy(&stderr)); assert_eq!(stdout, expected.as_bytes(), "{argv:?}"); } std::fs::copy( dir.path().join("world/bin/git.wasm"), dir.path().join("world/usr/local/bin/git.wasm"), )?; let mut stdout = Vec::new(); assert_eq!( exec.exec( Command::Argv(vec!["which".into(), "git".into()]), Options::default(), &mut |stream, bytes| if matches!(stream, Stream::Stdout) { stdout.extend_from_slice(bytes); } ) .await?, 0 ); assert_eq!(stdout, b"/usr/local/bin/git.wasm\n"); let config = dir.path().join("world/etc/gitconfig"); std::fs::write( &config, "[user]\nname = Custom\nemail = custom@example.test\n", )?; let _ = World::open(dir.path())?; assert_eq!( std::fs::read_to_string(config)?, "[user]\nname = Custom\nemail = custom@example.test\n" ); Ok(()) }