opys_engine/commands/
config.rs1use crate::error::{usage, Result};
10use crate::project::{find_root, start_dir};
11use crate::project_config::ProjectConfig;
12use crate::templates::DEFAULT_OPYS_CONFIG;
13use crate::Ctx;
14
15pub fn init(ctx: &Ctx) -> Result<()> {
17 let root = start_dir(&ctx.root)?;
18 std::fs::create_dir_all(&root)?;
19 let path = root.join("opys.toml");
20 if path.exists() {
21 println!("{} already exists; leaving it untouched", path.display());
22 } else {
23 std::fs::write(&path, DEFAULT_OPYS_CONFIG)?;
24 println!(
25 "created {} — edit it to model your document types",
26 path.display()
27 );
28 }
29 Ok(())
30}
31
32pub fn validate(ctx: &Ctx) -> Result<i32> {
36 let start = start_dir(&ctx.root)?;
37 let root = find_root(&start).ok_or_else(|| {
38 usage(format!(
39 "no opys.toml found in {} or any parent directory — run `opys config init`",
40 start.display()
41 ))
42 })?;
43 let cfg = ProjectConfig::load(&root.join("opys.toml"))?;
44 let problems = cfg.validate();
45 if problems.is_empty() {
46 println!(
47 "config: OK ({} types, {} rules)",
48 cfg.types.len(),
49 cfg.rules.len()
50 );
51 Ok(0)
52 } else {
53 eprintln!("config: {} problem(s)", problems.len());
54 for p in &problems {
55 eprintln!(" {p}");
56 }
57 Ok(1)
58 }
59}