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 #[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}