clnrm_core/cli/commands/
init.rs1use crate::error::{CleanroomError, Result};
7use crate::telemetry::cli_helpers::CliInitSpanBuilder;
8
9pub fn init_project(force: bool, with_config: bool) -> Result<()> {
11 let project_path = std::env::current_dir()
13 .map(|p| p.to_string_lossy().to_string())
14 .unwrap_or_else(|_| ".".to_string());
15
16 let tests_dir = std::path::Path::new("tests");
18 let scenarios_dir = std::path::Path::new("scenarios");
19 let basic_test_file = tests_dir.join("basic.clnrm.toml");
20
21 let exists_before = tests_dir.exists() && scenarios_dir.exists() && basic_test_file.exists();
22
23 let span = CliInitSpanBuilder::new(project_path, exists_before, force).start();
25
26 println!("🚀 Initializing cleanroom test project in current directory");
27
28 if exists_before {
29 if !force {
30 let error = CleanroomError::validation_error("Project already initialized")
31 .with_context("Use --force to reinitialize");
32
33 span.finish(
34 false,
35 false,
36 None,
37 0,
38 Some(("ConfigAlreadyExists".to_string(), error.to_string())),
39 );
40
41 return Err(error);
42 }
43 println!("Reinitializing existing project (--force flag used)");
44 }
45
46 let mut files_created = 0;
48
49 std::fs::create_dir_all(tests_dir)?;
51 std::fs::create_dir_all(scenarios_dir)?;
52
53 let test_content = r#"# Cleanroom Test Definition
55# Generated by clnrm init
56
57[test.metadata]
58name = "basic_test"
59description = "Basic integration test"
60timeout = "120s"
61
62[services.test_container]
63type = "generic_container"
64image = "alpine:latest"
65
66[[steps]]
67name = "hello_world"
68command = ["echo", "Hello from cleanroom!"]
69expected_output_regex = "Hello from cleanroom!"
70
71[[steps]]
72name = "verify_environment"
73command = ["uname", "-s"]
74expected_output_regex = "Linux"
75"#;
76
77 std::fs::write(&basic_test_file, test_content)?;
78 files_created += 1;
79
80 let config_path = basic_test_file.to_string_lossy().to_string();
81
82 let readme_content = r#"# Cleanroom Test Project
84
85This project uses the cleanroom testing framework for hermetic integration testing.
86
87## Quick Start
88
89```bash
90# Run tests
91clnrm run tests/
92
93# Validate configuration
94clnrm validate tests/
95
96# Show available plugins
97clnrm plugins
98```
99
100## Project Structure
101
102- `tests/` - Test definition files (.clnrm.toml)
103- `scenarios/` - Test scenario definitions
104- `cleanroom.toml` - Optional framework configuration
105- `README.md` - This file
106
107## Framework Self-Testing
108
109This project demonstrates the cleanroom framework testing itself through the "eat your own dog food" principle.
110"#;
111
112 std::fs::write("README.md", readme_content)?;
113 files_created += 1;
114
115 if with_config {
117 let config_content = r#"# Cleanroom Framework Configuration (optional)
118# The framework works without this file - only add when customizing
119
120[project]
121name = "my-project"
122version = "0.1.0"
123
124# Uncomment to enable parallel execution
125# [cli]
126# parallel = true
127# jobs = 4
128
129# Uncomment to enable container reuse (10-50x faster)
130# [containers]
131# reuse_enabled = true
132# default_image = "alpine:latest"
133
134# See docs for all options: https://docs.cleanroom.dev/config
135"#;
136 std::fs::write("cleanroom.toml", config_content)?;
137 files_created += 1;
138 println!("✅ Project initialized successfully with configuration");
139 println!("📁 Created: tests/basic.clnrm.toml, cleanroom.toml, README.md");
140 } else {
141 println!("✅ Project initialized successfully (zero-config)");
142 println!("📁 Created: tests/basic.clnrm.toml, README.md");
143 }
144
145 span.finish(true, true, Some(config_path), files_created, None);
147
148 Ok(())
149}