Skip to main content

wapm_cli/data/lock/
lockfile_command.rs

1use crate::data::manifest::Command;
2use semver::Version;
3use thiserror::Error;
4
5/// Describes a command for a wapm module
6#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
7pub struct LockfileCommand {
8    pub name: String,
9    pub package_name: String,
10    pub package_version: Version,
11    pub module: String,
12    pub is_top_level_dependency: bool,
13    pub main_args: Option<String>,
14}
15
16#[test]
17fn test_lockfile_command_ok() {
18    use wapm_toml::CommandV1;
19    assert_eq!(
20        LockfileCommand::from_command(
21            "Micheal-F-Bryan/wit-pack",
22            Version::new(1, 0, 0),
23            &Command::V1(CommandV1 {
24                name: "wit-pack".to_string(),
25                module: "wit-pack".to_string(),
26                main_args: None,
27                package: None,
28            })
29        ),
30        Ok(LockfileCommand {
31            name: "wit-pack".to_string(),
32            package_name: "Micheal-F-Bryan/wit-pack".to_string(),
33            package_version: Version::new(1, 0, 0),
34            module: "wit-pack".to_string(),
35            is_top_level_dependency: true,
36            main_args: None,
37        })
38    )
39}
40
41impl<'a> LockfileCommand {
42    pub fn from_command(
43        local_package_name: &str,
44        local_package_version: Version,
45        command: &'a Command,
46    ) -> Result<Self, Error> {
47        // split the "package" field of the command if it exists
48        // otherwise assume that this is a command for a local module
49        // extract the package name and version for this command and insert into the lockfile command
50        let package = command.get_package();
51        let (package_name, package_version): (&str, Version) = match &package {
52            Some(package_string) => {
53                let split = package_string.as_str().split(' ').collect::<Vec<_>>();
54                match &split[..] {
55                    [package_name, package_version] => {
56                        // this string must be parsed again because the package field on a command is a concatenated string
57                        // e.g. "_/pkg 1.0.0"
58                        let package_version = Version::parse(package_version).unwrap();
59                        (package_name, package_version)
60                    }
61                    [package_name] => (package_name, local_package_version),
62                    _ => {
63                        return Err(Error::CouldNotParsePackageVersionForCommand(
64                            package_string.clone(),
65                            command.get_name(),
66                        ));
67                    }
68                }
69            }
70            None => (local_package_name, local_package_version),
71        };
72
73        let lockfile_command = LockfileCommand {
74            name: command.get_name(),
75            package_name: package_name.to_string(),
76            package_version,
77            module: command.get_module(),
78            main_args: command.get_main_args(),
79            is_top_level_dependency: true,
80        };
81        Ok(lockfile_command)
82    }
83}
84
85#[derive(Clone, PartialEq, Eq, Debug, Error)]
86pub enum Error {
87    #[error("The module for this command does not exist. Did you modify the wapm.lock?")]
88    ModuleForCommandDoesNotExist,
89    #[error("Could not parse the package name and version \"{0}\" for the command \"{1}\".")]
90    CouldNotParsePackageVersionForCommand(String, String),
91}