Skip to content

Commit 2065c01

Browse files
wip: working workspace
Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>
1 parent e09daf1 commit 2065c01

File tree

1 file changed

+113
-58
lines changed

1 file changed

+113
-58
lines changed

src/command/release/manifest.rs

Lines changed: 113 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use semver::{Version, VersionReq};
1212

1313
use super::{cargo, git, Context, Options};
1414
use crate::{
15-
changelog,
16-
changelog::{write::Linkables, Section},
15+
changelog::{self, write::Linkables, Section},
1716
traverse::Dependency,
1817
utils::{names_and_versions, try_to_published_crate_and_new_version, version_req_unset_or_default, will},
1918
version, ChangeLog,
@@ -67,16 +66,8 @@ pub(in crate::command::release_impl) fn edit_version_and_fixup_dependent_crates_
6766
None,
6867
)?),
6968
};
70-
log::trace!("Updating {}", package.name);
71-
log::trace!(
72-
"Crates that may change {}",
73-
crates_with_version_change
74-
.iter()
75-
.map(|(p, _)| p.name.clone())
76-
.collect::<Vec<_>>()
77-
.join(", ")
78-
);
7969
made_change |= set_version_and_update_package_dependency(
70+
ctx,
8071
package,
8172
possibly_new_version,
8273
&crates_with_version_change,
@@ -503,6 +494,7 @@ fn gather_changelog_data<'meta>(
503494
}
504495

