Skip to content

Commit 30d4cfc

Browse files
fix(pnpm): respect deep for linkWorkspacePackages (#10558)
### Description Closes #10528 With #10391 we started reading `linkWorkspacePackages` from `pnpm-workspace.yaml`. This caused issues with single package vs monorepo detection as `deep` is a valid value here and we only expected a boolean. This would cause a detection of a single package repo and we would swallow the error of `pnpm-workspace.yaml` not parsing due to the usage of `deep`. This PR adds support for [`deep` on the parsing end](https://pnpm.io/settings#linkworkspacepackages) Follow up PR is to have noisy warnings if we find a `pnpm-workspace.yaml`, but do not understand it. ### Testing Instructions Added a red/green test. Verified with https://github.com/ocavue/starter-monorepo
1 parent 5804f61 commit 30d4cfc

File tree

1 file changed

+30
-3
lines changed
  • crates/turborepo-repository/src/package_manager

1 file changed

+30
-3
lines changed

crates/turborepo-repository/src/package_manager/pnpm.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub fn link_workspace_packages(pnpm_version: PnpmVersion, repo_root: &AbsoluteSy
111111
.ok()
112112
})
113113
.flatten()
114-
.and_then(|config| config.link_workspace_packages);
114+
.and_then(|config| config.link_workspace_packages());
115115
workspace_config
116116
.or(npmrc_config.link_workspace_packages)
117117
// The default for pnpm 9 is false if not explicitly set
@@ -139,17 +139,32 @@ pub fn get_default_exclusions() -> &'static [&'static str] {
139139
#[serde(rename_all = "camelCase")]
140140
struct PnpmWorkspace {
141141
pub packages: Vec<String>,
142-
link_workspace_packages: Option<bool>,
142+
link_workspace_packages: Option<LinkWorkspacePackages>,
143143
pub patched_dependencies:
144144
Option<std::collections::BTreeMap<String, turbopath::RelativeUnixPathBuf>>,
145145
}
146146

147+
#[derive(Debug, Deserialize)]
148+
#[serde(untagged)]
149+
enum LinkWorkspacePackages {
150+
Bool(bool),
151+
Str(String),
152+
}
153+
147154
impl PnpmWorkspace {
148155
pub fn from_file(repo_root: &AbsoluteSystemPath) -> Result<Self, Error> {
149156
let workspace_yaml_path = repo_root.join_component(WORKSPACE_CONFIGURATION_PATH);
150157
let workspace_yaml = workspace_yaml_path.read_to_string()?;
151158
Ok(serde_yaml::from_str(&workspace_yaml)?)
152159
}
160+
161+
fn link_workspace_packages(&self) -> Option<bool> {
162+
let config = self.link_workspace_packages.as_ref()?;
163+
match config {
164+
LinkWorkspacePackages::Bool(value) => Some(*value),
165+
LinkWorkspacePackages::Str(value) => Some(value == "deep"),
166+
}
167+
}
153168
}
154169

155170
#[derive(Debug)]
@@ -290,7 +305,7 @@ mod test {
290305
let config: PnpmWorkspace =
291306
serde_yaml::from_str("linkWorkspacePackages: true\npackages:\n - \"apps/*\"\n")
292307
.unwrap();
293-
assert_eq!(config.link_workspace_packages, Some(true));
308+
assert_eq!(config.link_workspace_packages(), Some(true));
294309
assert_eq!(config.packages, vec!["apps/*".to_string()]);
295310
}
296311

@@ -356,4 +371,16 @@ mod test {
356371
let actual = link_workspace_packages(PnpmVersion::Pnpm9, repo_root);
357372
assert!(actual);
358373
}
374+
375+
#[test]
376+
fn test_workspace_yaml_supports_deep() {
377+
let tmpdir = tempfile::tempdir().unwrap();
378+
let repo_root = AbsoluteSystemPath::from_std_path(tmpdir.path()).unwrap();
379+
repo_root
380+
.join_component(WORKSPACE_CONFIGURATION_PATH)
381+
.create_with_contents("linkWorkspacePackages: deep\npackages:\n - \"apps/*\"\n")
382+
.unwrap();
383+
let actual = link_workspace_packages(PnpmVersion::Pnpm9, repo_root);
384+
assert!(actual, "deep should be treated as true");
385+
}
359386
}

0 commit comments

Comments
 (0)