diff options
Diffstat (limited to 'pkgs/by-name/ro/rollup/src')
| -rw-r--r-- | pkgs/by-name/ro/rollup/src/main.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/pkgs/by-name/ro/rollup/src/main.rs b/pkgs/by-name/ro/rollup/src/main.rs new file mode 100644 index 00000000..8285e702 --- /dev/null +++ b/pkgs/by-name/ro/rollup/src/main.rs @@ -0,0 +1,106 @@ +use core::fmt; +use std::{path::PathBuf, process::Command}; + +use anyhow::{Context, Result}; +use clap::Parser; + +#[derive(Parser)] +struct Cli { + /// The file to pull the patch to rollup from. + patch_file: PathBuf, +} + +struct Diff { + files: Vec<FileDiff>, +} + +struct FileDiff { + from: PathBuf, + to: PathBuf, + diff: String, + index: String, +} + +impl fmt::Display for FileDiff { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!( + f, + "diff --git a/{} b/{}", + self.from.display(), + self.to.display() + )?; + writeln!(f, "--- a/{}", self.from.display())?; + writeln!(f, "+++ b/{}", self.to.display())?; + writeln!(f, "index {}", self.index)?; + writeln!(f, "{}", self.diff)?; + + Ok(()) + } +} + +macro_rules! take { + ($line:expr, $prefix:literal) => { + $line.strip_prefix($prefix).unwrap().trim() + }; +} + +fn main() -> Result<()> { + let args = Cli::parse(); + + let data = Command::new("filterdiff") + .arg(&args.patch_file) + .output() + .context("Failed to run `filterdiff` for patch analysis")?; + + let stdout = String::from_utf8(data.stdout).unwrap(); + + let mut diff = Diff { files: vec![] }; + let mut file_diff_from = None; + let mut file_diff_to = None; + let mut file_diff_diff: Option<String> = None; + let mut file_diff_index: Option<String> = None; + for (idx, line) in stdout.lines().enumerate() { + eprintln!("{}", line); + + if line.starts_with("---") { + file_diff_from = Some(PathBuf::from(take!(line, "--- a/"))); + } else if line.starts_with("+++") { + file_diff_to = Some(PathBuf::from(take!(line, "+++ b/"))); + } else if line.starts_with("index") { + file_diff_index = Some(take!(line, "index").to_owned()); + } else if line.starts_with("diff --git") { + if idx != 0 { + diff.files.push(FileDiff { + from: file_diff_from.take().unwrap(), + to: file_diff_to.take().unwrap(), + diff: file_diff_diff.take().unwrap(), + index: file_diff_index.take().unwrap(), + }); + } + } else { + match file_diff_diff.as_mut() { + Some(str) => { + str.push_str(line); + str.push('\n'); + } + None => { + let mut base = line.to_owned(); + base.push('\n'); + file_diff_diff = Some(base); + } + } + } + } + diff.files.push(FileDiff { + from: file_diff_from.unwrap(), + to: file_diff_to.unwrap(), + diff: file_diff_diff.unwrap(), + index: file_diff_index.unwrap(), + }); + + for file in diff.files { + eprintln!("{}", file) + } + + Ok(()) +} |