505496
fn set_version_and_update_package_dependency(
497+
ctx: &Context,
506498
package_to_update: &Package,
507499
new_package_version: Option<&semver::Version>,
508500
crates: &[(&Package, &semver::Version)],
@@ -516,61 +508,51 @@ fn set_version_and_update_package_dependency(
516508
let mut doc = toml_edit::Document::from_str(&manifest)?;
517509

518510
if let Some(new_version) = new_package_version {
519-
let new_version = new_version.to_string();
520-
if doc["package"]["version"].as_str() != Some(new_version.as_str()) {
511+
let new_version_string = new_version.to_string();
512+
if doc["package"]["version"].as_str() != Some(new_version_string.as_str()) {
521513
log::trace!(
522514
"Pending '{}' manifest version update: \"{}\"",
523515
package_to_update.name,
524-
new_version
516+
new_version_string
525517
);
526-
doc["package"]["version"] = toml_edit::value(new_version);
527-
}
528-
}
529-
for (dep_table, dep_type) in find_dependency_tables(&mut doc) {
530-
for (name_to_find, new_version) in crates.iter().map(|(p, nv)| (&p.name, nv)) {
531-
for name_to_find in package_to_update
532-
.dependencies
533-
.iter()
534-
.filter(|dep| &dep.name == name_to_find)
535-
.map(|dep| dep.rename.as_ref().unwrap_or(&dep.name))
536-
{
537-
if let Some(current_version_req) = dep_table
538-
.get_mut(name_to_find)
539-
.and_then(toml_edit::Item::as_inline_table_mut)
540-
.and_then(|name_table| name_table.get_mut("version"))
541-
{
542-
let version_req = VersionReq::parse(current_version_req.as_str().expect("versions are strings"))?;
543-
let force_update = conservative_pre_release_version_handling
544-
&& version::is_pre_release(new_version) // setting the lower bound unnecessarily can be harmful
545-
// don't claim to be conservative if this is necessary anyway
546-
&& req_as_version(&version_req).map_or(false, |req_version|!version::rhs_is_breaking_bump_for_lhs(&req_version, new_version));
547-
if !version_req.matches(new_version) || force_update {
548-
if !version_req_unset_or_default(&version_req) {
549-
bail!(
550-
"{} has it's {} dependency set to a version requirement with comparator {} - cannot currently handle that.",
551-
package_to_update.name,
552-
name_to_find,
553-
current_version_req
554-
);
555-
}
556-
let new_version = format!("^{new_version}");
557-
if version_req.to_string() != new_version {
558-
log::trace!(
559-
"Pending '{}' {}manifest {} update: '{} = \"{}\"' (from {})",
560-
package_to_update.name,
561-
if force_update { "conservative " } else { "" },
562-
dep_type,
563-
name_to_find,
564-
new_version,
565-
current_version_req.to_string()
566-
);
567-
}
568-
*current_version_req = toml_edit::Value::from(new_version.as_str());
518+
doc["package"]["version"] = toml_edit::value(new_version_string.clone());
519+
520+
// Ensure workspace root is updated if necessary TODO: see if this is specified in non-monorepos, and compare
521+
let wr_path = ctx.base.meta.workspace_root.join("Cargo.toml");
522+
// Update workspace dependency if specified
523+
if let Ok(manifest) = std::fs::read_to_string(&wr_path) {
524+
let mut workspace_doc = toml_edit::Document::from_str(&manifest)?;
525+
for (dep_table, dep_type) in find_dependency_tables(&mut workspace_doc) {
526+
if let Some(current_version_req) = dep_table
527+
.get_mut(&package_to_update.name)
528+
.and_then(toml_edit::Item::as_inline_table_mut)
529+
.and_then(|name_table| name_table.get_mut("version"))
530+
{
531+
update_dependency(
532+
current_version_req,
533+
conservative_pre_release_version_handling,
534+
new_version,
535+
package_to_update,
536+
&package_to_update.name,
537+
&dep_type,
538+
)?;
569539
}
570540
}
541+
542+
// TODO: use the workspace lock, this commits even if --execute is not set
543+
let new_manifest = workspace_doc.to_string();
544+
std::fs::write(wr_path, new_manifest)?;
571545
}
572546
}
573547
}
548+
549+
update_dependency_tables(
550+
&mut doc,
551+
crates,
552+
package_to_update,
553+
conservative_pre_release_version_handling,
554+
)?;
555+
574556
let new_manifest = doc.to_string();
575557
out.write_all(new_manifest.as_bytes())?;
576558

@@ -589,7 +571,6 @@ fn find_dependency_tables(
589571
.flat_map(|(k, v)| match DEP_TABLES.iter().find(|dtn| *dtn == &k.get()) {
590572
Some(dtn) if *dtn == "workspace" => {
591573
if let Some(deps) = v.get_mut("dependencies") {
592-
log::trace!("Found workspace dependencies");
593574
deps.as_table_like_mut()
594575
.into_iter()
595576
.map(|t| (t, "workspace-dependencies".into()))
@@ -636,3 +617,77 @@ fn req_as_version(req: &VersionReq) -> Option<Version> {
636617
build: Default::default(),
637618
})
638619
}
620+
621+
fn update_dependency_tables(
622+
doc: &mut toml_edit::Table,
623+
crates: &[(&Package, &semver::Version)],
624+
package_to_update: &Package,
625+
conservative_pre_release_version_handling: bool,
626+
) -> anyhow::Result<()> {
627+
for (dep_table, dep_type) in find_dependency_tables(doc) {
628+
for (name_to_find, new_version) in crates.iter().map(|(p, nv)| (&p.name, nv)) {
629+
for name_to_find in package_to_update
630+
.dependencies
631+
.iter()
632+
.filter(|dep| &dep.name == name_to_find)
633+
.map(|dep| dep.rename.as_ref().unwrap_or(&dep.name))
634+
{
635+
if let Some(current_version_req) = dep_table
636+
.get_mut(name_to_find)
637+
.and_then(toml_edit::Item::as_inline_table_mut)
638+
.and_then(|name_table| name_table.get_mut("version"))
639+
{
640+
update_dependency(
641+
current_version_req,
642+
conservative_pre_release_version_handling,
643+
new_version,
644+
package_to_update,
645+
name_to_find,
646+
&dep_type,
647+
)?;
648+
}
649+
}
650+
}
651+
}
652+
Ok(())
653+
}
654+
655+
fn update_dependency(
656+
current_version_req: &mut toml_edit::Value,
657+
conservative_pre_release_version_handling: bool,
658+
new_version: &Version,
659+
package_to_update: &Package,
660+
name_to_find: &str,
661+
dep_type: &str,
662+
) -> anyhow::Result<()> {
663+
let version_req = VersionReq::parse(current_version_req.as_str().expect("versions are strings"))?;
664+
let force_update = conservative_pre_release_version_handling
665+
&& version::is_pre_release(new_version) // setting the lower bound unnecessarily can be harmful
666+
// don't claim to be conservative if this is necessary anyway
667+
&& req_as_version(&version_req).map_or(false, |req_version|!version::rhs_is_breaking_bump_for_lhs(&req_version, new_version));
668+
669+
if !version_req.matches(new_version) || force_update {
670+
if !version_req_unset_or_default(&version_req) {
671+
bail!(
672+
"{} has it's {} dependency set to a version requirement with comparator {} - cannot currently handle that.",
673+
package_to_update.name,
674+
name_to_find,
675+
current_version_req
676+
);
677+
}
678+
let new_version = format!("^{new_version}");
679+
if version_req.to_string() != new_version {
680+
log::trace!(
681+
"Pending '{}' {}manifest {} update: '{} = \"{}\"' (from {})",
682+
package_to_update.name,
683+
if force_update { "conservative " } else { "" },
684+
dep_type,
685+
name_to_find,
686+
new_version,
687+
current_version_req.to_string()
688+
);
689+
}
690+
*current_version_req = toml_edit::Value::from(new_version.as_str());
691+
}
692+
Ok(())
693+
}

0 commit comments

Comments
 (0)