diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 125a38f4e..175d73418 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.27" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", @@ -454,9 +454,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", @@ -468,9 +468,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", @@ -1653,6 +1653,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kcl-bumper" +version = "0.1.45" +dependencies = [ + "anyhow", + "clap", + "semver", + "serde", + "toml_edit", +] + [[package]] name = "kcl-derive-docs" version = "0.1.45" @@ -1768,7 +1779,7 @@ dependencies = [ [[package]] name = "kcl-to-core" -version = "0.1.0" +version = "0.1.45" dependencies = [ "anyhow", "async-trait", @@ -1782,7 +1793,7 @@ dependencies = [ [[package]] name = "kcl-wasm-lib" -version = "0.1.0" +version = "0.1.45" dependencies = [ "bson", "console_error_panic_hook", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cd9ff4035..bd6e696da 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "kcl-bumper", "kcl-derive-docs", "kcl-lib", "kcl-python-bindings", diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 000000000..c5b361038 --- /dev/null +++ b/rust/README.md @@ -0,0 +1,23 @@ +# Rust Crates + +### Releasing + +1. Make sure your working directory is this directory. +1. Bump the versions of the crates: + ```bash + just bump-kcl-crate-versions + ``` +3. Commit the changes: + ```bash + git add . + git commit -m "Bump versions" + ``` +4. Push the changes and get your PR approved. +5. Publish the crates: + ```bash + just publish-kcl {version} + ``` + - This will publish the relevant crates and push a new tag with the prefix + `kcl-`. DO NOT SET THE PREFIX TO `kcl-` when you run the command. The `just` + command will do that for you. + - The tag will then trigger the release of kcl-python-bindings. diff --git a/rust/justfile b/rust/justfile index 25920beb6..7b4c32f39 100644 --- a/rust/justfile +++ b/rust/justfile @@ -44,6 +44,11 @@ overwrite-sim-test test_name: test: export RUST_BRACKTRACE="full" && cargo nextest run --workspace --no-fail-fast +bump-kcl-crate-versions bump='patch': + # First build the kcl-bumper tool. + cargo build -p kcl-bumper + ./target/debug/kcl-bumper --bump {{bump}} + publish-kcl version: git tag kcl-{{version}} cargo publish -p kcl-derive-docs diff --git a/rust/kcl-bumper/Cargo.toml b/rust/kcl-bumper/Cargo.toml new file mode 100644 index 000000000..b1482fc8f --- /dev/null +++ b/rust/kcl-bumper/Cargo.toml @@ -0,0 +1,21 @@ + +[package] +name = "kcl-bumper" +version = "0.1.45" +edition = "2021" +repository = "https://github.com/KittyCAD/modeling-api" +rust-version = "1.76" +description = "Bumps versions in Cargo.toml" +publish = false +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +clap = { version = "4.5.31", features = ["derive"] } +semver = "1.0.25" +serde = { workspace = true } +toml_edit = "0.22.16" + +[lints] +workspace = true + diff --git a/rust/kcl-bumper/src/main.rs b/rust/kcl-bumper/src/main.rs new file mode 100644 index 000000000..b74f526c2 --- /dev/null +++ b/rust/kcl-bumper/src/main.rs @@ -0,0 +1,159 @@ +//! Bumps versions in Cargo.toml. +use anyhow::{Context, Result}; +use clap::Parser; +use toml_edit::{value, DocumentMut}; + +fn main() -> Result<()> { + let args = Args::parse(); + // Get all the directories in the current directory. + let mut dirs = std::fs::read_dir(".").context("Could not read current directory")?; + for dir in dirs.by_ref() { + let dir = dir.context("Could not read directory")?; + if !(dir.path().display().to_string().starts_with("./kcl-") && dir.path().is_dir()) { + // We only care about the kcl-* directories. + continue; + } + println!("Found directory: {}", dir.path().display()); + run_on_manifest(dir.path().join("Cargo.toml"), &args)?; + eprintln!("Bumped version in {}", dir.path().display()); + } + + Ok(()) +} + +fn run_on_manifest(manifest_path: std::path::PathBuf, args: &Args) -> Result<()> { + let cargo_dot_toml = std::fs::read(&manifest_path).context("Could not read chosen Cargo.toml")?; + let cargo_dot_toml = String::from_utf8(cargo_dot_toml).context("Invalid UTF-8 in chosen Cargo.toml")?; + let mut doc = cargo_dot_toml + .parse::() + .context("Invalid TOML in Cargo.toml")?; + update_semver(args.bump, &mut doc).context("Could not bump semver")?; + std::fs::write(manifest_path, doc.to_string()).context("Could not write updated Cargo.toml")?; + Ok(()) +} + +fn parse_version(cargo_dot_toml: &mut DocumentMut) -> Result { + let current_version = cargo_dot_toml["package"]["version"] + .to_string() + // Clean quotations and whitespace. + .replace([' ', '"'], ""); + + semver::Version::parse(¤t_version).context("Could not parse semver version") +} + +/// Update the given TOML document (for a Cargo.toml file) by bumping its `version` field. +/// What kind of bump (major, minor, patch) is given by the `bump` argument. +fn update_semver(bump: Option, cargo_dot_toml: &mut DocumentMut) -> Result<()> { + let current_version = parse_version(cargo_dot_toml)?; + + // Get the next version. + let Some(bump) = bump else { + println!("{current_version}"); + return Ok(()); + }; + let mut next_version = current_version; + match bump { + SemverBump::Major => next_version.major += 1, + SemverBump::Minor => next_version.minor += 1, + SemverBump::Patch => next_version.patch += 1, + }; + + // Update the Cargo.toml + cargo_dot_toml["package"]["version"] = value(next_version.to_string()); + println!("{next_version}"); + Ok(()) +} + +/// Bumps versions in Cargo.toml +#[derive(Parser, Debug)] +struct Args { + /// What part of the semantic version (major, minor or patch) to bump. + /// If not given, bumper will just print the current version and then exit. + #[arg(short, long)] + bump: Option, +} + +#[derive(Debug, Clone, Copy)] +enum SemverBump { + Major, + Minor, + Patch, +} + +impl std::str::FromStr for SemverBump { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "major" => Ok(Self::Major), + "minor" => Ok(Self::Minor), + "patch" => Ok(Self::Patch), + _ => Err("valid options are 'major', 'minor' and 'patch'.".to_owned()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const EXAMPLE: &str = r#" +[package] +name = "bumper" +version = "0.1.0" + +[dependencies] +anyhow = "1.0.81" + "#; + + #[test] + fn test_bump_minor() { + let mut cargo_dot_toml = EXAMPLE.parse::().unwrap(); + update_semver(Some(SemverBump::Minor), &mut cargo_dot_toml).unwrap(); + assert_eq!( + cargo_dot_toml.to_string(), + r#" +[package] +name = "bumper" +version = "0.2.0" + +[dependencies] +anyhow = "1.0.81" + "# + ); + } + + #[test] + fn test_bump_major() { + let mut cargo_dot_toml = EXAMPLE.parse::().unwrap(); + update_semver(Some(SemverBump::Major), &mut cargo_dot_toml).unwrap(); + assert_eq!( + cargo_dot_toml.to_string(), + r#" +[package] +name = "bumper" +version = "1.1.0" + +[dependencies] +anyhow = "1.0.81" + "# + ); + } + + #[test] + fn test_bump_patch() { + let mut cargo_dot_toml = EXAMPLE.parse::().unwrap(); + update_semver(Some(SemverBump::Patch), &mut cargo_dot_toml).unwrap(); + assert_eq!( + cargo_dot_toml.to_string(), + r#" +[package] +name = "bumper" +version = "0.1.1" + +[dependencies] +anyhow = "1.0.81" + "# + ); + } +} diff --git a/rust/kcl-to-core/Cargo.toml b/rust/kcl-to-core/Cargo.toml index 3576e0c5f..35fc112c8 100644 --- a/rust/kcl-to-core/Cargo.toml +++ b/rust/kcl-to-core/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "kcl-to-core" description = "Utility methods to convert kcl to engine core executable tests" -version = "0.1.0" +version = "0.1.45" edition = "2021" license = "MIT" repository = "https://github.com/KittyCAD/modeling-app" +publish = false [lib] diff --git a/rust/kcl-wasm-lib/Cargo.toml b/rust/kcl-wasm-lib/Cargo.toml index a93cf11e2..069f9597e 100644 --- a/rust/kcl-wasm-lib/Cargo.toml +++ b/rust/kcl-wasm-lib/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "kcl-wasm-lib" -version = "0.1.0" +version = "0.1.45" edition = "2021" repository = "https://github.com/KittyCAD/modeling-app" rust-version = "1.83" +publish = false [lib] crate-type = ["cdylib"]