Skip to content

Commit

Permalink
Add --detach-path-deps
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Oct 17, 2023
1 parent 51fd8a2 commit e92d67e
Show file tree
Hide file tree
Showing 7 changed files with 348 additions and 89 deletions.
1 change: 1 addition & 0 deletions .deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ build.allow-build-scripts = [
{ name = "anyhow" },
{ name = "libc" }, # via ctrlc & is-terminal
{ name = "rustix" }, # via is-terminal
{ name = "semver" },
{ name = "serde_json" },
{ name = "serde" },
{ name = "winapi-i686-pc-windows-gnu" }, # via same-file & termcolor
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com

## [Unreleased]

- Add `--detach-path-deps` flag to run minimal versions check with `path` fields removed from dependencies. ([#4](https://github.com/taiki-e/cargo-minimal-versions/pull/4))

## [0.1.19] - 2023-09-11

- Remove dependency on `slab`, `shell-escape`, and `fs-err`.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ctrlc = { version = "3.1.4", features = ["termination"] }
is-terminal = "0.4"
lexopt = "0.3"
same-file = "1.0.1"
semver = "1"
serde_json = "1"
termcolor = "1"
toml_edit = "0.20"
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ Normally, crates with `publish = false` do not need minimal versions check. You
cargo minimal-versions check --workspace --ignore-private
```

If path dependencies exist, the above ways may miss the problem when you publish the crate (e.g., [tokio-rs/tokio#4376], [tokio-rs/tokio#4490]) <br>
By using `--detach-path-deps` flag, you can run minimal versions check with `path` fields removed from dependencies.

```sh
cargo minimal-versions check --workspace --ignore-private --detach-path-deps
```

`--detach-path-deps` flag removes all[^1] path fields by default.
By using `--detach-path-deps=skip-exact` flag, you can skip the removal of path fields in dependencies with exact version requirements (`"=<version>"`). For example, this is useful for [a pair of a proc-macro and a library that export it](https://github.com/taiki-e/pin-project/blob/df5ed4369e2c34d2111b71ef2fdd6b3621c55fa3/Cargo.toml#L32).

[^1]: To exactly, when neither version, git, nor path is specified, an error will occur, so we will remove the path field of all of dependencies for which the version or git URL is specified.

## Details

Using `-Z minimal-versions` in the usual way will not work properly in many cases. [To use `cargo check` with `-Z minimal-versions` properly, you need to run at least three processes.](https://github.com/tokio-rs/tokio/pull/3131#discussion_r521621961)
Expand Down Expand Up @@ -157,6 +169,8 @@ cargo binstall cargo-minimal-versions
[cargo-hack]: https://github.com/taiki-e/cargo-hack
[cargo-llvm-cov]: https://github.com/taiki-e/cargo-llvm-cov
[cargo#5657]: https://github.com/rust-lang/cargo/issues/5657
[tokio-rs/tokio#4376]: https://github.com/tokio-rs/tokio/pull/4376
[tokio-rs/tokio#4490]: https://github.com/tokio-rs/tokio/pull/4490

## License

Expand Down
49 changes: 38 additions & 11 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,47 @@ pub(crate) struct Args {
pub(crate) no_private: bool,
pub(crate) subcommand: Subcommand,
pub(crate) manifest_path: Option<String>,
pub(crate) detach_path_deps: Option<DetachPathDeps>,
pub(crate) cargo_args: Vec<String>,
pub(crate) rest: Vec<String>,
}

#[derive(PartialEq)]
pub(crate) enum Subcommand {
// build, check, run
Builtin,
// build, check, run, clippy
Builtin(String),
// test, bench
BuiltinDev,
Other,
BuiltinDev(String),
Other(String),
}

impl Subcommand {
fn new(s: &str) -> Self {
// https://github.com/rust-lang/cargo/blob/0.62.0/src/bin/cargo/main.rs#L48-L56
match s {
"b" | "build" | "c" | "check" | "r" | "run" => Self::Builtin,
"t" | "test" | "bench" => Self::BuiltinDev,
"b" | "build" | "c" | "check" | "r" | "run" | "clippy" => Self::Builtin(s.to_owned()),
"t" | "test" | "bench" => Self::BuiltinDev(s.to_owned()),
_ => {
warn!("unrecognized subcommand '{s}'");
Self::Other
warn!("unrecognized subcommand '{s}'; minimal-versions check may not work as expected");
Self::Other(s.to_owned())
}
}
}

pub(crate) fn always_needs_dev_deps(&self) -> bool {
*self == Self::BuiltinDev
matches!(self, Self::BuiltinDev(..))
}

pub(crate) fn as_str(&self) -> &str {
match self {
Self::Builtin(s) | Self::BuiltinDev(s) | Self::Other(s) => s,
}
}
}

#[derive(Clone, Copy, PartialEq)]
pub(crate) enum DetachPathDeps {
All,
SkipExact,
}

impl Args {
Expand Down Expand Up @@ -94,6 +106,7 @@ impl Args {
let mut color = None;
let mut manifest_path: Option<String> = None;
let mut verbose = 0;
let mut detach_path_deps = None;

let mut no_private = false;

Expand All @@ -120,6 +133,20 @@ impl Args {
Long("color") => parse_opt!(color),
Long("manifest-path") => parse_opt!(manifest_path),
Short('v') | Long("verbose") => verbose += 1,
Long("detach-path-deps") => {
if let Some(val) = parser.optional_value() {
if val == "all" {
detach_path_deps = Some(DetachPathDeps::All);
} else if val == "skip-exact" {
detach_path_deps = Some(DetachPathDeps::SkipExact);
} else {
bail!("unrecognized value for --detach-path-deps, must be all or skip-exact: {val:?}");
}
} else {
// TODO: Is this a reasonable default?
detach_path_deps = Some(DetachPathDeps::All);
}
}

// cargo-hack flags
// However, do not propagate to cargo-hack, as the same process
Expand Down Expand Up @@ -185,7 +212,7 @@ impl Args {
cargo_args.push(path.clone());
}

Ok(Self { no_private, subcommand, manifest_path, cargo_args, rest })
Ok(Self { no_private, subcommand, manifest_path, detach_path_deps, cargo_args, rest })
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ fn try_main() -> Result<()> {
a.starts_with("--example=") || a.starts_with("--test=") || a.starts_with("--bench=")
}
});
// TODO: provide option to keep updated Cargo.lock
let restore_lockfile = true;
manifest::with(&ws.metadata, remove_dev_deps, args.no_private, restore_lockfile, || {
manifest::with(&ws.metadata, &args, remove_dev_deps, || {
// Update Cargo.lock to minimal version dependencies.
let mut cargo = ws.cargo_nightly();
cargo.args(["update", "-Z", "minimal-versions"]);
Expand All @@ -62,10 +60,10 @@ fn try_main() -> Result<()> {
let mut cargo = ws.cargo();
// TODO: Provide a way to do this without using cargo-hack.
cargo.arg("hack");
cargo.args(args.cargo_args);
cargo.args(&args.cargo_args);
if !args.rest.is_empty() {
cargo.arg("--");
cargo.args(args.rest);
cargo.args(&args.rest);
}
info!("running {cargo}");
cargo.run()
Expand Down
Loading

0 comments on commit e92d67e

Please sign in to comment.