aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2020-07-25 13:22:04 +0200
committerTeddy Wing2020-07-25 16:56:12 +0200
commitd27d99084b58d19dc76443a03a0db445cbd9bcc7 (patch)
tree2048113386296bbd676ca05f3fe324e213c384d6
parent4b3016a512f6353c2766576d2b8bce2f472ccdf3 (diff)
downloadgit-suggestion-d27d99084b58d19dc76443a03a0db445cbd9bcc7.tar.bz2
Suggestion: Try applying a change to the file (WIP)
Not working yet, but the idea is to get the file referenced by the suggestion and apply the suggested change directly to it. Here, we read the original file, and write its contents to the new file, replacing the lines modified by the suggestion with the suggested change. Currently doesn't work because you can't pass file instances to `fs::rename`, only paths. I'd like to try a slightly different system so I can keep the original file's creation date. With the current system, it would be overwritten by the new temporary file created to store the change.
-rw-r--r--Cargo.lock88
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs41
3 files changed, 130 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3cad2f3..e8b4f7f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -221,6 +221,17 @@ dependencies = [
]
[[package]]
+name = "getrandom"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
name = "gimli"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -235,6 +246,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
+ "tempfile",
"thiserror",
"unidiff",
]
@@ -669,6 +681,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
[[package]]
+name = "ppv-lite86"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
+
+[[package]]
name = "proc-macro2"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -687,6 +705,47 @@ dependencies = [
]
[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom",
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -711,6 +770,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi 0.3.9",
+]
+
+[[package]]
name = "ring"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -869,6 +937,20 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "rand",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi 0.3.9",
+]
+
+[[package]]
name = "thiserror"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1219,6 +1301,12 @@ dependencies = [
]
[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
name = "webpki"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 8fb2e65..7f5a472 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,5 +9,6 @@ github-rs = "0.7.0"
regex = "1.3.9"
serde = { version = "1.0.114", features = ["derive"] }
serde_json = "1.0.56"
+tempfile = "3.1.0"
thiserror = "1.0.20"
unidiff = "0.3.3"
diff --git a/src/lib.rs b/src/lib.rs
index e4c45c2..b368747 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,11 +1,17 @@
#![warn(rust_2018_idioms)]
+use std::fs;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+
+use git2::Repository;
use github_rs::client::{Executor, Github};
use regex::Regex;
use serde::Deserialize;
use serde_json::Value;
use thiserror::Error;
+use tempfile::tempfile;
#[derive(Debug, Error)]
@@ -61,6 +67,11 @@ pub struct Suggestion {
#[serde(rename = "body")]
suggestion: String,
+
+ path: String,
+
+ original_start_line: usize,
+ original_end_line: usize,
}
impl Suggestion {
@@ -90,6 +101,36 @@ impl Suggestion {
let s = re.replace(&self.suggestion, "+");
s.replace("```", "")
}
+
+ fn apply(&self) -> Result<(), Error> {
+ let repo = Repository::open(".").unwrap();
+ let repo_root = repo.workdir().unwrap();
+
+ let original = File::open(repo_root.join(&self.path)).unwrap();
+ let metadata = original.metadata().unwrap();
+ let created_at = metadata.created().unwrap();
+ let mut reader = BufReader::new(original);
+
+ let mut new = tempfile().unwrap();
+
+ for (i, line) in reader.lines().enumerate() {
+ match line {
+ Ok(l) => {
+ if i < self.original_start_line
+ || i > self.original_end_line {
+ writeln!(new, "{}", l).unwrap();
+ } else if i == self.original_end_line {
+ write!(new, "{}", self.suggestion()).unwrap();
+ }
+ },
+ Err(e) => panic!(e),
+ }
+ }
+
+ fs::rename(new, original).unwrap();
+
+ Ok(())
+ }
}
#[cfg(test)]