diff options
author | Teddy Wing | 2020-07-26 18:17:11 +0200 |
---|---|---|
committer | Teddy Wing | 2020-07-26 18:17:11 +0200 |
commit | 1d15f9739f690f2e7afbb2bf868be74044ab3f30 (patch) | |
tree | ee40d91d56c475b84424e3f3bb9b70a0f775ee7e /src/lib.rs | |
parent | ced76c1ffce4da1dfcf286b3ef358c0662f6b5a1 (diff) | |
download | git-suggestion-1d15f9739f690f2e7afbb2bf868be74044ab3f30.tar.bz2 |
Suggestion: Add `diff` method
Create a patch file for the suggestion. Instead of building the patch
text manually, as in my earlier attempts (`patch` and `unified_diff`),
apply the patch to the file in memory, and then ask libgit2 to give us a
Git patch by comparing the original blob and the patched buffer.
Doing this because I was unsuccessful in manually composing a patch file
that Git would accept. I could create unified diffs that the `patch`
program would accept, but these wouldn't work with `git-apply`. My
current guess is that these didn't work because I didn't have both
before and after context in my manually-created patch files.
Since this tool is intended to be used with Git, I want a patch file
that will work transparently with Git utilities. The easiest alternative
to manually generating the patch file seemed to be to have Git create
the patch text.
Add a new binary, `git-sugpatch`, that outputs the patch text to
standard output.
TODO: This gets the original from the current HEAD in `apply_to()`. We
should instead be using the contents of `blob`, because the original is
not necessarily the working copy.
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 40 |
1 files changed, 38 insertions, 2 deletions
@@ -8,10 +8,10 @@ pub use crate::url::SuggestionUrl; use std::fs; use std::fs::{File, OpenOptions}; -use std::io::{BufRead, BufReader, Write}; +use std::io::{BufRead, BufReader, BufWriter, Write}; use std::path::Path; -use git2::Repository; +use git2::{Patch, Repository}; use github_rs::client::{Executor, Github}; use regex::Regex; use serde::Deserialize; @@ -80,6 +80,9 @@ pub struct Suggestion { #[serde(rename = "body")] comment: String, + #[serde(rename = "original_commit_id")] + commit: String, + path: String, original_start_line: Option<usize>, @@ -89,6 +92,7 @@ pub struct Suggestion { } impl Suggestion { + // TODO: Rename to `diff` pub fn patch(&self) -> String { let mut diff: Vec<_> = self.diff.lines() .filter(|l| !l.starts_with("-")) @@ -110,6 +114,38 @@ impl Suggestion { diff.join("\n") } + pub fn diff(&self) -> String { + let repo = Repository::open(".").unwrap(); + let commit = repo.find_commit(self.commit.parse().unwrap()).unwrap(); + + let path = Path::new(&self.path); + + let object = commit + .tree().unwrap() + .get_path(path).unwrap() + .to_object(&repo).unwrap(); + + let blob = object.as_blob().unwrap(); + + let mut new = BufWriter::new(Vec::new()); + self.apply_to(&self.path, &mut new).unwrap(); + let new_buffer = new.into_inner().unwrap(); + + let mut diff = Patch::from_blob_and_buffer( + blob, + Some(&path), + &new_buffer, + Some(&path), + None, + ).unwrap(); + + diff.to_buf() + .unwrap() + .as_str() + .unwrap_or("") + .to_owned() + } + fn suggestion_patch(&self) -> String { let re = Regex::new(r"(?s).*(?-s)```\s*suggestion.*\n").unwrap(); let s = re.replace(&self.comment, "+"); |