| @@ -3,7 +3,6 @@ use std::collections::BTreeSet; · 2 unmodified lines |
| 3 | use cargo_metadata::{DependencyKind, Metadata, Package, PackageId}; | 3 | use cargo_metadata::{DependencyKind, Metadata, Package, PackageId}; |
| 4 | | 4 | |
| 5 | use crate::utils::package_eq_dependency; | 5 | use crate::utils::package_eq_dependency; |
| 6 | use crate::version::rhs_is_breaking_bump_for_lhs; | | |
| 7 | use crate::{ | 6 | use crate::{ |
| 8 | git, | 7 | git, |
| 9 | traverse::dependency::VersionAdjustment, | 8 | traverse::dependency::VersionAdjustment, |
| @@ -35,19 +34,19 @@ pub mod dependency { · 25 unmodified lines |
| 35 | pub enum VersionAdjustment<'meta> { | 34 | pub enum VersionAdjustment<'meta> { |
| 36 | Changed { | 35 | Changed { |
| 37 | change: git::PackageChangeKind, | 36 | change: git::PackageChangeKind, |
| 38 | bump: version::bump::Outcome, | 37 | bump: version::Bump, |
| 39 | }, | 38 | }, |
| 40 | Breakage { | 39 | Breakage { |
| 41 | bump: version::bump::Outcome, | 40 | bump: version::Bump, |
| 42 | /// Set if there is a change at all, which might not be the case for previously skipped crates. | 41 | /// Set if there is a change at all, which might not be the case for previously skipped crates. |
| 43 | change: Option<git::PackageChangeKind>, | 42 | change: Option<git::PackageChangeKind>, |
| 44 | /// The direct dependency causing the breakage because it's breaking itself | 43 | /// The direct dependency causing the breakage because it's breaking itself |
| 45 | direct_dependency: &'meta Package, | 44 | causing_dependency: &'meta Package, |
| 46 | }, | 45 | }, |
| 47 | } | 46 | } |
| 48 | | 47 | |
| 49 | impl<'meta> VersionAdjustment<'meta> { | 48 | impl<'meta> VersionAdjustment<'meta> { |
| 50 | pub fn bump(&self) -> &version::bump::Outcome { | 49 | pub fn bump(&self) -> &version::Bump { |
| 51 | match self { | 50 | match self { |
| 52 | VersionAdjustment::Breakage { bump, .. } | VersionAdjustment::Changed { bump, .. } => bump, | 51 | VersionAdjustment::Breakage { bump, .. } | VersionAdjustment::Changed { bump, .. } => bump, |
| 53 | } | 52 | } |
| @@ -69,7 +68,7 @@ pub mod dependency { · 15 unmodified lines |
| 69 | } | 68 | } |
| 70 | | 69 | |
| 71 | impl<'meta> Mode<'meta> { | 70 | impl<'meta> Mode<'meta> { |
| 72 | pub fn version_adjustment_bump(&self) -> Option<&version::bump::Outcome> { | 71 | pub fn version_adjustment_bump(&self) -> Option<&version::Bump> { |
| 73 | match self { | 72 | match self { |
| 74 | Mode::ToBePublished { adjustment } | 73 | Mode::ToBePublished { adjustment } |
| 75 | | Mode::Skipped { | 74 | | Mode::Skipped { |
| @@ -186,26 +185,28 @@ pub fn dependencies( · 110 unmodified lines |
| 186 | Ok(crates) | 185 | Ok(crates) |
| 187 | } | 186 | } |
| 188 | | 187 | |
| 189 | struct EditForPublish { | 188 | struct EditForPublish<'a, 'meta> { |
| 190 | crates_idx: usize, | 189 | crates_idx: usize, |
| 191 | bump: Option<version::bump::Outcome>, | 190 | dependency: &'a Dependency<'meta>, |
| | 191 | causing_dependency: &'meta Package, |
| 192 | } | 192 | } |
| 193 | | 193 | |
| 194 | impl EditForPublish { | 194 | impl<'a, 'meta> EditForPublish<'a, 'meta> { |
| 195 | fn breaking_release(idx: usize, _existing: Option<&version::bump::Outcome>) -> Self { | 195 | fn from(idx: usize, dependency: &'a Dependency<'meta>, causing_dependency: &'meta Package) -> Self { |
| 196 | EditForPublish { | 196 | EditForPublish { |
| 197 | crates_idx: idx, | 197 | crates_idx: idx, |
| 198 | bump: todo!("breaking change"), | 198 | dependency, |
| | 199 | causing_dependency, |
| 199 | } | 200 | } |
| 200 | } | 201 | } |
| 201 | } | 202 | } |
| 202 | | 203 | |
| 203 | fn find_safety_bump_edits_backwards_from_crates_for_publish( | 204 | fn find_safety_bump_edits_backwards_from_crates_for_publish<'a, 'meta>( |
| 204 | crates: &[Dependency<'_>], | 205 | crates: &'a [Dependency<'meta>], |
| 205 | start: (usize, &Dependency<'_>), | 206 | start: (usize, &'a Dependency<'meta>), |
| 206 | seen: &mut BTreeSet<usize>, | 207 | seen: &mut BTreeSet<usize>, |
| 207 | edits: &mut Vec<EditForPublish>, | 208 | edits: &mut Vec<EditForPublish<'a, 'meta>>, |
| 208 | ) -> bool { | 209 | ) -> Option<&'meta Package> { |
| 209 | let (current_idx, current) = start; | 210 | let (current_idx, current) = start; |
| 210 | for (dep_idx, dep) in current.package.dependencies.iter().filter_map(|dep| { | 211 | for (dep_idx, dep) in current.package.dependencies.iter().filter_map(|dep| { |
| 211 | crates | 212 | crates |
| @@ -214,37 +215,26 @@ fn find_safety_bump_edits_backwards_from_crates_for_publish( · 2 unmodified lines |
| 214 | .find(|(_, c)| package_eq_dependency(c.package, dep)) | 215 | .find(|(_, c)| package_eq_dependency(c.package, dep)) |
| 215 | }) { | 216 | }) { |
| 216 | if seen.contains(&dep_idx) { | 217 | if seen.contains(&dep_idx) { |
| 217 | return false; | 218 | continue; |
| 218 | } | 219 | } |
| 219 | seen.insert(dep_idx); | 220 | seen.insert(dep_idx); |
| 220 | | 221 | |
| 221 | match dep.mode.version_adjustment_bump() { | 222 | match dep.mode.version_adjustment_bump() { |
| 222 | Some(dep_bump) | 223 | Some(dep_bump) if dep_bump.is_breaking() => { |
| 223 | if rhs_is_breaking_bump_for_lhs( | 224 | edits.push(EditForPublish::from(current_idx, current, dep.package)); |
| 224 | &dep.package.version, | 225 | return Some(dep.package); |
| 225 | dep_bump.next_release.as_ref().expect("only valid versions here"), | | |
| 226 | ) => | | |
| 227 | { | | |
| 228 | edits.push(EditForPublish::breaking_release( | | |
| 229 | current_idx, | | |
| 230 | current.mode.version_adjustment_bump(), | | |
| 231 | )); | | |
| 232 | return true; | | |
| 233 | } | 226 | } |
| 234 | _ => { | 227 | _ => { |
| 235 | let has_breaking_in_dependencies = | 228 | let root_cause_of_breakage = |
| 236 | find_safety_bump_edits_backwards_from_crates_for_publish(crates, (dep_idx, dep), seen, edits); | 229 | find_safety_bump_edits_backwards_from_crates_for_publish(crates, (dep_idx, dep), seen, edits); |
| 237 | if has_breaking_in_dependencies { | 230 | if let Some(breaking_package) = root_cause_of_breakage { |
| 238 | edits.push(EditForPublish::breaking_release( | 231 | edits.push(EditForPublish::from(current_idx, current, breaking_package)); |
| 239 | current_idx, | 232 | return breaking_package.into(); |
| 240 | current.mode.version_adjustment_bump(), | | |
| 241 | )); | | |
| 242 | return true; | | |
| 243 | } | 233 | } |
| 244 | } | 234 | } |
| 245 | } | 235 | } |
| 246 | } | 236 | } |
| 247 | false | 237 | None |
| 248 | } | 238 | } |
| 249 | | 239 | |
| 250 | fn depth_first_traversal<'meta>( | 240 | fn depth_first_traversal<'meta>( |