Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Publish using rust-version toolchain #381

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ Configuration is read from the following (in precedence order)
| `sign-tag` | `--sign-tag` | bool | Use GPG to sign git tag generated by cargo-release. |
| `push-remote` | `--push-remote` | string | Default git remote to push |
| `registry` | `--registry` | string | Cargo registry name to publish to (default uses Rust's default, which goes to `crates.io`) |
| `release` | `--exclude` | bool | Skip the entire release process (usually for internal crates in a workspace) |
| `push` | `--no-push` | bool | Don't do git push |
| `release` | `--exclude` | bool | Skip the entire release process (usually for internal crates in a workspace) |
| `push` | `--no-push` | bool | Don't do git push |
| `push-options` | \- | list of strings | Flags to send to the server when doing a `git push` |
| `tag` | `--no-tag` | bool | Don't do git tag |
| `publish` | `--no-publish` | bool | Don't do cargo publish right now, see [manifest `publish` field](https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish--field-optional) to permanently disable publish. |
| `tag` | `--no-tag` | bool | Don't do git tag |
| `publish` | `--no-publish` | bool | Don't do cargo publish right now, see [manifest `publish` field](https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish--field-optional) to permanently disable publish. |
| `rust-version` | | string | Toolchain version to use for publishing (specify `"manifest"` to use [Cargo.toml's `rust-version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field) |
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be concerned there isn't a way to turn this off?

I'm tempted to overlay this with a bool so you can just enable/disable it. Just lazy about writing the serde logic for it.

| `verify` | `--no-verify` | bool | Don't verify the contents by building them |
| `shared-version` | \- | bool | Ensure all crates with `shared_version` are the same version |
| `consolidate-commits` | \- | bool | When releasing a workspace, use a single commit for the pre-release version bump and a single commit for the post-release version bump. |
Expand Down
48 changes: 44 additions & 4 deletions src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,62 @@ pub fn package_content(manifest_path: &Path) -> Result<Vec<std::path::PathBuf>,
}
}

pub fn is_toolchain_present(toolchain_version: &str) -> bool {
let formatted_toolchain_version = format!("+{}", toolchain_version);

let output = std::process::Command::new("cargo")
.args([&formatted_toolchain_version, "publish", "--help"])
.output();
match output {
Ok(output) => {
if output.status.success() {
true
} else {
log::trace!(
"Error when checking for presence of {} toolchain: {}",
toolchain_version,
String::from_utf8_lossy(&output.stderr)
);
false
}
}
Err(err) => {
log::trace!(
"Error when checking for presence of {} toolchain: {}",
toolchain_version,
err
);
false
}
}
}

pub fn publish(
dry_run: bool,
verify: bool,
manifest_path: &Path,
features: &Features,
registry: Option<&str>,
token: Option<&str>,
toolchain_version: Option<&str>,
) -> Result<bool, FatalError> {
let cargo = cargo();
let mut command: Vec<&str>;

let bin: String;
let formatted_toolchain_version;
if let Some(toolchain_version) = toolchain_version {
formatted_toolchain_version = format!("+{}", toolchain_version);
command = vec!["cargo", &formatted_toolchain_version];
} else {
bin = cargo();
command = vec![&bin];
}
Comment on lines +96 to +102
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be concerned that we are ignoring CARGO when using the rust-version?


let mut command: Vec<&str> = vec![
&cargo,
command.extend([
"publish",
"--manifest-path",
manifest_path.to_str().unwrap(),
];
]);

if let Some(registry) = registry {
command.push("--registry");
Expand Down
8 changes: 4 additions & 4 deletions src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ fn do_call(
envs: Option<BTreeMap<&OsStr, &OsStr>>,
dry_run: bool,
) -> Result<bool, FatalError> {
if path.is_some() {
log::trace!("cd {}", path.unwrap().display());
}
log::trace!("{}", command.join(" "));
if dry_run {
if path.is_some() {
log::trace!("cd {}", path.unwrap().display());
}
log::trace!("{}", command.join(" "));
return Ok(true);
}
let mut iter = command.iter();
Expand Down
19 changes: 19 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct Config {
pub disable_release: Option<bool>,
pub publish: Option<bool>,
pub disable_publish: Option<bool>,
pub rust_version: Option<String>,
pub verify: Option<bool>,
pub no_verify: Option<bool>,
pub push: Option<bool>,
Expand Down Expand Up @@ -69,6 +70,9 @@ impl Config {
self.publish = Some(publish);
self.disable_publish = None;
}
if let Some(rust_version) = source.rust_version.as_deref() {
self.rust_version = Some(rust_version.to_owned());
}
if let Some(verify) = resolve_bool_arg(source.verify, source.no_verify) {
self.verify = Some(verify);
self.no_verify = None;
Expand Down Expand Up @@ -166,6 +170,10 @@ impl Config {
resolve_bool_arg(self.publish, self.disable_publish).unwrap_or(true)
}

pub fn rust_version(&self) -> Option<&str> {
self.rust_version.as_deref()
}

pub fn verify(&self) -> bool {
resolve_bool_arg(self.verify, self.no_verify).unwrap_or(true)
}
Expand Down Expand Up @@ -413,6 +421,17 @@ pub fn dump_config(
release_config.publish = Some(false);
release_config.disable_publish = None;
}
if release_config.rust_version() == Some("manifest") {
if let Some(rust_version) = cargo_file
.get("package")
.and_then(|p| p.get("rust-version"))
.and_then(|r| r.as_str())
{
release_config.rust_version = Some(rust_version.to_owned());
} else {
release_config.rust_version = None;
}
}

release_config
} else {
Expand Down
24 changes: 24 additions & 0 deletions src/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,29 @@ fn release_packages<'m>(

// STEP 0: Help the user make the right decisions.
git::git_version()?;

let mut toolchains = HashSet::new();
let mut missing_toolchain = false;
for pkg in pkgs {
if let Some(toolchain_version) = pkg.config.rust_version() {
if toolchains.insert(toolchain_version)
&& !cargo::is_toolchain_present(toolchain_version)
{
log::error!(
"{} requires rust {} toolchain to publish",
pkg.meta.name,
toolchain_version
);
missing_toolchain = true;
}
}
}
if missing_toolchain {
if !dry_run {
return Ok(101);
}
}

let mut dirty = false;
if ws_config.consolidate_commits() {
if git::is_dirty(ws_meta.workspace_root.as_std_path())? {
Expand Down Expand Up @@ -395,6 +418,7 @@ fn release_packages<'m>(
features,
pkg.config.registry(),
args.token.as_ref().map(AsRef::as_ref),
pkg.config.rust_version(),
)? {
return Ok(103);
}
Expand Down