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 skipped_throwaway = 0;
27 let mut newly_added_repos: Vec<PathBuf> = Vec::new();
28
29 for path_str in paths {
30 let path = Path::new(path_str)
31 .canonicalize()
32 .with_context(|| format!("Path not found: {path_str}"))?;
33
34 output::print_info(&format!(
35 "Scanning {} for Git repositories...",
36 output::clean_path(&path)
37 ));
38
39 let repos = scanner::scan_for_repos(&path)?;
40 total_found += repos.len();
41
42 for repo in repos {
43 if super::link::is_throwaway_checkout(&path, &repo) {
48 skipped_throwaway += 1;
49 continue;
50 }
51 if registry.add_repo(repo.clone()) {
52 newly_added_repos.push(repo.clone());
53 let verb = if dry_run {
54 "Would register"
55 } else {
56 "Registered"
57 };
58 output::print_success(&format!("{verb}: {}", output::clean_path(&repo)));
59 let adoption =
60 registry.adopt_moved_entry(&repo, scanner::git::repo_identity(&repo));
61 super::link::report_adoption(&adoption);
62 } else {
63 output::print_info(&format!(
64 "Already registered: {}",
65 output::clean_path(&repo)
66 ));
67 if registry.needs_identity(&repo) {
71 let adoption =
72 registry.adopt_moved_entry(&repo, scanner::git::repo_identity(&repo));
73 super::link::report_adoption(&adoption);
74 }
75 }
76 }
77 }
78
79 if !dry_run {
80 registry.last_added_repos = newly_added_repos.clone();
81 registry.save()?;
82 }
83
84 output::print_header("Summary");
85 output::print_info(&format!(
88 "Found {total_found} Git {}, {} {} new",
89 output::plural(total_found, "repo", "repos"),
90 if dry_run { "would add" } else { "added" },
91 newly_added_repos.len()
92 ));
93 if skipped_throwaway > 0 {
94 output::print_info(&format!(
97 "Skipped {skipped_throwaway} disposable {} (plugin-manager clones, temp directories). `devp link <path>` registers one anyway.",
98 output::plural(skipped_throwaway, "checkout", "checkouts"),
99 ));
100 }
101 output::print_info(&format!(
104 "{}: {}",
105 if dry_run {
106 "Would be tracked"
107 } else {
108 "Total tracked"
109 },
110 registry.repo_count()
111 ));
112
113 if !dry_run {
114 if let Some(report) = crate::setup::ensure_integrations_if_enabled(®istry)
117 && (report.changed_anything() || report.needs_attention())
118 {
119 output::print_header("Integrations");
120 report.print(false);
121 }
122 crate::setup::suppress_next_auto_setup();
123
124 if registry.settings.auto_config {
125 for repo in &newly_added_repos {
126 crate::commands::link::ensure_default_repo_config(repo);
127 }
128 }
129
130 for repo in registry.repositories.keys() {
136 if let Err(e) = PerRepoConfig::load_with_diagnostics(repo) {
137 output::print_warning(&format!(
138 "{}: `.devprune.json` could not be parsed and was left untouched — {e}",
139 output::clean_path(repo)
140 ));
141 }
142 }
143 }
144
145 output::print_header("Version");
150 output::print_info(&format!("Installed: v{}", crate::constants::VERSION));
151 if registry.settings.update_check {
152 let mut checked = registry;
153 if crate::commands::update::check_now(&mut checked) && !dry_run {
154 let _ = checked.save();
155 }
156 registry = checked;
157 } else {
158 output::print_info(
159 "The release check is off (`devp config set update_check true` re-enables it).",
160 );
161 }
162
163 if dry_run {
164 output::print_header("Dry Run Complete");
165 output::print_info("Nothing was written. Re-run without `--dry-run` to register.");
166 return Ok(());
167 }
168
169 output::print_header("Initialization Complete");
170 output::print_success(&format!(
171 "dev-prune initialization complete! All {} tracked {} registered & verified.",
172 registry.repo_count(),
173 output::plural(registry.repo_count(), "repository", "repositories")
174 ));
175
176 output::print_info("Review or undo the integrations with `devp setup --status`.");
177
178 Ok(())
179}