libwally/commands/
install.rs1use std::collections::BTreeSet;
2use std::path::PathBuf;
3use std::time::Duration;
4
5use crossterm::style::{Color, SetForegroundColor};
6use indicatif::{ProgressBar, ProgressStyle};
7use structopt::StructOpt;
8
9use crate::installation::InstallationContext;
10use crate::lockfile::{LockPackage, Lockfile};
11use crate::manifest::Manifest;
12use crate::package_id::PackageId;
13use crate::package_source::{PackageSource, PackageSourceMap, Registry, TestRegistry};
14use crate::resolution::resolve;
15
16use super::GlobalOptions;
17
18#[derive(Debug, StructOpt)]
20pub struct InstallSubcommand {
21 #[structopt(long = "project-path", default_value = ".")]
23 pub project_path: PathBuf,
24}
25
26impl InstallSubcommand {
27 pub fn run(self, global: GlobalOptions) -> anyhow::Result<()> {
28 let manifest = Manifest::load(&self.project_path)?;
29
30 let lockfile = Lockfile::load(&self.project_path)?
31 .unwrap_or_else(|| Lockfile::from_manifest(&manifest));
32
33 let default_registry: Box<PackageSource> = if global.test_registry {
34 Box::new(PackageSource::TestRegistry(TestRegistry::new(
35 &manifest.package.registry,
36 )))
37 } else {
38 Box::new(PackageSource::Registry(Registry::from_registry_spec(
39 &manifest.package.registry,
40 )?))
41 };
42
43 let mut package_sources = PackageSourceMap::new(default_registry);
44 package_sources.add_fallbacks()?;
45
46 let mut try_to_use = BTreeSet::new();
47 for package in lockfile.packages {
48 match package {
49 LockPackage::Registry(registry_package) => {
50 try_to_use.insert(PackageId::new(
51 registry_package.name,
52 registry_package.version,
53 ));
54 }
55 LockPackage::Git(_) => {}
56 }
57 }
58
59 let progress = ProgressBar::new(0)
60 .with_style(
61 ProgressStyle::with_template("{spinner:.cyan}{wide_msg}")?.tick_chars("⠁⠈⠐⠠⠄⠂ "),
62 )
63 .with_message(format!(
64 "{} Resolving {}packages...",
65 SetForegroundColor(Color::DarkGreen),
66 SetForegroundColor(Color::Reset)
67 ));
68 progress.enable_steady_tick(Duration::from_millis(100));
69
70 let resolved = resolve(&manifest, &try_to_use, &package_sources)?;
71
72 progress.println(format!(
73 "{} Resolved {}{} dependencies",
74 SetForegroundColor(Color::DarkGreen),
75 SetForegroundColor(Color::Reset),
76 resolved.activated.len() - 1
77 ));
78
79 let lockfile = Lockfile::from_resolve(&resolved);
80 lockfile.save(&self.project_path)?;
81
82 progress.println(format!(
83 "{} Generated {}lockfile",
84 SetForegroundColor(Color::DarkGreen),
85 SetForegroundColor(Color::Reset)
86 ));
87
88 progress.set_message(format!(
89 "{} Cleaning {}package destination...",
90 SetForegroundColor(Color::DarkGreen),
91 SetForegroundColor(Color::Reset)
92 ));
93 let root_package_id = PackageId::new(manifest.package.name, manifest.package.version);
94 let installation = InstallationContext::new(
95 &self.project_path,
96 manifest.place.shared_packages,
97 manifest.place.server_packages,
98 );
99
100 installation.clean()?;
101 progress.println(format!(
102 "{} Cleaned {}package destination",
103 SetForegroundColor(Color::DarkGreen),
104 SetForegroundColor(Color::Reset)
105 ));
106 progress.finish_and_clear();
107
108 installation.install(package_sources, root_package_id, resolved)?;
109
110 Ok(())
111 }
112}