From 010e50a25d1917f88f979af319849f0d01282c47 Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 3 Oct 2023 07:29:47 -0700 Subject: [PATCH] Add check to ensure plugin version matches cargo version (#794) This modifies Rojo's build script to throw a fit if we're building a plugin with a semver incompatible version. In the process, it moves the version of the plugin to a file named `Version.txt` that's parsed at runtime. This should be minimally invasive but it's technically worse for performance than the hardcoded table and string we had before. This feels better than a CI check or just manually verifying because it makes it physically impossible for us to forget since Rojo won't build with it being wrong. --- Cargo.lock | 5 ++-- Cargo.toml | 1 + build.rs | 15 +++++++++++ plugin/Version.txt | 1 + plugin/default.project.json | 50 +++++++++++++++++++------------------ plugin/src/Config.lua | 16 ++++++++++-- 6 files changed, 60 insertions(+), 28 deletions(-) create mode 100644 plugin/Version.txt diff --git a/Cargo.lock b/Cargo.lock index f106d61f6..5f9c5b7cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1916,6 +1916,7 @@ dependencies = [ "ritz", "roblox_install", "rojo-insta-ext", + "semver", "serde", "serde_json", "serde_yaml", @@ -2034,9 +2035,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" diff --git a/Cargo.toml b/Cargo.toml index 4c2109341..a200ac850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,6 +102,7 @@ anyhow = "1.0.44" bincode = "1.3.3" fs-err = "2.6.0" maplit = "1.0.2" +semver = "1.0.19" [dev-dependencies] rojo-insta-ext = { path = "crates/rojo-insta-ext" } diff --git a/build.rs b/build.rs index 8326fcdc9..b82f95422 100644 --- a/build.rs +++ b/build.rs @@ -7,6 +7,7 @@ use fs_err as fs; use fs_err::File; use maplit::hashmap; use memofs::VfsSnapshot; +use semver::Version; fn snapshot_from_fs_path(path: &Path) -> io::Result { println!("cargo:rerun-if-changed={}", path.display()); @@ -43,6 +44,19 @@ fn main() -> Result<(), anyhow::Error> { let root_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); let plugin_root = PathBuf::from(root_dir).join("plugin"); + let our_version = Version::parse(env::var_os("CARGO_PKG_VERSION").unwrap().to_str().unwrap())?; + let plugin_version = + Version::parse(fs::read_to_string(&plugin_root.join("Version.txt"))?.trim())?; + + assert!( + our_version.major == plugin_version.major, + "plugin version does not match Cargo version" + ); + assert!( + our_version.minor == plugin_version.minor, + "plugin version does not match Cargo version" + ); + let snapshot = VfsSnapshot::dir(hashmap! { "default.project.json" => snapshot_from_fs_path(&plugin_root.join("default.project.json"))?, "fmt" => snapshot_from_fs_path(&plugin_root.join("fmt"))?, @@ -51,6 +65,7 @@ fn main() -> Result<(), anyhow::Error> { "rbx_dom_lua" => snapshot_from_fs_path(&plugin_root.join("rbx_dom_lua"))?, "src" => snapshot_from_fs_path(&plugin_root.join("src"))?, "Packages" => snapshot_from_fs_path(&plugin_root.join("Packages"))?, + "Version.txt" => snapshot_from_fs_path(&plugin_root.join("Version.txt"))?, }); let out_path = Path::new(&out_dir).join("plugin.bincode"); diff --git a/plugin/Version.txt b/plugin/Version.txt new file mode 100644 index 000000000..8b23b8d47 --- /dev/null +++ b/plugin/Version.txt @@ -0,0 +1 @@ +7.3.0 \ No newline at end of file diff --git a/plugin/default.project.json b/plugin/default.project.json index 092344380..424f107e4 100644 --- a/plugin/default.project.json +++ b/plugin/default.project.json @@ -1,25 +1,27 @@ { - "name": "Rojo", - "tree": { - "$className": "Folder", - "Plugin": { - "$path": "src" - }, - "Packages": { - "$path": "Packages", - - "Log": { - "$path": "log" - }, - "Http": { - "$path": "http" - }, - "Fmt": { - "$path": "fmt" - }, - "RbxDom": { - "$path": "rbx_dom_lua" - } - } - } -} + "name": "Rojo", + "tree": { + "$className": "Folder", + "Plugin": { + "$path": "src" + }, + "Packages": { + "$path": "Packages", + "Log": { + "$path": "log" + }, + "Http": { + "$path": "http" + }, + "Fmt": { + "$path": "fmt" + }, + "RbxDom": { + "$path": "rbx_dom_lua" + } + }, + "Version": { + "$path": "Version.txt" + } + } +} \ No newline at end of file diff --git a/plugin/src/Config.lua b/plugin/src/Config.lua index a2909f51e..70eeccfa8 100644 --- a/plugin/src/Config.lua +++ b/plugin/src/Config.lua @@ -2,11 +2,23 @@ local strict = require(script.Parent.strict) local isDevBuild = script.Parent.Parent:FindFirstChild("ROJO_DEV_BUILD") ~= nil +local Version = script.Parent.Parent.Version +local realVersion = Version.Value:split(".") + +for i = 1, 3 do + local num = tonumber(realVersion[i]) + if num then + realVersion[i] = num + else + error(("invalid version `%s` (field %d)"):format(realVersion[i], i)) + end +end + return strict("Config", { isDevBuild = isDevBuild, codename = "Epiphany", - version = { 7, 3, 0 }, - expectedServerVersionString = "7.2 or newer", + version = realVersion, + expectedServerVersionString = ("%d.%d or newer"):format(realVersion[1], realVersion[2]), protocolVersion = 4, defaultHost = "localhost", defaultPort = "34872",