dev_prune/commands/
init.rs1use std::path::{Path, PathBuf};
10
11use anyhow::{Context, Result};
12
13use crate::config::{PerRepoConfig, Registry};
14use crate::output;
15use crate::scanner;
16
17pub fn run(paths: &[String], dry_run: bool) -> Result<()> {
21 output::print_banner();
22 output::print_header("dev-prune init");
23
24 let mut registry = Registry::load()?;
25 let mut total_found = 0;
26 let mut newly_added_repos: Vec<PathBuf> = Vec::new();
27
28 for path_str in paths {
29 let path = Path::new(path_str)
30 .canonicalize()
31 .with_context(|| format!("Path not found: {path_str}"))?;
32
33 output::print_info(&format!(
34 "Scanning {} for Git repositories...",
35 output::clean_path(&path)
36 ));
37
38 let repos = scanner::scan_for_repos(&path)?;
39 total_found += repos.len();
40
41 for repo in repos {
42 if registry.add_repo(repo.clone()) {
43 newly_added_repos.push(repo.clone());
44 let verb = if dry_run {
45 "Would register"
46 } else {
47 "Registered"
48 };
49 output::print_success(&format!("{verb}: {}", output::clean_path(&repo)));
50 } else {
51 output::print_info(&format!(
52 "Already registered: {}",
53 output::clean_path(&repo)
54 ));
55 }
56 }
57 }
58
59 if !dry_run {
60 registry.last_added_repos = newly_added_repos.clone();
61 registry.save()?;
62 }
63
64 output::print_header("Summary");
65 output::print_info(&format!(
68 "Found {total_found} Git {}, {} {} new",
69 output::plural(total_found, "repo", "repos"),
70 if dry_run { "would add" } else { "added" },
71 newly_added_repos.len()
72 ));
73 output::print_info(&format!(
76 "{}: {}",
77 if dry_run {
78 "Would be tracked"
79 } else {
80 "Total tracked"
81 },
82 registry.repo_count()
83 ));
84
85 if !dry_run {
86 if let Some(report) = crate::setup::ensure_integrations_if_enabled(®istry)
89 && (report.changed_anything() || report.needs_attention())
90 {
91 output::print_header("Integrations");
92 report.print(false);
93 }
94 crate::setup::suppress_next_auto_setup();
95
96 if registry.settings.auto_config {
97 for repo in &newly_added_repos {
98 crate::commands::link::ensure_default_repo_config(repo);
99 }
100 }
101
102 for repo in registry.repositories.keys() {
108 if let Err(e) = PerRepoConfig::load_with_diagnostics(repo) {
109 output::print_warning(&format!(
110 "{}: `.devprune.json` could not be parsed and was left untouched — {e}",
111 output::clean_path(repo)
112 ));
113 }
114 }
115 }
116
117 output::print_header("Version");
122 output::print_info(&format!("Installed: v{}", crate::constants::VERSION));
123 if registry.settings.update_check {
124 let mut checked = registry;
125 if crate::commands::update::check_now(&mut checked) && !dry_run {
126 let _ = checked.save();
127 }
128 registry = checked;
129 } else {
130 output::print_info(
131 "The release check is off (`devp config set update_check true` re-enables it).",
132 );
133 }
134
135 if dry_run {
136 output::print_header("Dry Run Complete");
137 output::print_info("Nothing was written. Re-run without `--dry-run` to register.");
138 return Ok(());
139 }
140
141 output::print_header("Initialization Complete");
142 output::print_success(&format!(
143 "dev-prune initialization complete! All {} tracked {} registered & verified.",
144 registry.repo_count(),
145 output::plural(registry.repo_count(), "repository", "repositories")
146 ));
147
148 output::print_info("Review or undo the integrations with `devp setup --status`.");
149
150 Ok(())
151}