aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--github-suggestion/src/suggestion.rs41
-rw-r--r--src/bin/git-sugdiff.rs48
2 files changed, 89 insertions, 0 deletions
diff --git a/github-suggestion/src/suggestion.rs b/github-suggestion/src/suggestion.rs
index 367757a..3f124ce 100644
--- a/github-suggestion/src/suggestion.rs
+++ b/github-suggestion/src/suggestion.rs
@@ -16,6 +16,7 @@
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
+use std::process::Command;
use git2::{Patch, Repository};
use regex::Regex;
@@ -46,6 +47,9 @@ pub enum Error {
#[error("{0} is not valid UTF-8")]
InvalidUtf8(String),
+ #[error("unable to convert from UTF-8: {0}")]
+ FromUtf8(#[from] std::str::Utf8Error),
+
#[error("Regex error: {0}")]
Regex(#[from] regex::Error),
}
@@ -123,6 +127,43 @@ impl Suggestion {
)
}
+ pub fn diff_command(&self) -> Result<(), Error> {
+ let repo = Repository::open(".")?;
+ let commit = repo.find_commit(self.commit.parse()?)?;
+
+ let path = Path::new(&self.path);
+
+ let object = commit
+ .tree()?
+ .get_path(path)?
+ .to_object(&repo)?;
+
+ let blob = object.as_blob()
+ .ok_or_else(|| Error::GitObjectNotBlob(object.id()))?;
+
+ let blob_reader = BufReader::new(blob.content());
+ let mut new = BufWriter::new(Vec::new());
+ self.apply_to(blob_reader, &mut new)?;
+ let new_buffer = new.into_inner()
+ .map_err(|e| Error::BufWriter {
+ source: e,
+ message: "unable to read right side of patch".to_owned(),
+ })?;
+
+ let patched_blob = repo.blob(&new_buffer)?;
+
+ Command::new("git")
+ .arg("diff")
+ .arg(format!("{}:{}", commit.id(), self.path))
+ .arg(patched_blob.to_string())
+ .spawn()
+ .unwrap();
+
+ // Maybe: Return blob
+
+ Ok(())
+ }
+
/// Extract suggestion code from a comment body.
fn suggestion_with_line_ending(
&self,
diff --git a/src/bin/git-sugdiff.rs b/src/bin/git-sugdiff.rs
new file mode 100644
index 0000000..c8ecf40
--- /dev/null
+++ b/src/bin/git-sugdiff.rs
@@ -0,0 +1,48 @@
+// Copyright (c) 2020 Teddy Wing
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+
+use std::env;
+use std::process;
+
+use exitcode;
+
+use github_suggestion_cli::{gseprintln, for_suggestion};
+use github_suggestion_cli::config::Config;
+
+
+fn main() {
+ let args: Vec<_> = env::args().collect();
+
+ let config = match Config::get(
+ &args,
+ "usage: git sugpatch [options] <suggestion>...",
+ ) {
+ Ok(c) => c,
+ Err(e) => {
+ gseprintln!(e);
+
+ process::exit(exitcode::CONFIG);
+ },
+ };
+
+ for_suggestion(
+ &config,
+ |suggestion| {
+ // TODO: Needs to work for multiple suggestions at once
+ suggestion.diff_command().unwrap();
+ },
+ );
+}