Skip to main content

wapm_cli/commands/
validate.rs

1use crate::util::create_temp_dir;
2use crate::validate::*;
3use flate2::read::GzDecoder;
4use std::{fs, io::Read, path::PathBuf};
5use structopt::StructOpt;
6use tar::Archive;
7
8#[derive(StructOpt, Debug)]
9pub struct ValidateOpt {
10    /// Directory or tar file to validate
11    package: String,
12}
13
14pub fn validate(validate_opts: ValidateOpt) -> anyhow::Result<()> {
15    let pkg_path = PathBuf::from(&validate_opts.package);
16    validate_manifest_and_modules(pkg_path)
17}
18
19pub fn validate_manifest_and_modules(pkg_path: PathBuf) -> anyhow::Result<()> {
20    if pkg_path.is_dir() {
21        validate_directory(pkg_path)
22    } else {
23        //unzip then validate as dir
24        let mut compressed_archive_data = Vec::new();
25        let mut compressed_archive =
26            fs::File::open(&pkg_path).map_err(|_| ValidationError::MissingFile {
27                file: pkg_path.to_string_lossy().to_string(),
28            })?;
29        compressed_archive
30            .read_to_end(&mut compressed_archive_data)
31            .map_err(|err| ValidationError::MiscCannotRead {
32                file: pkg_path.to_string_lossy().to_string(),
33                error: format!("{}", err),
34            })?;
35
36        let mut gz = GzDecoder::new(&compressed_archive_data[..]);
37        let mut archive_data = Vec::new();
38        gz.read_to_end(&mut archive_data)
39            .map_err(|e| anyhow!("Failed to read archive data: {}", e.to_string()))?;
40
41        let temp_out_dir = create_temp_dir()
42            .map_err(|e| anyhow!("Could not create temporary directory: {}", e.to_string()))?;
43        let out_dir = temp_out_dir.path();
44        let mut archive = Archive::new(archive_data.as_slice());
45        // TODO: consider doing this entirely in memory with multiple passes
46        archive
47            .unpack(out_dir)
48            .map_err(|err| ValidationError::CannotUnpackArchive {
49                file: pkg_path.to_string_lossy().to_string(),
50                error: format!("{}", err),
51            })?;
52
53        let archive_path = {
54            let mut ar_path = out_dir.to_path_buf();
55            let archive_folder_name = pkg_path
56                .file_name()
57                .and_then(|file_name| file_name.to_str())
58                .ok_or_else(|| anyhow!("Failed to get archive folder name"))?
59                .replace(".tar.gz", "");
60            ar_path.push(archive_folder_name);
61            ar_path
62        };
63
64        validate_directory(archive_path)
65    }
66}