runner: resolve repo root without NYASH_ROOT

This commit is contained in:
2025-12-28 13:57:05 +09:00
parent df7f63f3c0
commit bb92a538b4
3 changed files with 59 additions and 4 deletions

View File

@ -21,6 +21,7 @@
pub mod context;
pub mod path_util;
pub mod root;
pub mod prelude_manager;
pub mod seam;
pub mod selfhost_pipeline;

View File

@ -0,0 +1,54 @@
//! root — repository root resolution helpers (SSOT)
//!
//! `NYASH_ROOT` is allowed as an override for tools, but runtime semantics must
//! not depend on whether it is set. When we need to locate repo-relative assets
//! (e.g., operator preludes), prefer resolving a stable root via:
//! 1) `NYASH_ROOT` when set
//! 2) walking up from an on-disk hint file (e.g., the main source file)
//! 3) current working directory
//! 4) current executable path
use std::path::{Path, PathBuf};
pub fn resolve_repo_root(hint_file: Option<&str>) -> Option<PathBuf> {
if let Ok(root) = std::env::var("NYASH_ROOT") {
let p = PathBuf::from(root);
if p.exists() {
return Some(p);
}
}
if let Some(hint) = hint_file {
if let Some(root) = walk_up_to_repo_root(Path::new(hint).parent()?) {
return Some(root);
}
}
if let Ok(cwd) = std::env::current_dir() {
if let Some(root) = walk_up_to_repo_root(&cwd) {
return Some(root);
}
}
if let Ok(exe) = std::env::current_exe() {
if let Some(dir) = exe.parent() {
if let Some(root) = walk_up_to_repo_root(dir) {
return Some(root);
}
}
}
None
}
fn walk_up_to_repo_root(start: &Path) -> Option<PathBuf> {
let mut cur = start;
for _ in 0..16 {
if cur.join("Cargo.toml").exists() {
return Some(cur.to_path_buf());
}
cur = cur.parent()?;
}
None
}

View File

@ -31,14 +31,14 @@ pub fn resolve_prelude_paths_profiled(
let opbox_all = crate::config::env::env_bool("NYASH_OPERATOR_BOX_ALL")
|| crate::config::env::env_bool("NYASH_BUILDER_OPERATOR_BOX_ALL_CALL");
if let Ok(root) = std::env::var("NYASH_ROOT") {
if let Some(root) = crate::runner::modes::common_util::resolve::root::resolve_repo_root(Some(filename)) {
let must_have = [
"apps/lib/std/operators/stringify.hako",
"apps/lib/std/operators/compare.hako",
"apps/lib/std/operators/add.hako",
];
for rel in must_have.iter() {
let p = std::path::Path::new(&root).join(rel);
let p = root.join(rel);
if p.exists() {
let path = p.to_string_lossy().to_string();
if !out.iter().any(|x| x == &path) {
@ -49,7 +49,7 @@ pub fn resolve_prelude_paths_profiled(
}
// Inject remaining arithmetic/bitwise/unary operator modules when ALL is requested
if opbox_all {
if let Ok(root) = std::env::var("NYASH_ROOT") {
if let Some(root) = crate::runner::modes::common_util::resolve::root::resolve_repo_root(Some(filename)) {
let rels = vec![
"apps/lib/std/operators/sub.hako",
"apps/lib/std/operators/mul.hako",
@ -66,7 +66,7 @@ pub fn resolve_prelude_paths_profiled(
"apps/lib/std/operators/bitnot.hako",
];
for rel in rels {
let p = std::path::Path::new(&root).join(rel);
let p = root.join(rel);
if p.exists() {
let path = p.to_string_lossy().to_string();
if !out.iter().any(|x| x == &path) {