From 9ba36e68e9220c172ef40ab2b0a1bc54bb03a0fa Mon Sep 17 00:00:00 2001 From: innocentzero Date: Sat, 11 May 2024 18:37:34 +0530 Subject: [PATCH 1/3] fix(cargo): remove dependence on install-update Fixes the dependency of cargo update on cargo-install-update binary and also fixes the issue where packages are installed without the relevant features. Signed-off-by: innocentzero --- Cargo.lock | 5 +-- Cargo.toml | 1 + src/steps/generic.rs | 80 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66f40478..d47ad77d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2133,9 +2133,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -2610,6 +2610,7 @@ dependencies = [ "self_update", "semver", "serde", + "serde_json", "shell-words", "shellexpand", "strum", diff --git a/Cargo.toml b/Cargo.toml index 37566a79..ccdbdea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ merge = "~0.1" regex-split = "~0.1" notify-rust = "~4.10" wildmatch = "2.3.0" +serde_json = "1.0.117" [package.metadata.generate-rpm] assets = [{ source = "target/release/topgrade", dest = "/usr/bin/topgrade" }] diff --git a/src/steps/generic.rs b/src/steps/generic.rs index 731db822..0575c3d3 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -1,5 +1,6 @@ #![allow(unused_imports)] +use std::fs::File; use std::path::PathBuf; use std::process::Command; use std::{env, path::Path}; @@ -8,9 +9,12 @@ use std::{fs, io::Write}; use color_eyre::eyre::eyre; use color_eyre::eyre::Context; use color_eyre::eyre::Result; -use semver::Version; +use semver::{Version, VersionReq}; +use serde_json::Value; use tempfile::tempfile_in; +use tracing::instrument::WithSubscriber; use tracing::{debug, error}; +use tracing_subscriber::fmt::writer::MakeWriterExt; use crate::command::{CommandExt, Utf8Output}; use crate::execution_context::ExecutionContext; @@ -54,6 +58,22 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> { return Err(SkipStep(format!("{} exists but empty", &toml_file.display())).into()); } + let required = VersionReq::parse(">=1.77.0").unwrap(); + + let version = Command::new("cargo").arg("--version").output_checked_utf8()?.stdout; + + let version = version + .split_whitespace() + .nth(1) + .ok_or(SkipStep(format!("cargo --version output is malformed: {version}")))?; + debug!("{version}"); + + let version = Version::parse(version)?; + + if required.matches(&version) { + return manual_cargo_updates(cargo_dir.join(".crates2.json").require()?); + } + print_separator("Cargo"); let cargo_update = require("cargo-install-update") .ok() @@ -90,6 +110,64 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> { Ok(()) } +fn manual_cargo_updates(crates_json: PathBuf) -> Result<()> { + let file = File::open(crates_json)?; + let value: Value = serde_json::from_reader(file)?; + + let crate_map = value + .get("installs") + .ok_or(SkipStep("Improper .crates2.json".to_string()))?; + + let mut install_command = Command::new("cargo"); + install_command.arg("install"); + + let mut feature_packages = Vec::new(); + + match crate_map { + Value::Object(object) => { + for (package, meta) in object { + let to_install = package.contains("registry"); + let package = package.split_whitespace().next().unwrap(); + if to_install + && !meta["no_default_features"].as_bool().unwrap() + && !meta["all_features"].as_bool().unwrap() + && meta["features"].as_array().unwrap().is_empty() + { + install_command.arg(package); + } else if to_install { + feature_packages.push(( + package, + meta["all_features"].as_bool().unwrap(), + meta["no_default_features"].as_bool().unwrap(), + meta["features"].as_array().unwrap(), + )); + } + } + } + _ => { + return Err(SkipStep("Improper .crates2.json".to_string()).into()); + } + } + println!("{feature_packages:?}"); + + for (package, all_features, no_default, feature) in feature_packages { + let feature: Vec<_> = feature.iter().map(|feat| feat.as_str().unwrap()).collect(); + let mut command = Command::new("cargo"); + command.args(["install", package]); + if all_features { + command.arg("--all-features"); + } + if no_default { + command.arg("--no-default-features"); + } + command.arg("--features"); + command.args(feature); + + command.status_checked()?; + } + install_command.status_checked() +} + pub fn run_flutter_upgrade(ctx: &ExecutionContext) -> Result<()> { let flutter = require("flutter")?; From 9b27b546ad51d3e57ee1d47b4ac2605d01ce1be1 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Sat, 11 May 2024 19:03:05 +0530 Subject: [PATCH 2/3] refactor: remove unnecessary imports Signed-off-by: innocentzero --- src/steps/generic.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/steps/generic.rs b/src/steps/generic.rs index 0575c3d3..0d8cc3fb 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -12,9 +12,7 @@ use color_eyre::eyre::Result; use semver::{Version, VersionReq}; use serde_json::Value; use tempfile::tempfile_in; -use tracing::instrument::WithSubscriber; use tracing::{debug, error}; -use tracing_subscriber::fmt::writer::MakeWriterExt; use crate::command::{CommandExt, Utf8Output}; use crate::execution_context::ExecutionContext; From 0cb02dae28b2b12e07c9f322014a1a094d6bad6e Mon Sep 17 00:00:00 2001 From: innocentzero Date: Sun, 12 May 2024 20:57:26 +0530 Subject: [PATCH 3/3] fix: failing test fix Signed-off-by: innocentzero --- src/steps/generic.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/steps/generic.rs b/src/steps/generic.rs index 0d8cc3fb..c4d00c9b 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -146,7 +146,6 @@ fn manual_cargo_updates(crates_json: PathBuf) -> Result<()> { return Err(SkipStep("Improper .crates2.json".to_string()).into()); } } - println!("{feature_packages:?}"); for (package, all_features, no_default, feature) in feature_packages { let feature: Vec<_> = feature.iter().map(|feat| feat.as_str().unwrap()).collect();