Skip to content

Commit 2901775

Browse files
authored
Switch to using a centrally-located workspace version (#117)
This change should update the location of the version string to a central place: the top-level `Cargo.toml`. This causes some churn in the `xtask` commands but the overall result should be the same.
1 parent 30fa16c commit 2901775

File tree

7 files changed

+116
-77
lines changed

7 files changed

+116
-77
lines changed

Cargo.toml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
11
[workspace]
2-
members = ["crates/openvino", "crates/openvino-sys", "crates/openvino-finder", "crates/xtask"]
2+
resolver = "2"
3+
members = [
4+
"crates/openvino",
5+
"crates/openvino-sys",
6+
"crates/openvino-finder",
7+
"crates/xtask",
8+
]
9+
10+
[workspace.package]
11+
version = "0.6.0"
12+
authors = ["OpenVINO Project Developers"]
13+
edition = "2021"
14+
license = "Apache-2.0"
15+
readme = "README.md"
16+
repository = "https://github.com/intel/openvino-rs"
17+
18+
[workspace.dependencies]
19+
openvino-sys = { path = "crates/openvino-sys", version = "=0.6.0" }
20+
openvino-finder = { path = "crates/openvino-finder", version = "=0.6.0" }
21+
env_logger = "0.10"

crates/openvino-finder/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
[package]
22
name = "openvino-finder"
3-
version = "0.6.0"
43
description = "A helper crate for finding OpenVINO installations on a system."
5-
license = "Apache-2.0"
4+
version.workspace = true
5+
authors.workspace = true
6+
license.workspace = true
7+
edition.workspace = true
68
readme = "README.md"
7-
authors = ["OpenVINO Project Developers"]
89
repository = "https://github.com/intel/openvino-rs"
910
documentation = "https://docs.rs/openvino-finder"
1011
keywords = ["openvino", "machine-learning", "ml", "neural-network"]
1112
categories = ["development-tools"]
12-
edition = "2018"
1313

1414
[dependencies]
1515
cfg-if = "1.0"
1616
log = "0.4"
1717

1818
[dev-dependencies]
19-
env_logger = "0.10"
19+
env_logger = { workspace = true }

crates/openvino-sys/Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
[package]
22
name = "openvino-sys"
3-
version = "0.6.0"
4-
license = "Apache-2.0"
53
description = "Low-level bindings for OpenVINO (use the `openvino` crate for easier-to-use bindings)."
6-
readme = "README.md"
7-
authors = ["OpenVINO Project Developers"]
8-
repository = "https://github.com/intel/openvino-rs"
4+
version.workspace = true
5+
authors.workspace = true
6+
license.workspace = true
7+
edition.workspace = true
8+
readme.workspace = true
9+
repository.workspace = true
910
documentation = "https://docs.rs/openvino-sys"
1011
keywords = ["openvino", "machine-learning", "ml", "neural-network"]
1112
categories = ["external-ffi-bindings", "science"]
12-
edition = "2018"
1313
include = [
1414
"/Cargo.toml",
1515
"/README.md",
@@ -22,16 +22,16 @@ include = [
2222
# - built from an OpenVINO installation when used as a dependency
2323
"/upstream/src/bindings/c/include",
2424
]
25-
links = "inference_engine_c_api"
25+
links = "openvino_c_api"
2626

2727
[dependencies]
2828
once_cell = { version = "1.18", optional = true }
2929
libloading = { version = "0.8", optional = true }
30-
openvino-finder = { version = "0.6.0", path = "../openvino-finder" }
30+
openvino-finder = { workspace = true }
3131

3232
[build-dependencies]
33-
openvino-finder = { version = "0.6.0", path = "../openvino-finder" }
34-
env_logger = "0.10"
33+
openvino-finder = { workspace = true }
34+
env_logger = { workspace = true }
3535

3636
[features]
3737
# Linking features: `build.rs` will default to dynamic linking if none is selected.

crates/openvino/Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
[package]
22
name = "openvino"
3-
version = "0.6.0"
4-
license = "Apache-2.0"
53
description = "High-level bindings for OpenVINO."
6-
readme = "README.md"
7-
authors = ["OpenVINO Project Developers"]
8-
repository = "https://github.com/intel/openvino-rs"
4+
version.workspace = true
5+
authors.workspace = true
6+
license.workspace = true
7+
edition.workspace = true
8+
readme.workspace = true
9+
repository.workspace = true
910
documentation = "https://docs.rs/openvino"
1011
keywords = ["openvino", "machine-learning", "ml", "neural-network"]
1112
categories = ["api-bindings", "science"]
12-
edition = "2018"
1313
exclude = ["/tests"]
1414

1515
[dependencies]
16-
openvino-sys = { path = "../openvino-sys", version = "0.6.0" }
17-
openvino-finder = { path = "../openvino-finder", version = "0.6.0" }
16+
openvino-sys = { workspace = true }
17+
openvino-finder = { workspace = true }
1818
thiserror = "1.0"
1919

2020
[dev-dependencies]

crates/xtask/src/bump.rs

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::util::{get_crates, Crate};
2-
use anyhow::{bail, Context, Result};
1+
use crate::util::{get_crates, get_top_level_cargo_toml, get_top_level_version, Crate};
2+
use anyhow::{Context, Result};
33
use clap::Args;
44
use semver::{BuildMetadata, Prerelease};
55
use std::fs;
@@ -26,17 +26,10 @@ impl BumpCommand {
2626
let publishable_crates: Vec<Crate> =
2727
get_crates()?.into_iter().filter(|c| c.publish).collect();
2828

29-
// Check that all of the versions are the same.
30-
if !publishable_crates
31-
.windows(2)
32-
.all(|w| w[0].version == w[1].version)
33-
{
34-
bail!("Not all crate versions are the same: {publishable_crates:?}");
35-
}
36-
3729
// Change the version. Unless specified with a custom version, the `pre` and `build`
3830
// metadata are cleared.
39-
let mut next_version = semver::Version::parse(&publishable_crates[0].version)?;
31+
let current_version = get_top_level_version()?;
32+
let mut next_version = current_version.clone();
4033
next_version.pre = Prerelease::EMPTY;
4134
next_version.build = BuildMetadata::EMPTY;
4235
match &self.bump {
@@ -55,11 +48,17 @@ impl BumpCommand {
5548
Bump::Custom(v) => next_version = semver::Version::parse(v)?,
5649
}
5750

58-
// Update the Cargo.toml files.
59-
let next_version_str = &next_version.to_string();
60-
for c in &publishable_crates {
61-
update_version(c, &publishable_crates, next_version_str, self.dry_run)?;
62-
}
51+
// Update the top-level Cargo.toml version. We expect all the crates use the top-level
52+
// workspace version.
53+
assert!(publishable_crates.iter().all(uses_workspace_version));
54+
let current_version_str = current_version.to_string();
55+
let next_version_str = next_version.to_string();
56+
update_version(
57+
&publishable_crates,
58+
&current_version_str,
59+
&next_version_str,
60+
self.dry_run,
61+
)?;
6362

6463
// Update the Cargo.lock file.
6564
if !self.dry_run {
@@ -107,29 +106,41 @@ impl std::str::FromStr for Bump {
107106
}
108107
}
109108

110-
/// Update the version of `krate` and any dependencies in `crates` to match the version passed in
111-
/// `next_version`. Adapted from Wasmtime's [publish.rs] script.
109+
/// Check that a publishable crate pulls its version from the workspace version.
110+
fn uses_workspace_version(krate: &Crate) -> bool {
111+
let contents = fs::read_to_string(&krate.path).unwrap();
112+
let toml: toml::Value = contents.parse().unwrap();
113+
let version_workspace = &toml["package"]["version"]["workspace"];
114+
*version_workspace == toml::Value::Boolean(true)
115+
}
116+
117+
/// Update the version in the top-level Cargo.toml and any dependencies in its
118+
/// `[workspace.dependencies]` to match the version passed in `next_version`. Adapted from
119+
/// Wasmtime's [publish.rs] script.
112120
///
113121
/// [publish.rs]: https://github.com/bytecodealliance/wasmtime/blob/main/scripts/publish.rs
114122
fn update_version(
115-
krate: &Crate,
116123
crates: &[Crate],
124+
current_version: &str,
117125
next_version: &str,
118126
dry_run: bool,
119127
) -> Result<()> {
120-
let contents = fs::read_to_string(&krate.path)?;
128+
let top_level_cargo_toml_path = get_top_level_cargo_toml()?;
129+
let contents = fs::read_to_string(&top_level_cargo_toml_path)?;
121130
let mut new_contents = String::new();
122131
let mut reading_dependencies = false;
123132
for line in contents.lines() {
124133
let mut rewritten = false;
125134

126135
// Update top-level `version = "..."` line.
127136
if !reading_dependencies && line.starts_with("version =") {
137+
let modified_line = line.replace(current_version, next_version);
128138
println!(
129-
"> bump `{}` {} => {}",
130-
krate.name, krate.version, next_version
139+
"> bump: {} => {}",
140+
line.trim_start_matches("version =").trim(),
141+
modified_line.trim_start_matches("version =").trim()
131142
);
132-
new_contents.push_str(&line.replace(&krate.version.to_string(), next_version));
143+
new_contents.push_str(&modified_line);
133144
rewritten = true;
134145
}
135146

@@ -145,21 +156,21 @@ fn update_version(
145156
if !reading_dependencies || !line.starts_with(&format!("{} ", other.name)) {
146157
continue;
147158
}
148-
if !line.contains(&other.version.to_string()) {
159+
if !line.contains(current_version) {
149160
if !line.contains("version =") {
150161
continue;
151162
}
152163
panic!(
153-
"{:?} has a dependency on {} but doesn't list version {}",
154-
krate.path, other.name, other.version
164+
"workspace dependency {} doesn't list version {}",
165+
other.name, current_version
155166
);
156167
}
157168
println!(
158169
"> bump dependency `{}` {} => {}",
159-
other.name, other.version, next_version
170+
other.name, current_version, next_version
160171
);
161172
rewritten = true;
162-
new_contents.push_str(&line.replace(&other.version, next_version));
173+
new_contents.push_str(&line.replace(current_version, next_version));
163174
break;
164175
}
165176

@@ -172,7 +183,7 @@ fn update_version(
172183
}
173184

174185
if !dry_run {
175-
fs::write(&krate.path, new_contents)?;
186+
fs::write(top_level_cargo_toml_path, new_contents)?;
176187
}
177188

178189
Ok(())

crates/xtask/src/publish.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::util::{exec, get_crates, path_to_crates, Crate};
2-
use anyhow::{bail, Result};
1+
use crate::util::{exec, get_crates, get_top_level_version, path_to_crates, Crate};
2+
use anyhow::Result;
33
use clap::Args;
4-
use std::{process::Command, thread::sleep, time::Duration};
4+
use std::process::Command;
55

66
#[derive(Debug, Args)]
77
pub struct PublishCommand {
@@ -16,18 +16,13 @@ pub struct PublishCommand {
1616

1717
impl PublishCommand {
1818
pub fn execute(&self) -> Result<()> {
19+
// Find the single crate version in the top-level Cargo.toml.
20+
let version = get_top_level_version()?;
21+
1922
// Find the publishable crates.
2023
let publishable_crates: Vec<Crate> =
2124
get_crates()?.into_iter().filter(|c| c.publish).collect();
2225

23-
// Check that all of the versions are the same.
24-
if !publishable_crates
25-
.windows(2)
26-
.all(|w| w[0].version == w[1].version)
27-
{
28-
bail!("Not all crate versions are the same: {publishable_crates:?}");
29-
}
30-
3126
// Check that all of the publishable crates are in `PUBLICATION_ORDER`.
3227
assert_eq!(publishable_crates.len(), PUBLICATION_ORDER.len());
3328
assert!(publishable_crates
@@ -52,14 +47,11 @@ impl PublishCommand {
5247
if let Err(e) = exec_result {
5348
println!("Failed to publish crate {krate}, continuing:\n {e}");
5449
}
55-
56-
// Hopefully this gives crates.io enough time for subsequent publications to work.
57-
sleep(Duration::from_secs(20));
5850
}
5951
}
6052

6153
// Tag the repository.
62-
let tag = format!("v{}", publishable_crates[0].version);
54+
let tag = format!("v{}", version);
6355
if self.git {
6456
println!("> push Git tag: {tag}");
6557
if !self.dry_run {

crates/xtask/src/util.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,32 @@ pub fn path_to_crates() -> Result<PathBuf> {
2626
.into())
2727
}
2828

29+
/// Determine the path to the top-level `Cargo.toml` file.
30+
pub fn get_top_level_cargo_toml() -> Result<PathBuf> {
31+
let crates_dir = path_to_crates()?;
32+
let top_level_dir = crates_dir
33+
.parent()
34+
.with_context(|| "Failed to get parent of path.".to_string())?;
35+
let cargo_toml = top_level_dir.join("Cargo.toml");
36+
assert!(cargo_toml.is_file());
37+
Ok(cargo_toml)
38+
}
39+
40+
/// Parse the top-level `Cargo.toml` for the workspace version.
41+
pub fn get_top_level_version() -> Result<Version> {
42+
let path = get_top_level_cargo_toml()?;
43+
let contents = fs::read_to_string(&path)?;
44+
let toml: Value = contents
45+
.parse()
46+
.with_context(|| format!("unable to parse TOML of {}", &path.display()))?;
47+
48+
let version = toml["workspace"]["package"]["version"]
49+
.as_str()
50+
.with_context(|| "No top-level package version in workspace Cargo.toml")?
51+
.to_owned();
52+
Ok(Version::parse(&version)?)
53+
}
54+
2955
/// Retrieve information about all of the crates found in the `crates` directory.
3056
pub fn get_crates() -> Result<Vec<Crate>> {
3157
let crates_dir = path_to_crates()?;
@@ -38,18 +64,11 @@ pub fn get_crates() -> Result<Vec<Crate>> {
3864
let toml: Value = contents
3965
.parse()
4066
.with_context(|| format!("unable to parse TOML of {}", &path.display()))?;
41-
4267
let name = toml["package"]["name"]
4368
.as_str()
4469
.with_context(|| "Every Cargo.toml should have a package name")?
4570
.to_owned();
4671

47-
let version = toml["package"]["version"]
48-
.as_str()
49-
.with_context(|| "Every Cargo.toml should have a package name")?
50-
.to_owned();
51-
Version::parse(&version)?;
52-
5372
let publish = toml["package"]
5473
.get("publish")
5574
.unwrap_or(&Value::Boolean(true))
@@ -59,7 +78,6 @@ pub fn get_crates() -> Result<Vec<Crate>> {
5978
crates.push(Crate {
6079
name,
6180
path,
62-
version,
6381
publish,
6482
});
6583
}
@@ -72,6 +90,5 @@ pub fn get_crates() -> Result<Vec<Crate>> {
7290
pub struct Crate {
7391
pub name: String,
7492
pub path: PathBuf,
75-
pub version: String,
7693
pub publish: bool,
7794
}

0 commit comments

Comments
 (0)