Skip to main content

nash_cli/cmd/
check.rs

1use std::path::PathBuf;
2use std::sync::Arc;
3
4use miette::{IntoDiagnostic, Result};
5use nash_driver::{Database, FileSystemSource, Project, build, build_graph};
6use tokio::sync::Mutex;
7
8#[derive(clap::Args)]
9pub struct Args {
10    /// Path to the project (defaults to current directory)
11    #[arg(default_value = ".")]
12    pub path: PathBuf,
13}
14
15impl Args {
16    pub async fn exec(self) -> Result<()> {
17        eprintln!("Loading project from {:?}...", self.path);
18        let project = Project::load(&self.path).await.into_diagnostic()?;
19
20        eprintln!("Project root: {:?}", project.root);
21        eprintln!("Members: {}", project.members.len());
22
23        let db = Arc::new(Mutex::new(Database::new(FileSystemSource::new())));
24
25        eprintln!("Discovering modules...");
26        let modules = project
27            .discover_modules(&*db.lock().await)
28            .await
29            .into_diagnostic()?;
30
31        eprintln!("Found {} modules", modules.len());
32
33        if modules.is_empty() {
34            eprintln!("No Nash source files found.");
35            return Ok(());
36        }
37
38        eprintln!("Building dependency graph...");
39        let graph = build_graph(db.clone(), &modules).await.into_diagnostic()?;
40
41        eprintln!("Dependency order: {} modules", graph.order.len());
42
43        eprintln!("Compiling...");
44        let result = build(db, &graph).await;
45
46        eprintln!();
47        if result.is_success() {
48            eprintln!(
49                "Success! Compiled {} modules ({} declarations)",
50                result.total,
51                result
52                    .modules
53                    .values()
54                    .filter_map(|r| match r {
55                        nash_driver::ModuleResult::Success { decl_count } => Some(decl_count),
56                        _ => None,
57                    })
58                    .sum::<usize>()
59            );
60            Ok(())
61        } else {
62            eprintln!("Compilation failed.");
63            eprintln!("  {} succeeded", result.success);
64            eprintln!("  {} failed", result.failed);
65
66            for (uri, module_result) in &result.modules {
67                if let nash_driver::ModuleResult::Failed { message } = module_result {
68                    eprintln!();
69                    eprintln!("Error in {}:", uri.path());
70                    eprintln!("  {}", message);
71                }
72            }
73
74            std::process::exit(1);
75        }
76    }
77}