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!("Total tracked: {}", registry.repo_count()));
74
75 if !dry_run {
76 if let Some(report) = crate::setup::ensure_integrations_if_enabled(®istry) {
79 if report.changed_anything() || report.needs_attention() {
80 output::print_header("Integrations");
81 report.print(false);
82 }
83 }
84 crate::setup::suppress_next_auto_setup();
85
86 for repo in registry.repositories.keys() {
92 if let Err(e) = PerRepoConfig::load_with_diagnostics(repo) {
93 output::print_warning(&format!(
94 "{}: `.devprune.json` could not be parsed and was left untouched — {e}",
95 output::clean_path(repo)
96 ));
97 }
98 }
99 }
100
101 output::print_header("Version");
106 output::print_info(&format!("Installed: v{}", crate::constants::VERSION));
107 if registry.settings.update_check {
108 let mut checked = registry;
109 if crate::commands::update::check_now(&mut checked) && !dry_run {
110 let _ = checked.save();
111 }
112 registry = checked;
113 } else {
114 output::print_info(
115 "The release check is off (`devp config set update_check true` re-enables it).",
116 );
117 }
118
119 if dry_run {
120 output::print_header("Dry Run Complete");
121 output::print_info("Nothing was written. Re-run without `--dry-run` to register.");
122 return Ok(());
123 }
124
125 output::print_header("Initialization Complete");
126 output::print_success(&format!(
127 "dev-prune initialization complete! All {} tracked {} registered & verified.",
128 registry.repo_count(),
129 output::plural(registry.repo_count(), "repository", "repositories")
130 ));
131
132 output::print_info(
136 "Optional extra: `devp icon` gives .devprune.json its own icon in your file manager.",
137 );
138 output::print_info("Review or undo the integrations with `devp setup --status`.");
139
140 Ok(())
141}