Have our daemon apply changes to the local repository.
parent
dc56dbf80c
commit
90065a4ffe
13
README.md
13
README.md
|
@ -65,6 +65,19 @@ $ homesync pull --all
|
|||
This will load up a diff wrapper for you to ensure you make the changes you'd
|
||||
like.
|
||||
|
||||
## Known Issues
|
||||
|
||||
If using (neo)vim, the daemon watcher will stop watching a given configuration
|
||||
file after editing. Refer to [this issue](https://github.com/notify-rs/notify/issues/247)
|
||||
for more details. As a workaround, you can set the following in your `init.vim`
|
||||
file:
|
||||
|
||||
```vimscript
|
||||
backupcopy=yes
|
||||
```
|
||||
|
||||
Refer to `:h backupcopy` for details on how this works.
|
||||
|
||||
## Contribution
|
||||
|
||||
Install git hooks as follows:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{config, config::PathConfig, path, path::ResPathBuf};
|
||||
use super::{config, config::PathConfig, git, path, path::ResPathBuf};
|
||||
use git2::Repository;
|
||||
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use simplelog::{error, paris, trace, warn};
|
||||
use std::{
|
||||
|
@ -138,7 +139,7 @@ impl<'a> WatchState<'a> {
|
|||
// Daemon
|
||||
// ========================================
|
||||
|
||||
pub fn launch(mut pc: PathConfig, freq_secs: u64) -> Result<(), Box<dyn Error>> {
|
||||
pub fn launch(mut pc: PathConfig, repo: Repository, freq_secs: u64) -> Result<(), Box<dyn Error>> {
|
||||
let (poll_tx, poll_rx) = channel();
|
||||
let (watch_tx, watch_rx) = channel();
|
||||
let watch_tx1 = watch_tx.clone();
|
||||
|
@ -156,48 +157,62 @@ pub fn launch(mut pc: PathConfig, freq_secs: u64) -> Result<(), Box<dyn Error>>
|
|||
let mut state = WatchState::new(poll_tx, &mut watcher)?;
|
||||
state.update(&pc);
|
||||
loop {
|
||||
// Received paths should always be the fully resolved ones so safe to
|
||||
// compare against our current config path.
|
||||
git::apply(&pc, &repo)?;
|
||||
// Received paths should always be fully resolved.
|
||||
match watch_rx.recv() {
|
||||
Ok(DebouncedEvent::NoticeWrite(p)) => {
|
||||
trace!("NoticeWrite {}", p.display());
|
||||
trace!("NoticeWrite '{}'", p.display());
|
||||
}
|
||||
Ok(DebouncedEvent::NoticeRemove(p)) => {
|
||||
trace!("NoticeRemove {}", p.display());
|
||||
trace!("NoticeRemove '{}'", p.display());
|
||||
}
|
||||
Ok(DebouncedEvent::Create(p)) => {
|
||||
trace!("Create '{}'", p.display());
|
||||
if pc.homesync_yml == p {
|
||||
pc = config::reload(&pc)?;
|
||||
state.update(&pc);
|
||||
}
|
||||
trace!("Create {}", p.display());
|
||||
}
|
||||
Ok(DebouncedEvent::Write(p)) => {
|
||||
trace!("Write '{}'", p.display());
|
||||
if pc.homesync_yml == p {
|
||||
pc = config::reload(&pc)?;
|
||||
state.update(&pc);
|
||||
}
|
||||
trace!("Write {}", p.display());
|
||||
}
|
||||
// Do not try reloading our primary config in any of the following
|
||||
// cases since it may lead to undesired behavior. If our config has
|
||||
// e.g. been removed, let's just keep using what we have in memory
|
||||
// in the chance it may be added back.
|
||||
Ok(DebouncedEvent::Chmod(p)) => {
|
||||
trace!("Chmod {}", p.display());
|
||||
trace!("Chmod '{}'", p.display());
|
||||
}
|
||||
Ok(DebouncedEvent::Remove(p)) => {
|
||||
trace!("Remove {}", p.display());
|
||||
if pc.homesync_yml == p {
|
||||
warn!(
|
||||
"Removed primary config '{}'. Continuing to use last loaded state",
|
||||
p.display()
|
||||
);
|
||||
} else {
|
||||
trace!("Remove '{}'", p.display());
|
||||
}
|
||||
}
|
||||
Ok(DebouncedEvent::Rename(src, dst)) => {
|
||||
trace!("Rename {} {}", src.display(), dst.display())
|
||||
if pc.homesync_yml == src && pc.homesync_yml != dst {
|
||||
warn!(
|
||||
"Renamed primary config '{}'. Continuing to use last loaded state",
|
||||
src.display()
|
||||
);
|
||||
} else {
|
||||
trace!("Renamed '{}' to '{}'", src.display(), dst.display())
|
||||
}
|
||||
}
|
||||
Ok(DebouncedEvent::Rescan) => {
|
||||
trace!("Rescanning");
|
||||
}
|
||||
Ok(DebouncedEvent::Error(e, path)) => {
|
||||
warn!(
|
||||
"Error {} at {}",
|
||||
"Error {} at '{}'",
|
||||
e,
|
||||
path.unwrap_or_else(|| PathBuf::from("N/A")).display()
|
||||
);
|
||||
|
|
|
@ -16,7 +16,8 @@ pub fn run_apply(config: PathConfig) -> Result {
|
|||
}
|
||||
|
||||
pub fn run_daemon(config: PathConfig, freq_secs: u64) -> Result {
|
||||
daemon::launch(config, freq_secs)?;
|
||||
let repo = git::init(&config)?;
|
||||
daemon::launch(config, repo, freq_secs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -4,11 +4,21 @@ use simplelog;
|
|||
use simplelog::{error, paris};
|
||||
use std::{error::Error, io, path::PathBuf};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
fn log_level() -> simplelog::LevelFilter {
|
||||
simplelog::LevelFilter::Trace
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn log_level() {
|
||||
simplelog::LevelFilter::Info
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Only one logger should ever be initialized and it should be done at the
|
||||
// beginning of the program. Otherwise logs are ignored.
|
||||
simplelog::TermLogger::init(
|
||||
simplelog::LevelFilter::Info,
|
||||
log_level(),
|
||||
simplelog::Config::default(),
|
||||
simplelog::TerminalMode::Mixed,
|
||||
simplelog::ColorChoice::Auto,
|
||||
|
|
Loading…
Reference in New Issue