From ede04fdc47afbf829e83c693889ffee0ecc45022 Mon Sep 17 00:00:00 2001 From: Jamie Mason Date: Sat, 26 Oct 2024 19:12:23 +0100 Subject: [PATCH] [WIP] get source patterns from npm,yarn,pnpm,lerna --- Cargo.lock | 20 +++++++++++++ Cargo.toml | 1 + src/packages.rs | 78 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0689d5c..cc3f2ca0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -888,6 +888,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -935,6 +948,7 @@ dependencies = [ "regex", "serde", "serde_json", + "serde_yaml", "version-compare", ] @@ -991,6 +1005,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "utf16_iter" version = "1.0.5" diff --git a/Cargo.toml b/Cargo.toml index 45002c96..c017a8c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,4 +37,5 @@ node-semver = "2.1.0" regex = "1.11.1" serde = { version = "1.0.213", features = ["derive"] } serde_json = { version = "1.0.132", features = ["preserve_order"] } +serde_yaml = "0.9" version-compare = "0.2.0" diff --git a/src/packages.rs b/src/packages.rs index 7b7b31c2..d8819704 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -8,8 +8,16 @@ use { }, glob::glob, itertools::Itertools, + serde::Deserialize, serde_json::Value, - std::{cell::RefCell, cmp::Ordering, path::PathBuf, rc::Rc, vec::IntoIter}, + std::{ + cell::RefCell, + cmp::Ordering, + fs, + path::{Path, PathBuf}, + rc::Rc, + vec::IntoIter, + }, }; #[derive(Debug)] @@ -184,14 +192,26 @@ fn get_file_paths(config: &Config) -> Vec { fn get_source_patterns(config: &Config) -> Vec { get_cli_patterns(&config.cli.options) .or_else(|| get_rcfile_patterns(&config.rcfile)) - .or_else(get_npm_patterns) - .or_else(get_pnpm_patterns) - .or_else(get_yarn_patterns) - .or_else(get_lerna_patterns) + .or_else(|| get_npm_and_yarn_patterns(&config.cwd)) + .or_else(|| get_pnpm_patterns(&config.cwd)) + .or_else(|| get_lerna_patterns(&config.cwd)) + .map(|patterns| { + patterns + .into_iter() + .map(|pattern| { + if pattern.contains("package.json") { + pattern + } else { + format!("{}/package.json", pattern) + } + }) + .collect() + }) .or_else(get_default_patterns) .unwrap() } +/// Get source patterns provided via the `--source` CLI option fn get_cli_patterns(cli_options: &CliOptions) -> Option> { if cli_options.source.is_empty() { None @@ -200,6 +220,7 @@ fn get_cli_patterns(cli_options: &CliOptions) -> Option> { } } +/// Get source patterns from the syncpack config file fn get_rcfile_patterns(rcfile: &Rcfile) -> Option> { if rcfile.source.is_empty() { None @@ -208,22 +229,53 @@ fn get_rcfile_patterns(rcfile: &Rcfile) -> Option> { } } -fn get_npm_patterns() -> Option> { - None +/// Look for source patterns in the `pnpm-workspace.yaml` file +fn get_pnpm_patterns(cwd: &Path) -> Option> { + let file_path = cwd.join("pnpm-workspace.yaml"); + let json = fs::read_to_string(&file_path).ok()?; + let pnpm_workspace: SourcesUnderPackages = serde_yaml::from_str(&json).ok()?; + pnpm_workspace.packages +} + +#[derive(Debug, Deserialize)] +struct SourcesUnderPackages { + packages: Option>, +} + +#[derive(Debug, Deserialize)] +struct SourcesUnderWorkspacesDotPackages { + workspaces: SourcesUnderPackages, } -fn get_pnpm_patterns() -> Option> { - None +#[derive(Debug, Deserialize)] +struct SourcesUnderWorkspaces { + workspaces: Option>, } -fn get_yarn_patterns() -> Option> { - None +/// Look for source patterns in the `package.json` file in the locations +/// searched by `npm` and `yarn` +fn get_npm_and_yarn_patterns(cwd: &Path) -> Option> { + let file_path = cwd.join("package.json"); + let json = fs::read_to_string(&file_path).ok()?; + serde_json::from_str::(&json) + .ok() + .and_then(|package_json| package_json.workspaces.packages) + .or_else(|| { + serde_json::from_str::(&json) + .ok() + .and_then(|package_json| package_json.workspaces) + }) } -fn get_lerna_patterns() -> Option> { - None +/// Look for source patterns in the `lerna.json` file +fn get_lerna_patterns(cwd: &Path) -> Option> { + let file_path = cwd.join("lerna.json"); + let json = fs::read_to_string(&file_path).ok()?; + let lerna_json: SourcesUnderPackages = serde_json::from_str(&json).ok()?; + lerna_json.packages } +/// Default source patterns to use if no other source patterns are found fn get_default_patterns() -> Option> { Some(vec![String::from("package.json"), String::from("packages/*/package.json")]) }