From d27d99084b58d19dc76443a03a0db445cbd9bcc7 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 25 Jul 2020 13:22:04 +0200 Subject: 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. --- Cargo.lock | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/lib.rs | 41 +++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 3cad2f3..e8b4f7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,17 @@ dependencies = [ "num_cpus", ] +[[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" @@ -235,6 +246,7 @@ dependencies = [ "regex", "serde", "serde_json", + "tempfile", "thiserror", "unidiff", ] @@ -668,6 +680,12 @@ version = "0.3.18" 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" @@ -686,6 +704,47 @@ dependencies = [ "proc-macro2", ] +[[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" @@ -710,6 +769,15 @@ version = "0.6.18" 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" @@ -868,6 +936,20 @@ dependencies = [ "unicode-xid", ] +[[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" @@ -1218,6 +1300,12 @@ dependencies = [ "try-lock", ] +[[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" 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)] -- cgit v1.2.3