This commit is contained in:
JMARyA 2023-11-06 09:58:08 +01:00
parent c4f493966a
commit a9269e7dd1
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
2 changed files with 97 additions and 57 deletions

24
README.md Normal file
View file

@ -0,0 +1,24 @@
# mdpatch
Patch the frontmatter of markdown files
# Usage
```
Usage: mdpatch [OPTIONS] <markdown>
Arguments:
<markdown> Markdown File
Options:
-p, --patch <PATCH> Apply JSON Patch file. If set to '-' read from stdin
--merge <FILE> Merge Markdown frontmatter. If set to '-' read from stdin
-a, --add Only patch add operations
-m, --modify Only patch modify operations
-d, --delete Only patch delete operations
-v, --verbose Print out what changes will be made to the document
-n, --dryrun Dont modify the input file. Only print what would be done
-o, --output <OUTPUT> Write patched file to output path. Dont modify the input file directly. If set to '-' output to stdout
--notest Ignore tests in JSON Patch files
-x, --exclude <JSONPATH> Exclude json path from patch
-k, --keys <JSONPATH> Only include the specified json paths in patch
```

View file

@ -183,6 +183,54 @@ fn exclude_json_by_paths(paths: &[String], json_value: &Value) -> Value {
}
}
fn explain_patch_verbose(patch: Vec<PatchOperation>) {
for op in patch {
match op {
PatchOperation::Add(op) => {
eprintln!(
"Add {} at {}",
console::Style::new().green().apply_to(op.value),
console::Style::new().bright().red().apply_to(op.path)
);
}
PatchOperation::Remove(op) => {
eprintln!(
"Remove value at {}",
console::Style::new().bright().red().apply_to(op.path)
);
}
PatchOperation::Replace(op) => {
eprintln!(
"Replace value at {} with {}",
console::Style::new().bright().red().apply_to(op.path),
console::Style::new().green().apply_to(op.value)
);
}
PatchOperation::Move(op) => {
eprintln!(
"Move value from {} to {}",
console::Style::new().bright().red().apply_to(op.from),
console::Style::new().green().apply_to(op.path)
);
}
PatchOperation::Copy(op) => {
eprintln!(
"Copy value from {} to {}",
console::Style::new().bright().red().apply_to(op.from),
console::Style::new().green().apply_to(op.path)
);
}
PatchOperation::Test(op) => {
eprintln!(
"Test value at {} for {}",
console::Style::new().bright().red().apply_to(op.path),
console::Style::new().green().apply_to(op.value)
);
}
}
}
}
fn main() {
let args = args::get_args();
@ -245,51 +293,7 @@ fn main() {
let patch: Vec<json_patch::PatchOperation> = serde_json::from_value(patch).unwrap();
if args.get_flag("verbose") | args.get_flag("dryrun") {
for op in patch.clone() {
match op {
PatchOperation::Add(op) => {
eprintln!(
"Add {} at {}",
console::Style::new().green().apply_to(op.value),
console::Style::new().bright().red().apply_to(op.path)
);
}
PatchOperation::Remove(op) => {
eprintln!(
"Remove value at {}",
console::Style::new().bright().red().apply_to(op.path)
);
}
PatchOperation::Replace(op) => {
eprintln!(
"Replace value at {} with {}",
console::Style::new().bright().red().apply_to(op.path),
console::Style::new().green().apply_to(op.value)
);
}
PatchOperation::Move(op) => {
eprintln!(
"Move value from {} to {}",
console::Style::new().bright().red().apply_to(op.from),
console::Style::new().green().apply_to(op.path)
);
}
PatchOperation::Copy(op) => {
eprintln!(
"Copy value from {} to {}",
console::Style::new().bright().red().apply_to(op.from),
console::Style::new().green().apply_to(op.path)
);
}
PatchOperation::Test(op) => {
eprintln!(
"Test value at {} for {}",
console::Style::new().bright().red().apply_to(op.path),
console::Style::new().green().apply_to(op.value)
);
}
}
}
explain_patch_verbose(patch.clone());
}
if !args.get_flag("dryrun") {
@ -317,18 +321,30 @@ fn main() {
}
} else if let Some(merge_file) = args.get_one::<String>("merge") {
// TODO : Add support for merging frontmatter from markdown file
let mut merge_doc: serde_json::Value = serde_json::from_str(
&(if merge_file == "-" {
let mut str = String::new();
std::io::stdin()
.read_to_string(&mut str)
.quit_on_error("Coult not read stdin");
str
} else {
std::fs::read_to_string(merge_file).quit_on_error("Could not read merge file")
}),
)
.quit_on_error("Could not parse merge file");
let merge_file_content = if merge_file == "-" {
let mut str = String::new();
std::io::stdin()
.read_to_string(&mut str)
.quit_on_error("Coult not read stdin");
str
} else {
std::fs::read_to_string(merge_file).quit_on_error("Could not read merge file")
};
let mut merge_doc: serde_json::Result<serde_json::Value> =
serde_json::from_str(&merge_file_content);
if merge_doc.is_err() {
let (frontmatter, _) = markdown_with_frontmatter(&merge_file_content);
let frontmatter = frontmatter
.ok_or(0)
.quit_on_error("Could not get merge file frontmatter");
let frontmatter_val: serde_yaml::Value = serde_yaml::from_str(&frontmatter)
.quit_on_error("Could not parse merge file frontmatter");
merge_doc = serde_json::to_value(frontmatter_val)
}
let mut merge_doc = merge_doc.quit_on_error("Parsing merge file failed");
if let Some(excludes) = args.get_many::<String>("exclude") {
let excludes: Vec<String> = excludes.cloned().collect();