From f94b2eb86c0c7bd52408cd5e4ccf0282cd8d7966 Mon Sep 17 00:00:00 2001 From: Miguel Ramos Date: Wed, 24 Jul 2024 17:38:16 +0100 Subject: [PATCH] feat: remove PackageJsonSchema and safe parse only with serde --- Cargo.lock | 105 +++++++--------------------- Cargo.toml | 1 - src/bumps.rs | 40 +++++------ src/packages.rs | 180 ++++++++++++++++++++++++++---------------------- src/utils.rs | 101 +++++++++++++++++++++++++++ 5 files changed, 241 insertions(+), 186 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 694850e4..6dca2b68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,7 +354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -417,7 +417,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -472,7 +472,7 @@ checksum = "ce8cd46a041ad005ab9c71263f9a0ff5b529eac0fe4cc9b4a20f4f0765d8cf4b" dependencies = [ "execute-command-tokens", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -549,7 +549,7 @@ dependencies = [ "git-conventional", "git2", "glob", - "indexmap 2.2.6", + "indexmap", "lazy-regex", "lazy_static", "log", @@ -622,12 +622,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.5" @@ -1023,7 +1017,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1115,18 +1109,7 @@ dependencies = [ "libflate", "proc-macro2", "quote", - "syn 2.0.71", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "syn", ] [[package]] @@ -1136,7 +1119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown", ] [[package]] @@ -1192,7 +1175,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.71", + "syn", ] [[package]] @@ -1227,7 +1210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" dependencies = [ "core2", - "hashbrown 0.14.5", + "hashbrown", "rle-decode-fast", ] @@ -1347,7 +1330,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1362,7 +1345,7 @@ dependencies = [ "quote", "regex", "semver", - "syn 2.0.71", + "syn", ] [[package]] @@ -1489,24 +1472,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "package_json_schema" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d85fdafad8ab43df772bc1bd76abbb7740acf90f5bf1dbb89a52fc4348c23e" -dependencies = [ - "cfg-if", - "doc-comment", - "indexmap 1.9.3", - "lazy_static", - "regex", - "semver", - "serde", - "serde_json", - "thiserror", - "typed-builder", -] - [[package]] name = "parse-zoneinfo" version = "0.3.1" @@ -1559,7 +1524,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1768,7 +1733,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.71", + "syn", "walkdir", ] @@ -1854,7 +1819,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1863,7 +1828,6 @@ version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ - "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -1927,17 +1891,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.71" @@ -1957,7 +1910,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -2013,7 +1966,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -2112,24 +2065,13 @@ version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ - "indexmap 2.2.6", + "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] -[[package]] -name = "typed-builder" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cba322cb9b7bc6ca048de49e83918223f35e7a86311267013afff257004870" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "typenum" version = "1.17.0" @@ -2328,7 +2270,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn", "wasm-bindgen-shared", ] @@ -2350,7 +2292,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2584,7 +2526,6 @@ dependencies = [ "icu", "napi", "napi-derive", - "package_json_schema", "rand", "regex", "semver", @@ -2639,7 +2580,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", "synstructure", ] @@ -2660,7 +2601,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -2680,7 +2621,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", "synstructure", ] @@ -2720,5 +2661,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index c8928982..249b7694 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ napi = { version = "2.16.8", default-features = false, features = [ "serde-json", "tokio_rt", ], optional = true } -package_json_schema = "0.2.1" icu = "1.5.0" version-compare = "0.2" git-cliff-core = "2.4.0" diff --git a/src/bumps.rs b/src/bumps.rs index 2f4e0813..3b9934af 100644 --- a/src/bumps.rs +++ b/src/bumps.rs @@ -5,9 +5,9 @@ //! # Bumps //! //! This module is responsible for managing the bumps in the monorepo. -use package_json_schema::PackageJson; use semver::{BuildMetadata, Prerelease, Version as SemVersion}; use serde::{Deserialize, Serialize}; +use serde_json::json; use std::fs::OpenOptions; use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; @@ -144,20 +144,21 @@ pub fn sync_bumps(bump_package: &BumpPackage, cwd: Option) -> Vec) -> Vec) -> Vec) -> Vec PackageRepositoryInfo { PackageRepositoryInfo { domain: domain.to_string().replace("/", ""), orga: orga.to_string().replace("/", ""), - project: project.to_string().replace("/", ""), - } -} - -/// Generates and format the url of the project -fn format_repo_url(repo: &Option) -> String { - let regex = Regex::new(r"(?m)^((?git[/+]))?((?https?|ssh|git|ftps?)://)?((?[^/@]+)@)?(?[^/:]+)[/:](?[^/:]+)/(?.+/)?(?.+?)(?\.git[/]?)?$").unwrap(); - - match repo { - Some(Repository::Path(repo)) => { - let captures = regex.captures(&repo).unwrap(); - let mut url = "https://".to_string(); - - if captures.name("host").is_some() { - url.push_str(captures.name("host").unwrap().as_str()); - } - - if captures.name("port").is_some() { - url.push('/'); - url.push_str(captures.name("port").unwrap().as_str()); - } - - if captures.name("path").is_some() { - url.push('/'); - url.push_str(captures.name("repo").unwrap().as_str()); - } - - if captures.name("repo").is_some() { - url.push('/'); - url.push_str(captures.name("repo").unwrap().as_str()); - } - - url - } - Some(Repository::Object { url, .. }) => { - let url = url.as_ref().unwrap().to_string(); - let captures = regex.captures(&url).unwrap(); - let mut url = "https://".to_string(); - - if captures.name("host").is_some() { - url.push_str(captures.name("host").unwrap().as_str()); - } - - if captures.name("port").is_some() { - url.push('/'); - url.push_str(captures.name("port").unwrap().as_str()); - } - - if captures.name("path").is_some() { - url.push('/'); - url.push_str(captures.name("repo").unwrap().as_str()); - } - - if captures.name("repo").is_some() { - url.push('/'); - url.push_str(captures.name("repo").unwrap().as_str()); - } - - url - } - None => String::from("https://github.com/my-orga/my-repo"), + project: project.to_string().replace("/", "").replace(".git", ""), } } @@ -240,9 +179,43 @@ pub fn get_packages(cwd: Option) -> Vec { pnpm_info .iter() .map(|info| { - let package_json_path = format!("{}/package.json", info.path); - let package_json = std::fs::read_to_string(&package_json_path).unwrap(); - let pkg_json = PackageJson::try_from(package_json).unwrap(); + let ref package_json_path = format!("{}/package.json", info.path); + + let package_json_file = + std::fs::File::open(package_json_path.to_string()).unwrap(); + let package_json_reader = std::io::BufReader::new(package_json_file); + let pkg_json: serde_json::Value = + serde_json::from_reader(package_json_reader).unwrap(); + + let ref version = match pkg_json.get("version") { + Some(version) => { + if version.is_string() { + version.as_str().unwrap().to_string() + } else { + String::from("0.0.0") + } + } + None => String::from("0.0.0"), + }; + + let ref repo_url = match pkg_json.get("repository") { + Some(repository) => { + if repository.is_object() { + let repo = repository.as_object().unwrap(); + + match repo.get("url") { + Some(url) => url.as_str().unwrap().to_string(), + None => String::from("https://github.com/my-orga/my-repo"), + } + } else if repository.is_string() { + repository.as_str().unwrap().to_string() + } else { + String::from("https://github.com/my-orga/my-repo") + } + } + None => String::from("https://github.com/my-orga/my-repo"), + }; + let is_root = info.path == project_root; let relative_path = match is_root { @@ -255,21 +228,17 @@ pub fn get_packages(cwd: Option) -> Vec { } }; - let repo_url = format_repo_url(&pkg_json.repository); - let repository_info = get_package_repository_info(&repo_url); - + let repository_info = get_package_repository_info(repo_url); let name = &info.name.to_string(); let package_path = &info.path.to_string(); - let package_json = serde_json::to_value(&pkg_json).unwrap(); - let version = &pkg_json.version.unwrap_or(String::from("0.0.0")); PackageInfo { name: name.to_string(), private: info.private, - package_json_path, + package_json_path: package_json_path.to_string(), package_path: package_path.to_string(), package_relative_path: relative_path, - pkg_json: package_json, + pkg_json, root: is_root, version: version.to_string(), url: String::from(repo_url), @@ -332,18 +301,63 @@ pub fn get_packages(cwd: Option) -> Vec { if patterns.is_match(CandidatePath::from( entry.path().strip_prefix(&path).unwrap(), )) { - let package_json = std::fs::read_to_string(&entry.path()).unwrap(); - let pkg_json = PackageJson::try_from(package_json).unwrap(); - let private = - matches!(pkg_json.private, Some(package_json_schema::Private::True)); + let package_json_file = std::fs::File::open(&entry.path()).unwrap(); + let package_json_reader = std::io::BufReader::new(package_json_file); + let pkg_json: serde_json::Value = + serde_json::from_reader(package_json_reader).unwrap(); + + let private = match pkg_json.get("private") { + Some(private) => { + if private.is_boolean() { + private.as_bool().unwrap() + } else { + false + } + } + None => false, + }; + + let ref version = match pkg_json.get("version") { + Some(version) => { + if version.is_string() { + version.as_str().unwrap().to_string() + } else { + String::from("0.0.0") + } + } + None => String::from("0.0.0"), + }; - let package_json = serde_json::to_value(&pkg_json).unwrap(); + let ref repo_url = match pkg_json.get("repository") { + Some(repository) => { + if repository.is_object() { + let repo = repository.as_object().unwrap(); + + match repo.get("url") { + Some(url) => url.as_str().unwrap().to_string(), + None => String::from("https://github.com/my-orga/my-repo"), + } + } else if repository.is_string() { + repository.as_str().unwrap().to_string() + } else { + String::from("https://github.com/my-orga/my-repo") + } + } + None => String::from("https://github.com/my-orga/my-repo"), + }; - let repo_url = format_repo_url(&pkg_json.repository); - let repository_info = get_package_repository_info(&repo_url); + let name = match pkg_json.get("name") { + Some(name) => { + if name.is_string() { + name.as_str().unwrap().to_string() + } else { + String::from("unknown") + } + } + None => String::from("unknown"), + }; - let name = &pkg_json.name.unwrap().to_string(); - let version = &pkg_json.version.unwrap_or(String::from("0.0.0")); + let repository_info = get_package_repository_info(repo_url); let pkg_info = PackageInfo { name: name.to_string(), @@ -354,10 +368,10 @@ pub fn get_packages(cwd: Option) -> Vec { .strip_suffix("/package.json") .unwrap() .to_string(), - pkg_json: package_json, + pkg_json, root: false, version: version.to_string(), - url: repo_url, + url: repo_url.to_string(), repository_info: Some(repository_info), changed_files: vec![], }; diff --git a/src/utils.rs b/src/utils.rs index bd839840..741c4996 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -116,6 +116,20 @@ pub(crate) fn create_test_monorepo( "version": "1.0.0", "description": "My new package A", "main": "index.mjs", + "module": "./dist/index.mjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "typesVersions": { + "*": { + "index.d.ts": [ + "./dist/index.d.ts" + ] + } + }, "repository": { "url": "git+ssh://git@github.com/websublime/workspace-node-binding-tools.git", "type": "git" @@ -147,6 +161,20 @@ pub(crate) fn create_test_monorepo( "version": "1.0.0", "description": "My new package B", "main": "index.mjs", + "module": "./dist/index.mjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "typesVersions": { + "*": { + "index.d.ts": [ + "./dist/index.d.ts" + ] + } + }, "repository": { "url": "git+ssh://git@github.com/websublime/workspace-node-binding-tools.git", "type": "git" @@ -285,3 +313,76 @@ pub(crate) fn create_test_monorepo( Ok(PathBuf::from(root)) } + +#[cfg(test)] +mod tests { + //use super::*; + + #[test] + fn test_parse_package_json() { + let package_json = r#" + { + "name": "@websublime/workspace-tools", + "version": "1.0.0", + "description": "My package json", + "main": "./dist/index.js", + "module": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "typesVersions": { + "*": { + "index.d.ts": [ + "./dist/index.d.ts" + ] + } + }, + "scripts": { + "type-check": "vue-tsc --noEmit", + "test": "vitest run --coverage", + "build": "vite build --config vite.config.mts --mode=production --emptyOutDir=true", + "dev": "vite --config vite.config.mts --debug --force" + }, + "keywords": [], + "author": "", + "license": "ISL", + "publishConfig": { + "scope": "@websublime" + }, + "repository": { + "url": "git+ssh://git@github.com/websublime/workspace-tools.git", + "type": "git" + }, + "dependencies": { + "@websublime/workspace-tools": "^0.30.0" + }, + "devDependencies": { + "@types/jsdom": "^21.1.6", + "@types/node": "^20.11.6", + "@workbench/core": "^7.21.0", + "@vitest/coverage-v8": "^2.0.4", + "@vue/test-utils": "2.3.2", + "happy-dom": "^14.12.3", + "typescript": "^5.3.3", + "@vitejs/plugin-vue": "^5.0.3", + "vite": "^5.3.4", + "vitest": "^2.0.4", + "vue": "3.3.4", + "vue-tsc": "^1.8.27" + }, + "files": [ + "dist", + "manifest.json", + "./LICENSE.md", + "./README.md", + "./CHANGELOG.md" + ] + }"#; + let package_json_parsed = serde_json::from_str::(package_json).unwrap(); + + assert_eq!(package_json_parsed.is_object(), true); + } +}