diff --git a/crates/moon/tests/test_cases/general.in/.gitignore b/crates/moon/tests/test_cases/general.in/.gitignore new file mode 100644 index 00000000..b1283a74 --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/.gitignore @@ -0,0 +1,2 @@ +target/ +.mooncakes/ diff --git a/crates/moon/tests/test_cases/general.in/README.md b/crates/moon/tests/test_cases/general.in/README.md new file mode 100644 index 00000000..ae00983f --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/README.md @@ -0,0 +1 @@ +# username/hello \ No newline at end of file diff --git a/crates/moon/tests/test_cases/general.in/moon.mod.json b/crates/moon/tests/test_cases/general.in/moon.mod.json new file mode 100644 index 00000000..9e55a905 --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/moon.mod.json @@ -0,0 +1,10 @@ +{ + "name": "username/hello", + "version": "0.1.0", + "readme": "README.md", + "repository": "", + "license": "", + "keywords": [], + "description": "", + "source": "src" +} \ No newline at end of file diff --git a/crates/moon/tests/test_cases/general.in/src/lib/hello.mbt b/crates/moon/tests/test_cases/general.in/src/lib/hello.mbt new file mode 100644 index 00000000..9012592a --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/src/lib/hello.mbt @@ -0,0 +1,3 @@ +pub fn hello() -> String { + "Hello, world!" +} diff --git a/crates/moon/tests/test_cases/general.in/src/lib/hello_test.mbt b/crates/moon/tests/test_cases/general.in/src/lib/hello_test.mbt new file mode 100644 index 00000000..e0e3a7d1 --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/src/lib/hello_test.mbt @@ -0,0 +1,5 @@ +test "hello" { + if @lib.hello() != "Hello, world!" { + fail!("@lib.hello() != \"Hello, world!\"") + } +} diff --git a/crates/moon/tests/test_cases/general.in/src/lib/moon.pkg.json b/crates/moon/tests/test_cases/general.in/src/lib/moon.pkg.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/src/lib/moon.pkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/crates/moon/tests/test_cases/general.in/src/main/main.mbt b/crates/moon/tests/test_cases/general.in/src/main/main.mbt new file mode 100644 index 00000000..d25cb935 --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/src/main/main.mbt @@ -0,0 +1,3 @@ +fn main { + println(@lib.hello()) +} diff --git a/crates/moon/tests/test_cases/general.in/src/main/moon.pkg.json b/crates/moon/tests/test_cases/general.in/src/main/moon.pkg.json new file mode 100644 index 00000000..48783525 --- /dev/null +++ b/crates/moon/tests/test_cases/general.in/src/main/moon.pkg.json @@ -0,0 +1,6 @@ +{ + "is-main": true, + "import": [ + "username/hello/lib" + ] +} \ No newline at end of file diff --git a/crates/moon/tests/test_cases/mod.rs b/crates/moon/tests/test_cases/mod.rs index e47c66be..aabae4b0 100644 --- a/crates/moon/tests/test_cases/mod.rs +++ b/crates/moon/tests/test_cases/mod.rs @@ -20,8 +20,9 @@ use std::io::Write; use super::*; use expect_test::expect; -use moonutil::common::{ - get_cargo_pkg_version, CargoPathExt, TargetBackend, DEP_PATH, MOON_MOD_JSON, +use moonutil::{ + common::{get_cargo_pkg_version, CargoPathExt, TargetBackend, DEP_PATH, MOON_MOD_JSON}, + module::MoonModJSON, }; use serde::{Deserialize, Serialize}; use walkdir::WalkDir; @@ -6747,3 +6748,26 @@ fn test_moon_coverage() { expect!["Total: 3/6"], ); } + +#[test] +fn test_bad_version() { + let dir = TestDir::new("general.in"); + let content = std::fs::read_to_string(dir.join("moon.mod.json")).unwrap(); + let mut moon_mod: MoonModJSON = serde_json::from_str(&content).unwrap(); + moon_mod.version = Some("0.0".to_string()); + std::fs::write( + dir.join("moon.mod.json"), + serde_json::to_string(&moon_mod).unwrap(), + ) + .unwrap(); + check( + &get_err_stderr(&dir, ["check"]), + expect![[r#" + error: failed to load `$ROOT/moon.mod.json` + + Caused by: + 0: `version` bad format + 1: unexpected end of input while parsing minor version number + "#]], + ); +} diff --git a/crates/mooncake/src/registry/online.rs b/crates/mooncake/src/registry/online.rs index 37f4ce77..465707c7 100644 --- a/crates/mooncake/src/registry/online.rs +++ b/crates/mooncake/src/registry/online.rs @@ -83,7 +83,7 @@ impl super::Registry for OnlineRegistry { continue; } }; - let module: MoonMod = module.into(); + let module: MoonMod = module.try_into()?; if let Some(v) = &module.version { res.insert(v.clone(), Rc::new(module)); } @@ -144,7 +144,7 @@ impl OnlineRegistry { let lines = reader.lines().collect::>>()?; for line in lines.iter().rev() { let j: MoonModJSON = serde_json_lenient::from_str(line)?; - if j.version.as_ref() == Some(version) { + if j.version.as_ref() == Some(&version.to_string()) { if let Some(checksum) = j.checksum { return Ok(checksum); } else { diff --git a/crates/moonutil/src/common.rs b/crates/moonutil/src/common.rs index 6977a0b6..67ea5100 100644 --- a/crates/moonutil/src/common.rs +++ b/crates/moonutil/src/common.rs @@ -88,6 +88,8 @@ pub enum MoonModJSONFormatErrorKind { Parse(#[from] serde_json_lenient::Error), #[error("`source` bad format")] Source(#[from] SourceError), + #[error("`version` bad format")] + Version(#[from] semver::Error), } pub fn read_module_from_json(path: &Path) -> Result { @@ -114,7 +116,10 @@ pub fn read_module_from_json(path: &Path) -> Result anyhow::Result { diff --git a/crates/moonutil/src/module.rs b/crates/moonutil/src/module.rs index 36eda67a..787d34a2 100644 --- a/crates/moonutil/src/module.rs +++ b/crates/moonutil/src/module.rs @@ -16,6 +16,7 @@ // // For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. +use crate::common::MoonModJSONFormatErrorKind; use crate::common::MooncOpt; use crate::common::MOON_PKG_JSON; use crate::dependency::{DependencyInfo, DependencyInfoJson}; @@ -410,8 +411,7 @@ pub struct MoonModJSON { /// version of the module #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub version: Option, + pub version: Option, /// third-party dependencies of the module #[serde(skip_serializing_if = "Option::is_none")] @@ -471,8 +471,16 @@ pub struct MoonModJSON { pub alert_list: Option, } -impl From for MoonMod { - fn from(j: MoonModJSON) -> Self { +impl TryFrom for MoonMod { + type Error = MoonModJSONFormatErrorKind; + fn try_from(j: MoonModJSON) -> Result { + let version = match &j.version { + None => None, + Some(v) => { + Some(Version::parse(v.as_str()).map_err(MoonModJSONFormatErrorKind::Version)?) + } + }; + let deps = match j.deps { None => IndexMap::new(), Some(d) => d.into_iter().map(|(k, v)| (k, v.into())).collect(), @@ -480,9 +488,9 @@ impl From for MoonMod { let source = j.source.map(|s| if s.is_empty() { ".".into() } else { s }); - MoonMod { + Ok(MoonMod { name: j.name, - version: j.version, + version, deps, readme: j.readme, repository: j.repository, @@ -498,14 +506,14 @@ impl From for MoonMod { alert_list: j.alert_list, warn_list: j.warn_list, - } + }) } } pub fn convert_module_to_mod_json(m: MoonMod) -> MoonModJSON { MoonModJSON { name: m.name, - version: m.version, + version: m.version.map(|v| v.to_string()), deps: Some(m.deps.into_iter().map(|(k, v)| (k, v.into())).collect()), readme: m.readme, repository: m.repository,