feat(json-edit): added json-edit to update some json content with next global version
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
19e7adfedb
commit
c08918ad6f
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -520,6 +520,19 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cuddle-please-release-strategy"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"pretty_assertions",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"tempdir",
|
||||||
|
"tracing",
|
||||||
|
"tracing-test",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dagger-core"
|
name = "dagger-core"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
@ -4,6 +4,7 @@ members = [
|
|||||||
"crates/cuddle-please-frontend",
|
"crates/cuddle-please-frontend",
|
||||||
"crates/cuddle-please-commands",
|
"crates/cuddle-please-commands",
|
||||||
"crates/cuddle-please-misc",
|
"crates/cuddle-please-misc",
|
||||||
|
"crates/cuddle-please-release-strategy",
|
||||||
"ci"
|
"ci"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
@ -13,6 +14,7 @@ cuddle-please = { path = "crates/cuddle-please", version = "0.1.0" }
|
|||||||
cuddle-please-frontend = { path = "crates/cuddle-please-frontend", version = "0.1.0" }
|
cuddle-please-frontend = { path = "crates/cuddle-please-frontend", version = "0.1.0" }
|
||||||
cuddle-please-commands = { path = "crates/cuddle-please-commands", version = "0.1.0" }
|
cuddle-please-commands = { path = "crates/cuddle-please-commands", version = "0.1.0" }
|
||||||
cuddle-please-misc = { path = "crates/cuddle-please-misc", version = "0.1.0" }
|
cuddle-please-misc = { path = "crates/cuddle-please-misc", version = "0.1.0" }
|
||||||
|
cuddle-please-release-strategy = { path = "crates/cuddle-please-release-strategy", version = "0.1.0" }
|
||||||
|
|
||||||
anyhow = { version = "1.0.72" }
|
anyhow = { version = "1.0.72" }
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
tracing = { version = "0.1", features = ["log"] }
|
||||||
|
31
crates/cuddle-please-release-strategy/Cargo.toml
Normal file
31
crates/cuddle-please-release-strategy/Cargo.toml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[package]
|
||||||
|
name = "cuddle-please-release-strategy"
|
||||||
|
description = "A release-please inspired release manager tool, built on top of cuddle, but also useful standalone, cuddle-please supports, your ci of choice, as well as gitea, github"
|
||||||
|
repository = "https://git.front.kjuulh.io/kjuulh/cuddle-please"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
readme = "../../README.md"
|
||||||
|
license-file = "../../LICENSE"
|
||||||
|
publishable = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
semver.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tracing-test = { workspace = true, features = ["no-env-filter"] }
|
||||||
|
pretty_assertions.workspace = true
|
||||||
|
tempdir.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
rust-workspace = []
|
||||||
|
rust-crate = []
|
||||||
|
toml-edit = []
|
||||||
|
json-edit = []
|
||||||
|
yaml-edit = []
|
||||||
|
|
||||||
|
default = [
|
||||||
|
"json-edit"
|
||||||
|
]
|
57
crates/cuddle-please-release-strategy/src/json_edit.rs
Normal file
57
crates/cuddle-please-release-strategy/src/json_edit.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
6
crates/cuddle-please-release-strategy/src/lib.rs
Normal file
6
crates/cuddle-please-release-strategy/src/lib.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#[cfg(feature = "json-edit")]
|
||||||
|
mod json_edit;
|
||||||
|
mod strategy;
|
||||||
|
|
||||||
|
#[cfg(feature = "json-edit")]
|
||||||
|
pub use json_edit::JsonEditOptions;
|
59
crates/cuddle-please-release-strategy/src/strategy.rs
Normal file
59
crates/cuddle-please-release-strategy/src/strategy.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub struct UpdateOptions {
|
||||||
|
next_version: String,
|
||||||
|
global_changelog: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Projects = Vec<Project>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Project {
|
||||||
|
path: Option<PathBuf>,
|
||||||
|
r#type: ProjectType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ProjectType {
|
||||||
|
#[cfg(feature = "rust-workspace")]
|
||||||
|
#[serde(alias = "rust_workspace")]
|
||||||
|
RustWorkspace,
|
||||||
|
#[cfg(feature = "rust-crate")]
|
||||||
|
#[serde(alias = "json_edit")]
|
||||||
|
RustCrate,
|
||||||
|
#[cfg(feature = "toml-edit")]
|
||||||
|
#[serde(alias = "toml_edit")]
|
||||||
|
TomlEdit,
|
||||||
|
#[cfg(feature = "yaml-edit")]
|
||||||
|
#[serde(alias = "yaml_edit")]
|
||||||
|
YamlEdit,
|
||||||
|
#[cfg(feature = "json-edit")]
|
||||||
|
#[serde(alias = "json_edit")]
|
||||||
|
JsonEdit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Project {
|
||||||
|
pub fn new(path: Option<PathBuf>, r#type: ProjectType) -> Self {
|
||||||
|
Self { path, r#type }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute(&self, options: &UpdateOptions) -> anyhow::Result<()> {
|
||||||
|
match self.r#type {
|
||||||
|
#[cfg(feature = "rust-workspace")]
|
||||||
|
ProjectType::RustWorkspace => todo!(),
|
||||||
|
#[cfg(feature = "rust-crate")]
|
||||||
|
ProjectType::RustCrate => todo!(),
|
||||||
|
#[cfg(feature = "toml-edit")]
|
||||||
|
ProjectType::TomlEdit => todo!(),
|
||||||
|
#[cfg(feature = "yaml-edit")]
|
||||||
|
ProjectType::YamlEdit => todo!(),
|
||||||
|
#[cfg(feature = "json-edit")]
|
||||||
|
ProjectType::JsonEdit => todo!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
50
crates/cuddle-please-release-strategy/tests/json_edit.rs
Normal file
50
crates/cuddle-please-release-strategy/tests/json_edit.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use tracing_test::traced_test;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[traced_test]
|
||||||
|
#[cfg(feature = "json-edit")]
|
||||||
|
pub fn test_can_update_version_in_jq() {
|
||||||
|
use cuddle_please_release_strategy::JsonEditOptions;
|
||||||
|
|
||||||
|
let dir = tempdir::TempDir::new("can_update_version_in_jq").unwrap();
|
||||||
|
let dir_path = dir.path();
|
||||||
|
let json_file = dir_path.join("some-test.json");
|
||||||
|
let initial_content = r#"{
|
||||||
|
"some": {
|
||||||
|
"nested": [
|
||||||
|
{
|
||||||
|
"structure": {
|
||||||
|
"version": "v1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let expected = r#"{
|
||||||
|
"some": {
|
||||||
|
"nested": [
|
||||||
|
{
|
||||||
|
"structure": {
|
||||||
|
"version": "v1.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
std::fs::write(&json_file, initial_content).unwrap();
|
||||||
|
let actual_file = std::fs::read_to_string(&json_file).unwrap();
|
||||||
|
pretty_assertions::assert_eq!(initial_content, actual_file);
|
||||||
|
|
||||||
|
let edit_options = JsonEditOptions {
|
||||||
|
jq: r#".some.nested[].structure.version="%%version%%""#.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
edit_options.execute(&json_file, "v1.0.2").unwrap();
|
||||||
|
|
||||||
|
let actual_file = std::fs::read_to_string(&json_file).unwrap();
|
||||||
|
pretty_assertions::assert_eq!(expected, &actual_file);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user