Skip to content

v0.31.0

Compare
Choose a tag to compare
@github-actions github-actions released this 22 Apr 17:01
· 163 commits to main since this release
44d5e0b

What's Changed

In this release:

  • 5 new lints
  • support for rustdoc format v29
  • improved diagnostic messages
  • tightening existing lints to catch more breaking changes
  • new CLI flags for color output
  • improved API if using cargo-semver-checks as a library (breaking changes — see Migration Guide below!)

This release requires Rust 1.74+ both to install (MSRV) and at runtime.

New lints

Support for rustdoc format v29

Latest nightly Rust has switched to rustdoc format v29, so you'll want to update to this new release if you are using a nightly released in the last week or so. Implemented in #769 and obi1kenobi/trustfall-rustdoc-adapter@9fb656a

Improved diagnostic messages

cargo-semver-checks can only semver-check library crates, since binaries have no API surface area to check. But it might not be obvious which crates cargo-semver-checks considered while looking for library crates to check — that's how we get issues like #723. As of this release, we have a better error message here:

error: no crates with library targets selected, nothing to semver-check
note: only library targets contain an API surface that can be checked for semver
note: skipped the following crates since they have no library target: example, other_example

Implemented in #741.

Two other, smaller quality-of-life improvements here are printing which crate features are enabled in --verbose mode (#725), and improving the error message when a crate fails to compile in cases where no features are used (#726).

Huge thanks to @jw013 who has been on a roll here 🙏

Tightening existing lints to catch more breaking changes

cargo-semver-checks has an explicit goal of "zero false-positives" — every lint we emit should point to a real issue deserving of maintainers' attention. (We are decent at this, but not perfect yet. We're working on getting better!)

But many cases aren't clear-cut — some things might be a major breaking change, and the final "yes/no" decision on it depends on many factors. In such cases, cargo-semver-checks is conservative, meaning that we choose to not emit a lint unless absolutely certain. For example:

pub struct MyIterator;

impl MyIterator {
    // We *do not* consider removing this pub method
    // a major breaking change!
    //
    // If removed, *most* callers will seamlessly use
    // the `Iterator` trait's version of the `next()` method.
    pub fn next(&mut self) -> Option<i64> {
        <Self as Iterator>::next(self)
    }
}

impl Iterator for MyIterator {
    type Item = i64;

    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

In the above example, removing the inherent MyIterator::next() method will not trigger a lint because for most users it won't be breaking. (It could still be breaking for some users though! For example, users who use #![no_implicit_prelude] and don't have the Iterator trait in scope.)

In some cases, we might overshoot and end up being overly conservative: there was a real breaking change, but we failed to emit it because we were too worried about it being a false positive.

This release removes overly conservative cases in the inherent_associated_pub_const_missing and inherent_method_missing lints related to when the impl Trait whose items we're falling back to is #[doc(hidden)] and not public API. The PR has the full details: #763

New CLI flags for color output

The CLI now accepts --color=always/never/auto to match cargo's own behavior. If set, the CLI flag overrides any CARGO_TERM_COLOR env variable that might be set.

Implemented by @suaviloquence in #721

Improved API if using cargo-semver-checks as a library

@suaviloquence took on the work of improving our library APIs:

  • Switched us from termcolor to the newer anstyle crate for our terminal color needs, to match what cargo itself uses. (#737)
  • Allow directing our stdout/stderr to buffers instead of the "real" stdout/stderr (#765)
  • Improve the naming and structural consistency of our API's methods (#765)

Additional thanks go to @pksunkara for the help and advice around switching to anstyle!

@suaviloquence put together this handy migration guide to help library users migrate 👏

Major changes

  • Check::check_release takes a new &mut GlobalConfig parameter, and GlobalConfig now holds log level and color settings.

    • Change:
      let mut check = Check::new(rustdoc);
      check.with_packages(packages)
           .with_log_level(Some(log_level))
           .with_color_choice(Some(termcolor::ColorChoice::Always));
      let result = check.check_release();
    • To:
      let mut config = GlobalConfig::new()
         .set_level(Some(log_level));
      config.set_color_choice(true); // or set_{err,out)_color_choice for finer-grained control
      
      let mut check = Check::new(rustdoc);
      check.with_packages(packages);
      let result = check.check_release(&mut config);
  • Set color choice in one of three ways:

    • Change:
      let choice: termcolor::ColorChoice = ...;
      config = config.set_color_choice(choice);
    • To: one of the three following options, depending on desired granularity
      1. Set global color choice for all crates using the anstream library:
        let choice: anstream::ColorChoice = ...;
        // set *before* creating `GlobalConfig` instance (if using default stdout/stderr)
        // or before calling `GlobalConfig::set_std{out,err}` (if configuring them)
        choice.write_global(); // configures `choice` for all crates using `anstream`
      2. Set whether to use colors for both stdout and stderr in the cargo-semver-checks library:
        let use_colors: bool = ...;
        config.set_color_choice(use_colors);
      3. Set whether to use colors for a specific stream in the cargo-semver-checks library:
        let use_colors_for_stderr: bool = ...;
        let use_colors_for_stdout: bool = ...;
        config.set_err_color_choice(use_colors_for_stderr);
        config.set_out_color_choice(use_colors_for_stdout);
  • config structs (Check, GlobalConfig, PackageSelection) now have a consistent setter convention: pub fn set_[property](&mut self, prop: T) -> &mut Self:

    • note: this does not apply to Check::with_[...]_features() methods as they are toggles vs property setters.
    • Change:
      selection.with_excluded_packages(packages);
      check.with_selection(selection).with_all_features();
    • To:
      selection.set_excluded_packages(packages);
      check.set_package_selection(selection).with_all_features();
    • Change:
      config = config.set_level(level);
    • To:
      config.set_log_level(level); // now takes and returns &mut Self instead of owned Self

New features

  • Users can configure the stdout and stderr streams for cargo-semver-checks to be different from default:
    let stderr: Box<dyn std::io::Write> = Box::new(stderr_buffer);
    config.set_stderr(stderr);

Minor changes

  • #[must_use] added on GlobalConfig::std{err,out}
  • GlobalConfig::shell_print takes an anstyle::Color instead of a termcolor::Color:
    • Change config.shell_print(status, message, termcolor::Color::Red, justified)
    • To config.shell_print(status, message, anstyle::Color::Ansi(anstyle::AnsiColor::Red, justified)
  • To write colors to stdout/stderr, use writeln!(config.stdout(), "{}styled text", anstyle::Style::new().bold().[...]); instead of the termcolor API
  • use GlobalConfig::{out,err}_color_choice() to query whether to print colors for the stdout/stderr stream instead of using GlobalConfig::is_err_tty as a heuristic
  • GlobalConfig::std{out,err} returns an opaque impl Write + '_ type instead of a termcolor::StandardStream

All Merged PRs

New Contributors

Full Changelog: v0.30.0...v0.31.0