diff --git a/src/env.rs b/src/env.rs index 3dcfcbb..42de9e6 100644 --- a/src/env.rs +++ b/src/env.rs @@ -35,10 +35,7 @@ pub fn get_javac_ver() -> anyhow::Result { } pub fn set_cwd>(path: P) -> io::Result<()> { - let mut cwd = crate::PROJECT_ROOT - .lock() - .expect("Failed to lock Mutex") - .to_owned(); + let mut cwd = crate::PROJECT_ROOT.clone(); cwd.push(path.as_ref()); - std::env::set_current_dir(cwd) + std::env::set_current_dir(cwd.as_path()) } diff --git a/src/main.rs b/src/main.rs index 19566d2..4091fae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ mod nest; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use std::sync::{LazyLock, Mutex}; +use std::sync::LazyLock; use cli::{CONFIG, Command}; use java::{JAVA_EXT_CLASS, JAVA_EXT_SOURCE}; @@ -19,19 +19,29 @@ use bytesize::ByteSize; const DIR_TARGET: LazyLock = LazyLock::new(|| PathBuf::from("target/")); const DIR_SRC: LazyLock = LazyLock::new(|| PathBuf::from("src/")); -/// Cannot flatten this dir out of existence due to IDEs, Linters, -/// and probably also Java expecting it to exist. const DIR_MAIN: LazyLock = LazyLock::new(|| DIR_SRC.join("main/")); -/// Once again, I would love to pull this out of src/ and into parent, but -/// I can't do that due to IDEs, linters, and probably also Java expecting it to exist in src/. const DIR_TEST: LazyLock = LazyLock::new(|| DIR_SRC.join("test/")); const F_NEST_TOML: LazyLock = LazyLock::new(|| PathBuf::from("Nest.toml")); const F_NEST_LOCK: LazyLock = LazyLock::new(|| PathBuf::from("Nest.lock")); -/// This may not actually be the project root. -pub static PROJECT_ROOT: LazyLock> = LazyLock::new(|| { - Mutex::new(std::env::current_dir().expect("Failed to get current working directory")) +pub static PROJECT_ROOT: LazyLock = LazyLock::new(|| { + // Start from CWD + let cwd = std::env::current_dir().expect("Failed to get current working directory"); + let mut probe = cwd.clone(); + + while !probe.join(F_NEST_TOML.as_path()).exists() { + if !probe.pop() { + // This is easier than having a Result everywhere. For now. + panic!( + "No {} found in current directory or any ancestor. (cwd: {})", + F_NEST_TOML.display(), + cwd.display() + ) + } + } + + probe }); fn main() -> anyhow::Result<()> { @@ -70,12 +80,11 @@ fn main() -> anyhow::Result<()> { } fn init() -> anyhow::Result<()> { - let is_empty = std::fs::read_dir(PROJECT_ROOT.lock().expect("Failed to lock mutex").as_path()) - .is_ok_and(|tree| tree.count() == 0); + let cwd = std::env::current_dir()?; - let project_name = PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") + let is_empty = std::fs::read_dir(cwd.as_path()).is_ok_and(|tree| tree.count() == 0); + + let project_name = cwd .file_name() .context("Invalid directory name")? .to_str() @@ -167,18 +176,11 @@ fn init() -> anyhow::Result<()> { } fn new(project_name: String) -> anyhow::Result<()> { - let cwd = PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") - .join(project_name); + let cwd = std::env::current_dir()?.join(project_name); std::fs::create_dir(&cwd)?; std::env::set_current_dir(&cwd)?; - // Replace PathBuf within mutex - let mut state = PROJECT_ROOT.lock().expect("Failed to lock mutex"); - *state = std::env::current_dir().expect("Failed to change current working directory"); - Ok(()) } @@ -246,12 +248,7 @@ fn test(assertions: bool) -> anyhow::Result<(Option, Option)> { .compile(DIR_TEST.as_path())?; // Change cwd to avoid Java pathing issues. - crate::env::set_cwd( - PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") - .join(DIR_TARGET.as_path()), - )?; + crate::env::set_cwd(PROJECT_ROOT.join(DIR_TARGET.as_path()))?; java::JVMBuilder::new() .assertions(assertions) @@ -263,16 +260,6 @@ fn test(assertions: bool) -> anyhow::Result<(Option, Option)> { } fn clean() { - let _ = std::fs::remove_file( - PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") - .join(F_NEST_LOCK.as_path()), - ); - let _ = std::fs::remove_dir_all( - PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") - .join(DIR_TARGET.as_path()), - ); + let _ = std::fs::remove_file(PROJECT_ROOT.join(F_NEST_LOCK.as_path())); + let _ = std::fs::remove_dir_all(PROJECT_ROOT.join(DIR_TARGET.as_path())); } diff --git a/src/nest.rs b/src/nest.rs index f97010b..1a87251 100644 --- a/src/nest.rs +++ b/src/nest.rs @@ -11,14 +11,8 @@ use anyhow::Context; use semver::Version; use serde::{Deserialize, Serialize}; -pub static NEST: LazyLock> = LazyLock::new(|| { - Nest::try_from( - PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") - .join(F_NEST_TOML.as_path()), - ) -}); +pub static NEST: LazyLock> = + LazyLock::new(|| Nest::try_from(PROJECT_ROOT.join(F_NEST_TOML.as_path()))); #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Nest { @@ -133,16 +127,12 @@ impl Class { // If the source file exists, hasn't been moved to a package (path is a file) and // the associated compiled class file exists in DIR_TARGET PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") .join(DIR_TARGET.as_path()) .join(self.name.as_path()) .with_extension(JAVA_EXT_CLASS) .exists() && sha256::try_digest( PROJECT_ROOT - .lock() - .expect("Failed to lock mutex") .join(if self.test { DIR_TEST.clone() } else {