Skip to main content

commit_wizard/core/usecases/configs/
init.rs

1use std::time::Instant;
2
3use crate::{
4    core::{Context, CoreResult},
5    engine::{
6        capabilities::config::init::{self, ConfigContext, ConfigOption, ConfigSpec},
7        constants::{
8            PROJECT_CONFIG_FILE_NAME, PROJECT_CONFIG_FILE_NAME_HIDDEN, app_config_dir,
9            paths::resolve_new_project_config_path,
10        },
11    },
12};
13
14pub fn init_project_config(ctx: &Context, hidden: bool, profile: String) -> CoreResult<()> {
15    let ui = ctx.ui();
16
17    let scope = if hidden { "hidden" } else { "visible" };
18    let spec = match profile.as_str() {
19        "minimal" => ConfigSpec::Minimal,
20        "full" => ConfigSpec::Full,
21        _ => ConfigSpec::Standard,
22    };
23
24    let config_filename = if hidden {
25        PROJECT_CONFIG_FILE_NAME_HIDDEN
26    } else {
27        PROJECT_CONFIG_FILE_NAME
28    };
29
30    let config_path = resolve_new_project_config_path(
31        ctx.cwd(),
32        Some(ctx.repo_root().as_path()),
33        ctx.in_git_repo(),
34        ctx.explicit_config_path().map(|p| p.as_path()),
35        hidden,
36    );
37
38    let config_context = ConfigContext {
39        option: ConfigOption::Project,
40        output_path: config_path.clone(),
41        spec,
42        force: ctx.force(),
43        auto_yes: ctx.auto_yes(),
44        dry_run: ctx.dry_run(),
45        hidden,
46        with_rules: false,
47        registry_options: Default::default(),
48    };
49
50    let start = Instant::now();
51    let init_output = init::init_config(&config_context)?;
52    let duration_ms = start.elapsed().as_millis() as u64;
53
54    let meta = ui
55        .new_output_meta()
56        .with_duration_ms(duration_ms)
57        .with_timestamp(chrono::Utc::now().to_string())
58        .with_command("init".to_string())
59        .with_scope(scope.to_string())
60        .with_dry_run(ctx.dry_run());
61
62    let mut content = ui
63        .new_output_content()
64        .title("Initialized Project Configuration")
65        .subtitle(format!(
66            "Initialized {} config at {}",
67            config_filename,
68            config_path.display(),
69        ))
70        .data("path", config_path.display().to_string())
71        .data("profile", profile.clone());
72
73    if ctx.dry_run()
74        && let Some(rendered) = init_output.dry_run_content.clone()
75    {
76        content = content.section("Rendered Config", rendered, "toml".to_string());
77    }
78
79    ui.print_with_meta(&content, Some(&meta), true)
80}
81
82pub fn init_config(ctx: &Context, global: bool, profile: String) -> CoreResult<()> {
83    let ui = ctx.ui();
84
85    let spec = match profile.as_str() {
86        "minimal" => init::ConfigSpec::Minimal,
87        "full" => init::ConfigSpec::Full,
88        _ => init::ConfigSpec::Standard,
89    };
90
91    let target = if global {
92        app_config_dir()?
93    } else {
94        ctx.cwd().clone()
95    };
96
97    let config_context = init::ConfigContext {
98        option: if global {
99            init::ConfigOption::Global
100        } else {
101            init::ConfigOption::Project
102        },
103        output_path: target.clone(),
104        spec,
105        force: ctx.force(),
106        auto_yes: ctx.auto_yes(),
107        dry_run: ctx.dry_run(),
108        hidden: false,
109        with_rules: false,
110        registry_options: Default::default(),
111    };
112
113    let start = Instant::now();
114    let init_output = init::init_config(&config_context)?;
115    let duration_ms = start.elapsed().as_millis() as u64;
116
117    let scope = if global { "global" } else { "project" };
118
119    let meta = ui
120        .new_output_meta()
121        .with_duration_ms(duration_ms)
122        .with_timestamp(chrono::Utc::now().to_string())
123        .with_command("init.config".to_string())
124        .with_scope(scope.to_string())
125        .with_dry_run(ctx.dry_run());
126
127    let mut content = ui
128        .new_output_content()
129        .title("Initialized Configuration")
130        .subtitle(format!("Path: {}", target.display()))
131        .data("path", target.display().to_string())
132        .data("profile", profile.clone());
133
134    if ctx.dry_run()
135        && let Some(rendered) = init_output.dry_run_content.clone()
136    {
137        content = content.section("Rendered Config", rendered, "toml".to_string());
138    }
139
140    ui.print_with_meta(&content, Some(&meta), true)
141}
142
143pub fn init_rules(ctx: &Context, global: bool, profile: String) -> CoreResult<()> {
144    let ui = ctx.ui();
145
146    let spec = match profile.as_str() {
147        "minimal" => init::ConfigSpec::Minimal,
148        "full" => init::ConfigSpec::Full,
149        _ => init::ConfigSpec::Standard,
150    };
151
152    let target = if global {
153        app_config_dir()?
154    } else {
155        ctx.cwd().clone()
156    };
157
158    let config_context = init::ConfigContext {
159        option: if global {
160            init::ConfigOption::Global
161        } else {
162            init::ConfigOption::Project
163        },
164        output_path: target.clone(),
165        spec,
166        force: ctx.force(),
167        auto_yes: ctx.auto_yes(),
168        dry_run: ctx.dry_run(),
169        hidden: false,
170        with_rules: true, // Include rules for this operation
171        registry_options: Default::default(),
172    };
173
174    let start = Instant::now();
175    let init_output = init::init_config(&config_context)?;
176    let duration_ms = start.elapsed().as_millis() as u64;
177
178    let scope = if global { "global" } else { "project" };
179
180    let meta = ui
181        .new_output_meta()
182        .with_duration_ms(duration_ms)
183        .with_timestamp(chrono::Utc::now().to_string())
184        .with_command("init.rules".to_string())
185        .with_scope(scope.to_string())
186        .with_dry_run(ctx.dry_run());
187
188    let mut content = ui
189        .new_output_content()
190        .title("Initialized Rules")
191        .subtitle(format!("Path: {}", target.display()))
192        .data("path", target.display().to_string())
193        .data("profile", profile.clone());
194
195    if ctx.dry_run()
196        && let Some(rendered) = init_output.dry_run_content.clone()
197    {
198        content = content.section("Rendered Config", rendered, "toml".to_string());
199    }
200
201    ui.print_with_meta(&content, Some(&meta), true)
202}
203
204pub fn init_registry(
205    ctx: &Context,
206    path: std::path::PathBuf,
207    with_rules: bool,
208    sections: Vec<String>,
209    profile: String,
210) -> CoreResult<()> {
211    let ui = ctx.ui();
212
213    let spec = match profile.as_str() {
214        "minimal" => init::ConfigSpec::Minimal,
215        "full" => init::ConfigSpec::Full,
216        _ => init::ConfigSpec::Standard,
217    };
218
219    let registry_options = init::RegistryOptions {
220        git_init: false, // User can git init if needed
221        sections: !sections.is_empty(),
222        ..Default::default()
223    };
224
225    let config_context = init::ConfigContext {
226        option: init::ConfigOption::Registry,
227        output_path: path.clone(),
228        spec,
229        force: ctx.force(),
230        auto_yes: ctx.auto_yes(),
231        dry_run: ctx.dry_run(),
232        hidden: false,
233        with_rules,
234        registry_options,
235    };
236
237    let start = Instant::now();
238    let init_output = init::init_config(&config_context)?;
239    let duration_ms = start.elapsed().as_millis() as u64;
240
241    let meta = ui
242        .new_output_meta()
243        .with_duration_ms(duration_ms)
244        .with_timestamp(chrono::Utc::now().to_string())
245        .with_command("init.registry".to_string())
246        .with_scope("registry".to_string())
247        .with_dry_run(ctx.dry_run());
248
249    let mut content = ui
250        .new_output_content()
251        .title("Initialized Registry")
252        .subtitle(format!("Path: {}", path.display()))
253        .data("path", path.display().to_string())
254        .data("profile", profile);
255
256    if ctx.dry_run()
257        && let Some(rendered) = init_output.dry_run_content.clone()
258    {
259        content = content.section("Rendered Config", rendered, "toml".to_string());
260    }
261
262    ui.print_with_meta(&content, Some(&meta), true)
263}