mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-25 02:26:14 +03:00
add git watcher
This commit is contained in:
parent
3abded40ff
commit
1f4c96f827
@ -136,7 +136,7 @@ impl DeltaWatchers {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn unwatch(&mut self, project: projects::Project) -> Result<()> {
|
||||
pub fn unwatch(&mut self, project: &projects::Project) -> Result<()> {
|
||||
if let Some(mut watcher) = self.watchers.remove(&project.path) {
|
||||
watcher.unwatch(Path::new(&project.path))?;
|
||||
}
|
||||
|
108
src-tauri/src/watchers/git.rs
Normal file
108
src-tauri/src/watchers/git.rs
Normal file
@ -0,0 +1,108 @@
|
||||
use crate::projects;
|
||||
use anyhow::Result;
|
||||
use notify::{Config, RecommendedWatcher, Watcher};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::Path,
|
||||
sync::{mpsc, Arc, Mutex},
|
||||
};
|
||||
|
||||
pub enum Event {
|
||||
Head,
|
||||
}
|
||||
|
||||
pub struct GitWatchers {
|
||||
watchers: HashMap<String, RecommendedWatcher>,
|
||||
}
|
||||
|
||||
impl GitWatchers {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
watchers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwatch(&mut self, project: &projects::Project) -> Result<()> {
|
||||
if let Some(mut watcher) = self.watchers.remove(&project.id) {
|
||||
watcher.unwatch(&Path::new(&Path::new(&project.path).join(".git")))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn watch(&mut self, project: projects::Project) -> Result<mpsc::Receiver<Event>> {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let mut watcher = RecommendedWatcher::new(tx, Config::default())?;
|
||||
|
||||
watcher.watch(
|
||||
Path::new(&Path::new(&project.path).join(".git")),
|
||||
notify::RecursiveMode::Recursive,
|
||||
)?;
|
||||
self.watchers.insert(project.id.clone(), watcher);
|
||||
|
||||
let project = Arc::new(Mutex::new(project.clone()));
|
||||
|
||||
let (events_sender, events_receiver) = mpsc::channel();
|
||||
tauri::async_runtime::spawn_blocking(move || {
|
||||
log::info!("{}: watching git", project.lock().unwrap().id);
|
||||
|
||||
let project = project.lock().unwrap().clone();
|
||||
let project_path = Path::new(&project.path);
|
||||
|
||||
while let Ok(event) = rx.recv() {
|
||||
if let Err(e) = event {
|
||||
log::error!("{}: notify event error: {:#}", project.id.clone(), e);
|
||||
continue;
|
||||
}
|
||||
|
||||
let event = event.unwrap();
|
||||
|
||||
for file_path in event.paths {
|
||||
let relative_file_path = file_path
|
||||
.strip_prefix(Path::new(&project_path.join(".git")))
|
||||
.unwrap();
|
||||
|
||||
match is_interesting_event(&event.kind) {
|
||||
Some(kind_string) => {
|
||||
log::info!(
|
||||
"{}: \"{}\" {}",
|
||||
project.id,
|
||||
relative_file_path.display(),
|
||||
kind_string
|
||||
);
|
||||
|
||||
if relative_file_path == Path::new("HEAD") {
|
||||
if let Err(e) = events_sender.send(Event::Head) {
|
||||
log::error!("{}: failed to send event: {:#}", project.id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log::info!("{}: stopped watching git", project.id);
|
||||
});
|
||||
|
||||
Ok(events_receiver)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_interesting_event(kind: ¬ify::EventKind) -> Option<String> {
|
||||
match kind {
|
||||
notify::EventKind::Create(notify::event::CreateKind::File) => {
|
||||
Some("file created".to_string())
|
||||
}
|
||||
notify::EventKind::Modify(notify::event::ModifyKind::Data(_)) => {
|
||||
Some("file modified".to_string())
|
||||
}
|
||||
notify::EventKind::Modify(notify::event::ModifyKind::Name(_)) => {
|
||||
Some("file renamed".to_string())
|
||||
}
|
||||
notify::EventKind::Remove(notify::event::RemoveKind::File) => {
|
||||
Some("file removed".to_string())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
mod delta;
|
||||
mod git;
|
||||
mod session;
|
||||
|
||||
#[cfg(test)]
|
||||
@ -16,6 +17,7 @@ use std::{
|
||||
pub struct Watcher {
|
||||
session_watcher: session::SessionWatcher,
|
||||
delta_watcher: delta::DeltaWatchers,
|
||||
git_watcher: git::GitWatchers,
|
||||
}
|
||||
|
||||
impl Watcher {
|
||||
@ -27,9 +29,11 @@ impl Watcher {
|
||||
let session_watcher =
|
||||
session::SessionWatcher::new(projects_storage, users_storage, deltas_searcher);
|
||||
let delta_watcher = delta::DeltaWatchers::new();
|
||||
let git_watcher = git::GitWatchers::new();
|
||||
Self {
|
||||
session_watcher,
|
||||
delta_watcher,
|
||||
git_watcher,
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,12 +57,14 @@ impl Watcher {
|
||||
.watch(sender.clone(), project.clone(), lock_file.clone())?;
|
||||
self.session_watcher
|
||||
.watch(sender.clone(), project.clone(), lock_file.clone())?;
|
||||
self.git_watcher.watch(project.clone())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn unwatch(&mut self, project: projects::Project) -> Result<()> {
|
||||
self.delta_watcher.unwatch(project)?;
|
||||
self.delta_watcher.unwatch(&project)?;
|
||||
self.git_watcher.unwatch(&project)?;
|
||||
// TODO: how to unwatch session ?
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user