Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(upgrade): Process workspace.dependencies #811

Merged
merged 5 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions src/bin/upgrade/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,18 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
}

let metadata = resolve_ws(args.manifest_path.as_deref(), args.locked, args.offline)?;
let manifest_path = metadata.workspace_root.as_std_path().join("Cargo.toml");
let root_manifest_path = metadata.workspace_root.as_std_path().join("Cargo.toml");
let manifests = find_ws_members(&metadata);
let mut manifests = manifests
.into_iter()
.map(|p| (p.name, p.manifest_path.as_std_path().to_owned()))
.collect::<Vec<_>>();
if !manifests.iter().any(|(_, p)| *p == root_manifest_path) {
manifests.insert(
0,
("virtual workspace".to_owned(), root_manifest_path.clone()),
);
}

let selected_dependencies = args
.package
Expand All @@ -182,18 +192,17 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
let mut pinned_present = false;
let mut incompatible_present = false;
let mut uninteresting_crates = BTreeSet::new();
for package in &manifests {
let mut manifest = LocalManifest::try_new(package.manifest_path.as_std_path())?;
for (pkg_name, manifest_path) in &manifests {
let mut manifest = LocalManifest::try_new(manifest_path)?;
let mut crate_modified = false;
let mut table = Vec::new();
let manifest_path = manifest.path.clone();
shell_status("Checking", &format!("{}'s dependencies", package.name))?;
shell_status("Checking", &format!("{}'s dependencies", pkg_name))?;
for dep_table in manifest.get_dependency_tables_mut() {
for (dep_key, dep_item) in dep_table.iter_mut() {
let mut reason = None;

let dep_key = dep_key.get();
let dependency = match Dependency::from_toml(&manifest_path, dep_key, dep_item) {
let dependency = match Dependency::from_toml(manifest_path, dep_key, dep_item) {
Ok(dependency) => dependency,
Err(err) => {
shell_warn(&format!("ignoring {}, unsupported entry: {}", dep_key, err))?;
Expand Down Expand Up @@ -262,7 +271,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
// we're offline.
let registry_url = dependency
.registry()
.map(|registry| registry_url(&manifest_path, Some(registry)))
.map(|registry| registry_url(manifest_path, Some(registry)))
.transpose()?;
if !args.offline {
if let Some(registry_url) = &registry_url {
Expand All @@ -277,7 +286,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
get_compatible_dependency(
&dependency.name,
&old_version_req,
&manifest_path,
manifest_path,
registry_url.as_ref(),
)
.ok()
Expand All @@ -291,7 +300,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
let latest_version = get_latest_dependency(
&dependency.name,
is_prerelease,
&manifest_path,
manifest_path,
registry_url.as_ref(),
)
.map(|d| {
Expand Down Expand Up @@ -442,7 +451,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
} else {
// Ensure lock file is updated and collect data for `recursive`
let offline = true; // index should already be updated
let metadata = resolve_ws(Some(&manifest_path), args.locked, offline)?;
let metadata = resolve_ws(Some(&root_manifest_path), args.locked, offline)?;
let mut locked = metadata.packages;

let precise_deps = selected_dependencies
Expand All @@ -461,6 +470,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
//
// Reusing updates (resolve_ws) so we know what lock_version to reference
for (name, (req, precise)) in &precise_deps {
#[allow(clippy::unnecessary_lazy_evaluations)] // requires 1.62
for lock_version in locked
.iter()
.filter(|p| p.name == **name)
Expand All @@ -469,7 +479,7 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {
{
let mut cmd = std::process::Command::new("cargo");
cmd.arg("update");
cmd.arg("--manifest-path").arg(&manifest_path);
cmd.arg("--manifest-path").arg(&root_manifest_path);
if args.locked {
cmd.arg("--locked");
}
Expand All @@ -496,15 +506,15 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {

// Update data for `recursive` with precise_deps
let offline = true; // index should already be updated
let metadata = resolve_ws(Some(&manifest_path), args.locked, offline)?;
let metadata = resolve_ws(Some(&root_manifest_path), args.locked, offline)?;
locked = metadata.packages;
}

if !git_crates.is_empty() && args.compatible.as_bool() {
shell_status("Upgrading", "git dependencies")?;
let mut cmd = std::process::Command::new("cargo");
cmd.arg("update");
cmd.arg("--manifest-path").arg(&manifest_path);
cmd.arg("--manifest-path").arg(&root_manifest_path);
if args.locked {
cmd.arg("--locked");
}
Expand Down Expand Up @@ -533,15 +543,15 @@ fn exec(args: UpgradeArgs) -> CargoResult<()> {

// Update data for `recursive` with precise_deps
let offline = true; // index should already be updated
let metadata = resolve_ws(Some(&manifest_path), args.locked, offline)?;
let metadata = resolve_ws(Some(&root_manifest_path), args.locked, offline)?;
locked = metadata.packages;
}

if args.recursive {
shell_status("Upgrading", "recursive dependencies")?;
let mut cmd = std::process::Command::new("cargo");
cmd.arg("update");
cmd.arg("--manifest-path").arg(&manifest_path);
cmd.arg("--manifest-path").arg(&root_manifest_path);
if args.locked {
cmd.arg("--locked");
}
Expand Down
36 changes: 16 additions & 20 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,23 +229,6 @@ impl LocalManifest {

/// Write changes back to the file
pub fn write(&self) -> CargoResult<()> {
if !self.manifest.data.contains_key("package")
&& !self.manifest.data.contains_key("project")
{
if self.manifest.data.contains_key("workspace") {
anyhow::bail!(
"Found virtual manifest at {}, but this command requires running against an \
actual package in this workspace.",
self.path.display()
);
} else {
anyhow::bail!(
"Missing expected `package` or `project` fields in {}",
self.path.display()
);
}
}

let s = self.manifest.data.to_string();
let new_contents_bytes = s.as_bytes();

Expand Down Expand Up @@ -292,16 +275,28 @@ impl LocalManifest {
}

/// Allow mutating depedencies, wherever they live
pub fn get_dependency_tables_mut<'r>(
&'r mut self,
) -> impl Iterator<Item = &mut dyn toml_edit::TableLike> + 'r {
pub fn get_dependency_tables_mut(
&mut self,
) -> impl Iterator<Item = &mut dyn toml_edit::TableLike> + '_ {
let root = self.data.as_table_mut();
root.iter_mut().flat_map(|(k, v)| {
if DepTable::KINDS
.iter()
.any(|kind| kind.kind_table() == k.get())
{
v.as_table_like_mut().into_iter().collect::<Vec<_>>()
} else if k == "workspace" {
v.as_table_like_mut()
.unwrap()
.iter_mut()
.filter_map(|(k, v)| {
if k.get() == "dependencies" {
v.as_table_like_mut()
} else {
None
}
})
.collect::<Vec<_>>()
} else if k == "target" {
v.as_table_like_mut()
.unwrap()
Expand Down Expand Up @@ -390,6 +385,7 @@ fn remove_feature_activation(
.filter_map(|(idx, feature_activation)| {
if let toml_edit::Value::String(feature_activation) = feature_activation {
let activation = feature_activation.value();
#[allow(clippy::unnecessary_lazy_evaluations)] // requires 1.62
match status {
FeatureStatus::None => activation == dep || activation.starts_with(dep_feature),
FeatureStatus::DepFeature => activation == dep,
Expand Down
1 change: 1 addition & 0 deletions tests/cargo-upgrade/lockfile/stderr.log
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Updating '[ROOTURL]/registry' index
Checking virtual workspace's dependencies
Checking four's dependencies
name old req compatible latest new req
==== ======= ========== ====== =======
Expand Down
1 change: 1 addition & 0 deletions tests/cargo-upgrade/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod upgrade_renamed;
mod upgrade_verbose;
mod upgrade_workspace;
mod virtual_manifest;
mod workspace_inheritance;
mod workspace_member_cwd;
mod workspace_member_manifest_path;

Expand Down
1 change: 1 addition & 0 deletions tests/cargo-upgrade/upgrade_all/stderr.log
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Updating '[ROOTURL]/registry' index
Checking virtual workspace's dependencies
Checking four's dependencies
name old req compatible latest new req
==== ======= ========== ====== =======
Expand Down
1 change: 1 addition & 0 deletions tests/cargo-upgrade/upgrade_workspace/stderr.log
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Updating '[ROOTURL]/registry' index
Checking virtual workspace's dependencies
Checking four's dependencies
name old req compatible latest new req
==== ======= ========== ====== =======
Expand Down
1 change: 1 addition & 0 deletions tests/cargo-upgrade/virtual_manifest/stderr.log
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Updating '[ROOTURL]/registry' index
Checking virtual workspace's dependencies
Checking four's dependencies
name old req compatible latest new req
==== ======= ========== ====== =======
Expand Down
137 changes: 137 additions & 0 deletions tests/cargo-upgrade/workspace_inheritance/in/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions tests/cargo-upgrade/workspace_inheritance/in/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[workspace]
members = [
"one",
"two",
"explicit/*"
]

[workspace.dependencies]
my-package = "0.1.1"
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "four"
version = "0.1.0"

[lib]
path = "../../dummy.rs"

[dependencies]
my-package.workspace = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "three"
version = "0.1.0"

[lib]
path = "../../dummy.rs"

[dependencies]
my-package.workspace = true
Loading