libwally/commands/
install.rs

1use 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/// Install all of the dependencies of this project.
19#[derive(Debug, StructOpt)]
20pub struct InstallSubcommand {
21    /// Path to the project to install dependencies for.
22    #[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}