1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use super::*;
use clap::Parser;
use crossbundle_tools::types::Config;
use std::path::PathBuf;

const BUNDLETOOL_JAR_FILE_DOWNLOAD_URL: &str =
    "https://github.com/google/bundletool/releases/download";

#[derive(Parser, Clone, Debug, Default)]
pub struct BundletoolInstallCommand {
    /// Required. Version of download bundletool. For example:
    /// --version 1.8.2
    #[clap(long, short, default_value = "1.8.2")]
    version: String,
    /// Path to install bundletool. By default bundletool will be downloaded and saved in
    /// home directory
    #[clap(long, short)]
    path: Option<PathBuf>,
    /// Force install bundletool even if found.
    #[clap(long, short)]
    force: bool,
}

impl BundletoolInstallCommand {
    /// Download and install bundletool to provided or default path
    pub fn install(&self, config: &Config) -> crate::error::Result<()> {
        let home_dir = default_file_path(self.file_name())?
            .parent()
            .unwrap()
            .to_owned();
        if !self.force {
            for bundletool in std::fs::read_dir(&home_dir)? {
                let installed_bundletool = bundletool?.path();
                if installed_bundletool.ends_with(self.file_name()) {
                    config.status("You have installed budletool on your system already. Use `--force` command to overwrite.")?;
                    return Ok(());
                }
            }
        }
        let download_url = std::path::Path::new(BUNDLETOOL_JAR_FILE_DOWNLOAD_URL)
            .join(self.version.clone())
            .join(self.file_name());
        let download_url_str = String::from(download_url.to_str().unwrap());

        if let Some(install_path) = &self.path {
            config.status_message(
                format!("{} installing into", self.file_name()),
                install_path.to_string_lossy(),
            )?;
            let jar_path = install_path.join(self.file_name());
            download_to_file(&download_url_str, &jar_path)?;
        } else {
            config.status_message(
                format!("{} installing into", self.file_name()),
                home_dir.to_string_lossy(),
            )?;
            let default_jar_path = default_file_path(self.file_name())?;
            download_to_file(&download_url_str, &default_jar_path)?;
        };
        config.status("Bundletool was installed successfully")?;
        Ok(())
    }

    /// Return bundletool jar file name with specified version
    fn file_name(&self) -> String {
        format!("bundletool-all-{}.jar", self.version)
    }
}