Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit b04c59f

Browse files
Treehugger RobotGerrit Code Review
authored andcommitted
Merge "When updating crates, update dependent crates as well." into main
2 parents 5635099 + 3447ff3 commit b04c59f

File tree

4 files changed

+59
-44
lines changed

4 files changed

+59
-44
lines changed

tools/crate-updater/src/main.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
// limitations under the License.
1414

1515
use std::{
16-
collections::BTreeSet,
1716
path::{Path, PathBuf},
1817
process::{Command, ExitStatus, Output},
1918
str::from_utf8,
20-
sync::LazyLock,
2119
};
2220

2321
use anyhow::{bail, Result};
@@ -268,36 +266,6 @@ fn try_update(
268266
Ok(())
269267
}
270268

271-
#[rustfmt::skip]
272-
static DENYLIST: LazyLock<BTreeSet<&'static str>> = LazyLock::new(|| {
273-
BTreeSet::from([
274-
// Paired crates that need to be updated together
275-
"async-stream",
276-
"async-stream-impl",
277-
"clap",
278-
"clap_builder",
279-
"linkme",
280-
"linkme-impl",
281-
"pin-project",
282-
"pin-project-internal",
283-
"protobuf-support",
284-
"protobuf",
285-
"ptr_meta",
286-
"ptr_meta_derive",
287-
"regex",
288-
"regex-automata",
289-
"regex-syntax",
290-
"serde_derive",
291-
"serde",
292-
"thiserror-impl",
293-
"thiserror",
294-
"tikv-jemalloc-sys",
295-
"tikv-jemallocator",
296-
"zerocopy-derive",
297-
"zerocopy",
298-
])
299-
});
300-
301269
fn main() -> Result<()> {
302270
let args = Cli::parse();
303271
if !args.android_root.is_absolute() {
@@ -325,10 +293,6 @@ fn main() -> Result<()> {
325293
for suggestion in get_suggestions(&monorepo_path)? {
326294
let crate_name = suggestion.name.as_str();
327295
let version = suggestion.version.as_str();
328-
if DENYLIST.contains(crate_name) {
329-
println!("Skipping {crate_name} (on deny list)");
330-
continue;
331-
}
332296
if updates_tried.contains(crate_name, version) {
333297
println!("Skipping {crate_name} (already attempted recently)");
334298
continue;

tools/external_crates/crate_config/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ use serde::Deserialize;
2323
pub struct CrateConfig {
2424
#[serde(default, skip_serializing_if = "Vec::is_empty")]
2525
deletions: Vec<String>,
26+
27+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
28+
update_with: Vec<String>,
2629
}
2730

2831
#[allow(missing_docs)]
@@ -52,6 +55,10 @@ impl CrateConfig {
5255
pub fn deletions(&self) -> impl Iterator<Item = &str> {
5356
self.deletions.iter().map(|d| d.as_str())
5457
}
58+
/// Get an iterator of crates that also need to be updated at the same time as this crate.
59+
pub fn update_with(&self) -> impl Iterator<Item = &str> {
60+
self.update_with.iter().map(|d| d.as_str())
61+
}
5562
}
5663

5764
#[cfg(test)]

tools/external_crates/crate_tool/src/managed_crate.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,11 @@ impl<State: ManagedCrateState> ManagedCrate<State> {
237237
}
238238
pub fn fix_test_mapping(&self) -> Result<()> {
239239
let mut tm = TestMapping::read(self.android_crate_path().clone())?;
240-
println!("{}", self.name());
241240
let mut changed = tm.fix_import_paths();
242241
changed |= tm.add_new_tests_to_postsubmit()?;
243242
changed |= tm.remove_unknown_tests()?;
244243
if changed {
244+
println!("Updating TEST_MAPPING for {}", self.name());
245245
tm.write()?;
246246
}
247247
Ok(())
@@ -443,6 +443,7 @@ impl ManagedCrate<Vendored> {
443443
writeback |= true;
444444
}
445445
if writeback {
446+
println!("Updating METADATA for {}", staged.name());
446447
metadata.write()?;
447448
}
448449
}

tools/external_crates/crate_tool/src/managed_repo.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ use glob::glob;
2929
use google_metadata::GoogleMetadata;
3030
use itertools::Itertools;
3131
use license_checker::find_licenses;
32-
use name_and_version::{NameAndVersionMap, NameAndVersionRef, NamedAndVersioned};
32+
use name_and_version::{NameAndVersion, NameAndVersionMap, NameAndVersionRef, NamedAndVersioned};
3333
use repo_config::RepoConfig;
3434
use rooted_path::RootedPath;
35-
use semver::Version;
35+
use semver::{Version, VersionReq};
3636
use serde::Serialize;
3737
use spdx::Licensee;
3838

@@ -907,12 +907,55 @@ impl ManagedRepo {
907907
Ok(())
908908
}
909909
pub fn update(&self, crate_name: impl AsRef<str>, version: impl AsRef<str>) -> Result<()> {
910-
let pseudo_crate = self.pseudo_crate();
910+
let crate_name = crate_name.as_ref();
911911
let version = Version::parse(version.as_ref())?;
912-
let nv = NameAndVersionRef::new(crate_name.as_ref(), &version);
913-
pseudo_crate.remove(&crate_name)?;
914-
pseudo_crate.cargo_add(&nv)?;
915-
self.regenerate([&crate_name].iter(), true)?;
912+
913+
let pseudo_crate = self.pseudo_crate();
914+
let managed_crate = self.managed_crate_for(crate_name)?;
915+
let mut crate_updates = vec![NameAndVersion::new(crate_name.to_string(), version.clone())];
916+
917+
let cio_crate = self.crates_io.get_crate(crate_name)?;
918+
let cio_crate_version = cio_crate
919+
.get_version(&version)
920+
.ok_or(anyhow!("Could not find {crate_name} {version} on crates.io"))?;
921+
922+
for dependent_crate_name in managed_crate.config().update_with() {
923+
let dep = cio_crate_version
924+
.dependencies()
925+
.iter()
926+
.find(|dep| dep.crate_name() == dependent_crate_name)
927+
.ok_or(anyhow!(
928+
"Could not find crate {dependent_crate_name} as a dependency of {crate_name}"
929+
))?;
930+
let req = VersionReq::parse(dep.requirement())?;
931+
let dep_cio_crate = self.crates_io.get_crate(dependent_crate_name)?;
932+
let version = dep_cio_crate
933+
.safe_versions()
934+
.find(|v| {
935+
if let Ok(parsed_version) = Version::parse(v.version()) {
936+
req.matches(&parsed_version)
937+
} else {
938+
false
939+
}
940+
})
941+
.ok_or(anyhow!(
942+
"Failed to find a version of {dependent_crate_name} that satisfies {}",
943+
dep.requirement()
944+
))?;
945+
println!("Also updating {dependent_crate_name} to {}", version.version());
946+
crate_updates.push(NameAndVersion::new(
947+
dependent_crate_name.to_string(),
948+
Version::parse(version.version())?,
949+
));
950+
}
951+
952+
for nv in &crate_updates {
953+
pseudo_crate.remove(nv.name())?;
954+
}
955+
for nv in &crate_updates {
956+
pseudo_crate.cargo_add(nv)?;
957+
}
958+
self.regenerate(crate_updates.iter().map(|nv| nv.name()), true)?;
916959
Ok(())
917960
}
918961
pub fn init(&self) -> Result<()> {

0 commit comments

Comments
 (0)