feat: add rust actions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
237
crates/cuddle-please-actions/src/rust_action.rs
Normal file
237
crates/cuddle-please-actions/src/rust_action.rs
Normal file
@@ -0,0 +1,237 @@
|
||||
use std::io::Write;
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
use crate::{actions::Action, ActionConfig};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct RustAction {}
|
||||
|
||||
impl RustAction {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn execute_content(
|
||||
&self,
|
||||
version: &semver::Version,
|
||||
cargo_content: &str,
|
||||
) -> anyhow::Result<String> {
|
||||
tracing::trace!("parsing Cargo.toml file as tolm");
|
||||
let mut cargo_doc = cargo_content.parse::<toml_edit::DocumentMut>()?;
|
||||
|
||||
tracing::debug!(
|
||||
"updating cargo workspace package version to {}",
|
||||
version.to_string()
|
||||
);
|
||||
|
||||
let workspace = if cargo_doc.contains_table("workspace") {
|
||||
cargo_doc["workspace"].as_table_mut().unwrap()
|
||||
} else {
|
||||
let mut t = toml_edit::Table::new();
|
||||
t.set_implicit(true);
|
||||
cargo_doc["workspace"] = toml_edit::Item::Table(t);
|
||||
cargo_doc["workspace"].as_table_mut().unwrap()
|
||||
};
|
||||
let package = workspace["package"].or_insert(toml_edit::table());
|
||||
package["version"] = toml_edit::value(version.to_string());
|
||||
|
||||
Ok(cargo_doc.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Action for RustAction {
|
||||
fn enabled(&self, config: &ActionConfig) -> anyhow::Result<bool> {
|
||||
if let Ok(v) = std::env::var("CUDDLE_PLEASE_RUST_ACTION") {
|
||||
if let Ok(true) = v.parse::<bool>() {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
let val = &config[self.name().as_str()];
|
||||
|
||||
if val.is_badvalue() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
Ok(val.as_bool().unwrap_or(true))
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
"rust".into()
|
||||
}
|
||||
|
||||
fn execute(&self, version: &semver::Version) -> anyhow::Result<()> {
|
||||
tracing::info!(
|
||||
"running rust action for version: {} and file: Cargo.toml",
|
||||
version.to_string()
|
||||
);
|
||||
|
||||
let path = std::path::PathBuf::from("Cargo.toml");
|
||||
|
||||
tracing::trace!("reading Cargo.toml");
|
||||
|
||||
let file = match std::fs::read_to_string(&path) {
|
||||
Ok(file) => file,
|
||||
Err(e) => match e.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
anyhow::bail!("err: Cargo.toml was not found in dir")
|
||||
}
|
||||
_ => Err(e)?,
|
||||
},
|
||||
};
|
||||
|
||||
let cargo_doc = self.execute_content(version, &file)?;
|
||||
|
||||
let mut cargo_file = std::fs::File::create(&path)?;
|
||||
cargo_file.write_all(cargo_doc.as_bytes())?;
|
||||
cargo_file.sync_all()?;
|
||||
|
||||
tracing::debug!("finished writing cargo file");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use semver::{BuildMetadata, Prerelease};
|
||||
|
||||
use crate::{actions::Action, ActionConfig};
|
||||
|
||||
use super::RustAction;
|
||||
|
||||
#[test]
|
||||
fn test_is_enabled() {
|
||||
let config = ActionConfig::try_from(
|
||||
r#"
|
||||
please:
|
||||
actions:
|
||||
rust: true
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let enabled = RustAction::new().enabled(&config).unwrap();
|
||||
|
||||
assert!(enabled)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_disabled_by_default() {
|
||||
let config = ActionConfig::try_from(
|
||||
r#"
|
||||
please:
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let enabled = RustAction::new().enabled(&config).unwrap();
|
||||
|
||||
assert!(!enabled)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_disabled() {
|
||||
let config = ActionConfig::try_from(
|
||||
r#"
|
||||
please:
|
||||
actions:
|
||||
rust: false
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let enabled = RustAction::new().enabled(&config).unwrap();
|
||||
|
||||
assert!(!enabled)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_value_is_enabled() {
|
||||
let config = ActionConfig::try_from(
|
||||
r#"
|
||||
please:
|
||||
actions:
|
||||
rust:
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let enabled = RustAction::new().enabled(&config).unwrap();
|
||||
|
||||
assert!(enabled)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_can_edit_empty_file() {
|
||||
let output = RustAction::default()
|
||||
.execute_content(
|
||||
&semver::Version {
|
||||
major: 0,
|
||||
minor: 1,
|
||||
patch: 0,
|
||||
pre: Prerelease::default(),
|
||||
build: BuildMetadata::default(),
|
||||
},
|
||||
"",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
pretty_assertions::assert_eq!(
|
||||
r#"[workspace.package]
|
||||
version = "0.1.0"
|
||||
"#,
|
||||
&output,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_only_edits_stuff() {
|
||||
let input = r#"
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
|
||||
[package]
|
||||
something = {some = "something"}
|
||||
|
||||
# Some comment
|
||||
|
||||
[workspace.package]
|
||||
version = "0.0.0" # some comment
|
||||
readme = "../../"
|
||||
"#;
|
||||
|
||||
let output = RustAction::default()
|
||||
.execute_content(
|
||||
&semver::Version {
|
||||
major: 0,
|
||||
minor: 1,
|
||||
patch: 0,
|
||||
pre: Prerelease::default(),
|
||||
build: BuildMetadata::default(),
|
||||
},
|
||||
input,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
pretty_assertions::assert_eq!(
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
|
||||
[package]
|
||||
something = {some = "something"}
|
||||
|
||||
# Some comment
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
readme = "../../"
|
||||
"#,
|
||||
&output,
|
||||
)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user