58 lines
1.7 KiB
Rust
58 lines
1.7 KiB
Rust
|
use std::path::Path;
|
||
|
|
||
|
use anyhow::Context;
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
|
||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||
|
pub struct JsonEditOptions {
|
||
|
pub jq: String,
|
||
|
}
|
||
|
|
||
|
impl JsonEditOptions {
|
||
|
pub fn execute(&self, path: &Path, next_version: impl AsRef<str>) -> anyhow::Result<()> {
|
||
|
let next_version = next_version.as_ref();
|
||
|
|
||
|
let jq_query = self.jq.replace("%%version%%", next_version);
|
||
|
|
||
|
if !path.exists() {
|
||
|
anyhow::bail!("could not find file at: {}", path.display());
|
||
|
}
|
||
|
|
||
|
if let Ok(metadata) = path.metadata() {
|
||
|
if !metadata.is_file() {
|
||
|
anyhow::bail!("{} is not a file", path.display());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let abs_path = path.canonicalize().context(anyhow::anyhow!(
|
||
|
"could not get absolute path from {}",
|
||
|
path.display()
|
||
|
))?;
|
||
|
|
||
|
let output = std::process::Command::new("jq")
|
||
|
.arg(format!("{}", jq_query))
|
||
|
.arg(
|
||
|
abs_path
|
||
|
.to_str()
|
||
|
.ok_or(anyhow::anyhow!("path contains non utf-8 chars"))?,
|
||
|
)
|
||
|
.output()
|
||
|
.context(anyhow::anyhow!("failed to run jq on file"))?;
|
||
|
|
||
|
if !output.status.success() {
|
||
|
let err_content = std::str::from_utf8(output.stderr.as_slice())?;
|
||
|
anyhow::bail!("failed to run jq with output: {}", err_content);
|
||
|
}
|
||
|
|
||
|
let edited_json_content = std::str::from_utf8(output.stdout.as_slice())?;
|
||
|
tracing::trace!(
|
||
|
new_content = edited_json_content,
|
||
|
file = &abs_path.display().to_string(),
|
||
|
"applied jq to file"
|
||
|
);
|
||
|
std::fs::write(abs_path, edited_json_content)?;
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|