From 19cb8fcd22e9d2bc240cbd2b23efa2e19cf7ea52 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 5 Apr 2021 11:47:03 +0300 Subject: feat: update Cargo.lock int Rust projects If we update Cargo.toml, but not Cargo.lock, and Cargo.lock is in git, when cargo publish will refuse to publish, because the files are out of sync. --- bumper.md | 13 +++++++++++++ src/errors.rs | 6 ++++++ src/rust.rs | 17 +++++++++++++++++ subplot/bumper.py | 14 ++++++++++++++ subplot/bumper.yaml | 6 ++++++ 5 files changed, 56 insertions(+) diff --git a/bumper.md b/bumper.md index 43dd8c7..cebc1fb 100644 --- a/bumper.md +++ b/bumper.md @@ -91,17 +91,27 @@ project. We use a Rust project for simplicity. ~~~scenario given an installed Bumper +given file foo/src/main.rs from main.rs given file foo/Cargo.toml from Cargo.toml +given file foo/Cargo.lock from Cargo.lock given file foo/debian/changelog from changelog given all files in foo are committed to git when I run, in foo, bumper 1.2.0 then all changes in foo are committed then in foo, git tag v1.2.0 is a signed tag then file foo/Cargo.toml matches regex /version\s*=\s*"1\.2\.0"/ +then file foo/Cargo.lock is newer than foo/Cargo.toml +then file foo/Cargo.lock is committed to git then file foo/debian/changelog matches regex / \(0\.1\.0-1\) / then file foo/debian/changelog matches regex / \(1\.2\.0-1\) / ~~~ +~~~{#main.rs .file .rust} +fn main() { + println!("Hello, world!"); +} +~~~ + ~~~{#Cargo.toml .file .ini} [package] name = "foo" @@ -110,8 +120,11 @@ authors = ["J. Random Hacker "] edition = "2018" [dependencies] +anyhow = "1" ~~~ +~~~{#Cargo.lock .file .ini} +~~~ ~~~{#changelog .file} dummy (0.1.0-1) unstable; urgency=low diff --git a/src/errors.rs b/src/errors.rs index 6ea498d..bd09eba 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -43,4 +43,10 @@ pub enum BumperError { #[error("dch failed in {0}: {1}")] Dch(PathBuf, String), + + #[error("Failed to run cargo in {0}: {1}")] + CargoInvoke(PathBuf, #[source] std::io::Error), + + #[error("cargo failed in {0}: {1}")] + Cargo(PathBuf, String), } diff --git a/src/rust.rs b/src/rust.rs index 56778b1..10dc1a1 100644 --- a/src/rust.rs +++ b/src/rust.rs @@ -2,6 +2,7 @@ use crate::errors::BumperError; use cargo_edit::Manifest; use log::{debug, info}; use std::path::{Path, PathBuf}; +use std::process::Command; use toml_edit::{Item, Value}; pub struct Rust { @@ -26,6 +27,7 @@ impl Rust { // debug!("Cargo.toml:\n{:#?}", self.cargo_toml); self.cargo_toml.set_version(version)?; self.cargo_toml.write()?; + self.update_cargo_lock()?; let dirname = self .dirname @@ -40,6 +42,21 @@ impl Rust { ); Ok(()) } + + fn update_cargo_lock(&self) -> Result<(), BumperError> { + info!("running cargo update in {}", self.dirname.display()); + let output = Command::new("cargo") + .arg("update") + .current_dir(&self.dirname) + .output() + .map_err(|err| BumperError::CargoInvoke(self.dirname.to_path_buf(), err))?; + debug!("git exit code was {:?}", output.status.code()); + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr).into_owned(); + return Err(BumperError::Cargo(self.dirname.to_path_buf(), stderr)); + } + Ok(()) + } } #[derive(Debug)] diff --git a/subplot/bumper.py b/subplot/bumper.py index e340927..3edad5e 100644 --- a/subplot/bumper.py +++ b/subplot/bumper.py @@ -94,3 +94,17 @@ def git_working_tree_is_clean(ctx, dirname=None): runcmd_exit_code_is_zero(ctx) output = runcmd_get_stdout(ctx) assert_eq(output, "") + + +def file_is_newer_than_other_file(ctx, file1=None, file2=None): + assert os.path.getmtime(file1) > os.path.getmtime(file2) + + +def file_is_in_git(ctx, filename=None): + runcmd_run = globals()["runcmd_run"] + runcmd_exit_code_is_zero = globals()["runcmd_exit_code_is_zero"] + + dirname = os.path.dirname(filename) or "." + basename = os.path.basename(filename) + runcmd_run(ctx, ["git", "blame", basename], cwd=dirname) + runcmd_exit_code_is_zero(ctx) diff --git a/subplot/bumper.yaml b/subplot/bumper.yaml index 50cf83c..6109c59 100644 --- a/subplot/bumper.yaml +++ b/subplot/bumper.yaml @@ -21,3 +21,9 @@ - then: "all changes in {dirname} are committed" function: git_working_tree_is_clean + +- then: "file {file1} is newer than {file2}" + function: file_is_newer_than_other_file + +- then: "file {filename} is committed to git" + function: file_is_in_git -- cgit v1.2.1