feat: with rust workspaces
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2023-08-07 13:34:58 +02:00
parent 56b44cf2e2
commit b711258790
7 changed files with 179 additions and 2 deletions

View File

@@ -13,11 +13,13 @@ anyhow.workspace = true
tracing.workspace = true
serde.workspace = true
semver.workspace = true
cargo_metadata = "0.17.0"
[dev-dependencies]
tracing-test = { workspace = true, features = ["no-env-filter"] }
pretty_assertions.workspace = true
tempdir.workspace = true
serde_json.workspace = true
[features]
rust-workspace = []
@@ -27,5 +29,6 @@ json-edit = []
yaml-edit = []
default = [
"json-edit"
"json-edit",
"rust-workspace"
]

View File

@@ -1,6 +1,11 @@
#[cfg(feature = "json-edit")]
mod json_edit;
#[cfg(feature = "rust-workspace")]
mod rust_workspace;
mod strategy;
#[cfg(feature = "json-edit")]
pub use json_edit::JsonEditOptions;
#[cfg(feature = "rust-workspace")]
pub use rust_workspace::RustWorkspaceOptions;

View File

@@ -0,0 +1,72 @@
use std::path::{Path, PathBuf};
use anyhow::Context;
use cargo_metadata::camino::{Utf8Path, Utf8PathBuf};
use serde::{Deserialize, Serialize};
fn lock_step_default() -> bool {
true
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RustWorkspaceOptions {
#[serde(default = "lock_step_default")]
pub lock_step: bool,
}
impl RustWorkspaceOptions {
pub fn execute(&self, path: &Path, next_version: impl AsRef<str>) -> anyhow::Result<()> {
let members = self.get_workspace(path)?;
Ok(())
}
pub fn get_workspace(&self, path: &Path) -> anyhow::Result<Vec<cargo_metadata::Package>> {
let entries = std::fs::read_dir(path)
.context(anyhow::anyhow!("could not read dir: {}", path.display()))?
.flatten()
.filter(|p| p.file_name().to_str().unwrap() == "Cargo.toml")
.collect::<Vec<_>>();
let cargo_manifest_file = match entries.first() {
Some(x) => x,
None => anyhow::bail!("did not find any Cargo.toml in: {}", path.display()),
};
let mut cmd = cargo_metadata::MetadataCommand::new();
let manifest = cmd
.no_deps()
.manifest_path(cargo_manifest_file.path())
.exec()
.context("could not parse manifest")?;
let members = manifest.workspace_members.iter().collect::<Vec<_>>();
let workspace_members = manifest
.packages
.into_iter()
.filter(|p| members.contains(&&p.id))
.map(|mut p| {
p.manifest_path = abs_path(&p.manifest_path);
for dependency in p.dependencies.iter_mut() {
dependency.path = dependency.path.take().map(|path| abs_path(&path))
}
p
})
.collect::<Vec<_>>();
Ok(workspace_members)
}
}
fn abs_path(path: &Utf8Path) -> Utf8PathBuf {
match path.canonicalize_utf8() {
Ok(path) => path,
Err(e) => {
tracing::debug!("failed to transform manifest_path into abs path: {}", path);
path.to_path_buf()
}
}
}

View File

@@ -0,0 +1,60 @@
use cargo_metadata::{
camino::{Utf8Path, Utf8PathBuf},
Package,
};
use cuddle_please_release_strategy::RustWorkspaceOptions;
use serde_json::json;
use tracing_test::traced_test;
#[test]
#[traced_test]
fn test_can_read_manifest() {
let temp = tempdir::TempDir::new("test_rust_workspace_can_read_manifest").unwrap();
let temp_path = temp.path();
std::fs::write(
temp_path.join("Cargo.toml"),
r#"
[workspace]
members = [
"nested"
]
[workspace.dependencies]
nested = { path = "nested" }
"#,
)
.unwrap();
std::fs::create_dir_all(temp_path.join("nested")).unwrap();
std::fs::write(
temp_path.join("nested").join("Cargo.toml"),
r#"
[package]
name = "nested"
version = "0.1.0"
edition = "2021"
[dependencies]
nested.workspace = true
"#,
)
.unwrap();
std::fs::create_dir_all(temp_path.join("nested").join("src")).unwrap();
std::fs::write(
temp_path.join("nested").join("src").join("lib.rs"),
r#"
#[test]
test () {}
"#,
)
.unwrap();
let options = RustWorkspaceOptions { lock_step: true };
let members = options.get_workspace(temp_path).unwrap();
assert!(!members.is_empty());
let first = members.first().unwrap();
pretty_assertions::assert_eq!("nested", &first.name);
}