Skip to content

Commit

Permalink
feat: MVP for cargo set-version (#482)
Browse files Browse the repository at this point in the history
The name is not `version` because `cargo version` reports cargo's
version number.

The UI and implementation is lifted from `cargo-release`

Differences with `cargo-release`:
- Relative version changes is behind `--bump` rather than overloading
  the positional argument
  - Motivation: It didn't jive with `set-` in the name
  - Side benefit: Better error reporting

Differences with #414:
- `--bump <level>` vs `--<level>`
  - `--bump` scales better
- This PR supports `--metadata`, `--exclude`

Required future work
- Update workspace dependents when modifying versions

Possible future work
- `--at-least` flag to ignore downgrades, rather than error
- A flag to upgrade everything to the highest requested version (keep
  things in lockstep with `--bump patch`)
- A flag to upgrade min requirements on dependents (rather than just
  updating if semver is broken)
- `--pre` flag so you can do `--bump major --pre alpha` (even `1.0 --pre
  alpha` since I always forget that syntax)
  • Loading branch information
epage authored Sep 11, 2021
1 parent 71032c9 commit 8dbc81f
Show file tree
Hide file tree
Showing 12 changed files with 810 additions and 5 deletions.
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ name = "cargo-upgrade"
path = "src/bin/upgrade/main.rs"
required-features = ["upgrade"]

[[bin]]
name = "cargo-set-version"
path = "src/bin/set-version/main.rs"
required-features = ["set-version"]

[dependencies]
atty = { version = "0.2.14", optional = true }
cargo_metadata = "0.14.0"
Expand Down Expand Up @@ -79,10 +84,12 @@ default = [
"add",
"rm",
"upgrade",
"set-version",
]
add = ["cli"]
rm = ["cli"]
upgrade = ["cli"]
set-version = ["cli"]
cli = ["atty", "structopt"]
test-external-apis = []
vendored-openssl = ["git2/vendored-openssl"]
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Currently available subcommands:
- [`cargo add`](#cargo-add)
- [`cargo rm`](#cargo-rm)
- [`cargo upgrade`](#cargo-upgrade)
- [`cargo set-version`](#cargo-set-version)

[![Build Status](https://github.com/killercup/cargo-edit/workflows/build/badge.svg)](https://github.com/killercup/cargo-edit/actions)
[![Build Status](https://travis-ci.org/killercup/cargo-edit.svg?branch=master)](https://travis-ci.org/killercup/cargo-edit)
Expand Down Expand Up @@ -227,7 +228,7 @@ upgrade to for each can be specified with e.g. `[email protected]` or `serde@>=0.9,<2
Dev, build, and all target dependencies will also be upgraded. Only dependencies from crates.io are
supported. Git/path dependencies will be ignored.
All packages in the workspace will be upgraded if the `--workspace` flag is supplied.
All packages in the workspace will be upgraded if the `--workspace` flag is supplied.
The `--workspace` flag may be supplied in the presence of a virtual manifest.
If the '--to-lockfile' flag is supplied, all dependencies will be upgraded to the currently locked
Expand All @@ -236,6 +237,54 @@ up-to-date. If the lock file is missing, or it needs to be updated, cargo-upgrad
error. If the '--to-lockfile' flag is supplied then the network won't be accessed.
```

### `cargo set-version`

Set the version in your `Cargo.toml`.

#### Examples

```sh
# Set the version to the version 1.0.0
$ cargo set-version 1.0.0
# Bump the version to the next major
$ cargo set-version --bump major
# Bump version to the next minor
$ cargo set-version --bump minor
# Bump version to the next patch
$ cargo set-version --bump patch
```

#### Usage

```plain
cargo-set-version 0.7.0
Change a package's version in the local manifest file (i.e. Cargo.toml)
USAGE:
cargo set-version [FLAGS] [OPTIONS] [--] [target]
FLAGS:
--all [deprecated in favor of `--workspace`]
--dry-run Print changes to be made without making them
-h, --help Prints help information
-V, --version Prints version information
--workspace Modify all packages in the workspace
OPTIONS:
--bump <bump> Increment manifest version [possible values: major, minor, patch,
release, rc, beta, alpha]
--exclude <exclude>... Crates to exclude and not modify
--manifest-path <path> Path to the manifest to upgrade
-m, --metadata <metadata> Specify the version metadata field (e.g. a wrapped libraries version)
-p, --package <pkgid> Package id of the crate to change the version of
ARGS:
<target> Version to change manifests to
```

For more on `metadata`, see the
[semver crate's documentation](https://docs.rs/semver/1.0.4/semver/struct.BuildMetadata.html).

## License

Apache-2.0/MIT
64 changes: 64 additions & 0 deletions src/bin/set-version/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use std::path::PathBuf;

use structopt::{clap::AppSettings, StructOpt};

#[derive(Debug, StructOpt)]
#[structopt(bin_name = "cargo")]
pub(crate) enum Command {
/// Change a package's version in the local manifest file (i.e. Cargo.toml).
#[structopt(name = "set-version")]
Version(Args),
}

#[derive(Debug, StructOpt)]
#[structopt(setting = AppSettings::ColoredHelp)]
#[structopt(group = structopt::clap::ArgGroup::with_name("version").multiple(false))]
pub(crate) struct Args {
/// Version to change manifests to
#[structopt(parse(try_from_str), group = "version")]
pub(crate) target: Option<semver::Version>,

/// Increment manifest version
#[structopt(long, possible_values(&crate::version::BumpLevel::variants()), group = "version")]
pub(crate) bump: Option<crate::version::BumpLevel>,

/// Specify the version metadata field (e.g. a wrapped libraries version)
#[structopt(short = "m", long)]
pub metadata: Option<String>,

/// Path to the manifest to upgrade
#[structopt(long = "manifest-path", value_name = "path", conflicts_with = "pkgid")]
pub(crate) manifest_path: Option<PathBuf>,

/// Package id of the crate to change the version of.
#[structopt(
long = "package",
short = "p",
value_name = "pkgid",
conflicts_with = "path",
conflicts_with = "all",
conflicts_with = "workspace"
)]
pub(crate) pkgid: Option<String>,

/// Modify all packages in the workspace.
#[structopt(
long = "all",
help = "[deprecated in favor of `--workspace`]",
conflicts_with = "workspace",
conflicts_with = "pkgid"
)]
pub(crate) all: bool,

/// Modify all packages in the workspace.
#[structopt(long = "workspace", conflicts_with = "all", conflicts_with = "pkgid")]
pub(crate) workspace: bool,

/// Print changes to be made without making them.
#[structopt(long = "dry-run")]
pub(crate) dry_run: bool,

/// Crates to exclude and not modify.
#[structopt(long)]
pub(crate) exclude: Vec<String>,
}
19 changes: 19 additions & 0 deletions src/bin/set-version/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error_chain! {
errors {
/// We do not support this version requirement at this time
UnsupportedVersionReq(req: String) {
display("Support for modifying {} is currently unsupported", req)
}
/// User requested to downgrade a crate
VersionDowngreade(current: semver::Version, requested: semver::Version) {
display("Cannot downgrade from {} to {}", current, requested)
}
}
links {
CargoEditLib(::cargo_edit::Error, ::cargo_edit::ErrorKind);
}
foreign_links {
CargoMetadata(::failure::Compat<::cargo_metadata::Error>);
Version(::semver::Error)#[doc = "An error from the semver crate"];
}
}
Loading

0 comments on commit 8dbc81f

Please sign in to comment.