Skip to content

Commit

Permalink
fix(berry): add yarn berry support for built dependencies meta when p…
Browse files Browse the repository at this point in the history
…runing (#9605)

### Description

A rebase of #8550 as rebasing
those commits past #8813. I do
not know exactly what about that change resulted in my repo getting into
such a bad state, but I needed to do a fresh clone after trying to
rebase past it.

From the original PR:
Add support for [yarn berry built
option](https://yarnpkg.com/configuration/manifest#dependenciesMeta.built)
for dependencies meta to turbo prune.

Without this change, yarn install --immutable fails because built is
added after turbo accidentally removes it, triggering the following
error.

> The lockfile would have been modified by this install, which is
explicitly forbidden.

All credit to @vinnymac for the original PR

#### Additional Changes

I added some additional unit tests and reworked the `dependenciesMeta`
serialization logic so it support multiple fields per dependency.

### Testing Instructions

Added unit test along with updating the roundtrip text fixture to
include a dependency with `built: false`
  • Loading branch information
chris-olszewski authored Dec 11, 2024
1 parent ed31bac commit 34554db
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 17 deletions.
1 change: 1 addition & 0 deletions crates/turborepo-lockfiles/fixtures/berry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@ eslint-config-turbo@latest:
dependenciesMeta:
[email protected]:
unplugged: true
built: false
peerDependenciesMeta:
eslint:
optional: true
Expand Down
1 change: 1 addition & 0 deletions crates/turborepo-lockfiles/src/berry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct BerryPackage {
struct DependencyMeta {
optional: Option<bool>,
unplugged: Option<bool>,
built: Option<bool>,
}

#[derive(Debug, Clone, Deserialize)]
Expand Down
103 changes: 86 additions & 17 deletions crates/turborepo-lockfiles/src/berry/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl fmt::Display for Metadata {

const SPACE: char = ' ';
const NEWLINE: char = '\n';
const INDENT: &str = " ";

impl fmt::Display for BerryPackage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -144,34 +145,58 @@ where
I: Iterator<Item = (S, &'a DependencyMeta)>,
S: AsRef<str>,
{
let mut string = String::new();
let mut first = true;
struct Builder {
s: String,
}

let mut add_line = |dependency: &str, field: &str| {
if !first {
string.push('\n');
impl Builder {
fn new() -> Self {
Self { s: String::new() }
}

string.push_str(&format!(
" {}:\n {}: true",
wrap_string(dependency),
wrap_string(field)
));
fn add_field(&mut self, field: &str, value: bool) {
if !self.s.is_empty() {
self.s.push('\n');
}
self.s.push_str(&format!(
"{INDENT}{INDENT}{INDENT}{}: {value}",
wrap_string(field)
));
}

first = false;
};
fn add_dependency(&mut self, dependency: &str) {
if !self.s.is_empty() {
self.s.push('\n');
}
self.s
.push_str(&format!("{INDENT}{INDENT}{}:", wrap_string(dependency),));
}
}

let mut builder = Builder::new();

for (dependency, meta) in metadata {
let dependency = dependency.as_ref();
if meta.optional.unwrap_or_default() {
add_line(dependency, "optional");
let mut first = true;
let mut add_line = |field: &str, value: bool| {
if first {
builder.add_dependency(dependency);
}
builder.add_field(field, value);
first = false;
};
if let Some(optional) = meta.optional {
add_line("optional", optional);
}
if let Some(unplugged) = meta.unplugged {
add_line("unplugged", unplugged);
}
if meta.unplugged.unwrap_or_default() {
add_line(dependency, "unplugged");
if let Some(built) = meta.built {
add_line("built", built);
}
}

string
builder.s
}

fn wrap_string(s: &str) -> Cow<str> {
Expand Down Expand Up @@ -240,4 +265,48 @@ mod test {
let serialized = lockfile.to_string();
assert!(serialized.contains(&format!("? {long_key}\n")));
}

#[test]
fn test_stringify_dependencies_meta() {
let metadata = DependencyMeta {
optional: Some(false),
unplugged: None,
built: Some(true),
};
assert_eq!(
stringify_dependencies_meta(Some(("turbo", &metadata)).into_iter()),
" turbo:\n optional: false\n built: true"
);
}

#[test]
fn test_stringify_dependencies_meta_multi() {
let foo = DependencyMeta {
optional: Some(true),
unplugged: None,
built: None,
};
let bar = DependencyMeta {
optional: None,
unplugged: None,
built: Some(true),
};
assert_eq!(
stringify_dependencies_meta(vec![("foo", &foo), ("bar", &bar)].into_iter()),
" foo:\n optional: true\n bar:\n built: true"
);
}

#[test]
fn test_empty_dep_meta() {
let metadata = DependencyMeta {
optional: None,
unplugged: None,
built: None,
};
assert_eq!(
stringify_dependencies_meta(Some(("turbo", &metadata)).into_iter()),
""
);
}
}

0 comments on commit 34554db

Please sign in to comment.