1use crate::pkg::{local, resolve, types};
2use anyhow::{Result, anyhow};
3use colored::*;
4
5pub fn run(package_name: &str) -> Result<()> {
6 let request = resolve::parse_source_string(package_name)?;
7 let (pkg_meta, _, _, _, _) = resolve::resolve_package_and_version(package_name, false)?;
8
9 let user_manifest = local::is_package_installed(
10 &pkg_meta.name,
11 request.sub_package.as_deref(),
12 types::Scope::User,
13 )?;
14 let system_manifest = local::is_package_installed(
15 &pkg_meta.name,
16 request.sub_package.as_deref(),
17 types::Scope::System,
18 )?;
19 let _project_manifest = local::is_package_installed(
20 &pkg_meta.name,
21 request.sub_package.as_deref(),
22 types::Scope::Project,
23 )?;
24
25 let manifest = match (user_manifest, system_manifest) {
26 (Some(m), None) => m,
27 (None, Some(m)) => m,
28 (Some(_), Some(_)) => {
29 return Err(anyhow!(
30 "Package '{}' is installed in both user and system scopes. This is an ambiguous state.",
31 package_name
32 ));
33 }
34 (None, None) => {
35 return Err(anyhow!("Package '{}' is not installed.", package_name));
36 }
37 };
38
39 let pkg_dir = local::get_package_dir(
40 manifest.scope,
41 &manifest.registry_handle,
42 &manifest.repo,
43 &manifest.name,
44 )?;
45 let mut reasons = Vec::new();
46
47 if manifest.reason == types::InstallReason::Direct {
48 reasons.push("it was installed directly by the user".to_string());
49 }
50
51 let mut dependents = local::get_dependents(&pkg_dir)?;
52
53 if !dependents.is_empty() {
54 dependents.sort();
55 reasons.push(format!(
56 "it is a dependency for: {}",
57 dependents.join(", ").cyan()
58 ));
59 }
60
61 if reasons.is_empty() {
62 if matches!(manifest.reason, types::InstallReason::Dependency { .. }) {
63 println!(
64 "Package '{}' is installed as a dependency, but no packages list it as a requirement. It may be an orphan.",
65 package_name.bold()
66 );
67 } else {
68 println!(
69 "Package '{}' is installed, but its installation reason is unclear.",
70 package_name.bold()
71 );
72 }
73 } else {
74 println!(
75 "Package '{}' is installed because {}.",
76 package_name.bold(),
77 reasons.join(" and ")
78 );
79 }
80
81 Ok(())
82}